Whamcloud - gitweb
LU-14489 utils: fix 'lfs find --mdt-count'
[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         test_mkdir -p -c1 $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         test_mkdir $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 || "pool_add_targets failed"
2759         test_mkdir $DIR/$tdir
2760         $LFS setstripe -p $pool $DIR/$tdir
2761         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2762         $LFS getstripe $DIR/$tdir/$tfile
2763 }
2764 run_test 27I "check that root dir striping does not break parent dir one"
2765
2766 test_27J() {
2767         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2768                 skip "Need MDS version newer than 2.12.51"
2769
2770         test_mkdir $DIR/$tdir
2771         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2772         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2773
2774         # create foreign file (raw way)
2775         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2776                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2777
2778         ! $LFS setstripe --foreign --flags foo \
2779                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2780                         error "creating $tfile with '--flags foo' should fail"
2781
2782         ! $LFS setstripe --foreign --flags 0xffffffff \
2783                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2784                         error "creating $tfile w/ 0xffffffff flags should fail"
2785
2786         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2787                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2788
2789         # verify foreign file (raw way)
2790         parse_foreign_file -f $DIR/$tdir/$tfile |
2791                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2792                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2793         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2794                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2795         parse_foreign_file -f $DIR/$tdir/$tfile |
2796                 grep "lov_foreign_size: 73" ||
2797                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2798         parse_foreign_file -f $DIR/$tdir/$tfile |
2799                 grep "lov_foreign_type: 1" ||
2800                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2801         parse_foreign_file -f $DIR/$tdir/$tfile |
2802                 grep "lov_foreign_flags: 0x0000DA08" ||
2803                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2804         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2805                 grep "lov_foreign_value: 0x" |
2806                 sed -e 's/lov_foreign_value: 0x//')
2807         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2808         [[ $lov = ${lov2// /} ]] ||
2809                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2810
2811         # create foreign file (lfs + API)
2812         $LFS setstripe --foreign=none --flags 0xda08 \
2813                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2814                 error "$DIR/$tdir/${tfile}2: create failed"
2815
2816         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2817                 grep "lfm_magic:.*0x0BD70BD0" ||
2818                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2819         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2820         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2821                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2822         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2823                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2824         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2825                 grep "lfm_flags:.*0x0000DA08" ||
2826                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2827         $LFS getstripe $DIR/$tdir/${tfile}2 |
2828                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2829                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2830
2831         # modify striping should fail
2832         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2833                 error "$DIR/$tdir/$tfile: setstripe should fail"
2834         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2835                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2836
2837         # R/W should fail
2838         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2839         cat $DIR/$tdir/${tfile}2 &&
2840                 error "$DIR/$tdir/${tfile}2: read should fail"
2841         cat /etc/passwd > $DIR/$tdir/$tfile &&
2842                 error "$DIR/$tdir/$tfile: write should fail"
2843         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2844                 error "$DIR/$tdir/${tfile}2: write should fail"
2845
2846         # chmod should work
2847         chmod 222 $DIR/$tdir/$tfile ||
2848                 error "$DIR/$tdir/$tfile: chmod failed"
2849         chmod 222 $DIR/$tdir/${tfile}2 ||
2850                 error "$DIR/$tdir/${tfile}2: chmod failed"
2851
2852         # chown should work
2853         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2854                 error "$DIR/$tdir/$tfile: chown failed"
2855         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2856                 error "$DIR/$tdir/${tfile}2: chown failed"
2857
2858         # rename should work
2859         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2860                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2861         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2862                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2863
2864         #remove foreign file
2865         rm $DIR/$tdir/${tfile}.new ||
2866                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2867         rm $DIR/$tdir/${tfile}2.new ||
2868                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2869 }
2870 run_test 27J "basic ops on file with foreign LOV"
2871
2872 test_27K() {
2873         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2874                 skip "Need MDS version newer than 2.12.49"
2875
2876         test_mkdir $DIR/$tdir
2877         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2878         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2879
2880         # create foreign dir (raw way)
2881         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2882                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2883
2884         ! $LFS setdirstripe --foreign --flags foo \
2885                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2886                         error "creating $tdir with '--flags foo' should fail"
2887
2888         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2889                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2890                         error "creating $tdir w/ 0xffffffff flags should fail"
2891
2892         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2893                 error "create_foreign_dir FAILED"
2894
2895         # verify foreign dir (raw way)
2896         parse_foreign_dir -d $DIR/$tdir/$tdir |
2897                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2898                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2899         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2900                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2901         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2902                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2903         parse_foreign_dir -d $DIR/$tdir/$tdir |
2904                 grep "lmv_foreign_flags: 55813$" ||
2905                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2906         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2907                 grep "lmv_foreign_value: 0x" |
2908                 sed 's/lmv_foreign_value: 0x//')
2909         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2910                 sed 's/ //g')
2911         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2912
2913         # create foreign dir (lfs + API)
2914         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2915                 $DIR/$tdir/${tdir}2 ||
2916                 error "$DIR/$tdir/${tdir}2: create failed"
2917
2918         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2919                 grep "lfm_magic:.*0x0CD50CD0" ||
2920                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2921         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2922         # - sizeof(lfm_type) - sizeof(lfm_flags)
2923         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2924                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2925         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2926                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2927         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2928                 grep "lfm_flags:.*0x0000DA05" ||
2929                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2930         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2931                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2932                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2933
2934         # file create in dir should fail
2935         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2936         touch $DIR/$tdir/${tdir}2/$tfile &&
2937                 "$DIR/${tdir}2: file create should fail"
2938
2939         # chmod should work
2940         chmod 777 $DIR/$tdir/$tdir ||
2941                 error "$DIR/$tdir: chmod failed"
2942         chmod 777 $DIR/$tdir/${tdir}2 ||
2943                 error "$DIR/${tdir}2: chmod failed"
2944
2945         # chown should work
2946         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2947                 error "$DIR/$tdir: chown failed"
2948         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2949                 error "$DIR/${tdir}2: chown failed"
2950
2951         # rename should work
2952         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2953                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2954         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2955                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2956
2957         #remove foreign dir
2958         rmdir $DIR/$tdir/${tdir}.new ||
2959                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2960         rmdir $DIR/$tdir/${tdir}2.new ||
2961                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2962 }
2963 run_test 27K "basic ops on dir with foreign LMV"
2964
2965 test_27L() {
2966         remote_mds_nodsh && skip "remote MDS with nodsh"
2967
2968         local POOL=${POOL:-$TESTNAME}
2969
2970         pool_add $POOL || error "pool_add failed"
2971
2972         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2973                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2974                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2975 }
2976 run_test 27L "lfs pool_list gives correct pool name"
2977
2978 test_27M() {
2979         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2980                 skip "Need MDS version >= than 2.12.57"
2981         remote_mds_nodsh && skip "remote MDS with nodsh"
2982         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2983
2984         test_mkdir $DIR/$tdir
2985
2986         # Set default striping on directory
2987         $LFS setstripe -C 4 $DIR/$tdir
2988
2989         echo 1 > $DIR/$tdir/${tfile}.1
2990         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2991         local setcount=4
2992         [ $count -eq $setcount ] ||
2993                 error "(1) stripe count $count, should be $setcount"
2994
2995         # Capture existing append_stripe_count setting for restore
2996         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2997         local mdts=$(comma_list $(mdts_nodes))
2998         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2999
3000         local appendcount=$orig_count
3001         echo 1 >> $DIR/$tdir/${tfile}.2_append
3002         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3003         [ $count -eq $appendcount ] ||
3004                 error "(2)stripe count $count, should be $appendcount for append"
3005
3006         # Disable O_APPEND striping, verify it works
3007         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3008
3009         # Should now get the default striping, which is 4
3010         setcount=4
3011         echo 1 >> $DIR/$tdir/${tfile}.3_append
3012         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3013         [ $count -eq $setcount ] ||
3014                 error "(3) stripe count $count, should be $setcount"
3015
3016         # Try changing the stripe count for append files
3017         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3018
3019         # Append striping is now 2 (directory default is still 4)
3020         appendcount=2
3021         echo 1 >> $DIR/$tdir/${tfile}.4_append
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3023         [ $count -eq $appendcount ] ||
3024                 error "(4) stripe count $count, should be $appendcount for append"
3025
3026         # Test append stripe count of -1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3028         appendcount=$OSTCOUNT
3029         echo 1 >> $DIR/$tdir/${tfile}.5
3030         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3031         [ $count -eq $appendcount ] ||
3032                 error "(5) stripe count $count, should be $appendcount for append"
3033
3034         # Set append striping back to default of 1
3035         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3036
3037         # Try a new default striping, PFL + DOM
3038         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3039
3040         # Create normal DOM file, DOM returns stripe count == 0
3041         setcount=0
3042         touch $DIR/$tdir/${tfile}.6
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3044         [ $count -eq $setcount ] ||
3045                 error "(6) stripe count $count, should be $setcount"
3046
3047         # Show
3048         appendcount=1
3049         echo 1 >> $DIR/$tdir/${tfile}.7_append
3050         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3051         [ $count -eq $appendcount ] ||
3052                 error "(7) stripe count $count, should be $appendcount for append"
3053
3054         # Clean up DOM layout
3055         $LFS setstripe -d $DIR/$tdir
3056
3057         # Now test that append striping works when layout is from root
3058         $LFS setstripe -c 2 $MOUNT
3059         # Make a special directory for this
3060         mkdir $DIR/${tdir}/${tdir}.2
3061         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3062
3063         # Verify for normal file
3064         setcount=2
3065         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3066         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3067         [ $count -eq $setcount ] ||
3068                 error "(8) stripe count $count, should be $setcount"
3069
3070         appendcount=1
3071         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3072         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3073         [ $count -eq $appendcount ] ||
3074                 error "(9) stripe count $count, should be $appendcount for append"
3075
3076         # Now test O_APPEND striping with pools
3077         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3078         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3079
3080         # Create the pool
3081         pool_add $TESTNAME || error "pool creation failed"
3082         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3083
3084         echo 1 >> $DIR/$tdir/${tfile}.10_append
3085
3086         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3087         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3088
3089         # Check that count is still correct
3090         appendcount=1
3091         echo 1 >> $DIR/$tdir/${tfile}.11_append
3092         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3093         [ $count -eq $appendcount ] ||
3094                 error "(11) stripe count $count, should be $appendcount for append"
3095
3096         # Disable O_APPEND stripe count, verify pool works separately
3097         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3098
3099         echo 1 >> $DIR/$tdir/${tfile}.12_append
3100
3101         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3102         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3103
3104         # Remove pool setting, verify it's not applied
3105         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.13_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3110         [ "$pool" = "" ] || error "(13) pool found: $pool"
3111 }
3112 run_test 27M "test O_APPEND striping"
3113
3114 test_27N() {
3115         combined_mgs_mds && skip "needs separate MGS/MDT"
3116
3117         pool_add $TESTNAME || error "pool_add failed"
3118         do_facet mgs "$LCTL pool_list $FSNAME" |
3119                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3120                 error "lctl pool_list on MGS failed"
3121 }
3122 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3123
3124 clean_foreign_symlink() {
3125         trap 0
3126         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3127         for i in $DIR/$tdir/* ; do
3128                 $LFS unlink_foreign $i || true
3129         done
3130 }
3131
3132 test_27O() {
3133         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3134                 skip "Need MDS version newer than 2.12.51"
3135
3136         test_mkdir $DIR/$tdir
3137         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3138         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3139
3140         trap clean_foreign_symlink EXIT
3141
3142         # enable foreign_symlink behaviour
3143         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3144
3145         # foreign symlink LOV format is a partial path by default
3146
3147         # create foreign file (lfs + API)
3148         $LFS setstripe --foreign=symlink --flags 0xda05 \
3149                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3150                 error "$DIR/$tdir/${tfile}: create failed"
3151
3152         $LFS getstripe -v $DIR/$tdir/${tfile} |
3153                 grep "lfm_magic:.*0x0BD70BD0" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3155         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3156                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3157         $LFS getstripe -v $DIR/$tdir/${tfile} |
3158                 grep "lfm_flags:.*0x0000DA05" ||
3159                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3160         $LFS getstripe $DIR/$tdir/${tfile} |
3161                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3163
3164         # modify striping should fail
3165         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3166                 error "$DIR/$tdir/$tfile: setstripe should fail"
3167
3168         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3169         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3170         cat /etc/passwd > $DIR/$tdir/$tfile &&
3171                 error "$DIR/$tdir/$tfile: write should fail"
3172
3173         # rename should succeed
3174         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3175                 error "$DIR/$tdir/$tfile: rename has failed"
3176
3177         #remove foreign_symlink file should fail
3178         rm $DIR/$tdir/${tfile}.new &&
3179                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3180
3181         #test fake symlink
3182         mkdir /tmp/${uuid1} ||
3183                 error "/tmp/${uuid1}: mkdir has failed"
3184         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3185                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3186         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3187         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3188                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3189         #read should succeed now
3190         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3191                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3192         #write should succeed now
3193         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3195         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3197         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3198                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3199
3200         #check that getstripe still works
3201         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3203
3204         # chmod should still succeed
3205         chmod 644 $DIR/$tdir/${tfile}.new ||
3206                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3207
3208         # chown should still succeed
3209         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3211
3212         # rename should still succeed
3213         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3214                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3215
3216         #remove foreign_symlink file should still fail
3217         rm $DIR/$tdir/${tfile} &&
3218                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3219
3220         #use special ioctl() to unlink foreign_symlink file
3221         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3222                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3223
3224 }
3225 run_test 27O "basic ops on foreign file of symlink type"
3226
3227 test_27P() {
3228         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3229                 skip "Need MDS version newer than 2.12.49"
3230
3231         test_mkdir $DIR/$tdir
3232         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3233         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3234
3235         trap clean_foreign_symlink EXIT
3236
3237         # enable foreign_symlink behaviour
3238         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3239
3240         # foreign symlink LMV format is a partial path by default
3241
3242         # create foreign dir (lfs + API)
3243         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3244                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3245                 error "$DIR/$tdir/${tdir}: create failed"
3246
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3248                 grep "lfm_magic:.*0x0CD50CD0" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3250         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3251                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3252         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3253                 grep "lfm_flags:.*0x0000DA05" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3255         $LFS getdirstripe $DIR/$tdir/${tdir} |
3256                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3258
3259         # file create in dir should fail
3260         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3261         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3262
3263         # rename should succeed
3264         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3265                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3266
3267         #remove foreign_symlink dir should fail
3268         rmdir $DIR/$tdir/${tdir}.new &&
3269                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3270
3271         #test fake symlink
3272         mkdir -p /tmp/${uuid1}/${uuid2} ||
3273                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3274         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3275                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3276         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3277         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3278                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3279         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3280                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3281
3282         #check that getstripe fails now that foreign_symlink enabled
3283         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3284                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3285
3286         # file create in dir should work now
3287         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3288                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3289         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3290                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3291         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3292                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3293
3294         # chmod should still succeed
3295         chmod 755 $DIR/$tdir/${tdir}.new ||
3296                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3297
3298         # chown should still succeed
3299         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3300                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3301
3302         # rename should still succeed
3303         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3305
3306         #remove foreign_symlink dir should still fail
3307         rmdir $DIR/$tdir/${tdir} &&
3308                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3309
3310         #use special ioctl() to unlink foreign_symlink file
3311         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3312                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3313
3314         #created file should still exist
3315         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3316                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3317         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3318                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3319 }
3320 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3321
3322 test_27Q() {
3323         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3324         stack_trap "rm -f $TMP/$tfile*"
3325
3326         test_mkdir $DIR/$tdir-1
3327         test_mkdir $DIR/$tdir-2
3328
3329         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3330         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3331
3332         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3333         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3334
3335         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3336         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3337
3338         # Create some bad symlinks and ensure that we don't loop
3339         # forever or something. These should return ELOOP (40) and
3340         # ENOENT (2) but I don't want to test for that because there's
3341         # always some weirdo architecture that needs to ruin
3342         # everything by defining these error numbers differently.
3343
3344         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3345         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3346
3347         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3348         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3349
3350         return 0
3351 }
3352 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3353
3354 # createtest also checks that device nodes are created and
3355 # then visible correctly (#2091)
3356 test_28() { # bug 2091
3357         test_mkdir $DIR/d28
3358         $CREATETEST $DIR/d28/ct || error "createtest failed"
3359 }
3360 run_test 28 "create/mknod/mkdir with bad file types ============"
3361
3362 test_29() {
3363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3364
3365         sync; sleep 1; sync # flush out any dirty pages from previous tests
3366         cancel_lru_locks
3367         test_mkdir $DIR/d29
3368         touch $DIR/d29/foo
3369         log 'first d29'
3370         ls -l $DIR/d29
3371
3372         declare -i LOCKCOUNTORIG=0
3373         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3374                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3375         done
3376         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3377
3378         declare -i LOCKUNUSEDCOUNTORIG=0
3379         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3380                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3381         done
3382
3383         log 'second d29'
3384         ls -l $DIR/d29
3385         log 'done'
3386
3387         declare -i LOCKCOUNTCURRENT=0
3388         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3389                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3390         done
3391
3392         declare -i LOCKUNUSEDCOUNTCURRENT=0
3393         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3394                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3395         done
3396
3397         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3398                 $LCTL set_param -n ldlm.dump_namespaces ""
3399                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3400                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3401                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3402                 return 2
3403         fi
3404         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3405                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3406                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3407                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3408                 return 3
3409         fi
3410 }
3411 run_test 29 "IT_GETATTR regression  ============================"
3412
3413 test_30a() { # was test_30
3414         cp $(which ls) $DIR || cp /bin/ls $DIR
3415         $DIR/ls / || error "Can't execute binary from lustre"
3416         rm $DIR/ls
3417 }
3418 run_test 30a "execute binary from Lustre (execve) =============="
3419
3420 test_30b() {
3421         cp `which ls` $DIR || cp /bin/ls $DIR
3422         chmod go+rx $DIR/ls
3423         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3424         rm $DIR/ls
3425 }
3426 run_test 30b "execute binary from Lustre as non-root ==========="
3427
3428 test_30c() { # b=22376
3429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3430
3431         cp $(which ls) $DIR || cp /bin/ls $DIR
3432         chmod a-rw $DIR/ls
3433         cancel_lru_locks mdc
3434         cancel_lru_locks osc
3435         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3436         rm -f $DIR/ls
3437 }
3438 run_test 30c "execute binary from Lustre without read perms ===="
3439
3440 test_30d() {
3441         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3442
3443         for i in {1..10}; do
3444                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3445                 local PID=$!
3446                 sleep 1
3447                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3448                 wait $PID || error "executing dd from Lustre failed"
3449                 rm -f $DIR/$tfile
3450         done
3451
3452         rm -f $DIR/dd
3453 }
3454 run_test 30d "execute binary from Lustre while clear locks"
3455
3456 test_31a() {
3457         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3458         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3459 }
3460 run_test 31a "open-unlink file =================================="
3461
3462 test_31b() {
3463         touch $DIR/f31 || error "touch $DIR/f31 failed"
3464         ln $DIR/f31 $DIR/f31b || error "ln failed"
3465         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3466         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3467 }
3468 run_test 31b "unlink file with multiple links while open ======="
3469
3470 test_31c() {
3471         touch $DIR/f31 || error "touch $DIR/f31 failed"
3472         ln $DIR/f31 $DIR/f31c || error "ln failed"
3473         multiop_bg_pause $DIR/f31 O_uc ||
3474                 error "multiop_bg_pause for $DIR/f31 failed"
3475         MULTIPID=$!
3476         $MULTIOP $DIR/f31c Ouc
3477         kill -USR1 $MULTIPID
3478         wait $MULTIPID
3479 }
3480 run_test 31c "open-unlink file with multiple links ============="
3481
3482 test_31d() {
3483         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3484         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3485 }
3486 run_test 31d "remove of open directory ========================="
3487
3488 test_31e() { # bug 2904
3489         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3490 }
3491 run_test 31e "remove of open non-empty directory ==============="
3492
3493 test_31f() { # bug 4554
3494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3495
3496         set -vx
3497         test_mkdir $DIR/d31f
3498         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3499         cp /etc/hosts $DIR/d31f
3500         ls -l $DIR/d31f
3501         $LFS getstripe $DIR/d31f/hosts
3502         multiop_bg_pause $DIR/d31f D_c || return 1
3503         MULTIPID=$!
3504
3505         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3506         test_mkdir $DIR/d31f
3507         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3508         cp /etc/hosts $DIR/d31f
3509         ls -l $DIR/d31f
3510         $LFS getstripe $DIR/d31f/hosts
3511         multiop_bg_pause $DIR/d31f D_c || return 1
3512         MULTIPID2=$!
3513
3514         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3515         wait $MULTIPID || error "first opendir $MULTIPID failed"
3516
3517         sleep 6
3518
3519         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3520         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3521         set +vx
3522 }
3523 run_test 31f "remove of open directory with open-unlink file ==="
3524
3525 test_31g() {
3526         echo "-- cross directory link --"
3527         test_mkdir -c1 $DIR/${tdir}ga
3528         test_mkdir -c1 $DIR/${tdir}gb
3529         touch $DIR/${tdir}ga/f
3530         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3531         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3532         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3533         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3534         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3535 }
3536 run_test 31g "cross directory link==============="
3537
3538 test_31h() {
3539         echo "-- cross directory link --"
3540         test_mkdir -c1 $DIR/${tdir}
3541         test_mkdir -c1 $DIR/${tdir}/dir
3542         touch $DIR/${tdir}/f
3543         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3544         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3545         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3546         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3547         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3548 }
3549 run_test 31h "cross directory link under child==============="
3550
3551 test_31i() {
3552         echo "-- cross directory link --"
3553         test_mkdir -c1 $DIR/$tdir
3554         test_mkdir -c1 $DIR/$tdir/dir
3555         touch $DIR/$tdir/dir/f
3556         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3557         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3558         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3559         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3560         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3561 }
3562 run_test 31i "cross directory link under parent==============="
3563
3564 test_31j() {
3565         test_mkdir -c1 -p $DIR/$tdir
3566         test_mkdir -c1 -p $DIR/$tdir/dir1
3567         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3568         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3569         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3570         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3571         return 0
3572 }
3573 run_test 31j "link for directory==============="
3574
3575 test_31k() {
3576         test_mkdir -c1 -p $DIR/$tdir
3577         touch $DIR/$tdir/s
3578         touch $DIR/$tdir/exist
3579         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3580         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3581         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3582         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3583         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3584         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3585         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3586         return 0
3587 }
3588 run_test 31k "link to file: the same, non-existing, dir==============="
3589
3590 test_31m() {
3591         mkdir $DIR/d31m
3592         touch $DIR/d31m/s
3593         mkdir $DIR/d31m2
3594         touch $DIR/d31m2/exist
3595         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3596         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3597         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3598         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3599         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3600         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3601         return 0
3602 }
3603 run_test 31m "link to file: the same, non-existing, dir==============="
3604
3605 test_31n() {
3606         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3607         nlink=$(stat --format=%h $DIR/$tfile)
3608         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3609         local fd=$(free_fd)
3610         local cmd="exec $fd<$DIR/$tfile"
3611         eval $cmd
3612         cmd="exec $fd<&-"
3613         trap "eval $cmd" EXIT
3614         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3615         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3616         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3617         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3618         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3619         eval $cmd
3620 }
3621 run_test 31n "check link count of unlinked file"
3622
3623 link_one() {
3624         local tempfile=$(mktemp $1_XXXXXX)
3625         mlink $tempfile $1 2> /dev/null &&
3626                 echo "$BASHPID: link $tempfile to $1 succeeded"
3627         munlink $tempfile
3628 }
3629
3630 test_31o() { # LU-2901
3631         test_mkdir $DIR/$tdir
3632         for LOOP in $(seq 100); do
3633                 rm -f $DIR/$tdir/$tfile*
3634                 for THREAD in $(seq 8); do
3635                         link_one $DIR/$tdir/$tfile.$LOOP &
3636                 done
3637                 wait
3638                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3639                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3640                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3641                         break || true
3642         done
3643 }
3644 run_test 31o "duplicate hard links with same filename"
3645
3646 test_31p() {
3647         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3648
3649         test_mkdir $DIR/$tdir
3650         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3651         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3652
3653         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3654                 error "open unlink test1 failed"
3655         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3656                 error "open unlink test2 failed"
3657
3658         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3659                 error "test1 still exists"
3660         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3661                 error "test2 still exists"
3662 }
3663 run_test 31p "remove of open striped directory"
3664
3665 test_31q() {
3666         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3667
3668         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3669         index=$($LFS getdirstripe -i $DIR/$tdir)
3670         [ $index -eq 3 ] || error "first stripe index $index != 3"
3671         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3672         [ $index -eq 1 ] || error "second stripe index $index != 1"
3673
3674         # when "-c <stripe_count>" is set, the number of MDTs specified after
3675         # "-i" should equal to the stripe count
3676         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3677 }
3678 run_test 31q "create striped directory on specific MDTs"
3679
3680 cleanup_test32_mount() {
3681         local rc=0
3682         trap 0
3683         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3684         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3685         losetup -d $loopdev || true
3686         rm -rf $DIR/$tdir
3687         return $rc
3688 }
3689
3690 test_32a() {
3691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3692
3693         echo "== more mountpoints and symlinks ================="
3694         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3695         trap cleanup_test32_mount EXIT
3696         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3697         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3698                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3699         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3700                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3701         cleanup_test32_mount
3702 }
3703 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3704
3705 test_32b() {
3706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3707
3708         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3709         trap cleanup_test32_mount EXIT
3710         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3711         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3712                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3713         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3714                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3715         cleanup_test32_mount
3716 }
3717 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3718
3719 test_32c() {
3720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3721
3722         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3723         trap cleanup_test32_mount EXIT
3724         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3725         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3726                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3727         test_mkdir -p $DIR/$tdir/d2/test_dir
3728         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3729                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3730         cleanup_test32_mount
3731 }
3732 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3733
3734 test_32d() {
3735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3736
3737         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3738         trap cleanup_test32_mount EXIT
3739         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3740         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3741                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3742         test_mkdir -p $DIR/$tdir/d2/test_dir
3743         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3744                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3745         cleanup_test32_mount
3746 }
3747 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3748
3749 test_32e() {
3750         rm -fr $DIR/$tdir
3751         test_mkdir -p $DIR/$tdir/tmp
3752         local tmp_dir=$DIR/$tdir/tmp
3753         ln -s $DIR/$tdir $tmp_dir/symlink11
3754         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3755         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3756         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3757 }
3758 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3759
3760 test_32f() {
3761         rm -fr $DIR/$tdir
3762         test_mkdir -p $DIR/$tdir/tmp
3763         local tmp_dir=$DIR/$tdir/tmp
3764         ln -s $DIR/$tdir $tmp_dir/symlink11
3765         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3766         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3767         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3768 }
3769 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3770
3771 test_32g() {
3772         local tmp_dir=$DIR/$tdir/tmp
3773         test_mkdir -p $tmp_dir
3774         test_mkdir $DIR/${tdir}2
3775         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3776         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3777         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3778         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3779         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3780         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3781 }
3782 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3783
3784 test_32h() {
3785         rm -fr $DIR/$tdir $DIR/${tdir}2
3786         tmp_dir=$DIR/$tdir/tmp
3787         test_mkdir -p $tmp_dir
3788         test_mkdir $DIR/${tdir}2
3789         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3790         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3791         ls $tmp_dir/symlink12 || error "listing symlink12"
3792         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3793 }
3794 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3795
3796 test_32i() {
3797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3798
3799         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3800         trap cleanup_test32_mount EXIT
3801         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3802         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3803                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3804         touch $DIR/$tdir/test_file
3805         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3806                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3807         cleanup_test32_mount
3808 }
3809 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3810
3811 test_32j() {
3812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3813
3814         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3815         trap cleanup_test32_mount EXIT
3816         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3817         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3818                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3819         touch $DIR/$tdir/test_file
3820         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3821                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3822         cleanup_test32_mount
3823 }
3824 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3825
3826 test_32k() {
3827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3828
3829         rm -fr $DIR/$tdir
3830         trap cleanup_test32_mount EXIT
3831         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3832         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3833                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3834         test_mkdir -p $DIR/$tdir/d2
3835         touch $DIR/$tdir/d2/test_file || error "touch failed"
3836         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3837                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3838         cleanup_test32_mount
3839 }
3840 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3841
3842 test_32l() {
3843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3844
3845         rm -fr $DIR/$tdir
3846         trap cleanup_test32_mount EXIT
3847         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3848         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3849                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3850         test_mkdir -p $DIR/$tdir/d2
3851         touch $DIR/$tdir/d2/test_file || error "touch failed"
3852         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3853                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3854         cleanup_test32_mount
3855 }
3856 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3857
3858 test_32m() {
3859         rm -fr $DIR/d32m
3860         test_mkdir -p $DIR/d32m/tmp
3861         TMP_DIR=$DIR/d32m/tmp
3862         ln -s $DIR $TMP_DIR/symlink11
3863         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3864         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3865                 error "symlink11 not a link"
3866         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3867                 error "symlink01 not a link"
3868 }
3869 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3870
3871 test_32n() {
3872         rm -fr $DIR/d32n
3873         test_mkdir -p $DIR/d32n/tmp
3874         TMP_DIR=$DIR/d32n/tmp
3875         ln -s $DIR $TMP_DIR/symlink11
3876         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3877         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3878         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3879 }
3880 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3881
3882 test_32o() {
3883         touch $DIR/$tfile
3884         test_mkdir -p $DIR/d32o/tmp
3885         TMP_DIR=$DIR/d32o/tmp
3886         ln -s $DIR/$tfile $TMP_DIR/symlink12
3887         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3888         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3889                 error "symlink12 not a link"
3890         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3891         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3892                 error "$DIR/d32o/tmp/symlink12 not file type"
3893         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3894                 error "$DIR/d32o/symlink02 not file type"
3895 }
3896 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3897
3898 test_32p() {
3899         log 32p_1
3900         rm -fr $DIR/d32p
3901         log 32p_2
3902         rm -f $DIR/$tfile
3903         log 32p_3
3904         touch $DIR/$tfile
3905         log 32p_4
3906         test_mkdir -p $DIR/d32p/tmp
3907         log 32p_5
3908         TMP_DIR=$DIR/d32p/tmp
3909         log 32p_6
3910         ln -s $DIR/$tfile $TMP_DIR/symlink12
3911         log 32p_7
3912         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3913         log 32p_8
3914         cat $DIR/d32p/tmp/symlink12 ||
3915                 error "Can't open $DIR/d32p/tmp/symlink12"
3916         log 32p_9
3917         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3918         log 32p_10
3919 }
3920 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3921
3922 test_32q() {
3923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3924
3925         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3926         trap cleanup_test32_mount EXIT
3927         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3928         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3929         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3930                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3931         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3932         cleanup_test32_mount
3933 }
3934 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3935
3936 test_32r() {
3937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3938
3939         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3940         trap cleanup_test32_mount EXIT
3941         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3942         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3943         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3944                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3945         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3946         cleanup_test32_mount
3947 }
3948 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3949
3950 test_33aa() {
3951         rm -f $DIR/$tfile
3952         touch $DIR/$tfile
3953         chmod 444 $DIR/$tfile
3954         chown $RUNAS_ID $DIR/$tfile
3955         log 33_1
3956         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3957         log 33_2
3958 }
3959 run_test 33aa "write file with mode 444 (should return error)"
3960
3961 test_33a() {
3962         rm -fr $DIR/$tdir
3963         test_mkdir $DIR/$tdir
3964         chown $RUNAS_ID $DIR/$tdir
3965         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3966                 error "$RUNAS create $tdir/$tfile failed"
3967         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3968                 error "open RDWR" || true
3969 }
3970 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3971
3972 test_33b() {
3973         rm -fr $DIR/$tdir
3974         test_mkdir $DIR/$tdir
3975         chown $RUNAS_ID $DIR/$tdir
3976         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3977 }
3978 run_test 33b "test open file with malformed flags (No panic)"
3979
3980 test_33c() {
3981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3982         remote_ost_nodsh && skip "remote OST with nodsh"
3983
3984         local ostnum
3985         local ostname
3986         local write_bytes
3987         local all_zeros
3988
3989         all_zeros=true
3990         test_mkdir $DIR/$tdir
3991         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3992
3993         sync
3994         for ostnum in $(seq $OSTCOUNT); do
3995                 # test-framework's OST numbering is one-based, while Lustre's
3996                 # is zero-based
3997                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3998                 # check if at least some write_bytes stats are counted
3999                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4000                               obdfilter.$ostname.stats |
4001                               awk '/^write_bytes/ {print $7}' )
4002                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4003                 if (( ${write_bytes:-0} > 0 )); then
4004                         all_zeros=false
4005                         break
4006                 fi
4007         done
4008
4009         $all_zeros || return 0
4010
4011         # Write four bytes
4012         echo foo > $DIR/$tdir/bar
4013         # Really write them
4014         sync
4015
4016         # Total up write_bytes after writing.  We'd better find non-zeros.
4017         for ostnum in $(seq $OSTCOUNT); do
4018                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4019                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4020                               obdfilter/$ostname/stats |
4021                               awk '/^write_bytes/ {print $7}' )
4022                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4023                 if (( ${write_bytes:-0} > 0 )); then
4024                         all_zeros=false
4025                         break
4026                 fi
4027         done
4028
4029         if $all_zeros; then
4030                 for ostnum in $(seq $OSTCOUNT); do
4031                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4032                         echo "Check write_bytes is in obdfilter.*.stats:"
4033                         do_facet ost$ostnum lctl get_param -n \
4034                                 obdfilter.$ostname.stats
4035                 done
4036                 error "OST not keeping write_bytes stats (b=22312)"
4037         fi
4038 }
4039 run_test 33c "test write_bytes stats"
4040
4041 test_33d() {
4042         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4044
4045         local MDTIDX=1
4046         local remote_dir=$DIR/$tdir/remote_dir
4047
4048         test_mkdir $DIR/$tdir
4049         $LFS mkdir -i $MDTIDX $remote_dir ||
4050                 error "create remote directory failed"
4051
4052         touch $remote_dir/$tfile
4053         chmod 444 $remote_dir/$tfile
4054         chown $RUNAS_ID $remote_dir/$tfile
4055
4056         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4057
4058         chown $RUNAS_ID $remote_dir
4059         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4060                                         error "create" || true
4061         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4062                                     error "open RDWR" || true
4063         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4064 }
4065 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4066
4067 test_33e() {
4068         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4069
4070         mkdir $DIR/$tdir
4071
4072         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4073         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4074         mkdir $DIR/$tdir/local_dir
4075
4076         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4077         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4078         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4079
4080         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4081                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4082
4083         rmdir $DIR/$tdir/* || error "rmdir failed"
4084
4085         umask 777
4086         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4087         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4088         mkdir $DIR/$tdir/local_dir
4089
4090         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4091         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4092         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4093
4094         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4095                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4096
4097         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4098
4099         umask 000
4100         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4101         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4102         mkdir $DIR/$tdir/local_dir
4103
4104         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4105         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4106         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4107
4108         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4109                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4110 }
4111 run_test 33e "mkdir and striped directory should have same mode"
4112
4113 cleanup_33f() {
4114         trap 0
4115         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4116 }
4117
4118 test_33f() {
4119         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4120         remote_mds_nodsh && skip "remote MDS with nodsh"
4121
4122         mkdir $DIR/$tdir
4123         chmod go+rwx $DIR/$tdir
4124         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4125         trap cleanup_33f EXIT
4126
4127         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4128                 error "cannot create striped directory"
4129
4130         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4131                 error "cannot create files in striped directory"
4132
4133         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4134                 error "cannot remove files in striped directory"
4135
4136         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4137                 error "cannot remove striped directory"
4138
4139         cleanup_33f
4140 }
4141 run_test 33f "nonroot user can create, access, and remove a striped directory"
4142
4143 test_33g() {
4144         mkdir -p $DIR/$tdir/dir2
4145
4146         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4147         echo $err
4148         [[ $err =~ "exists" ]] || error "Not exists error"
4149 }
4150 run_test 33g "nonroot user create already existing root created file"
4151
4152 test_33h() {
4153         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4154         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4155                 skip "Need MDS version at least 2.13.50"
4156
4157         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4158                 error "mkdir $tdir failed"
4159         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4160
4161         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4162         local index2
4163
4164         for fname in $DIR/$tdir/$tfile.bak \
4165                      $DIR/$tdir/$tfile.SAV \
4166                      $DIR/$tdir/$tfile.orig \
4167                      $DIR/$tdir/$tfile~; do
4168                 touch $fname  || error "touch $fname failed"
4169                 index2=$($LFS getstripe -m $fname)
4170                 [ $index -eq $index2 ] ||
4171                         error "$fname MDT index mismatch $index != $index2"
4172         done
4173
4174         local failed=0
4175         for i in {1..250}; do
4176                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4177                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4178                         touch $fname  || error "touch $fname failed"
4179                         index2=$($LFS getstripe -m $fname)
4180                         if [[ $index != $index2 ]]; then
4181                                 failed=$((failed + 1))
4182                                 echo "$fname MDT index mismatch $index != $index2"
4183                         fi
4184                 done
4185         done
4186         echo "$failed MDT index mismatches"
4187         (( failed < 20 )) || error "MDT index mismatch $failed times"
4188
4189 }
4190 run_test 33h "temp file is located on the same MDT as target"
4191
4192 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4193 test_34a() {
4194         rm -f $DIR/f34
4195         $MCREATE $DIR/f34 || error "mcreate failed"
4196         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4197                 error "getstripe failed"
4198         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4199         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4200                 error "getstripe failed"
4201         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4202                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4203 }
4204 run_test 34a "truncate file that has not been opened ==========="
4205
4206 test_34b() {
4207         [ ! -f $DIR/f34 ] && test_34a
4208         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4209                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4210         $OPENFILE -f O_RDONLY $DIR/f34
4211         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4212                 error "getstripe failed"
4213         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4214                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4215 }
4216 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4217
4218 test_34c() {
4219         [ ! -f $DIR/f34 ] && test_34a
4220         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4221                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4222         $OPENFILE -f O_RDWR $DIR/f34
4223         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4224                 error "$LFS getstripe failed"
4225         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4226                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4227 }
4228 run_test 34c "O_RDWR opening file-with-size works =============="
4229
4230 test_34d() {
4231         [ ! -f $DIR/f34 ] && test_34a
4232         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4233                 error "dd failed"
4234         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4235                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4236         rm $DIR/f34
4237 }
4238 run_test 34d "write to sparse file ============================="
4239
4240 test_34e() {
4241         rm -f $DIR/f34e
4242         $MCREATE $DIR/f34e || error "mcreate failed"
4243         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4244         $CHECKSTAT -s 1000 $DIR/f34e ||
4245                 error "Size of $DIR/f34e not equal to 1000 bytes"
4246         $OPENFILE -f O_RDWR $DIR/f34e
4247         $CHECKSTAT -s 1000 $DIR/f34e ||
4248                 error "Size of $DIR/f34e not equal to 1000 bytes"
4249 }
4250 run_test 34e "create objects, some with size and some without =="
4251
4252 test_34f() { # bug 6242, 6243
4253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4254
4255         SIZE34F=48000
4256         rm -f $DIR/f34f
4257         $MCREATE $DIR/f34f || error "mcreate failed"
4258         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4259         dd if=$DIR/f34f of=$TMP/f34f
4260         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4261         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4262         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4263         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4264         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4265 }
4266 run_test 34f "read from a file with no objects until EOF ======="
4267
4268 test_34g() {
4269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4270
4271         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4272                 error "dd failed"
4273         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4274         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4275                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4276         cancel_lru_locks osc
4277         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4278                 error "wrong size after lock cancel"
4279
4280         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4281         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4282                 error "expanding truncate failed"
4283         cancel_lru_locks osc
4284         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4285                 error "wrong expanded size after lock cancel"
4286 }
4287 run_test 34g "truncate long file ==============================="
4288
4289 test_34h() {
4290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4291
4292         local gid=10
4293         local sz=1000
4294
4295         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4296         sync # Flush the cache so that multiop below does not block on cache
4297              # flush when getting the group lock
4298         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4299         MULTIPID=$!
4300
4301         # Since just timed wait is not good enough, let's do a sync write
4302         # that way we are sure enough time for a roundtrip + processing
4303         # passed + 2 seconds of extra margin.
4304         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4305         rm $DIR/${tfile}-1
4306         sleep 2
4307
4308         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4309                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4310                 kill -9 $MULTIPID
4311         fi
4312         wait $MULTIPID
4313         local nsz=`stat -c %s $DIR/$tfile`
4314         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4315 }
4316 run_test 34h "ftruncate file under grouplock should not block"
4317
4318 test_35a() {
4319         cp /bin/sh $DIR/f35a
4320         chmod 444 $DIR/f35a
4321         chown $RUNAS_ID $DIR/f35a
4322         $RUNAS $DIR/f35a && error || true
4323         rm $DIR/f35a
4324 }
4325 run_test 35a "exec file with mode 444 (should return and not leak)"
4326
4327 test_36a() {
4328         rm -f $DIR/f36
4329         utime $DIR/f36 || error "utime failed for MDS"
4330 }
4331 run_test 36a "MDS utime check (mknod, utime)"
4332
4333 test_36b() {
4334         echo "" > $DIR/f36
4335         utime $DIR/f36 || error "utime failed for OST"
4336 }
4337 run_test 36b "OST utime check (open, utime)"
4338
4339 test_36c() {
4340         rm -f $DIR/d36/f36
4341         test_mkdir $DIR/d36
4342         chown $RUNAS_ID $DIR/d36
4343         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4344 }
4345 run_test 36c "non-root MDS utime check (mknod, utime)"
4346
4347 test_36d() {
4348         [ ! -d $DIR/d36 ] && test_36c
4349         echo "" > $DIR/d36/f36
4350         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4351 }
4352 run_test 36d "non-root OST utime check (open, utime)"
4353
4354 test_36e() {
4355         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4356
4357         test_mkdir $DIR/$tdir
4358         touch $DIR/$tdir/$tfile
4359         $RUNAS utime $DIR/$tdir/$tfile &&
4360                 error "utime worked, expected failure" || true
4361 }
4362 run_test 36e "utime on non-owned file (should return error)"
4363
4364 subr_36fh() {
4365         local fl="$1"
4366         local LANG_SAVE=$LANG
4367         local LC_LANG_SAVE=$LC_LANG
4368         export LANG=C LC_LANG=C # for date language
4369
4370         DATESTR="Dec 20  2000"
4371         test_mkdir $DIR/$tdir
4372         lctl set_param fail_loc=$fl
4373         date; date +%s
4374         cp /etc/hosts $DIR/$tdir/$tfile
4375         sync & # write RPC generated with "current" inode timestamp, but delayed
4376         sleep 1
4377         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4378         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4379         cancel_lru_locks $OSC
4380         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4381         date; date +%s
4382         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4383                 echo "BEFORE: $LS_BEFORE" && \
4384                 echo "AFTER : $LS_AFTER" && \
4385                 echo "WANT  : $DATESTR" && \
4386                 error "$DIR/$tdir/$tfile timestamps changed" || true
4387
4388         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4389 }
4390
4391 test_36f() {
4392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4393
4394         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4395         subr_36fh "0x80000214"
4396 }
4397 run_test 36f "utime on file racing with OST BRW write =========="
4398
4399 test_36g() {
4400         remote_ost_nodsh && skip "remote OST with nodsh"
4401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4402         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4403                 skip "Need MDS version at least 2.12.51"
4404
4405         local fmd_max_age
4406         local fmd
4407         local facet="ost1"
4408         local tgt="obdfilter"
4409
4410         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4411
4412         test_mkdir $DIR/$tdir
4413         fmd_max_age=$(do_facet $facet \
4414                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4415                 head -n 1")
4416
4417         echo "FMD max age: ${fmd_max_age}s"
4418         touch $DIR/$tdir/$tfile
4419         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4420                 gawk '{cnt=cnt+$1}  END{print cnt}')
4421         echo "FMD before: $fmd"
4422         [[ $fmd == 0 ]] &&
4423                 error "FMD wasn't create by touch"
4424         sleep $((fmd_max_age + 12))
4425         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4426                 gawk '{cnt=cnt+$1}  END{print cnt}')
4427         echo "FMD after: $fmd"
4428         [[ $fmd == 0 ]] ||
4429                 error "FMD wasn't expired by ping"
4430 }
4431 run_test 36g "FMD cache expiry ====================="
4432
4433 test_36h() {
4434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4435
4436         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4437         subr_36fh "0x80000227"
4438 }
4439 run_test 36h "utime on file racing with OST BRW write =========="
4440
4441 test_36i() {
4442         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4443
4444         test_mkdir $DIR/$tdir
4445         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4446
4447         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4448         local new_mtime=$((mtime + 200))
4449
4450         #change Modify time of striped dir
4451         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4452                         error "change mtime failed"
4453
4454         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4455
4456         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4457 }
4458 run_test 36i "change mtime on striped directory"
4459
4460 # test_37 - duplicate with tests 32q 32r
4461
4462 test_38() {
4463         local file=$DIR/$tfile
4464         touch $file
4465         openfile -f O_DIRECTORY $file
4466         local RC=$?
4467         local ENOTDIR=20
4468         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4469         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4470 }
4471 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4472
4473 test_39a() { # was test_39
4474         touch $DIR/$tfile
4475         touch $DIR/${tfile}2
4476 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4477 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4478 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4479         sleep 2
4480         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4481         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4482                 echo "mtime"
4483                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4484                 echo "atime"
4485                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4486                 echo "ctime"
4487                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4488                 error "O_TRUNC didn't change timestamps"
4489         fi
4490 }
4491 run_test 39a "mtime changed on create"
4492
4493 test_39b() {
4494         test_mkdir -c1 $DIR/$tdir
4495         cp -p /etc/passwd $DIR/$tdir/fopen
4496         cp -p /etc/passwd $DIR/$tdir/flink
4497         cp -p /etc/passwd $DIR/$tdir/funlink
4498         cp -p /etc/passwd $DIR/$tdir/frename
4499         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4500
4501         sleep 1
4502         echo "aaaaaa" >> $DIR/$tdir/fopen
4503         echo "aaaaaa" >> $DIR/$tdir/flink
4504         echo "aaaaaa" >> $DIR/$tdir/funlink
4505         echo "aaaaaa" >> $DIR/$tdir/frename
4506
4507         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4508         local link_new=`stat -c %Y $DIR/$tdir/flink`
4509         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4510         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4511
4512         cat $DIR/$tdir/fopen > /dev/null
4513         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4514         rm -f $DIR/$tdir/funlink2
4515         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4516
4517         for (( i=0; i < 2; i++ )) ; do
4518                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4519                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4520                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4521                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4522
4523                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4524                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4525                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4526                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4527
4528                 cancel_lru_locks $OSC
4529                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4530         done
4531 }
4532 run_test 39b "mtime change on open, link, unlink, rename  ======"
4533
4534 # this should be set to past
4535 TEST_39_MTIME=`date -d "1 year ago" +%s`
4536
4537 # bug 11063
4538 test_39c() {
4539         touch $DIR1/$tfile
4540         sleep 2
4541         local mtime0=`stat -c %Y $DIR1/$tfile`
4542
4543         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4544         local mtime1=`stat -c %Y $DIR1/$tfile`
4545         [ "$mtime1" = $TEST_39_MTIME ] || \
4546                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4547
4548         local d1=`date +%s`
4549         echo hello >> $DIR1/$tfile
4550         local d2=`date +%s`
4551         local mtime2=`stat -c %Y $DIR1/$tfile`
4552         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4553                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4554
4555         mv $DIR1/$tfile $DIR1/$tfile-1
4556
4557         for (( i=0; i < 2; i++ )) ; do
4558                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4559                 [ "$mtime2" = "$mtime3" ] || \
4560                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4561
4562                 cancel_lru_locks $OSC
4563                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4564         done
4565 }
4566 run_test 39c "mtime change on rename ==========================="
4567
4568 # bug 21114
4569 test_39d() {
4570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4571
4572         touch $DIR1/$tfile
4573         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4574
4575         for (( i=0; i < 2; i++ )) ; do
4576                 local mtime=`stat -c %Y $DIR1/$tfile`
4577                 [ $mtime = $TEST_39_MTIME ] || \
4578                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4579
4580                 cancel_lru_locks $OSC
4581                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4582         done
4583 }
4584 run_test 39d "create, utime, stat =============================="
4585
4586 # bug 21114
4587 test_39e() {
4588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4589
4590         touch $DIR1/$tfile
4591         local mtime1=`stat -c %Y $DIR1/$tfile`
4592
4593         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4594
4595         for (( i=0; i < 2; i++ )) ; do
4596                 local mtime2=`stat -c %Y $DIR1/$tfile`
4597                 [ $mtime2 = $TEST_39_MTIME ] || \
4598                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4599
4600                 cancel_lru_locks $OSC
4601                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4602         done
4603 }
4604 run_test 39e "create, stat, utime, stat ========================"
4605
4606 # bug 21114
4607 test_39f() {
4608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4609
4610         touch $DIR1/$tfile
4611         mtime1=`stat -c %Y $DIR1/$tfile`
4612
4613         sleep 2
4614         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4615
4616         for (( i=0; i < 2; i++ )) ; do
4617                 local mtime2=`stat -c %Y $DIR1/$tfile`
4618                 [ $mtime2 = $TEST_39_MTIME ] || \
4619                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4620
4621                 cancel_lru_locks $OSC
4622                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4623         done
4624 }
4625 run_test 39f "create, stat, sleep, utime, stat ================="
4626
4627 # bug 11063
4628 test_39g() {
4629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4630
4631         echo hello >> $DIR1/$tfile
4632         local mtime1=`stat -c %Y $DIR1/$tfile`
4633
4634         sleep 2
4635         chmod o+r $DIR1/$tfile
4636
4637         for (( i=0; i < 2; i++ )) ; do
4638                 local mtime2=`stat -c %Y $DIR1/$tfile`
4639                 [ "$mtime1" = "$mtime2" ] || \
4640                         error "lost mtime: $mtime2, should be $mtime1"
4641
4642                 cancel_lru_locks $OSC
4643                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4644         done
4645 }
4646 run_test 39g "write, chmod, stat ==============================="
4647
4648 # bug 11063
4649 test_39h() {
4650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4651
4652         touch $DIR1/$tfile
4653         sleep 1
4654
4655         local d1=`date`
4656         echo hello >> $DIR1/$tfile
4657         local mtime1=`stat -c %Y $DIR1/$tfile`
4658
4659         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4660         local d2=`date`
4661         if [ "$d1" != "$d2" ]; then
4662                 echo "write and touch not within one second"
4663         else
4664                 for (( i=0; i < 2; i++ )) ; do
4665                         local mtime2=`stat -c %Y $DIR1/$tfile`
4666                         [ "$mtime2" = $TEST_39_MTIME ] || \
4667                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4668
4669                         cancel_lru_locks $OSC
4670                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4671                 done
4672         fi
4673 }
4674 run_test 39h "write, utime within one second, stat ============="
4675
4676 test_39i() {
4677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4678
4679         touch $DIR1/$tfile
4680         sleep 1
4681
4682         echo hello >> $DIR1/$tfile
4683         local mtime1=`stat -c %Y $DIR1/$tfile`
4684
4685         mv $DIR1/$tfile $DIR1/$tfile-1
4686
4687         for (( i=0; i < 2; i++ )) ; do
4688                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4689
4690                 [ "$mtime1" = "$mtime2" ] || \
4691                         error "lost mtime: $mtime2, should be $mtime1"
4692
4693                 cancel_lru_locks $OSC
4694                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4695         done
4696 }
4697 run_test 39i "write, rename, stat =============================="
4698
4699 test_39j() {
4700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4701
4702         start_full_debug_logging
4703         touch $DIR1/$tfile
4704         sleep 1
4705
4706         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4707         lctl set_param fail_loc=0x80000412
4708         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4709                 error "multiop failed"
4710         local multipid=$!
4711         local mtime1=`stat -c %Y $DIR1/$tfile`
4712
4713         mv $DIR1/$tfile $DIR1/$tfile-1
4714
4715         kill -USR1 $multipid
4716         wait $multipid || error "multiop close failed"
4717
4718         for (( i=0; i < 2; i++ )) ; do
4719                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4720                 [ "$mtime1" = "$mtime2" ] ||
4721                         error "mtime is lost on close: $mtime2, " \
4722                               "should be $mtime1"
4723
4724                 cancel_lru_locks
4725                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4726         done
4727         lctl set_param fail_loc=0
4728         stop_full_debug_logging
4729 }
4730 run_test 39j "write, rename, close, stat ======================="
4731
4732 test_39k() {
4733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4734
4735         touch $DIR1/$tfile
4736         sleep 1
4737
4738         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4739         local multipid=$!
4740         local mtime1=`stat -c %Y $DIR1/$tfile`
4741
4742         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4743
4744         kill -USR1 $multipid
4745         wait $multipid || error "multiop close failed"
4746
4747         for (( i=0; i < 2; i++ )) ; do
4748                 local mtime2=`stat -c %Y $DIR1/$tfile`
4749
4750                 [ "$mtime2" = $TEST_39_MTIME ] || \
4751                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4752
4753                 cancel_lru_locks
4754                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4755         done
4756 }
4757 run_test 39k "write, utime, close, stat ========================"
4758
4759 # this should be set to future
4760 TEST_39_ATIME=`date -d "1 year" +%s`
4761
4762 test_39l() {
4763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4764         remote_mds_nodsh && skip "remote MDS with nodsh"
4765
4766         local atime_diff=$(do_facet $SINGLEMDS \
4767                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4768         rm -rf $DIR/$tdir
4769         mkdir -p $DIR/$tdir
4770
4771         # test setting directory atime to future
4772         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4773         local atime=$(stat -c %X $DIR/$tdir)
4774         [ "$atime" = $TEST_39_ATIME ] ||
4775                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4776
4777         # test setting directory atime from future to now
4778         local now=$(date +%s)
4779         touch -a -d @$now $DIR/$tdir
4780
4781         atime=$(stat -c %X $DIR/$tdir)
4782         [ "$atime" -eq "$now"  ] ||
4783                 error "atime is not updated from future: $atime, $now"
4784
4785         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4786         sleep 3
4787
4788         # test setting directory atime when now > dir atime + atime_diff
4789         local d1=$(date +%s)
4790         ls $DIR/$tdir
4791         local d2=$(date +%s)
4792         cancel_lru_locks mdc
4793         atime=$(stat -c %X $DIR/$tdir)
4794         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4795                 error "atime is not updated  : $atime, should be $d2"
4796
4797         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4798         sleep 3
4799
4800         # test not setting directory atime when now < dir atime + atime_diff
4801         ls $DIR/$tdir
4802         cancel_lru_locks mdc
4803         atime=$(stat -c %X $DIR/$tdir)
4804         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4805                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4806
4807         do_facet $SINGLEMDS \
4808                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4809 }
4810 run_test 39l "directory atime update ==========================="
4811
4812 test_39m() {
4813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4814
4815         touch $DIR1/$tfile
4816         sleep 2
4817         local far_past_mtime=$(date -d "May 29 1953" +%s)
4818         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4819
4820         touch -m -d @$far_past_mtime $DIR1/$tfile
4821         touch -a -d @$far_past_atime $DIR1/$tfile
4822
4823         for (( i=0; i < 2; i++ )) ; do
4824                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4825                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4826                         error "atime or mtime set incorrectly"
4827
4828                 cancel_lru_locks $OSC
4829                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4830         done
4831 }
4832 run_test 39m "test atime and mtime before 1970"
4833
4834 test_39n() { # LU-3832
4835         remote_mds_nodsh && skip "remote MDS with nodsh"
4836
4837         local atime_diff=$(do_facet $SINGLEMDS \
4838                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4839         local atime0
4840         local atime1
4841         local atime2
4842
4843         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4844
4845         rm -rf $DIR/$tfile
4846         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4847         atime0=$(stat -c %X $DIR/$tfile)
4848
4849         sleep 5
4850         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4851         atime1=$(stat -c %X $DIR/$tfile)
4852
4853         sleep 5
4854         cancel_lru_locks mdc
4855         cancel_lru_locks osc
4856         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4857         atime2=$(stat -c %X $DIR/$tfile)
4858
4859         do_facet $SINGLEMDS \
4860                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4861
4862         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4863         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4864 }
4865 run_test 39n "check that O_NOATIME is honored"
4866
4867 test_39o() {
4868         TESTDIR=$DIR/$tdir/$tfile
4869         [ -e $TESTDIR ] && rm -rf $TESTDIR
4870         mkdir -p $TESTDIR
4871         cd $TESTDIR
4872         links1=2
4873         ls
4874         mkdir a b
4875         ls
4876         links2=$(stat -c %h .)
4877         [ $(($links1 + 2)) != $links2 ] &&
4878                 error "wrong links count $(($links1 + 2)) != $links2"
4879         rmdir b
4880         links3=$(stat -c %h .)
4881         [ $(($links1 + 1)) != $links3 ] &&
4882                 error "wrong links count $links1 != $links3"
4883         return 0
4884 }
4885 run_test 39o "directory cached attributes updated after create"
4886
4887 test_39p() {
4888         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4889
4890         local MDTIDX=1
4891         TESTDIR=$DIR/$tdir/$tdir
4892         [ -e $TESTDIR ] && rm -rf $TESTDIR
4893         test_mkdir -p $TESTDIR
4894         cd $TESTDIR
4895         links1=2
4896         ls
4897         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4898         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4899         ls
4900         links2=$(stat -c %h .)
4901         [ $(($links1 + 2)) != $links2 ] &&
4902                 error "wrong links count $(($links1 + 2)) != $links2"
4903         rmdir remote_dir2
4904         links3=$(stat -c %h .)
4905         [ $(($links1 + 1)) != $links3 ] &&
4906                 error "wrong links count $links1 != $links3"
4907         return 0
4908 }
4909 run_test 39p "remote directory cached attributes updated after create ========"
4910
4911 test_39r() {
4912         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4913                 skip "no atime update on old OST"
4914         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4915                 skip_env "ldiskfs only test"
4916         fi
4917
4918         local saved_adiff
4919         saved_adiff=$(do_facet ost1 \
4920                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4921         stack_trap "do_facet ost1 \
4922                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4923
4924         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4925
4926         $LFS setstripe -i 0 $DIR/$tfile
4927         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4928                 error "can't write initial file"
4929         cancel_lru_locks osc
4930
4931         # exceed atime_diff and access file
4932         sleep 6
4933         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4934                 error "can't udpate atime"
4935
4936         local atime_cli=$(stat -c %X $DIR/$tfile)
4937         echo "client atime: $atime_cli"
4938         # allow atime update to be written to device
4939         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4940         sleep 5
4941
4942         local ostdev=$(ostdevname 1)
4943         local fid=($(lfs getstripe -y $DIR/$tfile |
4944                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4945         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4946         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4947
4948         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4949         local atime_ost=$(do_facet ost1 "$cmd" |&
4950                           awk -F'[: ]' '/atime:/ { print $4 }')
4951         (( atime_cli == atime_ost )) ||
4952                 error "atime on client $atime_cli != ost $atime_ost"
4953 }
4954 run_test 39r "lazy atime update on OST"
4955
4956 test_39q() { # LU-8041
4957         local testdir=$DIR/$tdir
4958         mkdir -p $testdir
4959         multiop_bg_pause $testdir D_c || error "multiop failed"
4960         local multipid=$!
4961         cancel_lru_locks mdc
4962         kill -USR1 $multipid
4963         local atime=$(stat -c %X $testdir)
4964         [ "$atime" -ne 0 ] || error "atime is zero"
4965 }
4966 run_test 39q "close won't zero out atime"
4967
4968 test_40() {
4969         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4970         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4971                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4972         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4973                 error "$tfile is not 4096 bytes in size"
4974 }
4975 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4976
4977 test_41() {
4978         # bug 1553
4979         small_write $DIR/f41 18
4980 }
4981 run_test 41 "test small file write + fstat ====================="
4982
4983 count_ost_writes() {
4984         lctl get_param -n ${OSC}.*.stats |
4985                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4986                         END { printf("%0.0f", writes) }'
4987 }
4988
4989 # decent default
4990 WRITEBACK_SAVE=500
4991 DIRTY_RATIO_SAVE=40
4992 MAX_DIRTY_RATIO=50
4993 BG_DIRTY_RATIO_SAVE=10
4994 MAX_BG_DIRTY_RATIO=25
4995
4996 start_writeback() {
4997         trap 0
4998         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4999         # dirty_ratio, dirty_background_ratio
5000         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5001                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5002                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5003                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5004         else
5005                 # if file not here, we are a 2.4 kernel
5006                 kill -CONT `pidof kupdated`
5007         fi
5008 }
5009
5010 stop_writeback() {
5011         # setup the trap first, so someone cannot exit the test at the
5012         # exact wrong time and mess up a machine
5013         trap start_writeback EXIT
5014         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5015         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5016                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5017                 sysctl -w vm.dirty_writeback_centisecs=0
5018                 sysctl -w vm.dirty_writeback_centisecs=0
5019                 # save and increase /proc/sys/vm/dirty_ratio
5020                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5021                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5022                 # save and increase /proc/sys/vm/dirty_background_ratio
5023                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5024                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5025         else
5026                 # if file not here, we are a 2.4 kernel
5027                 kill -STOP `pidof kupdated`
5028         fi
5029 }
5030
5031 # ensure that all stripes have some grant before we test client-side cache
5032 setup_test42() {
5033         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5034                 dd if=/dev/zero of=$i bs=4k count=1
5035                 rm $i
5036         done
5037 }
5038
5039 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5040 # file truncation, and file removal.
5041 test_42a() {
5042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5043
5044         setup_test42
5045         cancel_lru_locks $OSC
5046         stop_writeback
5047         sync; sleep 1; sync # just to be safe
5048         BEFOREWRITES=`count_ost_writes`
5049         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5050         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5051         AFTERWRITES=`count_ost_writes`
5052         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5053                 error "$BEFOREWRITES < $AFTERWRITES"
5054         start_writeback
5055 }
5056 run_test 42a "ensure that we don't flush on close"
5057
5058 test_42b() {
5059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5060
5061         setup_test42
5062         cancel_lru_locks $OSC
5063         stop_writeback
5064         sync
5065         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5066         BEFOREWRITES=$(count_ost_writes)
5067         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5068         AFTERWRITES=$(count_ost_writes)
5069         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5070                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5071         fi
5072         BEFOREWRITES=$(count_ost_writes)
5073         sync || error "sync: $?"
5074         AFTERWRITES=$(count_ost_writes)
5075         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5076                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5077         fi
5078         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5079         start_writeback
5080         return 0
5081 }
5082 run_test 42b "test destroy of file with cached dirty data ======"
5083
5084 # if these tests just want to test the effect of truncation,
5085 # they have to be very careful.  consider:
5086 # - the first open gets a {0,EOF}PR lock
5087 # - the first write conflicts and gets a {0, count-1}PW
5088 # - the rest of the writes are under {count,EOF}PW
5089 # - the open for truncate tries to match a {0,EOF}PR
5090 #   for the filesize and cancels the PWs.
5091 # any number of fixes (don't get {0,EOF} on open, match
5092 # composite locks, do smarter file size management) fix
5093 # this, but for now we want these tests to verify that
5094 # the cancellation with truncate intent works, so we
5095 # start the file with a full-file pw lock to match against
5096 # until the truncate.
5097 trunc_test() {
5098         test=$1
5099         file=$DIR/$test
5100         offset=$2
5101         cancel_lru_locks $OSC
5102         stop_writeback
5103         # prime the file with 0,EOF PW to match
5104         touch $file
5105         $TRUNCATE $file 0
5106         sync; sync
5107         # now the real test..
5108         dd if=/dev/zero of=$file bs=1024 count=100
5109         BEFOREWRITES=`count_ost_writes`
5110         $TRUNCATE $file $offset
5111         cancel_lru_locks $OSC
5112         AFTERWRITES=`count_ost_writes`
5113         start_writeback
5114 }
5115
5116 test_42c() {
5117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5118
5119         trunc_test 42c 1024
5120         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5121                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5122         rm $file
5123 }
5124 run_test 42c "test partial truncate of file with cached dirty data"
5125
5126 test_42d() {
5127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5128
5129         trunc_test 42d 0
5130         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5131                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5132         rm $file
5133 }
5134 run_test 42d "test complete truncate of file with cached dirty data"
5135
5136 test_42e() { # bug22074
5137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5138
5139         local TDIR=$DIR/${tdir}e
5140         local pages=16 # hardcoded 16 pages, don't change it.
5141         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5142         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5143         local max_dirty_mb
5144         local warmup_files
5145
5146         test_mkdir $DIR/${tdir}e
5147         $LFS setstripe -c 1 $TDIR
5148         createmany -o $TDIR/f $files
5149
5150         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5151
5152         # we assume that with $OSTCOUNT files, at least one of them will
5153         # be allocated on OST0.
5154         warmup_files=$((OSTCOUNT * max_dirty_mb))
5155         createmany -o $TDIR/w $warmup_files
5156
5157         # write a large amount of data into one file and sync, to get good
5158         # avail_grant number from OST.
5159         for ((i=0; i<$warmup_files; i++)); do
5160                 idx=$($LFS getstripe -i $TDIR/w$i)
5161                 [ $idx -ne 0 ] && continue
5162                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5163                 break
5164         done
5165         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5166         sync
5167         $LCTL get_param $proc_osc0/cur_dirty_bytes
5168         $LCTL get_param $proc_osc0/cur_grant_bytes
5169
5170         # create as much dirty pages as we can while not to trigger the actual
5171         # RPCs directly. but depends on the env, VFS may trigger flush during this
5172         # period, hopefully we are good.
5173         for ((i=0; i<$warmup_files; i++)); do
5174                 idx=$($LFS getstripe -i $TDIR/w$i)
5175                 [ $idx -ne 0 ] && continue
5176                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5177         done
5178         $LCTL get_param $proc_osc0/cur_dirty_bytes
5179         $LCTL get_param $proc_osc0/cur_grant_bytes
5180
5181         # perform the real test
5182         $LCTL set_param $proc_osc0/rpc_stats 0
5183         for ((;i<$files; i++)); do
5184                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5185                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5186         done
5187         sync
5188         $LCTL get_param $proc_osc0/rpc_stats
5189
5190         local percent=0
5191         local have_ppr=false
5192         $LCTL get_param $proc_osc0/rpc_stats |
5193                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5194                         # skip lines until we are at the RPC histogram data
5195                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5196                         $have_ppr || continue
5197
5198                         # we only want the percent stat for < 16 pages
5199                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5200
5201                         percent=$((percent + WPCT))
5202                         if [[ $percent -gt 15 ]]; then
5203                                 error "less than 16-pages write RPCs" \
5204                                       "$percent% > 15%"
5205                                 break
5206                         fi
5207                 done
5208         rm -rf $TDIR
5209 }
5210 run_test 42e "verify sub-RPC writes are not done synchronously"
5211
5212 test_43A() { # was test_43
5213         test_mkdir $DIR/$tdir
5214         cp -p /bin/ls $DIR/$tdir/$tfile
5215         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5216         pid=$!
5217         # give multiop a chance to open
5218         sleep 1
5219
5220         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5221         kill -USR1 $pid
5222         # Wait for multiop to exit
5223         wait $pid
5224 }
5225 run_test 43A "execution of file opened for write should return -ETXTBSY"
5226
5227 test_43a() {
5228         test_mkdir $DIR/$tdir
5229         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5230         $DIR/$tdir/sleep 60 &
5231         SLEEP_PID=$!
5232         # Make sure exec of $tdir/sleep wins race with truncate
5233         sleep 1
5234         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5235         kill $SLEEP_PID
5236 }
5237 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5238
5239 test_43b() {
5240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5241
5242         test_mkdir $DIR/$tdir
5243         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5244         $DIR/$tdir/sleep 60 &
5245         SLEEP_PID=$!
5246         # Make sure exec of $tdir/sleep wins race with truncate
5247         sleep 1
5248         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5249         kill $SLEEP_PID
5250 }
5251 run_test 43b "truncate of file being executed should return -ETXTBSY"
5252
5253 test_43c() {
5254         local testdir="$DIR/$tdir"
5255         test_mkdir $testdir
5256         cp $SHELL $testdir/
5257         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5258                 ( cd $testdir && md5sum -c )
5259 }
5260 run_test 43c "md5sum of copy into lustre"
5261
5262 test_44A() { # was test_44
5263         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5264
5265         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5266         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5267 }
5268 run_test 44A "zero length read from a sparse stripe"
5269
5270 test_44a() {
5271         local nstripe=$($LFS getstripe -c -d $DIR)
5272         [ -z "$nstripe" ] && skip "can't get stripe info"
5273         [[ $nstripe -gt $OSTCOUNT ]] &&
5274                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5275
5276         local stride=$($LFS getstripe -S -d $DIR)
5277         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5278                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5279         fi
5280
5281         OFFSETS="0 $((stride/2)) $((stride-1))"
5282         for offset in $OFFSETS; do
5283                 for i in $(seq 0 $((nstripe-1))); do
5284                         local GLOBALOFFSETS=""
5285                         # size in Bytes
5286                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5287                         local myfn=$DIR/d44a-$size
5288                         echo "--------writing $myfn at $size"
5289                         ll_sparseness_write $myfn $size ||
5290                                 error "ll_sparseness_write"
5291                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5292                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5293                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5294
5295                         for j in $(seq 0 $((nstripe-1))); do
5296                                 # size in Bytes
5297                                 size=$((((j + $nstripe )*$stride + $offset)))
5298                                 ll_sparseness_write $myfn $size ||
5299                                         error "ll_sparseness_write"
5300                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5301                         done
5302                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5303                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5304                         rm -f $myfn
5305                 done
5306         done
5307 }
5308 run_test 44a "test sparse pwrite ==============================="
5309
5310 dirty_osc_total() {
5311         tot=0
5312         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5313                 tot=$(($tot + $d))
5314         done
5315         echo $tot
5316 }
5317 do_dirty_record() {
5318         before=`dirty_osc_total`
5319         echo executing "\"$*\""
5320         eval $*
5321         after=`dirty_osc_total`
5322         echo before $before, after $after
5323 }
5324 test_45() {
5325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5326
5327         f="$DIR/f45"
5328         # Obtain grants from OST if it supports it
5329         echo blah > ${f}_grant
5330         stop_writeback
5331         sync
5332         do_dirty_record "echo blah > $f"
5333         [[ $before -eq $after ]] && error "write wasn't cached"
5334         do_dirty_record "> $f"
5335         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5336         do_dirty_record "echo blah > $f"
5337         [[ $before -eq $after ]] && error "write wasn't cached"
5338         do_dirty_record "sync"
5339         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5340         do_dirty_record "echo blah > $f"
5341         [[ $before -eq $after ]] && error "write wasn't cached"
5342         do_dirty_record "cancel_lru_locks osc"
5343         [[ $before -gt $after ]] ||
5344                 error "lock cancellation didn't lower dirty count"
5345         start_writeback
5346 }
5347 run_test 45 "osc io page accounting ============================"
5348
5349 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5350 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5351 # objects offset and an assert hit when an rpc was built with 1023's mapped
5352 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5353 test_46() {
5354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5355
5356         f="$DIR/f46"
5357         stop_writeback
5358         sync
5359         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5360         sync
5361         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5362         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5363         sync
5364         start_writeback
5365 }
5366 run_test 46 "dirtying a previously written page ================"
5367
5368 # test_47 is removed "Device nodes check" is moved to test_28
5369
5370 test_48a() { # bug 2399
5371         [ "$mds1_FSTYPE" = "zfs" ] &&
5372         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5373                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5374
5375         test_mkdir $DIR/$tdir
5376         cd $DIR/$tdir
5377         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5378         test_mkdir $DIR/$tdir
5379         touch foo || error "'touch foo' failed after recreating cwd"
5380         test_mkdir bar
5381         touch .foo || error "'touch .foo' failed after recreating cwd"
5382         test_mkdir .bar
5383         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5384         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5385         cd . || error "'cd .' failed after recreating cwd"
5386         mkdir . && error "'mkdir .' worked after recreating cwd"
5387         rmdir . && error "'rmdir .' worked after recreating cwd"
5388         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5389         cd .. || error "'cd ..' failed after recreating cwd"
5390 }
5391 run_test 48a "Access renamed working dir (should return errors)="
5392
5393 test_48b() { # bug 2399
5394         rm -rf $DIR/$tdir
5395         test_mkdir $DIR/$tdir
5396         cd $DIR/$tdir
5397         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5398         touch foo && error "'touch foo' worked after removing cwd"
5399         mkdir foo && error "'mkdir foo' worked after removing cwd"
5400         touch .foo && error "'touch .foo' worked after removing cwd"
5401         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5402         ls . > /dev/null && error "'ls .' worked after removing cwd"
5403         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5404         mkdir . && error "'mkdir .' worked after removing cwd"
5405         rmdir . && error "'rmdir .' worked after removing cwd"
5406         ln -s . foo && error "'ln -s .' worked after removing cwd"
5407         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5408 }
5409 run_test 48b "Access removed working dir (should return errors)="
5410
5411 test_48c() { # bug 2350
5412         #lctl set_param debug=-1
5413         #set -vx
5414         rm -rf $DIR/$tdir
5415         test_mkdir -p $DIR/$tdir/dir
5416         cd $DIR/$tdir/dir
5417         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5418         $TRACE touch foo && error "touch foo worked after removing cwd"
5419         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5420         touch .foo && error "touch .foo worked after removing cwd"
5421         mkdir .foo && error "mkdir .foo worked after removing cwd"
5422         $TRACE ls . && error "'ls .' worked after removing cwd"
5423         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5424         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5425         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5426         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5427         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5428 }
5429 run_test 48c "Access removed working subdir (should return errors)"
5430
5431 test_48d() { # bug 2350
5432         #lctl set_param debug=-1
5433         #set -vx
5434         rm -rf $DIR/$tdir
5435         test_mkdir -p $DIR/$tdir/dir
5436         cd $DIR/$tdir/dir
5437         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5438         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5439         $TRACE touch foo && error "'touch foo' worked after removing parent"
5440         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5441         touch .foo && error "'touch .foo' worked after removing parent"
5442         mkdir .foo && error "mkdir .foo worked after removing parent"
5443         $TRACE ls . && error "'ls .' worked after removing parent"
5444         $TRACE ls .. && error "'ls ..' worked after removing parent"
5445         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5446         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5447         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5448         true
5449 }
5450 run_test 48d "Access removed parent subdir (should return errors)"
5451
5452 test_48e() { # bug 4134
5453         #lctl set_param debug=-1
5454         #set -vx
5455         rm -rf $DIR/$tdir
5456         test_mkdir -p $DIR/$tdir/dir
5457         cd $DIR/$tdir/dir
5458         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5459         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5460         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5461         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5462         # On a buggy kernel addition of "touch foo" after cd .. will
5463         # produce kernel oops in lookup_hash_it
5464         touch ../foo && error "'cd ..' worked after recreate parent"
5465         cd $DIR
5466         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5467 }
5468 run_test 48e "Access to recreated parent subdir (should return errors)"
5469
5470 test_48f() {
5471         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5472                 skip "need MDS >= 2.13.55"
5473         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5474         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5475                 skip "needs different host for mdt1 mdt2"
5476         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5477
5478         $LFS mkdir -i0 $DIR/$tdir
5479         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5480
5481         for d in sub1 sub2 sub3; do
5482                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5483                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5484                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5485         done
5486
5487         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5488 }
5489 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5490
5491 test_49() { # LU-1030
5492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5493         remote_ost_nodsh && skip "remote OST with nodsh"
5494
5495         # get ost1 size - $FSNAME-OST0000
5496         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5497                 awk '{ print $4 }')
5498         # write 800M at maximum
5499         [[ $ost1_size -lt 2 ]] && ost1_size=2
5500         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5501
5502         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5503         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5504         local dd_pid=$!
5505
5506         # change max_pages_per_rpc while writing the file
5507         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5508         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5509         # loop until dd process exits
5510         while ps ax -opid | grep -wq $dd_pid; do
5511                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5512                 sleep $((RANDOM % 5 + 1))
5513         done
5514         # restore original max_pages_per_rpc
5515         $LCTL set_param $osc1_mppc=$orig_mppc
5516         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5517 }
5518 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5519
5520 test_50() {
5521         # bug 1485
5522         test_mkdir $DIR/$tdir
5523         cd $DIR/$tdir
5524         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5525 }
5526 run_test 50 "special situations: /proc symlinks  ==============="
5527
5528 test_51a() {    # was test_51
5529         # bug 1516 - create an empty entry right after ".." then split dir
5530         test_mkdir -c1 $DIR/$tdir
5531         touch $DIR/$tdir/foo
5532         $MCREATE $DIR/$tdir/bar
5533         rm $DIR/$tdir/foo
5534         createmany -m $DIR/$tdir/longfile 201
5535         FNUM=202
5536         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5537                 $MCREATE $DIR/$tdir/longfile$FNUM
5538                 FNUM=$(($FNUM + 1))
5539                 echo -n "+"
5540         done
5541         echo
5542         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5543 }
5544 run_test 51a "special situations: split htree with empty entry =="
5545
5546 cleanup_print_lfs_df () {
5547         trap 0
5548         $LFS df
5549         $LFS df -i
5550 }
5551
5552 test_51b() {
5553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5554
5555         local dir=$DIR/$tdir
5556         local nrdirs=$((65536 + 100))
5557
5558         # cleanup the directory
5559         rm -fr $dir
5560
5561         test_mkdir -c1 $dir
5562
5563         $LFS df
5564         $LFS df -i
5565         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5566         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5567         [[ $numfree -lt $nrdirs ]] &&
5568                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5569
5570         # need to check free space for the directories as well
5571         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5572         numfree=$(( blkfree / $(fs_inode_ksize) ))
5573         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5574
5575         trap cleanup_print_lfs_df EXIT
5576
5577         # create files
5578         createmany -d $dir/d $nrdirs || {
5579                 unlinkmany $dir/d $nrdirs
5580                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5581         }
5582
5583         # really created :
5584         nrdirs=$(ls -U $dir | wc -l)
5585
5586         # unlink all but 100 subdirectories, then check it still works
5587         local left=100
5588         local delete=$((nrdirs - left))
5589
5590         $LFS df
5591         $LFS df -i
5592
5593         # for ldiskfs the nlink count should be 1, but this is OSD specific
5594         # and so this is listed for informational purposes only
5595         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5596         unlinkmany -d $dir/d $delete ||
5597                 error "unlink of first $delete subdirs failed"
5598
5599         echo "nlink between: $(stat -c %h $dir)"
5600         local found=$(ls -U $dir | wc -l)
5601         [ $found -ne $left ] &&
5602                 error "can't find subdirs: found only $found, expected $left"
5603
5604         unlinkmany -d $dir/d $delete $left ||
5605                 error "unlink of second $left subdirs failed"
5606         # regardless of whether the backing filesystem tracks nlink accurately
5607         # or not, the nlink count shouldn't be more than "." and ".." here
5608         local after=$(stat -c %h $dir)
5609         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5610                 echo "nlink after: $after"
5611
5612         cleanup_print_lfs_df
5613 }
5614 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5615
5616 test_51d() {
5617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5618         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5619
5620         test_mkdir $DIR/$tdir
5621         createmany -o $DIR/$tdir/t- 1000
5622         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5623         for N in $(seq 0 $((OSTCOUNT - 1))); do
5624                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5625                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5626                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5627                         '($1 == '$N') { objs += 1 } \
5628                         END { printf("%0.0f", objs) }')
5629                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5630         done
5631         unlinkmany $DIR/$tdir/t- 1000
5632
5633         NLAST=0
5634         for N in $(seq 1 $((OSTCOUNT - 1))); do
5635                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5636                         error "OST $N has less objects vs OST $NLAST" \
5637                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5638                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5639                         error "OST $N has less objects vs OST $NLAST" \
5640                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5641
5642                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5643                         error "OST $N has less #0 objects vs OST $NLAST" \
5644                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5645                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5646                         error "OST $N has less #0 objects vs OST $NLAST" \
5647                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5648                 NLAST=$N
5649         done
5650         rm -f $TMP/$tfile
5651 }
5652 run_test 51d "check object distribution"
5653
5654 test_51e() {
5655         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5656                 skip_env "ldiskfs only test"
5657         fi
5658
5659         test_mkdir -c1 $DIR/$tdir
5660         test_mkdir -c1 $DIR/$tdir/d0
5661
5662         touch $DIR/$tdir/d0/foo
5663         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5664                 error "file exceed 65000 nlink limit!"
5665         unlinkmany $DIR/$tdir/d0/f- 65001
5666         return 0
5667 }
5668 run_test 51e "check file nlink limit"
5669
5670 test_51f() {
5671         test_mkdir $DIR/$tdir
5672
5673         local max=100000
5674         local ulimit_old=$(ulimit -n)
5675         local spare=20 # number of spare fd's for scripts/libraries, etc.
5676         local mdt=$($LFS getstripe -m $DIR/$tdir)
5677         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5678
5679         echo "MDT$mdt numfree=$numfree, max=$max"
5680         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5681         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5682                 while ! ulimit -n $((numfree + spare)); do
5683                         numfree=$((numfree * 3 / 4))
5684                 done
5685                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5686         else
5687                 echo "left ulimit at $ulimit_old"
5688         fi
5689
5690         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5691                 unlinkmany $DIR/$tdir/f $numfree
5692                 error "create+open $numfree files in $DIR/$tdir failed"
5693         }
5694         ulimit -n $ulimit_old
5695
5696         # if createmany exits at 120s there will be fewer than $numfree files
5697         unlinkmany $DIR/$tdir/f $numfree || true
5698 }
5699 run_test 51f "check many open files limit"
5700
5701 test_52a() {
5702         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5703         test_mkdir $DIR/$tdir
5704         touch $DIR/$tdir/foo
5705         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5706         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5707         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5708         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5709         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5710                                         error "link worked"
5711         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5712         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5713         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5714                                                      error "lsattr"
5715         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5716         cp -r $DIR/$tdir $TMP/
5717         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5718 }
5719 run_test 52a "append-only flag test (should return errors)"
5720
5721 test_52b() {
5722         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5723         test_mkdir $DIR/$tdir
5724         touch $DIR/$tdir/foo
5725         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5726         cat test > $DIR/$tdir/foo && error "cat test worked"
5727         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5728         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5729         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5730                                         error "link worked"
5731         echo foo >> $DIR/$tdir/foo && error "echo worked"
5732         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5733         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5734         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5735         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5736                                                         error "lsattr"
5737         chattr -i $DIR/$tdir/foo || error "chattr failed"
5738
5739         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5740 }
5741 run_test 52b "immutable flag test (should return errors) ======="
5742
5743 test_53() {
5744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5745         remote_mds_nodsh && skip "remote MDS with nodsh"
5746         remote_ost_nodsh && skip "remote OST with nodsh"
5747
5748         local param
5749         local param_seq
5750         local ostname
5751         local mds_last
5752         local mds_last_seq
5753         local ost_last
5754         local ost_last_seq
5755         local ost_last_id
5756         local ostnum
5757         local node
5758         local found=false
5759         local support_last_seq=true
5760
5761         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5762                 support_last_seq=false
5763
5764         # only test MDT0000
5765         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5766         local value
5767         for value in $(do_facet $SINGLEMDS \
5768                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5769                 param=$(echo ${value[0]} | cut -d "=" -f1)
5770                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5771
5772                 if $support_last_seq; then
5773                         param_seq=$(echo $param |
5774                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5775                         mds_last_seq=$(do_facet $SINGLEMDS \
5776                                        $LCTL get_param -n $param_seq)
5777                 fi
5778                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5779
5780                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5781                 node=$(facet_active_host ost$((ostnum+1)))
5782                 param="obdfilter.$ostname.last_id"
5783                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5784                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5785                         ost_last_id=$ost_last
5786
5787                         if $support_last_seq; then
5788                                 ost_last_id=$(echo $ost_last |
5789                                               awk -F':' '{print $2}' |
5790                                               sed -e "s/^0x//g")
5791                                 ost_last_seq=$(echo $ost_last |
5792                                                awk -F':' '{print $1}')
5793                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5794                         fi
5795
5796                         if [[ $ost_last_id != $mds_last ]]; then
5797                                 error "$ost_last_id != $mds_last"
5798                         else
5799                                 found=true
5800                                 break
5801                         fi
5802                 done
5803         done
5804         $found || error "can not match last_seq/last_id for $mdtosc"
5805         return 0
5806 }
5807 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5808
5809 test_54a() {
5810         perl -MSocket -e ';' || skip "no Socket perl module installed"
5811
5812         $SOCKETSERVER $DIR/socket ||
5813                 error "$SOCKETSERVER $DIR/socket failed: $?"
5814         $SOCKETCLIENT $DIR/socket ||
5815                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5816         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5817 }
5818 run_test 54a "unix domain socket test =========================="
5819
5820 test_54b() {
5821         f="$DIR/f54b"
5822         mknod $f c 1 3
5823         chmod 0666 $f
5824         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5825 }
5826 run_test 54b "char device works in lustre ======================"
5827
5828 find_loop_dev() {
5829         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5830         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5831         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5832
5833         for i in $(seq 3 7); do
5834                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5835                 LOOPDEV=$LOOPBASE$i
5836                 LOOPNUM=$i
5837                 break
5838         done
5839 }
5840
5841 cleanup_54c() {
5842         local rc=0
5843         loopdev="$DIR/loop54c"
5844
5845         trap 0
5846         $UMOUNT $DIR/$tdir || rc=$?
5847         losetup -d $loopdev || true
5848         losetup -d $LOOPDEV || true
5849         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5850         return $rc
5851 }
5852
5853 test_54c() {
5854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5855
5856         loopdev="$DIR/loop54c"
5857
5858         find_loop_dev
5859         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5860         trap cleanup_54c EXIT
5861         mknod $loopdev b 7 $LOOPNUM
5862         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5863         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5864         losetup $loopdev $DIR/$tfile ||
5865                 error "can't set up $loopdev for $DIR/$tfile"
5866         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5867         test_mkdir $DIR/$tdir
5868         mount -t ext2 $loopdev $DIR/$tdir ||
5869                 error "error mounting $loopdev on $DIR/$tdir"
5870         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5871                 error "dd write"
5872         df $DIR/$tdir
5873         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5874                 error "dd read"
5875         cleanup_54c
5876 }
5877 run_test 54c "block device works in lustre ====================="
5878
5879 test_54d() {
5880         f="$DIR/f54d"
5881         string="aaaaaa"
5882         mknod $f p
5883         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5884 }
5885 run_test 54d "fifo device works in lustre ======================"
5886
5887 test_54e() {
5888         f="$DIR/f54e"
5889         string="aaaaaa"
5890         cp -aL /dev/console $f
5891         echo $string > $f || error "echo $string to $f failed"
5892 }
5893 run_test 54e "console/tty device works in lustre ======================"
5894
5895 test_56a() {
5896         local numfiles=3
5897         local numdirs=2
5898         local dir=$DIR/$tdir
5899
5900         rm -rf $dir
5901         test_mkdir -p $dir/dir
5902         for i in $(seq $numfiles); do
5903                 touch $dir/file$i
5904                 touch $dir/dir/file$i
5905         done
5906
5907         local numcomp=$($LFS getstripe --component-count $dir)
5908
5909         [[ $numcomp == 0 ]] && numcomp=1
5910
5911         # test lfs getstripe with --recursive
5912         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5913
5914         [[ $filenum -eq $((numfiles * 2)) ]] ||
5915                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5916         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5917         [[ $filenum -eq $numfiles ]] ||
5918                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5919         echo "$LFS getstripe showed obdidx or l_ost_idx"
5920
5921         # test lfs getstripe with file instead of dir
5922         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5923         [[ $filenum -eq 1 ]] ||
5924                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5925         echo "$LFS getstripe file1 passed"
5926
5927         #test lfs getstripe with --verbose
5928         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5929         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5930                 error "$LFS getstripe --verbose $dir: "\
5931                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5932         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5933                 error "$LFS getstripe $dir: showed lmm_magic"
5934
5935         #test lfs getstripe with -v prints lmm_fid
5936         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5937         local countfids=$((numdirs + numfiles * numcomp))
5938         [[ $filenum -eq $countfids ]] ||
5939                 error "$LFS getstripe -v $dir: "\
5940                       "got $filenum want $countfids lmm_fid"
5941         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5942                 error "$LFS getstripe $dir: showed lmm_fid by default"
5943         echo "$LFS getstripe --verbose passed"
5944
5945         #check for FID information
5946         local fid1=$($LFS getstripe --fid $dir/file1)
5947         local fid2=$($LFS getstripe --verbose $dir/file1 |
5948                      awk '/lmm_fid: / { print $2; exit; }')
5949         local fid3=$($LFS path2fid $dir/file1)
5950
5951         [ "$fid1" != "$fid2" ] &&
5952                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5953         [ "$fid1" != "$fid3" ] &&
5954                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5955         echo "$LFS getstripe --fid passed"
5956
5957         #test lfs getstripe with --obd
5958         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5959                 error "$LFS getstripe --obd wrong_uuid: should return error"
5960
5961         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5962
5963         local ostidx=1
5964         local obduuid=$(ostuuid_from_index $ostidx)
5965         local found=$($LFS getstripe -r --obd $obduuid $dir |
5966                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5967
5968         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5969         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5970                 ((filenum--))
5971         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5972                 ((filenum--))
5973
5974         [[ $found -eq $filenum ]] ||
5975                 error "$LFS getstripe --obd: found $found expect $filenum"
5976         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5977                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5978                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5979                 error "$LFS getstripe --obd: should not show file on other obd"
5980         echo "$LFS getstripe --obd passed"
5981 }
5982 run_test 56a "check $LFS getstripe"
5983
5984 test_56b() {
5985         local dir=$DIR/$tdir
5986         local numdirs=3
5987
5988         test_mkdir $dir
5989         for i in $(seq $numdirs); do
5990                 test_mkdir $dir/dir$i
5991         done
5992
5993         # test lfs getdirstripe default mode is non-recursion, which is
5994         # different from lfs getstripe
5995         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5996
5997         [[ $dircnt -eq 1 ]] ||
5998                 error "$LFS getdirstripe: found $dircnt, not 1"
5999         dircnt=$($LFS getdirstripe --recursive $dir |
6000                 grep -c lmv_stripe_count)
6001         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6002                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6003 }
6004 run_test 56b "check $LFS getdirstripe"
6005
6006 test_56c() {
6007         remote_ost_nodsh && skip "remote OST with nodsh"
6008
6009         local ost_idx=0
6010         local ost_name=$(ostname_from_index $ost_idx)
6011         local old_status=$(ost_dev_status $ost_idx)
6012         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6013
6014         [[ -z "$old_status" ]] ||
6015                 skip_env "OST $ost_name is in $old_status status"
6016
6017         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6018         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6019                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6020         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6021                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6022                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6023         fi
6024
6025         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6026                 error "$LFS df -v showing inactive devices"
6027         sleep_maxage
6028
6029         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6030
6031         [[ "$new_status" =~ "D" ]] ||
6032                 error "$ost_name status is '$new_status', missing 'D'"
6033         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6034                 [[ "$new_status" =~ "N" ]] ||
6035                         error "$ost_name status is '$new_status', missing 'N'"
6036         fi
6037         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6038                 [[ "$new_status" =~ "f" ]] ||
6039                         error "$ost_name status is '$new_status', missing 'f'"
6040         fi
6041
6042         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6043         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6044                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6045         [[ -z "$p" ]] && restore_lustre_params < $p || true
6046         sleep_maxage
6047
6048         new_status=$(ost_dev_status $ost_idx)
6049         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6050                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6051         # can't check 'f' as devices may actually be on flash
6052 }
6053 run_test 56c "check 'lfs df' showing device status"
6054
6055 test_56d() {
6056         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6057         local osts=$($LFS df -v $MOUNT | grep -c OST)
6058
6059         $LFS df $MOUNT
6060
6061         (( mdts == MDSCOUNT )) ||
6062                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6063         (( osts == OSTCOUNT )) ||
6064                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6065 }
6066 run_test 56d "'lfs df -v' prints only configured devices"
6067
6068 NUMFILES=3
6069 NUMDIRS=3
6070 setup_56() {
6071         local local_tdir="$1"
6072         local local_numfiles="$2"
6073         local local_numdirs="$3"
6074         local dir_params="$4"
6075         local dir_stripe_params="$5"
6076
6077         if [ ! -d "$local_tdir" ] ; then
6078                 test_mkdir -p $dir_stripe_params $local_tdir
6079                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6080                 for i in $(seq $local_numfiles) ; do
6081                         touch $local_tdir/file$i
6082                 done
6083                 for i in $(seq $local_numdirs) ; do
6084                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6085                         for j in $(seq $local_numfiles) ; do
6086                                 touch $local_tdir/dir$i/file$j
6087                         done
6088                 done
6089         fi
6090 }
6091
6092 setup_56_special() {
6093         local local_tdir=$1
6094         local local_numfiles=$2
6095         local local_numdirs=$3
6096
6097         setup_56 $local_tdir $local_numfiles $local_numdirs
6098
6099         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6100                 for i in $(seq $local_numfiles) ; do
6101                         mknod $local_tdir/loop${i}b b 7 $i
6102                         mknod $local_tdir/null${i}c c 1 3
6103                         ln -s $local_tdir/file1 $local_tdir/link${i}
6104                 done
6105                 for i in $(seq $local_numdirs) ; do
6106                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6107                         mknod $local_tdir/dir$i/null${i}c c 1 3
6108                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6109                 done
6110         fi
6111 }
6112
6113 test_56g() {
6114         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6115         local expected=$(($NUMDIRS + 2))
6116
6117         setup_56 $dir $NUMFILES $NUMDIRS
6118
6119         # test lfs find with -name
6120         for i in $(seq $NUMFILES) ; do
6121                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6122
6123                 [ $nums -eq $expected ] ||
6124                         error "lfs find -name '*$i' $dir wrong: "\
6125                               "found $nums, expected $expected"
6126         done
6127 }
6128 run_test 56g "check lfs find -name"
6129
6130 test_56h() {
6131         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6132         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6133
6134         setup_56 $dir $NUMFILES $NUMDIRS
6135
6136         # test lfs find with ! -name
6137         for i in $(seq $NUMFILES) ; do
6138                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6139
6140                 [ $nums -eq $expected ] ||
6141                         error "lfs find ! -name '*$i' $dir wrong: "\
6142                               "found $nums, expected $expected"
6143         done
6144 }
6145 run_test 56h "check lfs find ! -name"
6146
6147 test_56i() {
6148         local dir=$DIR/$tdir
6149
6150         test_mkdir $dir
6151
6152         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6153         local out=$($cmd)
6154
6155         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6156 }
6157 run_test 56i "check 'lfs find -ost UUID' skips directories"
6158
6159 test_56j() {
6160         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6161
6162         setup_56_special $dir $NUMFILES $NUMDIRS
6163
6164         local expected=$((NUMDIRS + 1))
6165         local cmd="$LFS find -type d $dir"
6166         local nums=$($cmd | wc -l)
6167
6168         [ $nums -eq $expected ] ||
6169                 error "'$cmd' wrong: found $nums, expected $expected"
6170 }
6171 run_test 56j "check lfs find -type d"
6172
6173 test_56k() {
6174         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6175
6176         setup_56_special $dir $NUMFILES $NUMDIRS
6177
6178         local expected=$(((NUMDIRS + 1) * NUMFILES))
6179         local cmd="$LFS find -type f $dir"
6180         local nums=$($cmd | wc -l)
6181
6182         [ $nums -eq $expected ] ||
6183                 error "'$cmd' wrong: found $nums, expected $expected"
6184 }
6185 run_test 56k "check lfs find -type f"
6186
6187 test_56l() {
6188         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6189
6190         setup_56_special $dir $NUMFILES $NUMDIRS
6191
6192         local expected=$((NUMDIRS + NUMFILES))
6193         local cmd="$LFS find -type b $dir"
6194         local nums=$($cmd | wc -l)
6195
6196         [ $nums -eq $expected ] ||
6197                 error "'$cmd' wrong: found $nums, expected $expected"
6198 }
6199 run_test 56l "check lfs find -type b"
6200
6201 test_56m() {
6202         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6203
6204         setup_56_special $dir $NUMFILES $NUMDIRS
6205
6206         local expected=$((NUMDIRS + NUMFILES))
6207         local cmd="$LFS find -type c $dir"
6208         local nums=$($cmd | wc -l)
6209         [ $nums -eq $expected ] ||
6210                 error "'$cmd' wrong: found $nums, expected $expected"
6211 }
6212 run_test 56m "check lfs find -type c"
6213
6214 test_56n() {
6215         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6216         setup_56_special $dir $NUMFILES $NUMDIRS
6217
6218         local expected=$((NUMDIRS + NUMFILES))
6219         local cmd="$LFS find -type l $dir"
6220         local nums=$($cmd | wc -l)
6221
6222         [ $nums -eq $expected ] ||
6223                 error "'$cmd' wrong: found $nums, expected $expected"
6224 }
6225 run_test 56n "check lfs find -type l"
6226
6227 test_56o() {
6228         local dir=$DIR/$tdir
6229
6230         setup_56 $dir $NUMFILES $NUMDIRS
6231         utime $dir/file1 > /dev/null || error "utime (1)"
6232         utime $dir/file2 > /dev/null || error "utime (2)"
6233         utime $dir/dir1 > /dev/null || error "utime (3)"
6234         utime $dir/dir2 > /dev/null || error "utime (4)"
6235         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6236         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6237
6238         local expected=4
6239         local nums=$($LFS find -mtime +0 $dir | wc -l)
6240
6241         [ $nums -eq $expected ] ||
6242                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6243
6244         expected=12
6245         cmd="$LFS find -mtime 0 $dir"
6246         nums=$($cmd | wc -l)
6247         [ $nums -eq $expected ] ||
6248                 error "'$cmd' wrong: found $nums, expected $expected"
6249 }
6250 run_test 56o "check lfs find -mtime for old files"
6251
6252 test_56ob() {
6253         local dir=$DIR/$tdir
6254         local expected=1
6255         local count=0
6256
6257         # just to make sure there is something that won't be found
6258         test_mkdir $dir
6259         touch $dir/$tfile.now
6260
6261         for age in year week day hour min; do
6262                 count=$((count + 1))
6263
6264                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6265                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6266                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6267
6268                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6269                 local nums=$($cmd | wc -l)
6270                 [ $nums -eq $expected ] ||
6271                         error "'$cmd' wrong: found $nums, expected $expected"
6272
6273                 cmd="$LFS find $dir -atime $count${age:0:1}"
6274                 nums=$($cmd | wc -l)
6275                 [ $nums -eq $expected ] ||
6276                         error "'$cmd' wrong: found $nums, expected $expected"
6277         done
6278
6279         sleep 2
6280         cmd="$LFS find $dir -ctime +1s -type f"
6281         nums=$($cmd | wc -l)
6282         (( $nums == $count * 2 + 1)) ||
6283                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6284 }
6285 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6286
6287 test_newerXY_base() {
6288         local x=$1
6289         local y=$2
6290         local dir=$DIR/$tdir
6291         local ref
6292         local negref
6293
6294         if [ $y == "t" ]; then
6295                 if [ $x == "b" ]; then
6296                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6297                 else
6298                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6299                 fi
6300         else
6301                 ref=$DIR/$tfile.newer.$x$y
6302                 touch $ref || error "touch $ref failed"
6303         fi
6304
6305         echo "before = $ref"
6306         sleep 2
6307         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6308         sleep 2
6309         if [ $y == "t" ]; then
6310                 if [ $x == "b" ]; then
6311                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6312                 else
6313                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6314                 fi
6315         else
6316                 negref=$DIR/$tfile.negnewer.$x$y
6317                 touch $negref || error "touch $negref failed"
6318         fi
6319
6320         echo "after = $negref"
6321         local cmd="$LFS find $dir -newer$x$y $ref"
6322         local nums=$(eval $cmd | wc -l)
6323         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6324
6325         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6326                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6327
6328         cmd="$LFS find $dir ! -newer$x$y $negref"
6329         nums=$(eval $cmd | wc -l)
6330         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6331                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6332
6333         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6334         nums=$(eval $cmd | wc -l)
6335         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6336                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6337
6338         rm -rf $DIR/*
6339 }
6340
6341 test_56oc() {
6342         test_newerXY_base "a" "a"
6343         test_newerXY_base "a" "m"
6344         test_newerXY_base "a" "c"
6345         test_newerXY_base "m" "a"
6346         test_newerXY_base "m" "m"
6347         test_newerXY_base "m" "c"
6348         test_newerXY_base "c" "a"
6349         test_newerXY_base "c" "m"
6350         test_newerXY_base "c" "c"
6351
6352         [[ -n "$sles_version" ]] &&
6353                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6354
6355         test_newerXY_base "a" "t"
6356         test_newerXY_base "m" "t"
6357         test_newerXY_base "c" "t"
6358
6359         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6360            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6361                 ! btime_supported && echo "btime unsupported" && return 0
6362
6363         test_newerXY_base "b" "b"
6364         test_newerXY_base "b" "t"
6365 }
6366 run_test 56oc "check lfs find -newerXY work"
6367
6368 btime_supported() {
6369         local dir=$DIR/$tdir
6370         local rc
6371
6372         mkdir -p $dir
6373         touch $dir/$tfile
6374         $LFS find $dir -btime -1d -type f
6375         rc=$?
6376         rm -rf $dir
6377         return $rc
6378 }
6379
6380 test_56od() {
6381         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6382                 ! btime_supported && skip "btime unsupported on MDS"
6383
6384         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6385                 ! btime_supported && skip "btime unsupported on clients"
6386
6387         local dir=$DIR/$tdir
6388         local ref=$DIR/$tfile.ref
6389         local negref=$DIR/$tfile.negref
6390
6391         mkdir $dir || error "mkdir $dir failed"
6392         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6393         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6394         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6395         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6396         touch $ref || error "touch $ref failed"
6397         # sleep 3 seconds at least
6398         sleep 3
6399
6400         local before=$(do_facet mds1 date +%s)
6401         local skew=$(($(date +%s) - before + 1))
6402
6403         if (( skew < 0 && skew > -5 )); then
6404                 sleep $((0 - skew + 1))
6405                 skew=0
6406         fi
6407
6408         # Set the dir stripe params to limit files all on MDT0,
6409         # otherwise we need to calc the max clock skew between
6410         # the client and MDTs.
6411         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6412         sleep 2
6413         touch $negref || error "touch $negref failed"
6414
6415         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6416         local nums=$($cmd | wc -l)
6417         local expected=$(((NUMFILES + 1) * NUMDIRS))
6418
6419         [ $nums -eq $expected ] ||
6420                 error "'$cmd' wrong: found $nums, expected $expected"
6421
6422         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6423         nums=$($cmd | wc -l)
6424         expected=$((NUMFILES + 1))
6425         [ $nums -eq $expected ] ||
6426                 error "'$cmd' wrong: found $nums, expected $expected"
6427
6428         [ $skew -lt 0 ] && return
6429
6430         local after=$(do_facet mds1 date +%s)
6431         local age=$((after - before + 1 + skew))
6432
6433         cmd="$LFS find $dir -btime -${age}s -type f"
6434         nums=$($cmd | wc -l)
6435         expected=$(((NUMFILES + 1) * NUMDIRS))
6436
6437         echo "Clock skew between client and server: $skew, age:$age"
6438         [ $nums -eq $expected ] ||
6439                 error "'$cmd' wrong: found $nums, expected $expected"
6440
6441         expected=$(($NUMDIRS + 1))
6442         cmd="$LFS find $dir -btime -${age}s -type d"
6443         nums=$($cmd | wc -l)
6444         [ $nums -eq $expected ] ||
6445                 error "'$cmd' wrong: found $nums, expected $expected"
6446         rm -f $ref $negref || error "Failed to remove $ref $negref"
6447 }
6448 run_test 56od "check lfs find -btime with units"
6449
6450 test_56p() {
6451         [ $RUNAS_ID -eq $UID ] &&
6452                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6453
6454         local dir=$DIR/$tdir
6455
6456         setup_56 $dir $NUMFILES $NUMDIRS
6457         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6458
6459         local expected=$NUMFILES
6460         local cmd="$LFS find -uid $RUNAS_ID $dir"
6461         local nums=$($cmd | wc -l)
6462
6463         [ $nums -eq $expected ] ||
6464                 error "'$cmd' wrong: found $nums, expected $expected"
6465
6466         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6467         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6468         nums=$($cmd | wc -l)
6469         [ $nums -eq $expected ] ||
6470                 error "'$cmd' wrong: found $nums, expected $expected"
6471 }
6472 run_test 56p "check lfs find -uid and ! -uid"
6473
6474 test_56q() {
6475         [ $RUNAS_ID -eq $UID ] &&
6476                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6477
6478         local dir=$DIR/$tdir
6479
6480         setup_56 $dir $NUMFILES $NUMDIRS
6481         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6482
6483         local expected=$NUMFILES
6484         local cmd="$LFS find -gid $RUNAS_GID $dir"
6485         local nums=$($cmd | wc -l)
6486
6487         [ $nums -eq $expected ] ||
6488                 error "'$cmd' wrong: found $nums, expected $expected"
6489
6490         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6491         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6492         nums=$($cmd | wc -l)
6493         [ $nums -eq $expected ] ||
6494                 error "'$cmd' wrong: found $nums, expected $expected"
6495 }
6496 run_test 56q "check lfs find -gid and ! -gid"
6497
6498 test_56r() {
6499         local dir=$DIR/$tdir
6500
6501         setup_56 $dir $NUMFILES $NUMDIRS
6502
6503         local expected=12
6504         local cmd="$LFS find -size 0 -type f -lazy $dir"
6505         local nums=$($cmd | wc -l)
6506
6507         [ $nums -eq $expected ] ||
6508                 error "'$cmd' wrong: found $nums, expected $expected"
6509         cmd="$LFS find -size 0 -type f $dir"
6510         nums=$($cmd | wc -l)
6511         [ $nums -eq $expected ] ||
6512                 error "'$cmd' wrong: found $nums, expected $expected"
6513
6514         expected=0
6515         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6516         nums=$($cmd | wc -l)
6517         [ $nums -eq $expected ] ||
6518                 error "'$cmd' wrong: found $nums, expected $expected"
6519         cmd="$LFS find ! -size 0 -type f $dir"
6520         nums=$($cmd | wc -l)
6521         [ $nums -eq $expected ] ||
6522                 error "'$cmd' wrong: found $nums, expected $expected"
6523
6524         echo "test" > $dir/$tfile
6525         echo "test2" > $dir/$tfile.2 && sync
6526         expected=1
6527         cmd="$LFS find -size 5 -type f -lazy $dir"
6528         nums=$($cmd | wc -l)
6529         [ $nums -eq $expected ] ||
6530                 error "'$cmd' wrong: found $nums, expected $expected"
6531         cmd="$LFS find -size 5 -type f $dir"
6532         nums=$($cmd | wc -l)
6533         [ $nums -eq $expected ] ||
6534                 error "'$cmd' wrong: found $nums, expected $expected"
6535
6536         expected=1
6537         cmd="$LFS find -size +5 -type f -lazy $dir"
6538         nums=$($cmd | wc -l)
6539         [ $nums -eq $expected ] ||
6540                 error "'$cmd' wrong: found $nums, expected $expected"
6541         cmd="$LFS find -size +5 -type f $dir"
6542         nums=$($cmd | wc -l)
6543         [ $nums -eq $expected ] ||
6544                 error "'$cmd' wrong: found $nums, expected $expected"
6545
6546         expected=2
6547         cmd="$LFS find -size +0 -type f -lazy $dir"
6548         nums=$($cmd | wc -l)
6549         [ $nums -eq $expected ] ||
6550                 error "'$cmd' wrong: found $nums, expected $expected"
6551         cmd="$LFS find -size +0 -type f $dir"
6552         nums=$($cmd | wc -l)
6553         [ $nums -eq $expected ] ||
6554                 error "'$cmd' wrong: found $nums, expected $expected"
6555
6556         expected=2
6557         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6558         nums=$($cmd | wc -l)
6559         [ $nums -eq $expected ] ||
6560                 error "'$cmd' wrong: found $nums, expected $expected"
6561         cmd="$LFS find ! -size -5 -type f $dir"
6562         nums=$($cmd | wc -l)
6563         [ $nums -eq $expected ] ||
6564                 error "'$cmd' wrong: found $nums, expected $expected"
6565
6566         expected=12
6567         cmd="$LFS find -size -5 -type f -lazy $dir"
6568         nums=$($cmd | wc -l)
6569         [ $nums -eq $expected ] ||
6570                 error "'$cmd' wrong: found $nums, expected $expected"
6571         cmd="$LFS find -size -5 -type f $dir"
6572         nums=$($cmd | wc -l)
6573         [ $nums -eq $expected ] ||
6574                 error "'$cmd' wrong: found $nums, expected $expected"
6575 }
6576 run_test 56r "check lfs find -size works"
6577
6578 test_56ra_sub() {
6579         local expected=$1
6580         local glimpses=$2
6581         local cmd="$3"
6582
6583         cancel_lru_locks $OSC
6584
6585         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6586         local nums=$($cmd | wc -l)
6587
6588         [ $nums -eq $expected ] ||
6589                 error "'$cmd' wrong: found $nums, expected $expected"
6590
6591         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6592
6593         if (( rpcs_before + glimpses != rpcs_after )); then
6594                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6595                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6596
6597                 if [[ $glimpses == 0 ]]; then
6598                         error "'$cmd' should not send glimpse RPCs to OST"
6599                 else
6600                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6601                 fi
6602         fi
6603 }
6604
6605 test_56ra() {
6606         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6607                 skip "MDS < 2.12.58 doesn't return LSOM data"
6608         local dir=$DIR/$tdir
6609         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6610
6611         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6612
6613         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6614         $LCTL set_param -n llite.*.statahead_agl=0
6615         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6616
6617         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6618         # open and close all files to ensure LSOM is updated
6619         cancel_lru_locks $OSC
6620         find $dir -type f | xargs cat > /dev/null
6621
6622         #   expect_found  glimpse_rpcs  command_to_run
6623         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6624         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6625         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6626         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6627
6628         echo "test" > $dir/$tfile
6629         echo "test2" > $dir/$tfile.2 && sync
6630         cancel_lru_locks $OSC
6631         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6632
6633         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6634         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6635         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6636         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6637
6638         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6639         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6640         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6641         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6642         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6643         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6644 }
6645 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6646
6647 test_56rb() {
6648         local dir=$DIR/$tdir
6649         local tmp=$TMP/$tfile.log
6650         local mdt_idx;
6651
6652         test_mkdir -p $dir || error "failed to mkdir $dir"
6653         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6654                 error "failed to setstripe $dir/$tfile"
6655         mdt_idx=$($LFS getdirstripe -i $dir)
6656         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6657
6658         stack_trap "rm -f $tmp" EXIT
6659         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6660         ! grep -q obd_uuid $tmp ||
6661                 error "failed to find --size +100K --ost 0 $dir"
6662         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6663         ! grep -q obd_uuid $tmp ||
6664                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6665 }
6666 run_test 56rb "check lfs find --size --ost/--mdt works"
6667
6668 test_56rc() {
6669         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6670         local dir=$DIR/$tdir
6671         local found
6672
6673         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6674         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6675         (( $MDSCOUNT > 2 )) &&
6676                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6677         mkdir $dir/$tdir-{1..10}
6678         touch $dir/$tfile-{1..10}
6679
6680         found=$($LFS find $dir --mdt-count 2 | wc -l)
6681         expect=11
6682         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6683
6684         found=$($LFS find $dir -T +1 | wc -l)
6685         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6686         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6687
6688         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6689         expect=11
6690         (( $found == $expect )) || error "found $found all_char, expect $expect"
6691
6692         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6693         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6694         (( $found == $expect )) || error "found $found all_char, expect $expect"
6695 }
6696 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6697
6698 test_56s() { # LU-611 #LU-9369
6699         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6700
6701         local dir=$DIR/$tdir
6702         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6703
6704         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6705         for i in $(seq $NUMDIRS); do
6706                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6707         done
6708
6709         local expected=$NUMDIRS
6710         local cmd="$LFS find -c $OSTCOUNT $dir"
6711         local nums=$($cmd | wc -l)
6712
6713         [ $nums -eq $expected ] || {
6714                 $LFS getstripe -R $dir
6715                 error "'$cmd' wrong: found $nums, expected $expected"
6716         }
6717
6718         expected=$((NUMDIRS + onestripe))
6719         cmd="$LFS find -stripe-count +0 -type f $dir"
6720         nums=$($cmd | wc -l)
6721         [ $nums -eq $expected ] || {
6722                 $LFS getstripe -R $dir
6723                 error "'$cmd' wrong: found $nums, expected $expected"
6724         }
6725
6726         expected=$onestripe
6727         cmd="$LFS find -stripe-count 1 -type f $dir"
6728         nums=$($cmd | wc -l)
6729         [ $nums -eq $expected ] || {
6730                 $LFS getstripe -R $dir
6731                 error "'$cmd' wrong: found $nums, expected $expected"
6732         }
6733
6734         cmd="$LFS find -stripe-count -2 -type f $dir"
6735         nums=$($cmd | wc -l)
6736         [ $nums -eq $expected ] || {
6737                 $LFS getstripe -R $dir
6738                 error "'$cmd' wrong: found $nums, expected $expected"
6739         }
6740
6741         expected=0
6742         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6743         nums=$($cmd | wc -l)
6744         [ $nums -eq $expected ] || {
6745                 $LFS getstripe -R $dir
6746                 error "'$cmd' wrong: found $nums, expected $expected"
6747         }
6748 }
6749 run_test 56s "check lfs find -stripe-count works"
6750
6751 test_56t() { # LU-611 #LU-9369
6752         local dir=$DIR/$tdir
6753
6754         setup_56 $dir 0 $NUMDIRS
6755         for i in $(seq $NUMDIRS); do
6756                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6757         done
6758
6759         local expected=$NUMDIRS
6760         local cmd="$LFS find -S 8M $dir"
6761         local nums=$($cmd | wc -l)
6762
6763         [ $nums -eq $expected ] || {
6764                 $LFS getstripe -R $dir
6765                 error "'$cmd' wrong: found $nums, expected $expected"
6766         }
6767         rm -rf $dir
6768
6769         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6770
6771         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6772
6773         expected=$(((NUMDIRS + 1) * NUMFILES))
6774         cmd="$LFS find -stripe-size 512k -type f $dir"
6775         nums=$($cmd | wc -l)
6776         [ $nums -eq $expected ] ||
6777                 error "'$cmd' wrong: found $nums, expected $expected"
6778
6779         cmd="$LFS find -stripe-size +320k -type f $dir"
6780         nums=$($cmd | wc -l)
6781         [ $nums -eq $expected ] ||
6782                 error "'$cmd' wrong: found $nums, expected $expected"
6783
6784         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6785         cmd="$LFS find -stripe-size +200k -type f $dir"
6786         nums=$($cmd | wc -l)
6787         [ $nums -eq $expected ] ||
6788                 error "'$cmd' wrong: found $nums, expected $expected"
6789
6790         cmd="$LFS find -stripe-size -640k -type f $dir"
6791         nums=$($cmd | wc -l)
6792         [ $nums -eq $expected ] ||
6793                 error "'$cmd' wrong: found $nums, expected $expected"
6794
6795         expected=4
6796         cmd="$LFS find -stripe-size 256k -type f $dir"
6797         nums=$($cmd | wc -l)
6798         [ $nums -eq $expected ] ||
6799                 error "'$cmd' wrong: found $nums, expected $expected"
6800
6801         cmd="$LFS find -stripe-size -320k -type f $dir"
6802         nums=$($cmd | wc -l)
6803         [ $nums -eq $expected ] ||
6804                 error "'$cmd' wrong: found $nums, expected $expected"
6805
6806         expected=0
6807         cmd="$LFS find -stripe-size 1024k -type f $dir"
6808         nums=$($cmd | wc -l)
6809         [ $nums -eq $expected ] ||
6810                 error "'$cmd' wrong: found $nums, expected $expected"
6811 }
6812 run_test 56t "check lfs find -stripe-size works"
6813
6814 test_56u() { # LU-611
6815         local dir=$DIR/$tdir
6816
6817         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6818
6819         if [[ $OSTCOUNT -gt 1 ]]; then
6820                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6821                 onestripe=4
6822         else
6823                 onestripe=0
6824         fi
6825
6826         local expected=$(((NUMDIRS + 1) * NUMFILES))
6827         local cmd="$LFS find -stripe-index 0 -type f $dir"
6828         local nums=$($cmd | wc -l)
6829
6830         [ $nums -eq $expected ] ||
6831                 error "'$cmd' wrong: found $nums, expected $expected"
6832
6833         expected=$onestripe
6834         cmd="$LFS find -stripe-index 1 -type f $dir"
6835         nums=$($cmd | wc -l)
6836         [ $nums -eq $expected ] ||
6837                 error "'$cmd' wrong: found $nums, expected $expected"
6838
6839         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6840         nums=$($cmd | wc -l)
6841         [ $nums -eq $expected ] ||
6842                 error "'$cmd' wrong: found $nums, expected $expected"
6843
6844         expected=0
6845         # This should produce an error and not return any files
6846         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6847         nums=$($cmd 2>/dev/null | wc -l)
6848         [ $nums -eq $expected ] ||
6849                 error "'$cmd' wrong: found $nums, expected $expected"
6850
6851         if [[ $OSTCOUNT -gt 1 ]]; then
6852                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6853                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6854                 nums=$($cmd | wc -l)
6855                 [ $nums -eq $expected ] ||
6856                         error "'$cmd' wrong: found $nums, expected $expected"
6857         fi
6858 }
6859 run_test 56u "check lfs find -stripe-index works"
6860
6861 test_56v() {
6862         local mdt_idx=0
6863         local dir=$DIR/$tdir
6864
6865         setup_56 $dir $NUMFILES $NUMDIRS
6866
6867         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6868         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6869
6870         for file in $($LFS find -m $UUID $dir); do
6871                 file_midx=$($LFS getstripe -m $file)
6872                 [ $file_midx -eq $mdt_idx ] ||
6873                         error "lfs find -m $UUID != getstripe -m $file_midx"
6874         done
6875 }
6876 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6877
6878 test_56w() {
6879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6881
6882         local dir=$DIR/$tdir
6883
6884         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6885
6886         local stripe_size=$($LFS getstripe -S -d $dir) ||
6887                 error "$LFS getstripe -S -d $dir failed"
6888         stripe_size=${stripe_size%% *}
6889
6890         local file_size=$((stripe_size * OSTCOUNT))
6891         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6892         local required_space=$((file_num * file_size))
6893         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6894                            head -n1)
6895         [[ $free_space -le $((required_space / 1024)) ]] &&
6896                 skip_env "need $required_space, have $free_space kbytes"
6897
6898         local dd_bs=65536
6899         local dd_count=$((file_size / dd_bs))
6900
6901         # write data into the files
6902         local i
6903         local j
6904         local file
6905
6906         for i in $(seq $NUMFILES); do
6907                 file=$dir/file$i
6908                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6909                         error "write data into $file failed"
6910         done
6911         for i in $(seq $NUMDIRS); do
6912                 for j in $(seq $NUMFILES); do
6913                         file=$dir/dir$i/file$j
6914                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6915                                 error "write data into $file failed"
6916                 done
6917         done
6918
6919         # $LFS_MIGRATE will fail if hard link migration is unsupported
6920         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6921                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6922                         error "creating links to $dir/dir1/file1 failed"
6923         fi
6924
6925         local expected=-1
6926
6927         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6928
6929         # lfs_migrate file
6930         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6931
6932         echo "$cmd"
6933         eval $cmd || error "$cmd failed"
6934
6935         check_stripe_count $dir/file1 $expected
6936
6937         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6938         then
6939                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6940                 # OST 1 if it is on OST 0. This file is small enough to
6941                 # be on only one stripe.
6942                 file=$dir/migr_1_ost
6943                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6944                         error "write data into $file failed"
6945                 local obdidx=$($LFS getstripe -i $file)
6946                 local oldmd5=$(md5sum $file)
6947                 local newobdidx=0
6948
6949                 [[ $obdidx -eq 0 ]] && newobdidx=1
6950                 cmd="$LFS migrate -i $newobdidx $file"
6951                 echo $cmd
6952                 eval $cmd || error "$cmd failed"
6953
6954                 local realobdix=$($LFS getstripe -i $file)
6955                 local newmd5=$(md5sum $file)
6956
6957                 [[ $newobdidx -ne $realobdix ]] &&
6958                         error "new OST is different (was=$obdidx, "\
6959                               "wanted=$newobdidx, got=$realobdix)"
6960                 [[ "$oldmd5" != "$newmd5" ]] &&
6961                         error "md5sum differ: $oldmd5, $newmd5"
6962         fi
6963
6964         # lfs_migrate dir
6965         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6966         echo "$cmd"
6967         eval $cmd || error "$cmd failed"
6968
6969         for j in $(seq $NUMFILES); do
6970                 check_stripe_count $dir/dir1/file$j $expected
6971         done
6972
6973         # lfs_migrate works with lfs find
6974         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6975              $LFS_MIGRATE -y -c $expected"
6976         echo "$cmd"
6977         eval $cmd || error "$cmd failed"
6978
6979         for i in $(seq 2 $NUMFILES); do
6980                 check_stripe_count $dir/file$i $expected
6981         done
6982         for i in $(seq 2 $NUMDIRS); do
6983                 for j in $(seq $NUMFILES); do
6984                 check_stripe_count $dir/dir$i/file$j $expected
6985                 done
6986         done
6987 }
6988 run_test 56w "check lfs_migrate -c stripe_count works"
6989
6990 test_56wb() {
6991         local file1=$DIR/$tdir/file1
6992         local create_pool=false
6993         local initial_pool=$($LFS getstripe -p $DIR)
6994         local pool_list=()
6995         local pool=""
6996
6997         echo -n "Creating test dir..."
6998         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6999         echo "done."
7000
7001         echo -n "Creating test file..."
7002         touch $file1 || error "cannot create file"
7003         echo "done."
7004
7005         echo -n "Detecting existing pools..."
7006         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7007
7008         if [ ${#pool_list[@]} -gt 0 ]; then
7009                 echo "${pool_list[@]}"
7010                 for thispool in "${pool_list[@]}"; do
7011                         if [[ -z "$initial_pool" ||
7012                               "$initial_pool" != "$thispool" ]]; then
7013                                 pool="$thispool"
7014                                 echo "Using existing pool '$pool'"
7015                                 break
7016                         fi
7017                 done
7018         else
7019                 echo "none detected."
7020         fi
7021         if [ -z "$pool" ]; then
7022                 pool=${POOL:-testpool}
7023                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7024                 echo -n "Creating pool '$pool'..."
7025                 create_pool=true
7026                 pool_add $pool &> /dev/null ||
7027                         error "pool_add failed"
7028                 echo "done."
7029
7030                 echo -n "Adding target to pool..."
7031                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7032                         error "pool_add_targets failed"
7033                 echo "done."
7034         fi
7035
7036         echo -n "Setting pool using -p option..."
7037         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7038                 error "migrate failed rc = $?"
7039         echo "done."
7040
7041         echo -n "Verifying test file is in pool after migrating..."
7042         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7043                 error "file was not migrated to pool $pool"
7044         echo "done."
7045
7046         echo -n "Removing test file from pool '$pool'..."
7047         # "lfs migrate $file" won't remove the file from the pool
7048         # until some striping information is changed.
7049         $LFS migrate -c 1 $file1 &> /dev/null ||
7050                 error "cannot remove from pool"
7051         [ "$($LFS getstripe -p $file1)" ] &&
7052                 error "pool still set"
7053         echo "done."
7054
7055         echo -n "Setting pool using --pool option..."
7056         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7057                 error "migrate failed rc = $?"
7058         echo "done."
7059
7060         # Clean up
7061         rm -f $file1
7062         if $create_pool; then
7063                 destroy_test_pools 2> /dev/null ||
7064                         error "destroy test pools failed"
7065         fi
7066 }
7067 run_test 56wb "check lfs_migrate pool support"
7068
7069 test_56wc() {
7070         local file1="$DIR/$tdir/file1"
7071         local parent_ssize
7072         local parent_scount
7073         local cur_ssize
7074         local cur_scount
7075         local orig_ssize
7076
7077         echo -n "Creating test dir..."
7078         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7079         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7080                 error "cannot set stripe by '-S 1M -c 1'"
7081         echo "done"
7082
7083         echo -n "Setting initial stripe for test file..."
7084         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7085                 error "cannot set stripe"
7086         cur_ssize=$($LFS getstripe -S "$file1")
7087         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7088         echo "done."
7089
7090         # File currently set to -S 512K -c 1
7091
7092         # Ensure -c and -S options are rejected when -R is set
7093         echo -n "Verifying incompatible options are detected..."
7094         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7095                 error "incompatible -c and -R options not detected"
7096         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7097                 error "incompatible -S and -R options not detected"
7098         echo "done."
7099
7100         # Ensure unrecognized options are passed through to 'lfs migrate'
7101         echo -n "Verifying -S option is passed through to lfs migrate..."
7102         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7103                 error "migration failed"
7104         cur_ssize=$($LFS getstripe -S "$file1")
7105         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7106         echo "done."
7107
7108         # File currently set to -S 1M -c 1
7109
7110         # Ensure long options are supported
7111         echo -n "Verifying long options supported..."
7112         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7113                 error "long option without argument not supported"
7114         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7115                 error "long option with argument not supported"
7116         cur_ssize=$($LFS getstripe -S "$file1")
7117         [ $cur_ssize -eq 524288 ] ||
7118                 error "migrate --stripe-size $cur_ssize != 524288"
7119         echo "done."
7120
7121         # File currently set to -S 512K -c 1
7122
7123         if [ "$OSTCOUNT" -gt 1 ]; then
7124                 echo -n "Verifying explicit stripe count can be set..."
7125                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7126                         error "migrate failed"
7127                 cur_scount=$($LFS getstripe -c "$file1")
7128                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7129                 echo "done."
7130         fi
7131
7132         # File currently set to -S 512K -c 1 or -S 512K -c 2
7133
7134         # Ensure parent striping is used if -R is set, and no stripe
7135         # count or size is specified
7136         echo -n "Setting stripe for parent directory..."
7137         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7138                 error "cannot set stripe '-S 2M -c 1'"
7139         echo "done."
7140
7141         echo -n "Verifying restripe option uses parent stripe settings..."
7142         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7143         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7144         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7145                 error "migrate failed"
7146         cur_ssize=$($LFS getstripe -S "$file1")
7147         [ $cur_ssize -eq $parent_ssize ] ||
7148                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7149         cur_scount=$($LFS getstripe -c "$file1")
7150         [ $cur_scount -eq $parent_scount ] ||
7151                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7152         echo "done."
7153
7154         # File currently set to -S 1M -c 1
7155
7156         # Ensure striping is preserved if -R is not set, and no stripe
7157         # count or size is specified
7158         echo -n "Verifying striping size preserved when not specified..."
7159         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7160         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7161                 error "cannot set stripe on parent directory"
7162         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7163                 error "migrate failed"
7164         cur_ssize=$($LFS getstripe -S "$file1")
7165         [ $cur_ssize -eq $orig_ssize ] ||
7166                 error "migrate by default $cur_ssize != $orig_ssize"
7167         echo "done."
7168
7169         # Ensure file name properly detected when final option has no argument
7170         echo -n "Verifying file name properly detected..."
7171         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7172                 error "file name interpreted as option argument"
7173         echo "done."
7174
7175         # Clean up
7176         rm -f "$file1"
7177 }
7178 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7179
7180 test_56wd() {
7181         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7182
7183         local file1=$DIR/$tdir/file1
7184
7185         echo -n "Creating test dir..."
7186         test_mkdir $DIR/$tdir || error "cannot create dir"
7187         echo "done."
7188
7189         echo -n "Creating test file..."
7190         touch $file1
7191         echo "done."
7192
7193         # Ensure 'lfs migrate' will fail by using a non-existent option,
7194         # and make sure rsync is not called to recover
7195         echo -n "Make sure --no-rsync option works..."
7196         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7197                 grep -q 'refusing to fall back to rsync' ||
7198                 error "rsync was called with --no-rsync set"
7199         echo "done."
7200
7201         # Ensure rsync is called without trying 'lfs migrate' first
7202         echo -n "Make sure --rsync option works..."
7203         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7204                 grep -q 'falling back to rsync' &&
7205                 error "lfs migrate was called with --rsync set"
7206         echo "done."
7207
7208         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7209         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7210                 grep -q 'at the same time' ||
7211                 error "--rsync and --no-rsync accepted concurrently"
7212         echo "done."
7213
7214         # Clean up
7215         rm -f $file1
7216 }
7217 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7218
7219 test_56we() {
7220         local td=$DIR/$tdir
7221         local tf=$td/$tfile
7222
7223         test_mkdir $td || error "cannot create $td"
7224         touch $tf || error "cannot touch $tf"
7225
7226         echo -n "Make sure --non-direct|-D works..."
7227         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7228                 grep -q "lfs migrate --non-direct" ||
7229                 error "--non-direct option cannot work correctly"
7230         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7231                 grep -q "lfs migrate -D" ||
7232                 error "-D option cannot work correctly"
7233         echo "done."
7234 }
7235 run_test 56we "check lfs_migrate --non-direct|-D support"
7236
7237 test_56x() {
7238         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7239         check_swap_layouts_support
7240
7241         local dir=$DIR/$tdir
7242         local ref1=/etc/passwd
7243         local file1=$dir/file1
7244
7245         test_mkdir $dir || error "creating dir $dir"
7246         $LFS setstripe -c 2 $file1
7247         cp $ref1 $file1
7248         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7249         stripe=$($LFS getstripe -c $file1)
7250         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7251         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7252
7253         # clean up
7254         rm -f $file1
7255 }
7256 run_test 56x "lfs migration support"
7257
7258 test_56xa() {
7259         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7260         check_swap_layouts_support
7261
7262         local dir=$DIR/$tdir/$testnum
7263
7264         test_mkdir -p $dir
7265
7266         local ref1=/etc/passwd
7267         local file1=$dir/file1
7268
7269         $LFS setstripe -c 2 $file1
7270         cp $ref1 $file1
7271         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7272
7273         local stripe=$($LFS getstripe -c $file1)
7274
7275         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7276         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7277
7278         # clean up
7279         rm -f $file1
7280 }
7281 run_test 56xa "lfs migration --block support"
7282
7283 check_migrate_links() {
7284         local dir="$1"
7285         local file1="$dir/file1"
7286         local begin="$2"
7287         local count="$3"
7288         local runas="$4"
7289         local total_count=$(($begin + $count - 1))
7290         local symlink_count=10
7291         local uniq_count=10
7292
7293         if [ ! -f "$file1" ]; then
7294                 echo -n "creating initial file..."
7295                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7296                         error "cannot setstripe initial file"
7297                 echo "done"
7298
7299                 echo -n "creating symlinks..."
7300                 for s in $(seq 1 $symlink_count); do
7301                         ln -s "$file1" "$dir/slink$s" ||
7302                                 error "cannot create symlinks"
7303                 done
7304                 echo "done"
7305
7306                 echo -n "creating nonlinked files..."
7307                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7308                         error "cannot create nonlinked files"
7309                 echo "done"
7310         fi
7311
7312         # create hard links
7313         if [ ! -f "$dir/file$total_count" ]; then
7314                 echo -n "creating hard links $begin:$total_count..."
7315                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7316                         /dev/null || error "cannot create hard links"
7317                 echo "done"
7318         fi
7319
7320         echo -n "checking number of hard links listed in xattrs..."
7321         local fid=$($LFS getstripe -F "$file1")
7322         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7323
7324         echo "${#paths[*]}"
7325         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7326                         skip "hard link list has unexpected size, skipping test"
7327         fi
7328         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7329                         error "link names should exceed xattrs size"
7330         fi
7331
7332         echo -n "migrating files..."
7333         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7334         local rc=$?
7335         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7336         echo "done"
7337
7338         # make sure all links have been properly migrated
7339         echo -n "verifying files..."
7340         fid=$($LFS getstripe -F "$file1") ||
7341                 error "cannot get fid for file $file1"
7342         for i in $(seq 2 $total_count); do
7343                 local fid2=$($LFS getstripe -F $dir/file$i)
7344
7345                 [ "$fid2" == "$fid" ] ||
7346                         error "migrated hard link has mismatched FID"
7347         done
7348
7349         # make sure hard links were properly detected, and migration was
7350         # performed only once for the entire link set; nonlinked files should
7351         # also be migrated
7352         local actual=$(grep -c 'done' <<< "$migrate_out")
7353         local expected=$(($uniq_count + 1))
7354
7355         [ "$actual" -eq  "$expected" ] ||
7356                 error "hard links individually migrated ($actual != $expected)"
7357
7358         # make sure the correct number of hard links are present
7359         local hardlinks=$(stat -c '%h' "$file1")
7360
7361         [ $hardlinks -eq $total_count ] ||
7362                 error "num hard links $hardlinks != $total_count"
7363         echo "done"
7364
7365         return 0
7366 }
7367
7368 test_56xb() {
7369         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7370                 skip "Need MDS version at least 2.10.55"
7371
7372         local dir="$DIR/$tdir"
7373
7374         test_mkdir "$dir" || error "cannot create dir $dir"
7375
7376         echo "testing lfs migrate mode when all links fit within xattrs"
7377         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7378
7379         echo "testing rsync mode when all links fit within xattrs"
7380         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7381
7382         echo "testing lfs migrate mode when all links do not fit within xattrs"
7383         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7384
7385         echo "testing rsync mode when all links do not fit within xattrs"
7386         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7387
7388         chown -R $RUNAS_ID $dir
7389         echo "testing non-root lfs migrate mode when not all links are in xattr"
7390         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7391
7392         # clean up
7393         rm -rf $dir
7394 }
7395 run_test 56xb "lfs migration hard link support"
7396
7397 test_56xc() {
7398         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7399
7400         local dir="$DIR/$tdir"
7401
7402         test_mkdir "$dir" || error "cannot create dir $dir"
7403
7404         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7405         echo -n "Setting initial stripe for 20MB test file..."
7406         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7407                 error "cannot setstripe 20MB file"
7408         echo "done"
7409         echo -n "Sizing 20MB test file..."
7410         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7411         echo "done"
7412         echo -n "Verifying small file autostripe count is 1..."
7413         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7414                 error "cannot migrate 20MB file"
7415         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7416                 error "cannot get stripe for $dir/20mb"
7417         [ $stripe_count -eq 1 ] ||
7418                 error "unexpected stripe count $stripe_count for 20MB file"
7419         rm -f "$dir/20mb"
7420         echo "done"
7421
7422         # Test 2: File is small enough to fit within the available space on
7423         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7424         # have at least an additional 1KB for each desired stripe for test 3
7425         echo -n "Setting stripe for 1GB test file..."
7426         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7427         echo "done"
7428         echo -n "Sizing 1GB test file..."
7429         # File size is 1GB + 3KB
7430         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7431         echo "done"
7432
7433         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7434         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7435         if (( avail > 524288 * OSTCOUNT )); then
7436                 echo -n "Migrating 1GB file..."
7437                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7438                         error "cannot migrate 1GB file"
7439                 echo "done"
7440                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7441                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7442                         error "cannot getstripe for 1GB file"
7443                 [ $stripe_count -eq 2 ] ||
7444                         error "unexpected stripe count $stripe_count != 2"
7445                 echo "done"
7446         fi
7447
7448         # Test 3: File is too large to fit within the available space on
7449         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7450         if [ $OSTCOUNT -ge 3 ]; then
7451                 # The required available space is calculated as
7452                 # file size (1GB + 3KB) / OST count (3).
7453                 local kb_per_ost=349526
7454
7455                 echo -n "Migrating 1GB file with limit..."
7456                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7457                         error "cannot migrate 1GB file with limit"
7458                 echo "done"
7459
7460                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7461                 echo -n "Verifying 1GB autostripe count with limited space..."
7462                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7463                         error "unexpected stripe count $stripe_count (min 3)"
7464                 echo "done"
7465         fi
7466
7467         # clean up
7468         rm -rf $dir
7469 }
7470 run_test 56xc "lfs migration autostripe"
7471
7472 test_56xd() {
7473         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7474
7475         local dir=$DIR/$tdir
7476         local f_mgrt=$dir/$tfile.mgrt
7477         local f_yaml=$dir/$tfile.yaml
7478         local f_copy=$dir/$tfile.copy
7479         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7480         local layout_copy="-c 2 -S 2M -i 1"
7481         local yamlfile=$dir/yamlfile
7482         local layout_before;
7483         local layout_after;
7484
7485         test_mkdir "$dir" || error "cannot create dir $dir"
7486         $LFS setstripe $layout_yaml $f_yaml ||
7487                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7488         $LFS getstripe --yaml $f_yaml > $yamlfile
7489         $LFS setstripe $layout_copy $f_copy ||
7490                 error "cannot setstripe $f_copy with layout $layout_copy"
7491         touch $f_mgrt
7492         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7493
7494         # 1. test option --yaml
7495         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7496                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7497         layout_before=$(get_layout_param $f_yaml)
7498         layout_after=$(get_layout_param $f_mgrt)
7499         [ "$layout_after" == "$layout_before" ] ||
7500                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7501
7502         # 2. test option --copy
7503         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7504                 error "cannot migrate $f_mgrt with --copy $f_copy"
7505         layout_before=$(get_layout_param $f_copy)
7506         layout_after=$(get_layout_param $f_mgrt)
7507         [ "$layout_after" == "$layout_before" ] ||
7508                 error "lfs_migrate --copy: $layout_after != $layout_before"
7509 }
7510 run_test 56xd "check lfs_migrate --yaml and --copy support"
7511
7512 test_56xe() {
7513         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7514
7515         local dir=$DIR/$tdir
7516         local f_comp=$dir/$tfile
7517         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7518         local layout_before=""
7519         local layout_after=""
7520
7521         test_mkdir "$dir" || error "cannot create dir $dir"
7522         $LFS setstripe $layout $f_comp ||
7523                 error "cannot setstripe $f_comp with layout $layout"
7524         layout_before=$(get_layout_param $f_comp)
7525         dd if=/dev/zero of=$f_comp bs=1M count=4
7526
7527         # 1. migrate a comp layout file by lfs_migrate
7528         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7529         layout_after=$(get_layout_param $f_comp)
7530         [ "$layout_before" == "$layout_after" ] ||
7531                 error "lfs_migrate: $layout_before != $layout_after"
7532
7533         # 2. migrate a comp layout file by lfs migrate
7534         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7535         layout_after=$(get_layout_param $f_comp)
7536         [ "$layout_before" == "$layout_after" ] ||
7537                 error "lfs migrate: $layout_before != $layout_after"
7538 }
7539 run_test 56xe "migrate a composite layout file"
7540
7541 test_56xf() {
7542         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7543
7544         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7545                 skip "Need server version at least 2.13.53"
7546
7547         local dir=$DIR/$tdir
7548         local f_comp=$dir/$tfile
7549         local layout="-E 1M -c1 -E -1 -c2"
7550         local fid_before=""
7551         local fid_after=""
7552
7553         test_mkdir "$dir" || error "cannot create dir $dir"
7554         $LFS setstripe $layout $f_comp ||
7555                 error "cannot setstripe $f_comp with layout $layout"
7556         fid_before=$($LFS getstripe --fid $f_comp)
7557         dd if=/dev/zero of=$f_comp bs=1M count=4
7558
7559         # 1. migrate a comp layout file to a comp layout
7560         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7561         fid_after=$($LFS getstripe --fid $f_comp)
7562         [ "$fid_before" == "$fid_after" ] ||
7563                 error "comp-to-comp migrate: $fid_before != $fid_after"
7564
7565         # 2. migrate a comp layout file to a plain layout
7566         $LFS migrate -c2 $f_comp ||
7567                 error "cannot migrate $f_comp by lfs migrate"
7568         fid_after=$($LFS getstripe --fid $f_comp)
7569         [ "$fid_before" == "$fid_after" ] ||
7570                 error "comp-to-plain migrate: $fid_before != $fid_after"
7571
7572         # 3. migrate a plain layout file to a comp layout
7573         $LFS migrate $layout $f_comp ||
7574                 error "cannot migrate $f_comp by lfs migrate"
7575         fid_after=$($LFS getstripe --fid $f_comp)
7576         [ "$fid_before" == "$fid_after" ] ||
7577                 error "plain-to-comp migrate: $fid_before != $fid_after"
7578 }
7579 run_test 56xf "FID is not lost during migration of a composite layout file"
7580
7581 test_56y() {
7582         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7583                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7584
7585         local res=""
7586         local dir=$DIR/$tdir
7587         local f1=$dir/file1
7588         local f2=$dir/file2
7589
7590         test_mkdir -p $dir || error "creating dir $dir"
7591         touch $f1 || error "creating std file $f1"
7592         $MULTIOP $f2 H2c || error "creating released file $f2"
7593
7594         # a directory can be raid0, so ask only for files
7595         res=$($LFS find $dir -L raid0 -type f | wc -l)
7596         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7597
7598         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7599         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7600
7601         # only files can be released, so no need to force file search
7602         res=$($LFS find $dir -L released)
7603         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7604
7605         res=$($LFS find $dir -type f \! -L released)
7606         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7607 }
7608 run_test 56y "lfs find -L raid0|released"
7609
7610 test_56z() { # LU-4824
7611         # This checks to make sure 'lfs find' continues after errors
7612         # There are two classes of errors that should be caught:
7613         # - If multiple paths are provided, all should be searched even if one
7614         #   errors out
7615         # - If errors are encountered during the search, it should not terminate
7616         #   early
7617         local dir=$DIR/$tdir
7618         local i
7619
7620         test_mkdir $dir
7621         for i in d{0..9}; do
7622                 test_mkdir $dir/$i
7623                 touch $dir/$i/$tfile
7624         done
7625         $LFS find $DIR/non_existent_dir $dir &&
7626                 error "$LFS find did not return an error"
7627         # Make a directory unsearchable. This should NOT be the last entry in
7628         # directory order.  Arbitrarily pick the 6th entry
7629         chmod 700 $($LFS find $dir -type d | sed '6!d')
7630
7631         $RUNAS $LFS find $DIR/non_existent $dir
7632         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7633
7634         # The user should be able to see 10 directories and 9 files
7635         (( count == 19 )) ||
7636                 error "$LFS find found $count != 19 entries after error"
7637 }
7638 run_test 56z "lfs find should continue after an error"
7639
7640 test_56aa() { # LU-5937
7641         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7642
7643         local dir=$DIR/$tdir
7644
7645         mkdir $dir
7646         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7647
7648         createmany -o $dir/striped_dir/${tfile}- 1024
7649         local dirs=$($LFS find --size +8k $dir/)
7650
7651         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7652 }
7653 run_test 56aa "lfs find --size under striped dir"
7654
7655 test_56ab() { # LU-10705
7656         test_mkdir $DIR/$tdir
7657         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7658         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7659         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7660         # Flush writes to ensure valid blocks.  Need to be more thorough for
7661         # ZFS, since blocks are not allocated/returned to client immediately.
7662         sync_all_data
7663         wait_zfs_commit ost1 2
7664         cancel_lru_locks osc
7665         ls -ls $DIR/$tdir
7666
7667         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7668
7669         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7670
7671         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7672         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7673
7674         rm -f $DIR/$tdir/$tfile.[123]
7675 }
7676 run_test 56ab "lfs find --blocks"
7677
7678 # LU-11188
7679 test_56aca() {
7680         local dir="$DIR/$tdir"
7681         local perms=(001 002 003 004 005 006 007
7682                      010 020 030 040 050 060 070
7683                      100 200 300 400 500 600 700
7684                      111 222 333 444 555 666 777)
7685         local perm_minus=(8 8 4 8 4 4 2
7686                           8 8 4 8 4 4 2
7687                           8 8 4 8 4 4 2
7688                           4 4 2 4 2 2 1)
7689         local perm_slash=(8  8 12  8 12 12 14
7690                           8  8 12  8 12 12 14
7691                           8  8 12  8 12 12 14
7692                          16 16 24 16 24 24 28)
7693
7694         test_mkdir "$dir"
7695         for perm in ${perms[*]}; do
7696                 touch "$dir/$tfile.$perm"
7697                 chmod $perm "$dir/$tfile.$perm"
7698         done
7699
7700         for ((i = 0; i < ${#perms[*]}; i++)); do
7701                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7702                 (( $num == 1 )) ||
7703                         error "lfs find -perm ${perms[i]}:"\
7704                               "$num != 1"
7705
7706                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7707                 (( $num == ${perm_minus[i]} )) ||
7708                         error "lfs find -perm -${perms[i]}:"\
7709                               "$num != ${perm_minus[i]}"
7710
7711                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7712                 (( $num == ${perm_slash[i]} )) ||
7713                         error "lfs find -perm /${perms[i]}:"\
7714                               "$num != ${perm_slash[i]}"
7715         done
7716 }
7717 run_test 56aca "check lfs find -perm with octal representation"
7718
7719 test_56acb() {
7720         local dir=$DIR/$tdir
7721         # p is the permission of write and execute for user, group and other
7722         # without the umask. It is used to test +wx.
7723         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7724         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7725         local symbolic=(+t  a+t u+t g+t o+t
7726                         g+s u+s o+s +s o+sr
7727                         o=r,ug+o,u+w
7728                         u+ g+ o+ a+ ugo+
7729                         u- g- o- a- ugo-
7730                         u= g= o= a= ugo=
7731                         o=r,ug+o,u+w u=r,a+u,u+w
7732                         g=r,ugo=g,u+w u+x,+X +X
7733                         u+x,u+X u+X u+x,g+X o+r,+X
7734                         u+x,go+X +wx +rwx)
7735
7736         test_mkdir $dir
7737         for perm in ${perms[*]}; do
7738                 touch "$dir/$tfile.$perm"
7739                 chmod $perm "$dir/$tfile.$perm"
7740         done
7741
7742         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7743                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7744
7745                 (( $num == 1 )) ||
7746                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7747         done
7748 }
7749 run_test 56acb "check lfs find -perm with symbolic representation"
7750
7751 test_56acc() {
7752         local dir=$DIR/$tdir
7753         local tests="17777 787 789 abcd
7754                 ug=uu ug=a ug=gu uo=ou urw
7755                 u+xg+x a=r,u+x,"
7756
7757         test_mkdir $dir
7758         for err in $tests; do
7759                 if $LFS find $dir -perm $err 2>/dev/null; then
7760                         error "lfs find -perm $err: parsing should have failed"
7761                 fi
7762         done
7763 }
7764 run_test 56acc "check parsing error for lfs find -perm"
7765
7766 test_56ba() {
7767         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7768                 skip "Need MDS version at least 2.10.50"
7769
7770         # Create composite files with one component
7771         local dir=$DIR/$tdir
7772
7773         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7774         # Create composite files with three components
7775         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7776         # Create non-composite files
7777         createmany -o $dir/${tfile}- 10
7778
7779         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7780
7781         [[ $nfiles == 10 ]] ||
7782                 error "lfs find -E 1M found $nfiles != 10 files"
7783
7784         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7785         [[ $nfiles == 25 ]] ||
7786                 error "lfs find ! -E 1M found $nfiles != 25 files"
7787
7788         # All files have a component that starts at 0
7789         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7790         [[ $nfiles == 35 ]] ||
7791                 error "lfs find --component-start 0 - $nfiles != 35 files"
7792
7793         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7794         [[ $nfiles == 15 ]] ||
7795                 error "lfs find --component-start 2M - $nfiles != 15 files"
7796
7797         # All files created here have a componenet that does not starts at 2M
7798         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7799         [[ $nfiles == 35 ]] ||
7800                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7801
7802         # Find files with a specified number of components
7803         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7804         [[ $nfiles == 15 ]] ||
7805                 error "lfs find --component-count 3 - $nfiles != 15 files"
7806
7807         # Remember non-composite files have a component count of zero
7808         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7809         [[ $nfiles == 10 ]] ||
7810                 error "lfs find --component-count 0 - $nfiles != 10 files"
7811
7812         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7813         [[ $nfiles == 20 ]] ||
7814                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7815
7816         # All files have a flag called "init"
7817         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7818         [[ $nfiles == 35 ]] ||
7819                 error "lfs find --component-flags init - $nfiles != 35 files"
7820
7821         # Multi-component files will have a component not initialized
7822         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7823         [[ $nfiles == 15 ]] ||
7824                 error "lfs find !--component-flags init - $nfiles != 15 files"
7825
7826         rm -rf $dir
7827
7828 }
7829 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7830
7831 test_56ca() {
7832         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7833                 skip "Need MDS version at least 2.10.57"
7834
7835         local td=$DIR/$tdir
7836         local tf=$td/$tfile
7837         local dir
7838         local nfiles
7839         local cmd
7840         local i
7841         local j
7842
7843         # create mirrored directories and mirrored files
7844         mkdir $td || error "mkdir $td failed"
7845         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7846         createmany -o $tf- 10 || error "create $tf- failed"
7847
7848         for i in $(seq 2); do
7849                 dir=$td/dir$i
7850                 mkdir $dir || error "mkdir $dir failed"
7851                 $LFS mirror create -N$((3 + i)) $dir ||
7852                         error "create mirrored dir $dir failed"
7853                 createmany -o $dir/$tfile- 10 ||
7854                         error "create $dir/$tfile- failed"
7855         done
7856
7857         # change the states of some mirrored files
7858         echo foo > $tf-6
7859         for i in $(seq 2); do
7860                 dir=$td/dir$i
7861                 for j in $(seq 4 9); do
7862                         echo foo > $dir/$tfile-$j
7863                 done
7864         done
7865
7866         # find mirrored files with specific mirror count
7867         cmd="$LFS find --mirror-count 3 --type f $td"
7868         nfiles=$($cmd | wc -l)
7869         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7870
7871         cmd="$LFS find ! --mirror-count 3 --type f $td"
7872         nfiles=$($cmd | wc -l)
7873         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7874
7875         cmd="$LFS find --mirror-count +2 --type f $td"
7876         nfiles=$($cmd | wc -l)
7877         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7878
7879         cmd="$LFS find --mirror-count -6 --type f $td"
7880         nfiles=$($cmd | wc -l)
7881         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7882
7883         # find mirrored files with specific file state
7884         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7885         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7886
7887         cmd="$LFS find --mirror-state=ro --type f $td"
7888         nfiles=$($cmd | wc -l)
7889         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7890
7891         cmd="$LFS find ! --mirror-state=ro --type f $td"
7892         nfiles=$($cmd | wc -l)
7893         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7894
7895         cmd="$LFS find --mirror-state=wp --type f $td"
7896         nfiles=$($cmd | wc -l)
7897         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7898
7899         cmd="$LFS find ! --mirror-state=sp --type f $td"
7900         nfiles=$($cmd | wc -l)
7901         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7902 }
7903 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7904
7905 test_56da() { # LU-14179
7906         local path=$DIR/$tdir
7907
7908         test_mkdir $path
7909         cd $path
7910
7911         local longdir=$(str_repeat 'a' 255)
7912
7913         for i in {1..15}; do
7914                 path=$path/$longdir
7915                 test_mkdir $longdir
7916                 cd $longdir
7917         done
7918
7919         local len=${#path}
7920         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7921
7922         test_mkdir $lastdir
7923         cd $lastdir
7924         # PATH_MAX-1
7925         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7926
7927         # NAME_MAX
7928         touch $(str_repeat 'f' 255)
7929
7930         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7931                 error "lfs find reported an error"
7932
7933         rm -rf $DIR/$tdir
7934 }
7935 run_test 56da "test lfs find with long paths"
7936
7937 test_57a() {
7938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7939         # note test will not do anything if MDS is not local
7940         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7941                 skip_env "ldiskfs only test"
7942         fi
7943         remote_mds_nodsh && skip "remote MDS with nodsh"
7944
7945         local MNTDEV="osd*.*MDT*.mntdev"
7946         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7947         [ -z "$DEV" ] && error "can't access $MNTDEV"
7948         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7949                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7950                         error "can't access $DEV"
7951                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7952                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7953                 rm $TMP/t57a.dump
7954         done
7955 }
7956 run_test 57a "verify MDS filesystem created with large inodes =="
7957
7958 test_57b() {
7959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7960         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7961                 skip_env "ldiskfs only test"
7962         fi
7963         remote_mds_nodsh && skip "remote MDS with nodsh"
7964
7965         local dir=$DIR/$tdir
7966         local filecount=100
7967         local file1=$dir/f1
7968         local fileN=$dir/f$filecount
7969
7970         rm -rf $dir || error "removing $dir"
7971         test_mkdir -c1 $dir
7972         local mdtidx=$($LFS getstripe -m $dir)
7973         local mdtname=MDT$(printf %04x $mdtidx)
7974         local facet=mds$((mdtidx + 1))
7975
7976         echo "mcreating $filecount files"
7977         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7978
7979         # verify that files do not have EAs yet
7980         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7981                 error "$file1 has an EA"
7982         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7983                 error "$fileN has an EA"
7984
7985         sync
7986         sleep 1
7987         df $dir  #make sure we get new statfs data
7988         local mdsfree=$(do_facet $facet \
7989                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7990         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7991         local file
7992
7993         echo "opening files to create objects/EAs"
7994         for file in $(seq -f $dir/f%g 1 $filecount); do
7995                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7996                         error "opening $file"
7997         done
7998
7999         # verify that files have EAs now
8000         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8001         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8002
8003         sleep 1  #make sure we get new statfs data
8004         df $dir
8005         local mdsfree2=$(do_facet $facet \
8006                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8007         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8008
8009         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8010                 if [ "$mdsfree" != "$mdsfree2" ]; then
8011                         error "MDC before $mdcfree != after $mdcfree2"
8012                 else
8013                         echo "MDC before $mdcfree != after $mdcfree2"
8014                         echo "unable to confirm if MDS has large inodes"
8015                 fi
8016         fi
8017         rm -rf $dir
8018 }
8019 run_test 57b "default LOV EAs are stored inside large inodes ==="
8020
8021 test_58() {
8022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8023         [ -z "$(which wiretest 2>/dev/null)" ] &&
8024                         skip_env "could not find wiretest"
8025
8026         wiretest
8027 }
8028 run_test 58 "verify cross-platform wire constants =============="
8029
8030 test_59() {
8031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8032
8033         echo "touch 130 files"
8034         createmany -o $DIR/f59- 130
8035         echo "rm 130 files"
8036         unlinkmany $DIR/f59- 130
8037         sync
8038         # wait for commitment of removal
8039         wait_delete_completed
8040 }
8041 run_test 59 "verify cancellation of llog records async ========="
8042
8043 TEST60_HEAD="test_60 run $RANDOM"
8044 test_60a() {
8045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8046         remote_mgs_nodsh && skip "remote MGS with nodsh"
8047         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8048                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8049                         skip_env "missing subtest run-llog.sh"
8050
8051         log "$TEST60_HEAD - from kernel mode"
8052         do_facet mgs "$LCTL dk > /dev/null"
8053         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8054         do_facet mgs $LCTL dk > $TMP/$tfile
8055
8056         # LU-6388: test llog_reader
8057         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8058         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8059         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8060                         skip_env "missing llog_reader"
8061         local fstype=$(facet_fstype mgs)
8062         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8063                 skip_env "Only for ldiskfs or zfs type mgs"
8064
8065         local mntpt=$(facet_mntpt mgs)
8066         local mgsdev=$(mgsdevname 1)
8067         local fid_list
8068         local fid
8069         local rec_list
8070         local rec
8071         local rec_type
8072         local obj_file
8073         local path
8074         local seq
8075         local oid
8076         local pass=true
8077
8078         #get fid and record list
8079         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8080                 tail -n 4))
8081         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8082                 tail -n 4))
8083         #remount mgs as ldiskfs or zfs type
8084         stop mgs || error "stop mgs failed"
8085         mount_fstype mgs || error "remount mgs failed"
8086         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8087                 fid=${fid_list[i]}
8088                 rec=${rec_list[i]}
8089                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8090                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8091                 oid=$((16#$oid))
8092
8093                 case $fstype in
8094                         ldiskfs )
8095                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8096                         zfs )
8097                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8098                 esac
8099                 echo "obj_file is $obj_file"
8100                 do_facet mgs $llog_reader $obj_file
8101
8102                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8103                         awk '{ print $3 }' | sed -e "s/^type=//g")
8104                 if [ $rec_type != $rec ]; then
8105                         echo "FAILED test_60a wrong record type $rec_type," \
8106                               "should be $rec"
8107                         pass=false
8108                         break
8109                 fi
8110
8111                 #check obj path if record type is LLOG_LOGID_MAGIC
8112                 if [ "$rec" == "1064553b" ]; then
8113                         path=$(do_facet mgs $llog_reader $obj_file |
8114                                 grep "path=" | awk '{ print $NF }' |
8115                                 sed -e "s/^path=//g")
8116                         if [ $obj_file != $mntpt/$path ]; then
8117                                 echo "FAILED test_60a wrong obj path" \
8118                                       "$montpt/$path, should be $obj_file"
8119                                 pass=false
8120                                 break
8121                         fi
8122                 fi
8123         done
8124         rm -f $TMP/$tfile
8125         #restart mgs before "error", otherwise it will block the next test
8126         stop mgs || error "stop mgs failed"
8127         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8128         $pass || error "test failed, see FAILED test_60a messages for specifics"
8129 }
8130 run_test 60a "llog_test run from kernel module and test llog_reader"
8131
8132 test_60b() { # bug 6411
8133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8134
8135         dmesg > $DIR/$tfile
8136         LLOG_COUNT=$(do_facet mgs dmesg |
8137                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8138                           /llog_[a-z]*.c:[0-9]/ {
8139                                 if (marker)
8140                                         from_marker++
8141                                 from_begin++
8142                           }
8143                           END {
8144                                 if (marker)
8145                                         print from_marker
8146                                 else
8147                                         print from_begin
8148                           }")
8149
8150         [[ $LLOG_COUNT -gt 120 ]] &&
8151                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8152 }
8153 run_test 60b "limit repeated messages from CERROR/CWARN"
8154
8155 test_60c() {
8156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8157
8158         echo "create 5000 files"
8159         createmany -o $DIR/f60c- 5000
8160 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8161         lctl set_param fail_loc=0x80000137
8162         unlinkmany $DIR/f60c- 5000
8163         lctl set_param fail_loc=0
8164 }
8165 run_test 60c "unlink file when mds full"
8166
8167 test_60d() {
8168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8169
8170         SAVEPRINTK=$(lctl get_param -n printk)
8171         # verify "lctl mark" is even working"
8172         MESSAGE="test message ID $RANDOM $$"
8173         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8174         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8175
8176         lctl set_param printk=0 || error "set lnet.printk failed"
8177         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8178         MESSAGE="new test message ID $RANDOM $$"
8179         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8180         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8181         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8182
8183         lctl set_param -n printk="$SAVEPRINTK"
8184 }
8185 run_test 60d "test printk console message masking"
8186
8187 test_60e() {
8188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8189         remote_mds_nodsh && skip "remote MDS with nodsh"
8190
8191         touch $DIR/$tfile
8192 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8193         do_facet mds1 lctl set_param fail_loc=0x15b
8194         rm $DIR/$tfile
8195 }
8196 run_test 60e "no space while new llog is being created"
8197
8198 test_60f() {
8199         local old_path=$($LCTL get_param -n debug_path)
8200
8201         stack_trap "$LCTL set_param debug_path=$old_path"
8202         stack_trap "rm -f $TMP/$tfile*"
8203         rm -f $TMP/$tfile* 2> /dev/null
8204         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8205         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8206         test_mkdir $DIR/$tdir
8207         # retry in case the open is cached and not released
8208         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8209                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8210                 sleep 0.1
8211         done
8212         ls $TMP/$tfile*
8213         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8214 }
8215 run_test 60f "change debug_path works"
8216
8217 test_60g() {
8218         local pid
8219         local i
8220
8221         test_mkdir -c $MDSCOUNT $DIR/$tdir
8222
8223         (
8224                 local index=0
8225                 while true; do
8226                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8227                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8228                                 2>/dev/null
8229                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8230                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8231                         index=$((index + 1))
8232                 done
8233         ) &
8234
8235         pid=$!
8236
8237         for i in {0..100}; do
8238                 # define OBD_FAIL_OSD_TXN_START    0x19a
8239                 local index=$((i % MDSCOUNT + 1))
8240
8241                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8242                         > /dev/null
8243                 sleep 0.01
8244         done
8245
8246         kill -9 $pid
8247
8248         for i in $(seq $MDSCOUNT); do
8249                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8250         done
8251
8252         mkdir $DIR/$tdir/new || error "mkdir failed"
8253         rmdir $DIR/$tdir/new || error "rmdir failed"
8254
8255         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8256                 -t namespace
8257         for i in $(seq $MDSCOUNT); do
8258                 wait_update_facet mds$i "$LCTL get_param -n \
8259                         mdd.$(facet_svc mds$i).lfsck_namespace |
8260                         awk '/^status/ { print \\\$2 }'" "completed"
8261         done
8262
8263         ls -R $DIR/$tdir || error "ls failed"
8264         rm -rf $DIR/$tdir || error "rmdir failed"
8265 }
8266 run_test 60g "transaction abort won't cause MDT hung"
8267
8268 test_60h() {
8269         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8270                 skip "Need MDS version at least 2.12.52"
8271         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8272
8273         local f
8274
8275         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8276         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8277         for fail_loc in 0x80000188 0x80000189; do
8278                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8279                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8280                         error "mkdir $dir-$fail_loc failed"
8281                 for i in {0..10}; do
8282                         # create may fail on missing stripe
8283                         echo $i > $DIR/$tdir-$fail_loc/$i
8284                 done
8285                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8286                         error "getdirstripe $tdir-$fail_loc failed"
8287                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8288                         error "migrate $tdir-$fail_loc failed"
8289                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8290                         error "getdirstripe $tdir-$fail_loc failed"
8291                 pushd $DIR/$tdir-$fail_loc
8292                 for f in *; do
8293                         echo $f | cmp $f - || error "$f data mismatch"
8294                 done
8295                 popd
8296                 rm -rf $DIR/$tdir-$fail_loc
8297         done
8298 }
8299 run_test 60h "striped directory with missing stripes can be accessed"
8300
8301 function t60i_load() {
8302         mkdir $DIR/$tdir
8303         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8304         $LCTL set_param fail_loc=0x131c fail_val=1
8305         for ((i=0; i<5000; i++)); do
8306                 touch $DIR/$tdir/f$i
8307         done
8308 }
8309
8310 test_60i() {
8311         changelog_register || error "changelog_register failed"
8312         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8313         changelog_users $SINGLEMDS | grep -q $cl_user ||
8314                 error "User $cl_user not found in changelog_users"
8315         changelog_chmask "ALL"
8316         t60i_load &
8317         local PID=$!
8318         for((i=0; i<100; i++)); do
8319                 changelog_dump >/dev/null ||
8320                         error "can't read changelog"
8321         done
8322         kill $PID
8323         wait $PID
8324         changelog_deregister || error "changelog_deregister failed"
8325         $LCTL set_param fail_loc=0
8326 }
8327 run_test 60i "llog: new record vs reader race"
8328
8329 test_61a() {
8330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8331
8332         f="$DIR/f61"
8333         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8334         cancel_lru_locks osc
8335         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8336         sync
8337 }
8338 run_test 61a "mmap() writes don't make sync hang ================"
8339
8340 test_61b() {
8341         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8342 }
8343 run_test 61b "mmap() of unstriped file is successful"
8344
8345 # bug 2330 - insufficient obd_match error checking causes LBUG
8346 test_62() {
8347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8348
8349         f="$DIR/f62"
8350         echo foo > $f
8351         cancel_lru_locks osc
8352         lctl set_param fail_loc=0x405
8353         cat $f && error "cat succeeded, expect -EIO"
8354         lctl set_param fail_loc=0
8355 }
8356 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8357 # match every page all of the time.
8358 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8359
8360 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8361 # Though this test is irrelevant anymore, it helped to reveal some
8362 # other grant bugs (LU-4482), let's keep it.
8363 test_63a() {   # was test_63
8364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8365
8366         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8367
8368         for i in `seq 10` ; do
8369                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8370                 sleep 5
8371                 kill $!
8372                 sleep 1
8373         done
8374
8375         rm -f $DIR/f63 || true
8376 }
8377 run_test 63a "Verify oig_wait interruption does not crash ======="
8378
8379 # bug 2248 - async write errors didn't return to application on sync
8380 # bug 3677 - async write errors left page locked
8381 test_63b() {
8382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8383
8384         debugsave
8385         lctl set_param debug=-1
8386
8387         # ensure we have a grant to do async writes
8388         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8389         rm $DIR/$tfile
8390
8391         sync    # sync lest earlier test intercept the fail_loc
8392
8393         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8394         lctl set_param fail_loc=0x80000406
8395         $MULTIOP $DIR/$tfile Owy && \
8396                 error "sync didn't return ENOMEM"
8397         sync; sleep 2; sync     # do a real sync this time to flush page
8398         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8399                 error "locked page left in cache after async error" || true
8400         debugrestore
8401 }
8402 run_test 63b "async write errors should be returned to fsync ==="
8403
8404 test_64a () {
8405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8406
8407         lfs df $DIR
8408         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8409 }
8410 run_test 64a "verify filter grant calculations (in kernel) ====="
8411
8412 test_64b () {
8413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8414
8415         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8416 }
8417 run_test 64b "check out-of-space detection on client"
8418
8419 test_64c() {
8420         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8421 }
8422 run_test 64c "verify grant shrink"
8423
8424 import_param() {
8425         local tgt=$1
8426         local param=$2
8427
8428         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8429 }
8430
8431 # this does exactly what osc_request.c:osc_announce_cached() does in
8432 # order to calculate max amount of grants to ask from server
8433 want_grant() {
8434         local tgt=$1
8435
8436         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8437         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8438
8439         ((rpc_in_flight++));
8440         nrpages=$((nrpages * rpc_in_flight))
8441
8442         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8443
8444         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8445
8446         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8447         local undirty=$((nrpages * PAGE_SIZE))
8448
8449         local max_extent_pages
8450         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8451         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8452         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8453         local grant_extent_tax
8454         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8455
8456         undirty=$((undirty + nrextents * grant_extent_tax))
8457
8458         echo $undirty
8459 }
8460
8461 # this is size of unit for grant allocation. It should be equal to
8462 # what tgt_grant.c:tgt_grant_chunk() calculates
8463 grant_chunk() {
8464         local tgt=$1
8465         local max_brw_size
8466         local grant_extent_tax
8467
8468         max_brw_size=$(import_param $tgt max_brw_size)
8469
8470         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8471
8472         echo $(((max_brw_size + grant_extent_tax) * 2))
8473 }
8474
8475 test_64d() {
8476         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8477                 skip "OST < 2.10.55 doesn't limit grants enough"
8478
8479         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8480
8481         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8482                 skip "no grant_param connect flag"
8483
8484         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8485
8486         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8487         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8488
8489
8490         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8491         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8492
8493         $LFS setstripe $DIR/$tfile -i 0 -c 1
8494         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8495         ddpid=$!
8496
8497         while kill -0 $ddpid; do
8498                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8499
8500                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8501                         kill $ddpid
8502                         error "cur_grant $cur_grant > $max_cur_granted"
8503                 fi
8504
8505                 sleep 1
8506         done
8507 }
8508 run_test 64d "check grant limit exceed"
8509
8510 check_grants() {
8511         local tgt=$1
8512         local expected=$2
8513         local msg=$3
8514         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8515
8516         ((cur_grants == expected)) ||
8517                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8518 }
8519
8520 round_up_p2() {
8521         echo $((($1 + $2 - 1) & ~($2 - 1)))
8522 }
8523
8524 test_64e() {
8525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8526         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8527                 skip "Need OSS version at least 2.11.56"
8528
8529         # Remount client to reset grant
8530         remount_client $MOUNT || error "failed to remount client"
8531         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8532
8533         local init_grants=$(import_param $osc_tgt initial_grant)
8534
8535         check_grants $osc_tgt $init_grants "init grants"
8536
8537         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8538         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8539         local gbs=$(import_param $osc_tgt grant_block_size)
8540
8541         # write random number of bytes from max_brw_size / 4 to max_brw_size
8542         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8543         # align for direct io
8544         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8545         # round to grant consumption unit
8546         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8547
8548         local grants=$((wb_round_up + extent_tax))
8549
8550         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8551
8552         # define OBD_FAIL_TGT_NO_GRANT 0x725
8553         # make the server not grant more back
8554         do_facet ost1 $LCTL set_param fail_loc=0x725
8555         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8556
8557         do_facet ost1 $LCTL set_param fail_loc=0
8558
8559         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8560
8561         rm -f $DIR/$tfile || error "rm failed"
8562
8563         # Remount client to reset grant
8564         remount_client $MOUNT || error "failed to remount client"
8565         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8566
8567         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8568
8569         # define OBD_FAIL_TGT_NO_GRANT 0x725
8570         # make the server not grant more back
8571         do_facet ost1 $LCTL set_param fail_loc=0x725
8572         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8573         do_facet ost1 $LCTL set_param fail_loc=0
8574
8575         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8576 }
8577 run_test 64e "check grant consumption (no grant allocation)"
8578
8579 test_64f() {
8580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8581
8582         # Remount client to reset grant
8583         remount_client $MOUNT || error "failed to remount client"
8584         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8585
8586         local init_grants=$(import_param $osc_tgt initial_grant)
8587         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8588         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8589         local gbs=$(import_param $osc_tgt grant_block_size)
8590         local chunk=$(grant_chunk $osc_tgt)
8591
8592         # write random number of bytes from max_brw_size / 4 to max_brw_size
8593         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8594         # align for direct io
8595         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8596         # round to grant consumption unit
8597         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8598
8599         local grants=$((wb_round_up + extent_tax))
8600
8601         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8602         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8603                 error "error writing to $DIR/$tfile"
8604
8605         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8606                 "direct io with grant allocation"
8607
8608         rm -f $DIR/$tfile || error "rm failed"
8609
8610         # Remount client to reset grant
8611         remount_client $MOUNT || error "failed to remount client"
8612         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8613
8614         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8615
8616         local cmd="oO_WRONLY:w${write_bytes}_yc"
8617
8618         $MULTIOP $DIR/$tfile $cmd &
8619         MULTIPID=$!
8620         sleep 1
8621
8622         check_grants $osc_tgt $((init_grants - grants)) \
8623                 "buffered io, not write rpc"
8624
8625         kill -USR1 $MULTIPID
8626         wait
8627
8628         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8629                 "buffered io, one RPC"
8630 }
8631 run_test 64f "check grant consumption (with grant allocation)"
8632
8633 # bug 1414 - set/get directories' stripe info
8634 test_65a() {
8635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8636
8637         test_mkdir $DIR/$tdir
8638         touch $DIR/$tdir/f1
8639         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8640 }
8641 run_test 65a "directory with no stripe info"
8642
8643 test_65b() {
8644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8645
8646         test_mkdir $DIR/$tdir
8647         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8648
8649         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8650                                                 error "setstripe"
8651         touch $DIR/$tdir/f2
8652         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8653 }
8654 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8655
8656 test_65c() {
8657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8658         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8659
8660         test_mkdir $DIR/$tdir
8661         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8662
8663         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8664                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8665         touch $DIR/$tdir/f3
8666         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8667 }
8668 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8669
8670 test_65d() {
8671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8672
8673         test_mkdir $DIR/$tdir
8674         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8675         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8676
8677         if [[ $STRIPECOUNT -le 0 ]]; then
8678                 sc=1
8679         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8680                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8681                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8682         else
8683                 sc=$(($STRIPECOUNT - 1))
8684         fi
8685         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8686         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8687         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8688                 error "lverify failed"
8689 }
8690 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8691
8692 test_65e() {
8693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8694
8695         test_mkdir $DIR/$tdir
8696
8697         $LFS setstripe $DIR/$tdir || error "setstripe"
8698         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8699                                         error "no stripe info failed"
8700         touch $DIR/$tdir/f6
8701         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8702 }
8703 run_test 65e "directory setstripe defaults"
8704
8705 test_65f() {
8706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8707
8708         test_mkdir $DIR/${tdir}f
8709         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8710                 error "setstripe succeeded" || true
8711 }
8712 run_test 65f "dir setstripe permission (should return error) ==="
8713
8714 test_65g() {
8715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8716
8717         test_mkdir $DIR/$tdir
8718         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8719
8720         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8721                 error "setstripe -S failed"
8722         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8723         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8724                 error "delete default stripe failed"
8725 }
8726 run_test 65g "directory setstripe -d"
8727
8728 test_65h() {
8729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8730
8731         test_mkdir $DIR/$tdir
8732         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8733
8734         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8735                 error "setstripe -S failed"
8736         test_mkdir $DIR/$tdir/dd1
8737         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8738                 error "stripe info inherit failed"
8739 }
8740 run_test 65h "directory stripe info inherit ===================="
8741
8742 test_65i() {
8743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8744
8745         save_layout_restore_at_exit $MOUNT
8746
8747         # bug6367: set non-default striping on root directory
8748         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8749
8750         # bug12836: getstripe on -1 default directory striping
8751         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8752
8753         # bug12836: getstripe -v on -1 default directory striping
8754         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8755
8756         # bug12836: new find on -1 default directory striping
8757         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8758 }
8759 run_test 65i "various tests to set root directory striping"
8760
8761 test_65j() { # bug6367
8762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8763
8764         sync; sleep 1
8765
8766         # if we aren't already remounting for each test, do so for this test
8767         if [ "$I_MOUNTED" = "yes" ]; then
8768                 cleanup || error "failed to unmount"
8769                 setup
8770         fi
8771
8772         save_layout_restore_at_exit $MOUNT
8773
8774         $LFS setstripe -d $MOUNT || error "setstripe failed"
8775 }
8776 run_test 65j "set default striping on root directory (bug 6367)="
8777
8778 cleanup_65k() {
8779         rm -rf $DIR/$tdir
8780         wait_delete_completed
8781         do_facet $SINGLEMDS "lctl set_param -n \
8782                 osp.$ost*MDT0000.max_create_count=$max_count"
8783         do_facet $SINGLEMDS "lctl set_param -n \
8784                 osp.$ost*MDT0000.create_count=$count"
8785         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8786         echo $INACTIVE_OSC "is Activate"
8787
8788         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8789 }
8790
8791 test_65k() { # bug11679
8792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8793         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8794         remote_mds_nodsh && skip "remote MDS with nodsh"
8795
8796         local disable_precreate=true
8797         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8798                 disable_precreate=false
8799
8800         echo "Check OST status: "
8801         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8802                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8803
8804         for OSC in $MDS_OSCS; do
8805                 echo $OSC "is active"
8806                 do_facet $SINGLEMDS lctl --device %$OSC activate
8807         done
8808
8809         for INACTIVE_OSC in $MDS_OSCS; do
8810                 local ost=$(osc_to_ost $INACTIVE_OSC)
8811                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8812                                lov.*md*.target_obd |
8813                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8814
8815                 mkdir -p $DIR/$tdir
8816                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8817                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8818
8819                 echo "Deactivate: " $INACTIVE_OSC
8820                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8821
8822                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8823                               osp.$ost*MDT0000.create_count")
8824                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8825                                   osp.$ost*MDT0000.max_create_count")
8826                 $disable_precreate &&
8827                         do_facet $SINGLEMDS "lctl set_param -n \
8828                                 osp.$ost*MDT0000.max_create_count=0"
8829
8830                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8831                         [ -f $DIR/$tdir/$idx ] && continue
8832                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8833                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8834                                 { cleanup_65k;
8835                                   error "setstripe $idx should succeed"; }
8836                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8837                 done
8838                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8839                 rmdir $DIR/$tdir
8840
8841                 do_facet $SINGLEMDS "lctl set_param -n \
8842                         osp.$ost*MDT0000.max_create_count=$max_count"
8843                 do_facet $SINGLEMDS "lctl set_param -n \
8844                         osp.$ost*MDT0000.create_count=$count"
8845                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8846                 echo $INACTIVE_OSC "is Activate"
8847
8848                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8849         done
8850 }
8851 run_test 65k "validate manual striping works properly with deactivated OSCs"
8852
8853 test_65l() { # bug 12836
8854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8855
8856         test_mkdir -p $DIR/$tdir/test_dir
8857         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8858         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8859 }
8860 run_test 65l "lfs find on -1 stripe dir ========================"
8861
8862 test_65m() {
8863         local layout=$(save_layout $MOUNT)
8864         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8865                 restore_layout $MOUNT $layout
8866                 error "setstripe should fail by non-root users"
8867         }
8868         true
8869 }
8870 run_test 65m "normal user can't set filesystem default stripe"
8871
8872 test_65n() {
8873         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8874         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8875                 skip "Need MDS version at least 2.12.50"
8876         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8877
8878         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8879         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8880         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8881
8882         save_layout_restore_at_exit $MOUNT
8883
8884         # new subdirectory under root directory should not inherit
8885         # the default layout from root
8886         local dir1=$MOUNT/$tdir-1
8887         mkdir $dir1 || error "mkdir $dir1 failed"
8888         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8889                 error "$dir1 shouldn't have LOV EA"
8890
8891         # delete the default layout on root directory
8892         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8893
8894         local dir2=$MOUNT/$tdir-2
8895         mkdir $dir2 || error "mkdir $dir2 failed"
8896         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8897                 error "$dir2 shouldn't have LOV EA"
8898
8899         # set a new striping pattern on root directory
8900         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8901         local new_def_stripe_size=$((def_stripe_size * 2))
8902         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8903                 error "set stripe size on $MOUNT failed"
8904
8905         # new file created in $dir2 should inherit the new stripe size from
8906         # the filesystem default
8907         local file2=$dir2/$tfile-2
8908         touch $file2 || error "touch $file2 failed"
8909
8910         local file2_stripe_size=$($LFS getstripe -S $file2)
8911         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8912         {
8913                 echo "file2_stripe_size: '$file2_stripe_size'"
8914                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8915                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8916         }
8917
8918         local dir3=$MOUNT/$tdir-3
8919         mkdir $dir3 || error "mkdir $dir3 failed"
8920         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8921         # the root layout, which is the actual default layout that will be used
8922         # when new files are created in $dir3.
8923         local dir3_layout=$(get_layout_param $dir3)
8924         local root_dir_layout=$(get_layout_param $MOUNT)
8925         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8926         {
8927                 echo "dir3_layout: '$dir3_layout'"
8928                 echo "root_dir_layout: '$root_dir_layout'"
8929                 error "$dir3 should show the default layout from $MOUNT"
8930         }
8931
8932         # set OST pool on root directory
8933         local pool=$TESTNAME
8934         pool_add $pool || error "add $pool failed"
8935         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8936                 error "add targets to $pool failed"
8937
8938         $LFS setstripe -p $pool $MOUNT ||
8939                 error "set OST pool on $MOUNT failed"
8940
8941         # new file created in $dir3 should inherit the pool from
8942         # the filesystem default
8943         local file3=$dir3/$tfile-3
8944         touch $file3 || error "touch $file3 failed"
8945
8946         local file3_pool=$($LFS getstripe -p $file3)
8947         [[ "$file3_pool" = "$pool" ]] ||
8948                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8949
8950         local dir4=$MOUNT/$tdir-4
8951         mkdir $dir4 || error "mkdir $dir4 failed"
8952         local dir4_layout=$(get_layout_param $dir4)
8953         root_dir_layout=$(get_layout_param $MOUNT)
8954         echo "$LFS getstripe -d $dir4"
8955         $LFS getstripe -d $dir4
8956         echo "$LFS getstripe -d $MOUNT"
8957         $LFS getstripe -d $MOUNT
8958         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8959         {
8960                 echo "dir4_layout: '$dir4_layout'"
8961                 echo "root_dir_layout: '$root_dir_layout'"
8962                 error "$dir4 should show the default layout from $MOUNT"
8963         }
8964
8965         # new file created in $dir4 should inherit the pool from
8966         # the filesystem default
8967         local file4=$dir4/$tfile-4
8968         touch $file4 || error "touch $file4 failed"
8969
8970         local file4_pool=$($LFS getstripe -p $file4)
8971         [[ "$file4_pool" = "$pool" ]] ||
8972                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8973
8974         # new subdirectory under non-root directory should inherit
8975         # the default layout from its parent directory
8976         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8977                 error "set directory layout on $dir4 failed"
8978
8979         local dir5=$dir4/$tdir-5
8980         mkdir $dir5 || error "mkdir $dir5 failed"
8981
8982         dir4_layout=$(get_layout_param $dir4)
8983         local dir5_layout=$(get_layout_param $dir5)
8984         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8985         {
8986                 echo "dir4_layout: '$dir4_layout'"
8987                 echo "dir5_layout: '$dir5_layout'"
8988                 error "$dir5 should inherit the default layout from $dir4"
8989         }
8990
8991         # though subdir under ROOT doesn't inherit default layout, but
8992         # its sub dir/file should be created with default layout.
8993         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8994         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8995                 skip "Need MDS version at least 2.12.59"
8996
8997         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8998         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8999         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9000
9001         if [ $default_lmv_hash == "none" ]; then
9002                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9003         else
9004                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9005                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9006         fi
9007
9008         $LFS setdirstripe -D -c 2 $MOUNT ||
9009                 error "setdirstripe -D -c 2 failed"
9010         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9011         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9012         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9013 }
9014 run_test 65n "don't inherit default layout from root for new subdirectories"
9015
9016 # bug 2543 - update blocks count on client
9017 test_66() {
9018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9019
9020         COUNT=${COUNT:-8}
9021         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9022         sync; sync_all_data; sync; sync_all_data
9023         cancel_lru_locks osc
9024         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9025         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9026 }
9027 run_test 66 "update inode blocks count on client ==============="
9028
9029 meminfo() {
9030         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9031 }
9032
9033 swap_used() {
9034         swapon -s | awk '($1 == "'$1'") { print $4 }'
9035 }
9036
9037 # bug5265, obdfilter oa2dentry return -ENOENT
9038 # #define OBD_FAIL_SRV_ENOENT 0x217
9039 test_69() {
9040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9041         remote_ost_nodsh && skip "remote OST with nodsh"
9042
9043         f="$DIR/$tfile"
9044         $LFS setstripe -c 1 -i 0 $f
9045
9046         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9047
9048         do_facet ost1 lctl set_param fail_loc=0x217
9049         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9050         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9051
9052         do_facet ost1 lctl set_param fail_loc=0
9053         $DIRECTIO write $f 0 2 || error "write error"
9054
9055         cancel_lru_locks osc
9056         $DIRECTIO read $f 0 1 || error "read error"
9057
9058         do_facet ost1 lctl set_param fail_loc=0x217
9059         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9060
9061         do_facet ost1 lctl set_param fail_loc=0
9062         rm -f $f
9063 }
9064 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9065
9066 test_71() {
9067         test_mkdir $DIR/$tdir
9068         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9069         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9070 }
9071 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9072
9073 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9075         [ "$RUNAS_ID" = "$UID" ] &&
9076                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9077         # Check that testing environment is properly set up. Skip if not
9078         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9079                 skip_env "User $RUNAS_ID does not exist - skipping"
9080
9081         touch $DIR/$tfile
9082         chmod 777 $DIR/$tfile
9083         chmod ug+s $DIR/$tfile
9084         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9085                 error "$RUNAS dd $DIR/$tfile failed"
9086         # See if we are still setuid/sgid
9087         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9088                 error "S/gid is not dropped on write"
9089         # Now test that MDS is updated too
9090         cancel_lru_locks mdc
9091         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9092                 error "S/gid is not dropped on MDS"
9093         rm -f $DIR/$tfile
9094 }
9095 run_test 72a "Test that remove suid works properly (bug5695) ===="
9096
9097 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9098         local perm
9099
9100         [ "$RUNAS_ID" = "$UID" ] &&
9101                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9102         [ "$RUNAS_ID" -eq 0 ] &&
9103                 skip_env "RUNAS_ID = 0 -- skipping"
9104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9105         # Check that testing environment is properly set up. Skip if not
9106         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9107                 skip_env "User $RUNAS_ID does not exist - skipping"
9108
9109         touch $DIR/${tfile}-f{g,u}
9110         test_mkdir $DIR/${tfile}-dg
9111         test_mkdir $DIR/${tfile}-du
9112         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9113         chmod g+s $DIR/${tfile}-{f,d}g
9114         chmod u+s $DIR/${tfile}-{f,d}u
9115         for perm in 777 2777 4777; do
9116                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9117                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9118                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9119                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9120         done
9121         true
9122 }
9123 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9124
9125 # bug 3462 - multiple simultaneous MDC requests
9126 test_73() {
9127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9128
9129         test_mkdir $DIR/d73-1
9130         test_mkdir $DIR/d73-2
9131         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9132         pid1=$!
9133
9134         lctl set_param fail_loc=0x80000129
9135         $MULTIOP $DIR/d73-1/f73-2 Oc &
9136         sleep 1
9137         lctl set_param fail_loc=0
9138
9139         $MULTIOP $DIR/d73-2/f73-3 Oc &
9140         pid3=$!
9141
9142         kill -USR1 $pid1
9143         wait $pid1 || return 1
9144
9145         sleep 25
9146
9147         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9148         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9149         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9150
9151         rm -rf $DIR/d73-*
9152 }
9153 run_test 73 "multiple MDC requests (should not deadlock)"
9154
9155 test_74a() { # bug 6149, 6184
9156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9157
9158         touch $DIR/f74a
9159         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9160         #
9161         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9162         # will spin in a tight reconnection loop
9163         $LCTL set_param fail_loc=0x8000030e
9164         # get any lock that won't be difficult - lookup works.
9165         ls $DIR/f74a
9166         $LCTL set_param fail_loc=0
9167         rm -f $DIR/f74a
9168         true
9169 }
9170 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9171
9172 test_74b() { # bug 13310
9173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9174
9175         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9176         #
9177         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9178         # will spin in a tight reconnection loop
9179         $LCTL set_param fail_loc=0x8000030e
9180         # get a "difficult" lock
9181         touch $DIR/f74b
9182         $LCTL set_param fail_loc=0
9183         rm -f $DIR/f74b
9184         true
9185 }
9186 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9187
9188 test_74c() {
9189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9190
9191         #define OBD_FAIL_LDLM_NEW_LOCK
9192         $LCTL set_param fail_loc=0x319
9193         touch $DIR/$tfile && error "touch successful"
9194         $LCTL set_param fail_loc=0
9195         true
9196 }
9197 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9198
9199 slab_lic=/sys/kernel/slab/lustre_inode_cache
9200 num_objects() {
9201         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9202         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9203                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9204 }
9205
9206 test_76a() { # Now for b=20433, added originally in b=1443
9207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9208
9209         cancel_lru_locks osc
9210         # there may be some slab objects cached per core
9211         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9212         local before=$(num_objects)
9213         local count=$((512 * cpus))
9214         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9215         local margin=$((count / 10))
9216         if [[ -f $slab_lic/aliases ]]; then
9217                 local aliases=$(cat $slab_lic/aliases)
9218                 (( aliases > 0 )) && margin=$((margin * aliases))
9219         fi
9220
9221         echo "before slab objects: $before"
9222         for i in $(seq $count); do
9223                 touch $DIR/$tfile
9224                 rm -f $DIR/$tfile
9225         done
9226         cancel_lru_locks osc
9227         local after=$(num_objects)
9228         echo "created: $count, after slab objects: $after"
9229         # shared slab counts are not very accurate, allow significant margin
9230         # the main goal is that the cache growth is not permanently > $count
9231         while (( after > before + margin )); do
9232                 sleep 1
9233                 after=$(num_objects)
9234                 wait=$((wait + 1))
9235                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9236                 if (( wait > 60 )); then
9237                         error "inode slab grew from $before+$margin to $after"
9238                 fi
9239         done
9240 }
9241 run_test 76a "confirm clients recycle inodes properly ===="
9242
9243 test_76b() {
9244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9245         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9246
9247         local count=512
9248         local before=$(num_objects)
9249
9250         for i in $(seq $count); do
9251                 mkdir $DIR/$tdir
9252                 rmdir $DIR/$tdir
9253         done
9254
9255         local after=$(num_objects)
9256         local wait=0
9257
9258         while (( after > before )); do
9259                 sleep 1
9260                 after=$(num_objects)
9261                 wait=$((wait + 1))
9262                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9263                 if (( wait > 60 )); then
9264                         error "inode slab grew from $before to $after"
9265                 fi
9266         done
9267
9268         echo "slab objects before: $before, after: $after"
9269 }
9270 run_test 76b "confirm clients recycle directory inodes properly ===="
9271
9272 export ORIG_CSUM=""
9273 set_checksums()
9274 {
9275         # Note: in sptlrpc modes which enable its own bulk checksum, the
9276         # original crc32_le bulk checksum will be automatically disabled,
9277         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9278         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9279         # In this case set_checksums() will not be no-op, because sptlrpc
9280         # bulk checksum will be enabled all through the test.
9281
9282         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9283         lctl set_param -n osc.*.checksums $1
9284         return 0
9285 }
9286
9287 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9288                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9289 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9290                              tr -d [] | head -n1)}
9291 set_checksum_type()
9292 {
9293         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9294         rc=$?
9295         log "set checksum type to $1, rc = $rc"
9296         return $rc
9297 }
9298
9299 get_osc_checksum_type()
9300 {
9301         # arugment 1: OST name, like OST0000
9302         ost=$1
9303         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9304                         sed 's/.*\[\(.*\)\].*/\1/g')
9305         rc=$?
9306         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9307         echo $checksum_type
9308 }
9309
9310 F77_TMP=$TMP/f77-temp
9311 F77SZ=8
9312 setup_f77() {
9313         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9314                 error "error writing to $F77_TMP"
9315 }
9316
9317 test_77a() { # bug 10889
9318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9319         $GSS && skip_env "could not run with gss"
9320
9321         [ ! -f $F77_TMP ] && setup_f77
9322         set_checksums 1
9323         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9324         set_checksums 0
9325         rm -f $DIR/$tfile
9326 }
9327 run_test 77a "normal checksum read/write operation"
9328
9329 test_77b() { # bug 10889
9330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9331         $GSS && skip_env "could not run with gss"
9332
9333         [ ! -f $F77_TMP ] && setup_f77
9334         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9335         $LCTL set_param fail_loc=0x80000409
9336         set_checksums 1
9337
9338         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9339                 error "dd error: $?"
9340         $LCTL set_param fail_loc=0
9341
9342         for algo in $CKSUM_TYPES; do
9343                 cancel_lru_locks osc
9344                 set_checksum_type $algo
9345                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9346                 $LCTL set_param fail_loc=0x80000408
9347                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9348                 $LCTL set_param fail_loc=0
9349         done
9350         set_checksums 0
9351         set_checksum_type $ORIG_CSUM_TYPE
9352         rm -f $DIR/$tfile
9353 }
9354 run_test 77b "checksum error on client write, read"
9355
9356 cleanup_77c() {
9357         trap 0
9358         set_checksums 0
9359         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9360         $check_ost &&
9361                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9362         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9363         $check_ost && [ -n "$ost_file_prefix" ] &&
9364                 do_facet ost1 rm -f ${ost_file_prefix}\*
9365 }
9366
9367 test_77c() {
9368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9369         $GSS && skip_env "could not run with gss"
9370         remote_ost_nodsh && skip "remote OST with nodsh"
9371
9372         local bad1
9373         local osc_file_prefix
9374         local osc_file
9375         local check_ost=false
9376         local ost_file_prefix
9377         local ost_file
9378         local orig_cksum
9379         local dump_cksum
9380         local fid
9381
9382         # ensure corruption will occur on first OSS/OST
9383         $LFS setstripe -i 0 $DIR/$tfile
9384
9385         [ ! -f $F77_TMP ] && setup_f77
9386         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9387                 error "dd write error: $?"
9388         fid=$($LFS path2fid $DIR/$tfile)
9389
9390         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9391         then
9392                 check_ost=true
9393                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9394                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9395         else
9396                 echo "OSS do not support bulk pages dump upon error"
9397         fi
9398
9399         osc_file_prefix=$($LCTL get_param -n debug_path)
9400         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9401
9402         trap cleanup_77c EXIT
9403
9404         set_checksums 1
9405         # enable bulk pages dump upon error on Client
9406         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9407         # enable bulk pages dump upon error on OSS
9408         $check_ost &&
9409                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9410
9411         # flush Client cache to allow next read to reach OSS
9412         cancel_lru_locks osc
9413
9414         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9415         $LCTL set_param fail_loc=0x80000408
9416         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9417         $LCTL set_param fail_loc=0
9418
9419         rm -f $DIR/$tfile
9420
9421         # check cksum dump on Client
9422         osc_file=$(ls ${osc_file_prefix}*)
9423         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9424         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9425         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9426         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9427         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9428                      cksum)
9429         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9430         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9431                 error "dump content does not match on Client"
9432
9433         $check_ost || skip "No need to check cksum dump on OSS"
9434
9435         # check cksum dump on OSS
9436         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9437         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9438         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9439         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9440         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9441                 error "dump content does not match on OSS"
9442
9443         cleanup_77c
9444 }
9445 run_test 77c "checksum error on client read with debug"
9446
9447 test_77d() { # bug 10889
9448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9449         $GSS && skip_env "could not run with gss"
9450
9451         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9452         $LCTL set_param fail_loc=0x80000409
9453         set_checksums 1
9454         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9455                 error "direct write: rc=$?"
9456         $LCTL set_param fail_loc=0
9457         set_checksums 0
9458
9459         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9460         $LCTL set_param fail_loc=0x80000408
9461         set_checksums 1
9462         cancel_lru_locks osc
9463         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9464                 error "direct read: rc=$?"
9465         $LCTL set_param fail_loc=0
9466         set_checksums 0
9467 }
9468 run_test 77d "checksum error on OST direct write, read"
9469
9470 test_77f() { # bug 10889
9471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9472         $GSS && skip_env "could not run with gss"
9473
9474         set_checksums 1
9475         for algo in $CKSUM_TYPES; do
9476                 cancel_lru_locks osc
9477                 set_checksum_type $algo
9478                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9479                 $LCTL set_param fail_loc=0x409
9480                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9481                         error "direct write succeeded"
9482                 $LCTL set_param fail_loc=0
9483         done
9484         set_checksum_type $ORIG_CSUM_TYPE
9485         set_checksums 0
9486 }
9487 run_test 77f "repeat checksum error on write (expect error)"
9488
9489 test_77g() { # bug 10889
9490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9491         $GSS && skip_env "could not run with gss"
9492         remote_ost_nodsh && skip "remote OST with nodsh"
9493
9494         [ ! -f $F77_TMP ] && setup_f77
9495
9496         local file=$DIR/$tfile
9497         stack_trap "rm -f $file" EXIT
9498
9499         $LFS setstripe -c 1 -i 0 $file
9500         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9501         do_facet ost1 lctl set_param fail_loc=0x8000021a
9502         set_checksums 1
9503         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9504                 error "write error: rc=$?"
9505         do_facet ost1 lctl set_param fail_loc=0
9506         set_checksums 0
9507
9508         cancel_lru_locks osc
9509         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9510         do_facet ost1 lctl set_param fail_loc=0x8000021b
9511         set_checksums 1
9512         cmp $F77_TMP $file || error "file compare failed"
9513         do_facet ost1 lctl set_param fail_loc=0
9514         set_checksums 0
9515 }
9516 run_test 77g "checksum error on OST write, read"
9517
9518 test_77k() { # LU-10906
9519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9520         $GSS && skip_env "could not run with gss"
9521
9522         local cksum_param="osc.$FSNAME*.checksums"
9523         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9524         local checksum
9525         local i
9526
9527         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9528         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9529         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9530
9531         for i in 0 1; do
9532                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9533                         error "failed to set checksum=$i on MGS"
9534                 wait_update $HOSTNAME "$get_checksum" $i
9535                 #remount
9536                 echo "remount client, checksum should be $i"
9537                 remount_client $MOUNT || error "failed to remount client"
9538                 checksum=$(eval $get_checksum)
9539                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9540         done
9541         # remove persistent param to avoid races with checksum mountopt below
9542         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9543                 error "failed to delete checksum on MGS"
9544
9545         for opt in "checksum" "nochecksum"; do
9546                 #remount with mount option
9547                 echo "remount client with option $opt, checksum should be $i"
9548                 umount_client $MOUNT || error "failed to umount client"
9549                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9550                         error "failed to mount client with option '$opt'"
9551                 checksum=$(eval $get_checksum)
9552                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9553                 i=$((i - 1))
9554         done
9555
9556         remount_client $MOUNT || error "failed to remount client"
9557 }
9558 run_test 77k "enable/disable checksum correctly"
9559
9560 test_77l() {
9561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9562         $GSS && skip_env "could not run with gss"
9563
9564         set_checksums 1
9565         stack_trap "set_checksums $ORIG_CSUM" EXIT
9566         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9567
9568         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9569
9570         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9571         for algo in $CKSUM_TYPES; do
9572                 set_checksum_type $algo || error "fail to set checksum type $algo"
9573                 osc_algo=$(get_osc_checksum_type OST0000)
9574                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9575
9576                 # no locks, no reqs to let the connection idle
9577                 cancel_lru_locks osc
9578                 lru_resize_disable osc
9579                 wait_osc_import_state client ost1 IDLE
9580
9581                 # ensure ost1 is connected
9582                 stat $DIR/$tfile >/dev/null || error "can't stat"
9583                 wait_osc_import_state client ost1 FULL
9584
9585                 osc_algo=$(get_osc_checksum_type OST0000)
9586                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9587         done
9588         return 0
9589 }
9590 run_test 77l "preferred checksum type is remembered after reconnected"
9591
9592 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9593 rm -f $F77_TMP
9594 unset F77_TMP
9595
9596 cleanup_test_78() {
9597         trap 0
9598         rm -f $DIR/$tfile
9599 }
9600
9601 test_78() { # bug 10901
9602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9603         remote_ost || skip_env "local OST"
9604
9605         NSEQ=5
9606         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9607         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9608         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9609         echo "MemTotal: $MEMTOTAL"
9610
9611         # reserve 256MB of memory for the kernel and other running processes,
9612         # and then take 1/2 of the remaining memory for the read/write buffers.
9613         if [ $MEMTOTAL -gt 512 ] ;then
9614                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9615         else
9616                 # for those poor memory-starved high-end clusters...
9617                 MEMTOTAL=$((MEMTOTAL / 2))
9618         fi
9619         echo "Mem to use for directio: $MEMTOTAL"
9620
9621         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9622         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9623         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9624         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9625                 head -n1)
9626         echo "Smallest OST: $SMALLESTOST"
9627         [[ $SMALLESTOST -lt 10240 ]] &&
9628                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9629
9630         trap cleanup_test_78 EXIT
9631
9632         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9633                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9634
9635         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9636         echo "File size: $F78SIZE"
9637         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9638         for i in $(seq 1 $NSEQ); do
9639                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9640                 echo directIO rdwr round $i of $NSEQ
9641                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9642         done
9643
9644         cleanup_test_78
9645 }
9646 run_test 78 "handle large O_DIRECT writes correctly ============"
9647
9648 test_79() { # bug 12743
9649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9650
9651         wait_delete_completed
9652
9653         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9654         BKFREE=$(calc_osc_kbytes kbytesfree)
9655         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9656
9657         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9658         DFTOTAL=`echo $STRING | cut -d, -f1`
9659         DFUSED=`echo $STRING  | cut -d, -f2`
9660         DFAVAIL=`echo $STRING | cut -d, -f3`
9661         DFFREE=$(($DFTOTAL - $DFUSED))
9662
9663         ALLOWANCE=$((64 * $OSTCOUNT))
9664
9665         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9666            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9667                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9668         fi
9669         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9670            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9671                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9672         fi
9673         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9674            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9675                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9676         fi
9677 }
9678 run_test 79 "df report consistency check ======================="
9679
9680 test_80() { # bug 10718
9681         remote_ost_nodsh && skip "remote OST with nodsh"
9682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9683
9684         # relax strong synchronous semantics for slow backends like ZFS
9685         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9686                 local soc="obdfilter.*.sync_lock_cancel"
9687                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9688
9689                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9690                 if [ -z "$save" ]; then
9691                         soc="obdfilter.*.sync_on_lock_cancel"
9692                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9693                 fi
9694
9695                 if [ "$save" != "never" ]; then
9696                         local hosts=$(comma_list $(osts_nodes))
9697
9698                         do_nodes $hosts $LCTL set_param $soc=never
9699                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9700                 fi
9701         fi
9702
9703         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9704         sync; sleep 1; sync
9705         local before=$(date +%s)
9706         cancel_lru_locks osc
9707         local after=$(date +%s)
9708         local diff=$((after - before))
9709         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9710
9711         rm -f $DIR/$tfile
9712 }
9713 run_test 80 "Page eviction is equally fast at high offsets too"
9714
9715 test_81a() { # LU-456
9716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9717         remote_ost_nodsh && skip "remote OST with nodsh"
9718
9719         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9720         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9721         do_facet ost1 lctl set_param fail_loc=0x80000228
9722
9723         # write should trigger a retry and success
9724         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9725         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9726         RC=$?
9727         if [ $RC -ne 0 ] ; then
9728                 error "write should success, but failed for $RC"
9729         fi
9730 }
9731 run_test 81a "OST should retry write when get -ENOSPC ==============="
9732
9733 test_81b() { # LU-456
9734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9735         remote_ost_nodsh && skip "remote OST with nodsh"
9736
9737         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9738         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9739         do_facet ost1 lctl set_param fail_loc=0x228
9740
9741         # write should retry several times and return -ENOSPC finally
9742         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9743         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9744         RC=$?
9745         ENOSPC=28
9746         if [ $RC -ne $ENOSPC ] ; then
9747                 error "dd should fail for -ENOSPC, but succeed."
9748         fi
9749 }
9750 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9751
9752 test_99() {
9753         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9754
9755         test_mkdir $DIR/$tdir.cvsroot
9756         chown $RUNAS_ID $DIR/$tdir.cvsroot
9757
9758         cd $TMP
9759         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9760
9761         cd /etc/init.d
9762         # some versions of cvs import exit(1) when asked to import links or
9763         # files they can't read.  ignore those files.
9764         local toignore=$(find . -type l -printf '-I %f\n' -o \
9765                          ! -perm /4 -printf '-I %f\n')
9766         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9767                 $tdir.reposname vtag rtag
9768
9769         cd $DIR
9770         test_mkdir $DIR/$tdir.reposname
9771         chown $RUNAS_ID $DIR/$tdir.reposname
9772         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9773
9774         cd $DIR/$tdir.reposname
9775         $RUNAS touch foo99
9776         $RUNAS cvs add -m 'addmsg' foo99
9777         $RUNAS cvs update
9778         $RUNAS cvs commit -m 'nomsg' foo99
9779         rm -fr $DIR/$tdir.cvsroot
9780 }
9781 run_test 99 "cvs strange file/directory operations"
9782
9783 test_100() {
9784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9785         [[ "$NETTYPE" =~ tcp ]] ||
9786                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9787         remote_ost_nodsh && skip "remote OST with nodsh"
9788         remote_mds_nodsh && skip "remote MDS with nodsh"
9789         remote_servers ||
9790                 skip "useless for local single node setup"
9791
9792         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9793                 [ "$PROT" != "tcp" ] && continue
9794                 RPORT=$(echo $REMOTE | cut -d: -f2)
9795                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9796
9797                 rc=0
9798                 LPORT=`echo $LOCAL | cut -d: -f2`
9799                 if [ $LPORT -ge 1024 ]; then
9800                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9801                         netstat -tna
9802                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9803                 fi
9804         done
9805         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9806 }
9807 run_test 100 "check local port using privileged port ==========="
9808
9809 function get_named_value()
9810 {
9811     local tag=$1
9812
9813     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9814 }
9815
9816 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9817                    awk '/^max_cached_mb/ { print $2 }')
9818
9819 cleanup_101a() {
9820         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9821         trap 0
9822 }
9823
9824 test_101a() {
9825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9826
9827         local s
9828         local discard
9829         local nreads=10000
9830         local cache_limit=32
9831
9832         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9833         trap cleanup_101a EXIT
9834         $LCTL set_param -n llite.*.read_ahead_stats=0
9835         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9836
9837         #
9838         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9839         #
9840         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9841         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9842
9843         discard=0
9844         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9845                    get_named_value 'read.but.discarded'); do
9846                         discard=$(($discard + $s))
9847         done
9848         cleanup_101a
9849
9850         $LCTL get_param osc.*-osc*.rpc_stats
9851         $LCTL get_param llite.*.read_ahead_stats
9852
9853         # Discard is generally zero, but sometimes a few random reads line up
9854         # and trigger larger readahead, which is wasted & leads to discards.
9855         if [[ $(($discard)) -gt $nreads ]]; then
9856                 error "too many ($discard) discarded pages"
9857         fi
9858         rm -f $DIR/$tfile || true
9859 }
9860 run_test 101a "check read-ahead for random reads"
9861
9862 setup_test101bc() {
9863         test_mkdir $DIR/$tdir
9864         local ssize=$1
9865         local FILE_LENGTH=$2
9866         STRIPE_OFFSET=0
9867
9868         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9869
9870         local list=$(comma_list $(osts_nodes))
9871         set_osd_param $list '' read_cache_enable 0
9872         set_osd_param $list '' writethrough_cache_enable 0
9873
9874         trap cleanup_test101bc EXIT
9875         # prepare the read-ahead file
9876         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9877
9878         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9879                                 count=$FILE_SIZE_MB 2> /dev/null
9880
9881 }
9882
9883 cleanup_test101bc() {
9884         trap 0
9885         rm -rf $DIR/$tdir
9886         rm -f $DIR/$tfile
9887
9888         local list=$(comma_list $(osts_nodes))
9889         set_osd_param $list '' read_cache_enable 1
9890         set_osd_param $list '' writethrough_cache_enable 1
9891 }
9892
9893 calc_total() {
9894         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9895 }
9896
9897 ra_check_101() {
9898         local READ_SIZE=$1
9899         local STRIPE_SIZE=$2
9900         local FILE_LENGTH=$3
9901         local RA_INC=1048576
9902         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9903         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9904                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9905         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9906                   get_named_value 'read.but.discarded' | calc_total)
9907         if [[ $DISCARD -gt $discard_limit ]]; then
9908                 $LCTL get_param llite.*.read_ahead_stats
9909                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9910         else
9911                 echo "Read-ahead success for size ${READ_SIZE}"
9912         fi
9913 }
9914
9915 test_101b() {
9916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9917         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9918
9919         local STRIPE_SIZE=1048576
9920         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9921
9922         if [ $SLOW == "yes" ]; then
9923                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9924         else
9925                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9926         fi
9927
9928         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9929
9930         # prepare the read-ahead file
9931         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9932         cancel_lru_locks osc
9933         for BIDX in 2 4 8 16 32 64 128 256
9934         do
9935                 local BSIZE=$((BIDX*4096))
9936                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9937                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9938                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9939                 $LCTL set_param -n llite.*.read_ahead_stats=0
9940                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9941                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9942                 cancel_lru_locks osc
9943                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9944         done
9945         cleanup_test101bc
9946         true
9947 }
9948 run_test 101b "check stride-io mode read-ahead ================="
9949
9950 test_101c() {
9951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9952
9953         local STRIPE_SIZE=1048576
9954         local FILE_LENGTH=$((STRIPE_SIZE*100))
9955         local nreads=10000
9956         local rsize=65536
9957         local osc_rpc_stats
9958
9959         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9960
9961         cancel_lru_locks osc
9962         $LCTL set_param osc.*.rpc_stats=0
9963         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9964         $LCTL get_param osc.*.rpc_stats
9965         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9966                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9967                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9968                 local size
9969
9970                 if [ $lines -le 20 ]; then
9971                         echo "continue debug"
9972                         continue
9973                 fi
9974                 for size in 1 2 4 8; do
9975                         local rpc=$(echo "$stats" |
9976                                     awk '($1 == "'$size':") {print $2; exit; }')
9977                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9978                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9979                 done
9980                 echo "$osc_rpc_stats check passed!"
9981         done
9982         cleanup_test101bc
9983         true
9984 }
9985 run_test 101c "check stripe_size aligned read-ahead"
9986
9987 test_101d() {
9988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9989
9990         local file=$DIR/$tfile
9991         local sz_MB=${FILESIZE_101d:-80}
9992         local ra_MB=${READAHEAD_MB:-40}
9993
9994         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9995         [ $free_MB -lt $sz_MB ] &&
9996                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9997
9998         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9999         $LFS setstripe -c -1 $file || error "setstripe failed"
10000
10001         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10002         echo Cancel LRU locks on lustre client to flush the client cache
10003         cancel_lru_locks osc
10004
10005         echo Disable read-ahead
10006         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10007         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10008         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10009         $LCTL get_param -n llite.*.max_read_ahead_mb
10010
10011         echo "Reading the test file $file with read-ahead disabled"
10012         local sz_KB=$((sz_MB * 1024 / 4))
10013         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10014         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10015         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10016                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10017
10018         echo "Cancel LRU locks on lustre client to flush the client cache"
10019         cancel_lru_locks osc
10020         echo Enable read-ahead with ${ra_MB}MB
10021         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10022
10023         echo "Reading the test file $file with read-ahead enabled"
10024         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10025                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10026
10027         echo "read-ahead disabled time read $raOFF"
10028         echo "read-ahead enabled time read $raON"
10029
10030         rm -f $file
10031         wait_delete_completed
10032
10033         # use awk for this check instead of bash because it handles decimals
10034         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10035                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10036 }
10037 run_test 101d "file read with and without read-ahead enabled"
10038
10039 test_101e() {
10040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10041
10042         local file=$DIR/$tfile
10043         local size_KB=500  #KB
10044         local count=100
10045         local bsize=1024
10046
10047         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10048         local need_KB=$((count * size_KB))
10049         [[ $free_KB -le $need_KB ]] &&
10050                 skip_env "Need free space $need_KB, have $free_KB"
10051
10052         echo "Creating $count ${size_KB}K test files"
10053         for ((i = 0; i < $count; i++)); do
10054                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10055         done
10056
10057         echo "Cancel LRU locks on lustre client to flush the client cache"
10058         cancel_lru_locks $OSC
10059
10060         echo "Reset readahead stats"
10061         $LCTL set_param -n llite.*.read_ahead_stats=0
10062
10063         for ((i = 0; i < $count; i++)); do
10064                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10065         done
10066
10067         $LCTL get_param llite.*.max_cached_mb
10068         $LCTL get_param llite.*.read_ahead_stats
10069         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10070                      get_named_value 'misses' | calc_total)
10071
10072         for ((i = 0; i < $count; i++)); do
10073                 rm -rf $file.$i 2>/dev/null
10074         done
10075
10076         #10000 means 20% reads are missing in readahead
10077         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10078 }
10079 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10080
10081 test_101f() {
10082         which iozone || skip_env "no iozone installed"
10083
10084         local old_debug=$($LCTL get_param debug)
10085         old_debug=${old_debug#*=}
10086         $LCTL set_param debug="reada mmap"
10087
10088         # create a test file
10089         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10090
10091         echo Cancel LRU locks on lustre client to flush the client cache
10092         cancel_lru_locks osc
10093
10094         echo Reset readahead stats
10095         $LCTL set_param -n llite.*.read_ahead_stats=0
10096
10097         echo mmap read the file with small block size
10098         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10099                 > /dev/null 2>&1
10100
10101         echo checking missing pages
10102         $LCTL get_param llite.*.read_ahead_stats
10103         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10104                         get_named_value 'misses' | calc_total)
10105
10106         $LCTL set_param debug="$old_debug"
10107         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10108         rm -f $DIR/$tfile
10109 }
10110 run_test 101f "check mmap read performance"
10111
10112 test_101g_brw_size_test() {
10113         local mb=$1
10114         local pages=$((mb * 1048576 / PAGE_SIZE))
10115         local file=$DIR/$tfile
10116
10117         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10118                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10119         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10120                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10121                         return 2
10122         done
10123
10124         stack_trap "rm -f $file" EXIT
10125         $LCTL set_param -n osc.*.rpc_stats=0
10126
10127         # 10 RPCs should be enough for the test
10128         local count=10
10129         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10130                 { error "dd write ${mb} MB blocks failed"; return 3; }
10131         cancel_lru_locks osc
10132         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10133                 { error "dd write ${mb} MB blocks failed"; return 4; }
10134
10135         # calculate number of full-sized read and write RPCs
10136         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10137                 sed -n '/pages per rpc/,/^$/p' |
10138                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10139                 END { print reads,writes }'))
10140         # allow one extra full-sized read RPC for async readahead
10141         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10142                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10143         [[ ${rpcs[1]} == $count ]] ||
10144                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10145 }
10146
10147 test_101g() {
10148         remote_ost_nodsh && skip "remote OST with nodsh"
10149
10150         local rpcs
10151         local osts=$(get_facets OST)
10152         local list=$(comma_list $(osts_nodes))
10153         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10154         local brw_size="obdfilter.*.brw_size"
10155
10156         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10157
10158         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10159
10160         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10161                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10162                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10163            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10164                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10165                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10166
10167                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10168                         suffix="M"
10169
10170                 if [[ $orig_mb -lt 16 ]]; then
10171                         save_lustre_params $osts "$brw_size" > $p
10172                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10173                                 error "set 16MB RPC size failed"
10174
10175                         echo "remount client to enable new RPC size"
10176                         remount_client $MOUNT || error "remount_client failed"
10177                 fi
10178
10179                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10180                 # should be able to set brw_size=12, but no rpc_stats for that
10181                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10182         fi
10183
10184         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10185
10186         if [[ $orig_mb -lt 16 ]]; then
10187                 restore_lustre_params < $p
10188                 remount_client $MOUNT || error "remount_client restore failed"
10189         fi
10190
10191         rm -f $p $DIR/$tfile
10192 }
10193 run_test 101g "Big bulk(4/16 MiB) readahead"
10194
10195 test_101h() {
10196         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10197
10198         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10199                 error "dd 70M file failed"
10200         echo Cancel LRU locks on lustre client to flush the client cache
10201         cancel_lru_locks osc
10202
10203         echo "Reset readahead stats"
10204         $LCTL set_param -n llite.*.read_ahead_stats 0
10205
10206         echo "Read 10M of data but cross 64M bundary"
10207         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10208         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10209                      get_named_value 'misses' | calc_total)
10210         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10211         rm -f $p $DIR/$tfile
10212 }
10213 run_test 101h "Readahead should cover current read window"
10214
10215 test_101i() {
10216         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10217                 error "dd 10M file failed"
10218
10219         local max_per_file_mb=$($LCTL get_param -n \
10220                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10221         cancel_lru_locks osc
10222         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10223         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10224                 error "set max_read_ahead_per_file_mb to 1 failed"
10225
10226         echo "Reset readahead stats"
10227         $LCTL set_param llite.*.read_ahead_stats=0
10228
10229         dd if=$DIR/$tfile of=/dev/null bs=2M
10230
10231         $LCTL get_param llite.*.read_ahead_stats
10232         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10233                      awk '/misses/ { print $2 }')
10234         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10235         rm -f $DIR/$tfile
10236 }
10237 run_test 101i "allow current readahead to exceed reservation"
10238
10239 test_101j() {
10240         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10241                 error "setstripe $DIR/$tfile failed"
10242         local file_size=$((1048576 * 16))
10243         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10244         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10245
10246         echo Disable read-ahead
10247         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10248
10249         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10250         for blk in $PAGE_SIZE 1048576 $file_size; do
10251                 cancel_lru_locks osc
10252                 echo "Reset readahead stats"
10253                 $LCTL set_param -n llite.*.read_ahead_stats=0
10254                 local count=$(($file_size / $blk))
10255                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10256                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10257                              get_named_value 'failed.to.fast.read' | calc_total)
10258                 $LCTL get_param -n llite.*.read_ahead_stats
10259                 [ $miss -eq $count ] || error "expected $count got $miss"
10260         done
10261
10262         rm -f $p $DIR/$tfile
10263 }
10264 run_test 101j "A complete read block should be submitted when no RA"
10265
10266 setup_test102() {
10267         test_mkdir $DIR/$tdir
10268         chown $RUNAS_ID $DIR/$tdir
10269         STRIPE_SIZE=65536
10270         STRIPE_OFFSET=1
10271         STRIPE_COUNT=$OSTCOUNT
10272         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10273
10274         trap cleanup_test102 EXIT
10275         cd $DIR
10276         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10277         cd $DIR/$tdir
10278         for num in 1 2 3 4; do
10279                 for count in $(seq 1 $STRIPE_COUNT); do
10280                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10281                                 local size=`expr $STRIPE_SIZE \* $num`
10282                                 local file=file"$num-$idx-$count"
10283                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10284                         done
10285                 done
10286         done
10287
10288         cd $DIR
10289         $1 tar cf $TMP/f102.tar $tdir --xattrs
10290 }
10291
10292 cleanup_test102() {
10293         trap 0
10294         rm -f $TMP/f102.tar
10295         rm -rf $DIR/d0.sanity/d102
10296 }
10297
10298 test_102a() {
10299         [ "$UID" != 0 ] && skip "must run as root"
10300         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10301                 skip_env "must have user_xattr"
10302
10303         [ -z "$(which setfattr 2>/dev/null)" ] &&
10304                 skip_env "could not find setfattr"
10305
10306         local testfile=$DIR/$tfile
10307
10308         touch $testfile
10309         echo "set/get xattr..."
10310         setfattr -n trusted.name1 -v value1 $testfile ||
10311                 error "setfattr -n trusted.name1=value1 $testfile failed"
10312         getfattr -n trusted.name1 $testfile 2> /dev/null |
10313           grep "trusted.name1=.value1" ||
10314                 error "$testfile missing trusted.name1=value1"
10315
10316         setfattr -n user.author1 -v author1 $testfile ||
10317                 error "setfattr -n user.author1=author1 $testfile failed"
10318         getfattr -n user.author1 $testfile 2> /dev/null |
10319           grep "user.author1=.author1" ||
10320                 error "$testfile missing trusted.author1=author1"
10321
10322         echo "listxattr..."
10323         setfattr -n trusted.name2 -v value2 $testfile ||
10324                 error "$testfile unable to set trusted.name2"
10325         setfattr -n trusted.name3 -v value3 $testfile ||
10326                 error "$testfile unable to set trusted.name3"
10327         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10328             grep "trusted.name" | wc -l) -eq 3 ] ||
10329                 error "$testfile missing 3 trusted.name xattrs"
10330
10331         setfattr -n user.author2 -v author2 $testfile ||
10332                 error "$testfile unable to set user.author2"
10333         setfattr -n user.author3 -v author3 $testfile ||
10334                 error "$testfile unable to set user.author3"
10335         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10336             grep "user.author" | wc -l) -eq 3 ] ||
10337                 error "$testfile missing 3 user.author xattrs"
10338
10339         echo "remove xattr..."
10340         setfattr -x trusted.name1 $testfile ||
10341                 error "$testfile error deleting trusted.name1"
10342         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10343                 error "$testfile did not delete trusted.name1 xattr"
10344
10345         setfattr -x user.author1 $testfile ||
10346                 error "$testfile error deleting user.author1"
10347         echo "set lustre special xattr ..."
10348         $LFS setstripe -c1 $testfile
10349         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10350                 awk -F "=" '/trusted.lov/ { print $2 }' )
10351         setfattr -n "trusted.lov" -v $lovea $testfile ||
10352                 error "$testfile doesn't ignore setting trusted.lov again"
10353         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10354                 error "$testfile allow setting invalid trusted.lov"
10355         rm -f $testfile
10356 }
10357 run_test 102a "user xattr test =================================="
10358
10359 check_102b_layout() {
10360         local layout="$*"
10361         local testfile=$DIR/$tfile
10362
10363         echo "test layout '$layout'"
10364         $LFS setstripe $layout $testfile || error "setstripe failed"
10365         $LFS getstripe -y $testfile
10366
10367         echo "get/set/list trusted.lov xattr ..." # b=10930
10368         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10369         [[ "$value" =~ "trusted.lov" ]] ||
10370                 error "can't get trusted.lov from $testfile"
10371         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10372                 error "getstripe failed"
10373
10374         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10375
10376         value=$(cut -d= -f2 <<<$value)
10377         # LU-13168: truncated xattr should fail if short lov_user_md header
10378         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10379                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10380         for len in $lens; do
10381                 echo "setfattr $len $testfile.2"
10382                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10383                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10384         done
10385         local stripe_size=$($LFS getstripe -S $testfile.2)
10386         local stripe_count=$($LFS getstripe -c $testfile.2)
10387         [[ $stripe_size -eq 65536 ]] ||
10388                 error "stripe size $stripe_size != 65536"
10389         [[ $stripe_count -eq $stripe_count_orig ]] ||
10390                 error "stripe count $stripe_count != $stripe_count_orig"
10391         rm $testfile $testfile.2
10392 }
10393
10394 test_102b() {
10395         [ -z "$(which setfattr 2>/dev/null)" ] &&
10396                 skip_env "could not find setfattr"
10397         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10398
10399         # check plain layout
10400         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10401
10402         # and also check composite layout
10403         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10404
10405 }
10406 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10407
10408 test_102c() {
10409         [ -z "$(which setfattr 2>/dev/null)" ] &&
10410                 skip_env "could not find setfattr"
10411         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10412
10413         # b10930: get/set/list lustre.lov xattr
10414         echo "get/set/list lustre.lov xattr ..."
10415         test_mkdir $DIR/$tdir
10416         chown $RUNAS_ID $DIR/$tdir
10417         local testfile=$DIR/$tdir/$tfile
10418         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10419                 error "setstripe failed"
10420         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10421                 error "getstripe failed"
10422         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10423         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10424
10425         local testfile2=${testfile}2
10426         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10427                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10428
10429         $RUNAS $MCREATE $testfile2
10430         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10431         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10432         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10433         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10434         [ $stripe_count -eq $STRIPECOUNT ] ||
10435                 error "stripe count $stripe_count != $STRIPECOUNT"
10436 }
10437 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10438
10439 compare_stripe_info1() {
10440         local stripe_index_all_zero=true
10441
10442         for num in 1 2 3 4; do
10443                 for count in $(seq 1 $STRIPE_COUNT); do
10444                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10445                                 local size=$((STRIPE_SIZE * num))
10446                                 local file=file"$num-$offset-$count"
10447                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10448                                 [[ $stripe_size -ne $size ]] &&
10449                                     error "$file: size $stripe_size != $size"
10450                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10451                                 # allow fewer stripes to be created, ORI-601
10452                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10453                                     error "$file: count $stripe_count != $count"
10454                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10455                                 [[ $stripe_index -ne 0 ]] &&
10456                                         stripe_index_all_zero=false
10457                         done
10458                 done
10459         done
10460         $stripe_index_all_zero &&
10461                 error "all files are being extracted starting from OST index 0"
10462         return 0
10463 }
10464
10465 have_xattrs_include() {
10466         tar --help | grep -q xattrs-include &&
10467                 echo --xattrs-include="lustre.*"
10468 }
10469
10470 test_102d() {
10471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10472         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10473
10474         XINC=$(have_xattrs_include)
10475         setup_test102
10476         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10477         cd $DIR/$tdir/$tdir
10478         compare_stripe_info1
10479 }
10480 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10481
10482 test_102f() {
10483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10484         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10485
10486         XINC=$(have_xattrs_include)
10487         setup_test102
10488         test_mkdir $DIR/$tdir.restore
10489         cd $DIR
10490         tar cf - --xattrs $tdir | tar xf - \
10491                 -C $DIR/$tdir.restore --xattrs $XINC
10492         cd $DIR/$tdir.restore/$tdir
10493         compare_stripe_info1
10494 }
10495 run_test 102f "tar copy files, not keep osts"
10496
10497 grow_xattr() {
10498         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10499                 skip "must have user_xattr"
10500         [ -z "$(which setfattr 2>/dev/null)" ] &&
10501                 skip_env "could not find setfattr"
10502         [ -z "$(which getfattr 2>/dev/null)" ] &&
10503                 skip_env "could not find getfattr"
10504
10505         local xsize=${1:-1024}  # in bytes
10506         local file=$DIR/$tfile
10507         local value="$(generate_string $xsize)"
10508         local xbig=trusted.big
10509         local toobig=$2
10510
10511         touch $file
10512         log "save $xbig on $file"
10513         if [ -z "$toobig" ]
10514         then
10515                 setfattr -n $xbig -v $value $file ||
10516                         error "saving $xbig on $file failed"
10517         else
10518                 setfattr -n $xbig -v $value $file &&
10519                         error "saving $xbig on $file succeeded"
10520                 return 0
10521         fi
10522
10523         local orig=$(get_xattr_value $xbig $file)
10524         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10525
10526         local xsml=trusted.sml
10527         log "save $xsml on $file"
10528         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10529
10530         local new=$(get_xattr_value $xbig $file)
10531         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10532
10533         log "grow $xsml on $file"
10534         setfattr -n $xsml -v "$value" $file ||
10535                 error "growing $xsml on $file failed"
10536
10537         new=$(get_xattr_value $xbig $file)
10538         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10539         log "$xbig still valid after growing $xsml"
10540
10541         rm -f $file
10542 }
10543
10544 test_102h() { # bug 15777
10545         grow_xattr 1024
10546 }
10547 run_test 102h "grow xattr from inside inode to external block"
10548
10549 test_102ha() {
10550         large_xattr_enabled || skip_env "ea_inode feature disabled"
10551
10552         echo "setting xattr of max xattr size: $(max_xattr_size)"
10553         grow_xattr $(max_xattr_size)
10554
10555         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10556         echo "This should fail:"
10557         grow_xattr $(($(max_xattr_size) + 10)) 1
10558 }
10559 run_test 102ha "grow xattr from inside inode to external inode"
10560
10561 test_102i() { # bug 17038
10562         [ -z "$(which getfattr 2>/dev/null)" ] &&
10563                 skip "could not find getfattr"
10564
10565         touch $DIR/$tfile
10566         ln -s $DIR/$tfile $DIR/${tfile}link
10567         getfattr -n trusted.lov $DIR/$tfile ||
10568                 error "lgetxattr on $DIR/$tfile failed"
10569         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10570                 grep -i "no such attr" ||
10571                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10572         rm -f $DIR/$tfile $DIR/${tfile}link
10573 }
10574 run_test 102i "lgetxattr test on symbolic link ============"
10575
10576 test_102j() {
10577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10578         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10579
10580         XINC=$(have_xattrs_include)
10581         setup_test102 "$RUNAS"
10582         chown $RUNAS_ID $DIR/$tdir
10583         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10584         cd $DIR/$tdir/$tdir
10585         compare_stripe_info1 "$RUNAS"
10586 }
10587 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10588
10589 test_102k() {
10590         [ -z "$(which setfattr 2>/dev/null)" ] &&
10591                 skip "could not find setfattr"
10592
10593         touch $DIR/$tfile
10594         # b22187 just check that does not crash for regular file.
10595         setfattr -n trusted.lov $DIR/$tfile
10596         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10597         local test_kdir=$DIR/$tdir
10598         test_mkdir $test_kdir
10599         local default_size=$($LFS getstripe -S $test_kdir)
10600         local default_count=$($LFS getstripe -c $test_kdir)
10601         local default_offset=$($LFS getstripe -i $test_kdir)
10602         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10603                 error 'dir setstripe failed'
10604         setfattr -n trusted.lov $test_kdir
10605         local stripe_size=$($LFS getstripe -S $test_kdir)
10606         local stripe_count=$($LFS getstripe -c $test_kdir)
10607         local stripe_offset=$($LFS getstripe -i $test_kdir)
10608         [ $stripe_size -eq $default_size ] ||
10609                 error "stripe size $stripe_size != $default_size"
10610         [ $stripe_count -eq $default_count ] ||
10611                 error "stripe count $stripe_count != $default_count"
10612         [ $stripe_offset -eq $default_offset ] ||
10613                 error "stripe offset $stripe_offset != $default_offset"
10614         rm -rf $DIR/$tfile $test_kdir
10615 }
10616 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10617
10618 test_102l() {
10619         [ -z "$(which getfattr 2>/dev/null)" ] &&
10620                 skip "could not find getfattr"
10621
10622         # LU-532 trusted. xattr is invisible to non-root
10623         local testfile=$DIR/$tfile
10624
10625         touch $testfile
10626
10627         echo "listxattr as user..."
10628         chown $RUNAS_ID $testfile
10629         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10630             grep -q "trusted" &&
10631                 error "$testfile trusted xattrs are user visible"
10632
10633         return 0;
10634 }
10635 run_test 102l "listxattr size test =================================="
10636
10637 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10638         local path=$DIR/$tfile
10639         touch $path
10640
10641         listxattr_size_check $path || error "listattr_size_check $path failed"
10642 }
10643 run_test 102m "Ensure listxattr fails on small bufffer ========"
10644
10645 cleanup_test102
10646
10647 getxattr() { # getxattr path name
10648         # Return the base64 encoding of the value of xattr name on path.
10649         local path=$1
10650         local name=$2
10651
10652         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10653         # file: $path
10654         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10655         #
10656         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10657
10658         getfattr --absolute-names --encoding=base64 --name=$name $path |
10659                 awk -F= -v name=$name '$1 == name {
10660                         print substr($0, index($0, "=") + 1);
10661         }'
10662 }
10663
10664 test_102n() { # LU-4101 mdt: protect internal xattrs
10665         [ -z "$(which setfattr 2>/dev/null)" ] &&
10666                 skip "could not find setfattr"
10667         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10668         then
10669                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10670         fi
10671
10672         local file0=$DIR/$tfile.0
10673         local file1=$DIR/$tfile.1
10674         local xattr0=$TMP/$tfile.0
10675         local xattr1=$TMP/$tfile.1
10676         local namelist="lov lma lmv link fid version som hsm"
10677         local name
10678         local value
10679
10680         rm -rf $file0 $file1 $xattr0 $xattr1
10681         touch $file0 $file1
10682
10683         # Get 'before' xattrs of $file1.
10684         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10685
10686         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10687                 namelist+=" lfsck_namespace"
10688         for name in $namelist; do
10689                 # Try to copy xattr from $file0 to $file1.
10690                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10691
10692                 setfattr --name=trusted.$name --value="$value" $file1 ||
10693                         error "setxattr 'trusted.$name' failed"
10694
10695                 # Try to set a garbage xattr.
10696                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10697
10698                 if [[ x$name == "xlov" ]]; then
10699                         setfattr --name=trusted.lov --value="$value" $file1 &&
10700                         error "setxattr invalid 'trusted.lov' success"
10701                 else
10702                         setfattr --name=trusted.$name --value="$value" $file1 ||
10703                                 error "setxattr invalid 'trusted.$name' failed"
10704                 fi
10705
10706                 # Try to remove the xattr from $file1. We don't care if this
10707                 # appears to succeed or fail, we just don't want there to be
10708                 # any changes or crashes.
10709                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10710         done
10711
10712         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10713         then
10714                 name="lfsck_ns"
10715                 # Try to copy xattr from $file0 to $file1.
10716                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10717
10718                 setfattr --name=trusted.$name --value="$value" $file1 ||
10719                         error "setxattr 'trusted.$name' failed"
10720
10721                 # Try to set a garbage xattr.
10722                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10723
10724                 setfattr --name=trusted.$name --value="$value" $file1 ||
10725                         error "setxattr 'trusted.$name' failed"
10726
10727                 # Try to remove the xattr from $file1. We don't care if this
10728                 # appears to succeed or fail, we just don't want there to be
10729                 # any changes or crashes.
10730                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10731         fi
10732
10733         # Get 'after' xattrs of file1.
10734         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10735
10736         if ! diff $xattr0 $xattr1; then
10737                 error "before and after xattrs of '$file1' differ"
10738         fi
10739
10740         rm -rf $file0 $file1 $xattr0 $xattr1
10741
10742         return 0
10743 }
10744 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10745
10746 test_102p() { # LU-4703 setxattr did not check ownership
10747         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10748                 skip "MDS needs to be at least 2.5.56"
10749
10750         local testfile=$DIR/$tfile
10751
10752         touch $testfile
10753
10754         echo "setfacl as user..."
10755         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10756         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10757
10758         echo "setfattr as user..."
10759         setfacl -m "u:$RUNAS_ID:---" $testfile
10760         $RUNAS setfattr -x system.posix_acl_access $testfile
10761         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10762 }
10763 run_test 102p "check setxattr(2) correctly fails without permission"
10764
10765 test_102q() {
10766         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10767                 skip "MDS needs to be at least 2.6.92"
10768
10769         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10770 }
10771 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10772
10773 test_102r() {
10774         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10775                 skip "MDS needs to be at least 2.6.93"
10776
10777         touch $DIR/$tfile || error "touch"
10778         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10779         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10780         rm $DIR/$tfile || error "rm"
10781
10782         #normal directory
10783         mkdir -p $DIR/$tdir || error "mkdir"
10784         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10785         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10786         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10787                 error "$testfile error deleting user.author1"
10788         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10789                 grep "user.$(basename $tdir)" &&
10790                 error "$tdir did not delete user.$(basename $tdir)"
10791         rmdir $DIR/$tdir || error "rmdir"
10792
10793         #striped directory
10794         test_mkdir $DIR/$tdir
10795         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10796         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10797         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10798                 error "$testfile error deleting user.author1"
10799         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10800                 grep "user.$(basename $tdir)" &&
10801                 error "$tdir did not delete user.$(basename $tdir)"
10802         rmdir $DIR/$tdir || error "rm striped dir"
10803 }
10804 run_test 102r "set EAs with empty values"
10805
10806 test_102s() {
10807         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10808                 skip "MDS needs to be at least 2.11.52"
10809
10810         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10811
10812         save_lustre_params client "llite.*.xattr_cache" > $save
10813
10814         for cache in 0 1; do
10815                 lctl set_param llite.*.xattr_cache=$cache
10816
10817                 rm -f $DIR/$tfile
10818                 touch $DIR/$tfile || error "touch"
10819                 for prefix in lustre security system trusted user; do
10820                         # Note getxattr() may fail with 'Operation not
10821                         # supported' or 'No such attribute' depending
10822                         # on prefix and cache.
10823                         getfattr -n $prefix.n102s $DIR/$tfile &&
10824                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10825                 done
10826         done
10827
10828         restore_lustre_params < $save
10829 }
10830 run_test 102s "getting nonexistent xattrs should fail"
10831
10832 test_102t() {
10833         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10834                 skip "MDS needs to be at least 2.11.52"
10835
10836         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10837
10838         save_lustre_params client "llite.*.xattr_cache" > $save
10839
10840         for cache in 0 1; do
10841                 lctl set_param llite.*.xattr_cache=$cache
10842
10843                 for buf_size in 0 256; do
10844                         rm -f $DIR/$tfile
10845                         touch $DIR/$tfile || error "touch"
10846                         setfattr -n user.multiop $DIR/$tfile
10847                         $MULTIOP $DIR/$tfile oa$buf_size ||
10848                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10849                 done
10850         done
10851
10852         restore_lustre_params < $save
10853 }
10854 run_test 102t "zero length xattr values handled correctly"
10855
10856 run_acl_subtest()
10857 {
10858     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10859     return $?
10860 }
10861
10862 test_103a() {
10863         [ "$UID" != 0 ] && skip "must run as root"
10864         $GSS && skip_env "could not run under gss"
10865         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10866                 skip_env "must have acl enabled"
10867         [ -z "$(which setfacl 2>/dev/null)" ] &&
10868                 skip_env "could not find setfacl"
10869         remote_mds_nodsh && skip "remote MDS with nodsh"
10870
10871         gpasswd -a daemon bin                           # LU-5641
10872         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10873
10874         declare -a identity_old
10875
10876         for num in $(seq $MDSCOUNT); do
10877                 switch_identity $num true || identity_old[$num]=$?
10878         done
10879
10880         SAVE_UMASK=$(umask)
10881         umask 0022
10882         mkdir -p $DIR/$tdir
10883         cd $DIR/$tdir
10884
10885         echo "performing cp ..."
10886         run_acl_subtest cp || error "run_acl_subtest cp failed"
10887         echo "performing getfacl-noacl..."
10888         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10889         echo "performing misc..."
10890         run_acl_subtest misc || error  "misc test failed"
10891         echo "performing permissions..."
10892         run_acl_subtest permissions || error "permissions failed"
10893         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10894         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10895                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10896                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10897         then
10898                 echo "performing permissions xattr..."
10899                 run_acl_subtest permissions_xattr ||
10900                         error "permissions_xattr failed"
10901         fi
10902         echo "performing setfacl..."
10903         run_acl_subtest setfacl || error  "setfacl test failed"
10904
10905         # inheritance test got from HP
10906         echo "performing inheritance..."
10907         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10908         chmod +x make-tree || error "chmod +x failed"
10909         run_acl_subtest inheritance || error "inheritance test failed"
10910         rm -f make-tree
10911
10912         echo "LU-974 ignore umask when acl is enabled..."
10913         run_acl_subtest 974 || error "LU-974 umask test failed"
10914         if [ $MDSCOUNT -ge 2 ]; then
10915                 run_acl_subtest 974_remote ||
10916                         error "LU-974 umask test failed under remote dir"
10917         fi
10918
10919         echo "LU-2561 newly created file is same size as directory..."
10920         if [ "$mds1_FSTYPE" != "zfs" ]; then
10921                 run_acl_subtest 2561 || error "LU-2561 test failed"
10922         else
10923                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10924         fi
10925
10926         run_acl_subtest 4924 || error "LU-4924 test failed"
10927
10928         cd $SAVE_PWD
10929         umask $SAVE_UMASK
10930
10931         for num in $(seq $MDSCOUNT); do
10932                 if [ "${identity_old[$num]}" = 1 ]; then
10933                         switch_identity $num false || identity_old[$num]=$?
10934                 fi
10935         done
10936 }
10937 run_test 103a "acl test"
10938
10939 test_103b() {
10940         declare -a pids
10941         local U
10942
10943         for U in {0..511}; do
10944                 {
10945                 local O=$(printf "%04o" $U)
10946
10947                 umask $(printf "%04o" $((511 ^ $O)))
10948                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10949                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10950
10951                 (( $S == ($O & 0666) )) ||
10952                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10953
10954                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10955                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10956                 (( $S == ($O & 0666) )) ||
10957                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10958
10959                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10960                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10961                 (( $S == ($O & 0666) )) ||
10962                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10963                 rm -f $DIR/$tfile.[smp]$0
10964                 } &
10965                 local pid=$!
10966
10967                 # limit the concurrently running threads to 64. LU-11878
10968                 local idx=$((U % 64))
10969                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10970                 pids[idx]=$pid
10971         done
10972         wait
10973 }
10974 run_test 103b "umask lfs setstripe"
10975
10976 test_103c() {
10977         mkdir -p $DIR/$tdir
10978         cp -rp $DIR/$tdir $DIR/$tdir.bak
10979
10980         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10981                 error "$DIR/$tdir shouldn't contain default ACL"
10982         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10983                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10984         true
10985 }
10986 run_test 103c "'cp -rp' won't set empty acl"
10987
10988 test_103e() {
10989         local numacl
10990         local fileacl
10991         local saved_debug=$($LCTL get_param -n debug)
10992
10993         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
10994                 skip "MDS needs to be at least 2.14.0"
10995
10996         large_xattr_enabled || skip_env "ea_inode feature disabled"
10997
10998         mkdir -p $DIR/$tdir
10999         # add big LOV EA to cause reply buffer overflow earlier
11000         $LFS setstripe -C 1000 $DIR/$tdir
11001         lctl set_param mdc.*-mdc*.stats=clear
11002
11003         $LCTL set_param debug=0
11004         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11005         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11006
11007         # add a large number of default ACLs (expect 8000+ for 2.13+)
11008         for U in {2..7000}; do
11009                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11010                         error "Able to add just $U default ACLs"
11011         done
11012         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11013         echo "$numacl default ACLs created"
11014
11015         stat $DIR/$tdir || error "Cannot stat directory"
11016         # check file creation
11017         touch $DIR/$tdir/$tfile ||
11018                 error "failed to create $tfile with $numacl default ACLs"
11019         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11020         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11021         echo "$fileacl ACLs were inherited"
11022         (( $fileacl == $numacl )) ||
11023                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11024         # check that new ACLs creation adds new ACLs to inherited ACLs
11025         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11026                 error "Cannot set new ACL"
11027         numacl=$((numacl + 1))
11028         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11029         (( $fileacl == $numacl )) ||
11030                 error "failed to add new ACL: $fileacl != $numacl as expected"
11031         # adds more ACLs to a file to reach their maximum at 8000+
11032         numacl=0
11033         for U in {20000..25000}; do
11034                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11035                 numacl=$((numacl + 1))
11036         done
11037         echo "Added $numacl more ACLs to the file"
11038         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11039         echo "Total $fileacl ACLs in file"
11040         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11041         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11042         rmdir $DIR/$tdir || error "Cannot remove directory"
11043 }
11044 run_test 103e "inheritance of big amount of default ACLs"
11045
11046 test_103f() {
11047         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11048                 skip "MDS needs to be at least 2.14.51"
11049
11050         large_xattr_enabled || skip_env "ea_inode feature disabled"
11051
11052         # enable changelog to consume more internal MDD buffers
11053         changelog_register
11054
11055         mkdir -p $DIR/$tdir
11056         # add big LOV EA
11057         $LFS setstripe -C 1000 $DIR/$tdir
11058         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11059         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11060         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11061         rmdir $DIR/$tdir || error "Cannot remove directory"
11062 }
11063 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11064
11065 test_104a() {
11066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11067
11068         touch $DIR/$tfile
11069         lfs df || error "lfs df failed"
11070         lfs df -ih || error "lfs df -ih failed"
11071         lfs df -h $DIR || error "lfs df -h $DIR failed"
11072         lfs df -i $DIR || error "lfs df -i $DIR failed"
11073         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11074         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11075
11076         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11077         lctl --device %$OSC deactivate
11078         lfs df || error "lfs df with deactivated OSC failed"
11079         lctl --device %$OSC activate
11080         # wait the osc back to normal
11081         wait_osc_import_ready client ost
11082
11083         lfs df || error "lfs df with reactivated OSC failed"
11084         rm -f $DIR/$tfile
11085 }
11086 run_test 104a "lfs df [-ih] [path] test ========================="
11087
11088 test_104b() {
11089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11090         [ $RUNAS_ID -eq $UID ] &&
11091                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11092
11093         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11094                         grep "Permission denied" | wc -l)))
11095         if [ $denied_cnt -ne 0 ]; then
11096                 error "lfs check servers test failed"
11097         fi
11098 }
11099 run_test 104b "$RUNAS lfs check servers test ===================="
11100
11101 #
11102 # Verify $1 is within range of $2.
11103 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11104 # $1 is <= 2% of $2. Else Fail.
11105 #
11106 value_in_range() {
11107         # Strip all units (M, G, T)
11108         actual=$(echo $1 | tr -d A-Z)
11109         expect=$(echo $2 | tr -d A-Z)
11110
11111         expect_lo=$(($expect * 98 / 100)) # 2% below
11112         expect_hi=$(($expect * 102 / 100)) # 2% above
11113
11114         # permit 2% drift above and below
11115         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11116 }
11117
11118 test_104c() {
11119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11120         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11121
11122         local ost_param="osd-zfs.$FSNAME-OST0000."
11123         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11124         local ofacets=$(get_facets OST)
11125         local mfacets=$(get_facets MDS)
11126         local saved_ost_blocks=
11127         local saved_mdt_blocks=
11128
11129         echo "Before recordsize change"
11130         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11131         df=($(df -h | grep "/mnt/lustre"$))
11132
11133         # For checking.
11134         echo "lfs output : ${lfs_df[*]}"
11135         echo "df  output : ${df[*]}"
11136
11137         for facet in ${ofacets//,/ }; do
11138                 if [ -z $saved_ost_blocks ]; then
11139                         saved_ost_blocks=$(do_facet $facet \
11140                                 lctl get_param -n $ost_param.blocksize)
11141                         echo "OST Blocksize: $saved_ost_blocks"
11142                 fi
11143                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11144                 do_facet $facet zfs set recordsize=32768 $ost
11145         done
11146
11147         # BS too small. Sufficient for functional testing.
11148         for facet in ${mfacets//,/ }; do
11149                 if [ -z $saved_mdt_blocks ]; then
11150                         saved_mdt_blocks=$(do_facet $facet \
11151                                 lctl get_param -n $mdt_param.blocksize)
11152                         echo "MDT Blocksize: $saved_mdt_blocks"
11153                 fi
11154                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11155                 do_facet $facet zfs set recordsize=32768 $mdt
11156         done
11157
11158         # Give new values chance to reflect change
11159         sleep 2
11160
11161         echo "After recordsize change"
11162         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11163         df_after=($(df -h | grep "/mnt/lustre"$))
11164
11165         # For checking.
11166         echo "lfs output : ${lfs_df_after[*]}"
11167         echo "df  output : ${df_after[*]}"
11168
11169         # Verify lfs df
11170         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11171                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11172         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11173                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11174         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11175                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11176
11177         # Verify df
11178         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11179                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11180         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11181                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11182         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11183                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11184
11185         # Restore MDT recordize back to original
11186         for facet in ${mfacets//,/ }; do
11187                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11188                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11189         done
11190
11191         # Restore OST recordize back to original
11192         for facet in ${ofacets//,/ }; do
11193                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11194                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11195         done
11196
11197         return 0
11198 }
11199 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11200
11201 test_105a() {
11202         # doesn't work on 2.4 kernels
11203         touch $DIR/$tfile
11204         if $(flock_is_enabled); then
11205                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11206         else
11207                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11208         fi
11209         rm -f $DIR/$tfile
11210 }
11211 run_test 105a "flock when mounted without -o flock test ========"
11212
11213 test_105b() {
11214         touch $DIR/$tfile
11215         if $(flock_is_enabled); then
11216                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11217         else
11218                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11219         fi
11220         rm -f $DIR/$tfile
11221 }
11222 run_test 105b "fcntl when mounted without -o flock test ========"
11223
11224 test_105c() {
11225         touch $DIR/$tfile
11226         if $(flock_is_enabled); then
11227                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11228         else
11229                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11230         fi
11231         rm -f $DIR/$tfile
11232 }
11233 run_test 105c "lockf when mounted without -o flock test"
11234
11235 test_105d() { # bug 15924
11236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11237
11238         test_mkdir $DIR/$tdir
11239         flock_is_enabled || skip_env "mount w/o flock enabled"
11240         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11241         $LCTL set_param fail_loc=0x80000315
11242         flocks_test 2 $DIR/$tdir
11243 }
11244 run_test 105d "flock race (should not freeze) ========"
11245
11246 test_105e() { # bug 22660 && 22040
11247         flock_is_enabled || skip_env "mount w/o flock enabled"
11248
11249         touch $DIR/$tfile
11250         flocks_test 3 $DIR/$tfile
11251 }
11252 run_test 105e "Two conflicting flocks from same process"
11253
11254 test_106() { #bug 10921
11255         test_mkdir $DIR/$tdir
11256         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11257         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11258 }
11259 run_test 106 "attempt exec of dir followed by chown of that dir"
11260
11261 test_107() {
11262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11263
11264         CDIR=`pwd`
11265         local file=core
11266
11267         cd $DIR
11268         rm -f $file
11269
11270         local save_pattern=$(sysctl -n kernel.core_pattern)
11271         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11272         sysctl -w kernel.core_pattern=$file
11273         sysctl -w kernel.core_uses_pid=0
11274
11275         ulimit -c unlimited
11276         sleep 60 &
11277         SLEEPPID=$!
11278
11279         sleep 1
11280
11281         kill -s 11 $SLEEPPID
11282         wait $SLEEPPID
11283         if [ -e $file ]; then
11284                 size=`stat -c%s $file`
11285                 [ $size -eq 0 ] && error "Fail to create core file $file"
11286         else
11287                 error "Fail to create core file $file"
11288         fi
11289         rm -f $file
11290         sysctl -w kernel.core_pattern=$save_pattern
11291         sysctl -w kernel.core_uses_pid=$save_uses_pid
11292         cd $CDIR
11293 }
11294 run_test 107 "Coredump on SIG"
11295
11296 test_110() {
11297         test_mkdir $DIR/$tdir
11298         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11299         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11300                 error "mkdir with 256 char should fail, but did not"
11301         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11302                 error "create with 255 char failed"
11303         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11304                 error "create with 256 char should fail, but did not"
11305
11306         ls -l $DIR/$tdir
11307         rm -rf $DIR/$tdir
11308 }
11309 run_test 110 "filename length checking"
11310
11311 #
11312 # Purpose: To verify dynamic thread (OSS) creation.
11313 #
11314 test_115() {
11315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11316         remote_ost_nodsh && skip "remote OST with nodsh"
11317
11318         # Lustre does not stop service threads once they are started.
11319         # Reset number of running threads to default.
11320         stopall
11321         setupall
11322
11323         local OSTIO_pre
11324         local save_params="$TMP/sanity-$TESTNAME.parameters"
11325
11326         # Get ll_ost_io count before I/O
11327         OSTIO_pre=$(do_facet ost1 \
11328                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11329         # Exit if lustre is not running (ll_ost_io not running).
11330         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11331
11332         echo "Starting with $OSTIO_pre threads"
11333         local thread_max=$((OSTIO_pre * 2))
11334         local rpc_in_flight=$((thread_max * 2))
11335         # Number of I/O Process proposed to be started.
11336         local nfiles
11337         local facets=$(get_facets OST)
11338
11339         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11340         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11341
11342         # Set in_flight to $rpc_in_flight
11343         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11344                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11345         nfiles=${rpc_in_flight}
11346         # Set ost thread_max to $thread_max
11347         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11348
11349         # 5 Minutes should be sufficient for max number of OSS
11350         # threads(thread_max) to be created.
11351         local timeout=300
11352
11353         # Start I/O.
11354         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11355         test_mkdir $DIR/$tdir
11356         for i in $(seq $nfiles); do
11357                 local file=$DIR/$tdir/${tfile}-$i
11358                 $LFS setstripe -c -1 -i 0 $file
11359                 ($WTL $file $timeout)&
11360         done
11361
11362         # I/O Started - Wait for thread_started to reach thread_max or report
11363         # error if thread_started is more than thread_max.
11364         echo "Waiting for thread_started to reach thread_max"
11365         local thread_started=0
11366         local end_time=$((SECONDS + timeout))
11367
11368         while [ $SECONDS -le $end_time ] ; do
11369                 echo -n "."
11370                 # Get ost i/o thread_started count.
11371                 thread_started=$(do_facet ost1 \
11372                         "$LCTL get_param \
11373                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11374                 # Break out if thread_started is equal/greater than thread_max
11375                 if [[ $thread_started -ge $thread_max ]]; then
11376                         echo ll_ost_io thread_started $thread_started, \
11377                                 equal/greater than thread_max $thread_max
11378                         break
11379                 fi
11380                 sleep 1
11381         done
11382
11383         # Cleanup - We have the numbers, Kill i/o jobs if running.
11384         jobcount=($(jobs -p))
11385         for i in $(seq 0 $((${#jobcount[@]}-1)))
11386         do
11387                 kill -9 ${jobcount[$i]}
11388                 if [ $? -ne 0 ] ; then
11389                         echo Warning: \
11390                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11391                 fi
11392         done
11393
11394         # Cleanup files left by WTL binary.
11395         for i in $(seq $nfiles); do
11396                 local file=$DIR/$tdir/${tfile}-$i
11397                 rm -rf $file
11398                 if [ $? -ne 0 ] ; then
11399                         echo "Warning: Failed to delete file $file"
11400                 fi
11401         done
11402
11403         restore_lustre_params <$save_params
11404         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11405
11406         # Error out if no new thread has started or Thread started is greater
11407         # than thread max.
11408         if [[ $thread_started -le $OSTIO_pre ||
11409                         $thread_started -gt $thread_max ]]; then
11410                 error "ll_ost_io: thread_started $thread_started" \
11411                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11412                       "No new thread started or thread started greater " \
11413                       "than thread_max."
11414         fi
11415 }
11416 run_test 115 "verify dynamic thread creation===================="
11417
11418 free_min_max () {
11419         wait_delete_completed
11420         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11421         echo "OST kbytes available: ${AVAIL[@]}"
11422         MAXV=${AVAIL[0]}
11423         MAXI=0
11424         MINV=${AVAIL[0]}
11425         MINI=0
11426         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11427                 #echo OST $i: ${AVAIL[i]}kb
11428                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11429                         MAXV=${AVAIL[i]}
11430                         MAXI=$i
11431                 fi
11432                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11433                         MINV=${AVAIL[i]}
11434                         MINI=$i
11435                 fi
11436         done
11437         echo "Min free space: OST $MINI: $MINV"
11438         echo "Max free space: OST $MAXI: $MAXV"
11439 }
11440
11441 test_116a() { # was previously test_116()
11442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11443         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11444         remote_mds_nodsh && skip "remote MDS with nodsh"
11445
11446         echo -n "Free space priority "
11447         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11448                 head -n1
11449         declare -a AVAIL
11450         free_min_max
11451
11452         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11453         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11454         trap simple_cleanup_common EXIT
11455
11456         # Check if we need to generate uneven OSTs
11457         test_mkdir -p $DIR/$tdir/OST${MINI}
11458         local FILL=$((MINV / 4))
11459         local DIFF=$((MAXV - MINV))
11460         local DIFF2=$((DIFF * 100 / MINV))
11461
11462         local threshold=$(do_facet $SINGLEMDS \
11463                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11464         threshold=${threshold%%%}
11465         echo -n "Check for uneven OSTs: "
11466         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11467
11468         if [[ $DIFF2 -gt $threshold ]]; then
11469                 echo "ok"
11470                 echo "Don't need to fill OST$MINI"
11471         else
11472                 # generate uneven OSTs. Write 2% over the QOS threshold value
11473                 echo "no"
11474                 DIFF=$((threshold - DIFF2 + 2))
11475                 DIFF2=$((MINV * DIFF / 100))
11476                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11477                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11478                         error "setstripe failed"
11479                 DIFF=$((DIFF2 / 2048))
11480                 i=0
11481                 while [ $i -lt $DIFF ]; do
11482                         i=$((i + 1))
11483                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11484                                 bs=2M count=1 2>/dev/null
11485                         echo -n .
11486                 done
11487                 echo .
11488                 sync
11489                 sleep_maxage
11490                 free_min_max
11491         fi
11492
11493         DIFF=$((MAXV - MINV))
11494         DIFF2=$((DIFF * 100 / MINV))
11495         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11496         if [ $DIFF2 -gt $threshold ]; then
11497                 echo "ok"
11498         else
11499                 echo "failed - QOS mode won't be used"
11500                 simple_cleanup_common
11501                 skip "QOS imbalance criteria not met"
11502         fi
11503
11504         MINI1=$MINI
11505         MINV1=$MINV
11506         MAXI1=$MAXI
11507         MAXV1=$MAXV
11508
11509         # now fill using QOS
11510         $LFS setstripe -c 1 $DIR/$tdir
11511         FILL=$((FILL / 200))
11512         if [ $FILL -gt 600 ]; then
11513                 FILL=600
11514         fi
11515         echo "writing $FILL files to QOS-assigned OSTs"
11516         i=0
11517         while [ $i -lt $FILL ]; do
11518                 i=$((i + 1))
11519                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11520                         count=1 2>/dev/null
11521                 echo -n .
11522         done
11523         echo "wrote $i 200k files"
11524         sync
11525         sleep_maxage
11526
11527         echo "Note: free space may not be updated, so measurements might be off"
11528         free_min_max
11529         DIFF2=$((MAXV - MINV))
11530         echo "free space delta: orig $DIFF final $DIFF2"
11531         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11532         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11533         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11534         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11535         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11536         if [[ $DIFF -gt 0 ]]; then
11537                 FILL=$((DIFF2 * 100 / DIFF - 100))
11538                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11539         fi
11540
11541         # Figure out which files were written where
11542         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11543                awk '/'$MINI1': / {print $2; exit}')
11544         echo $UUID
11545         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11546         echo "$MINC files created on smaller OST $MINI1"
11547         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11548                awk '/'$MAXI1': / {print $2; exit}')
11549         echo $UUID
11550         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11551         echo "$MAXC files created on larger OST $MAXI1"
11552         if [[ $MINC -gt 0 ]]; then
11553                 FILL=$((MAXC * 100 / MINC - 100))
11554                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11555         fi
11556         [[ $MAXC -gt $MINC ]] ||
11557                 error_ignore LU-9 "stripe QOS didn't balance free space"
11558         simple_cleanup_common
11559 }
11560 run_test 116a "stripe QOS: free space balance ==================="
11561
11562 test_116b() { # LU-2093
11563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11564         remote_mds_nodsh && skip "remote MDS with nodsh"
11565
11566 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11567         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11568                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11569         [ -z "$old_rr" ] && skip "no QOS"
11570         do_facet $SINGLEMDS lctl set_param \
11571                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11572         mkdir -p $DIR/$tdir
11573         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11574         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11575         do_facet $SINGLEMDS lctl set_param fail_loc=0
11576         rm -rf $DIR/$tdir
11577         do_facet $SINGLEMDS lctl set_param \
11578                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11579 }
11580 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11581
11582 test_117() # bug 10891
11583 {
11584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11585
11586         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11587         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11588         lctl set_param fail_loc=0x21e
11589         > $DIR/$tfile || error "truncate failed"
11590         lctl set_param fail_loc=0
11591         echo "Truncate succeeded."
11592         rm -f $DIR/$tfile
11593 }
11594 run_test 117 "verify osd extend =========="
11595
11596 NO_SLOW_RESENDCOUNT=4
11597 export OLD_RESENDCOUNT=""
11598 set_resend_count () {
11599         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11600         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11601         lctl set_param -n $PROC_RESENDCOUNT $1
11602         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11603 }
11604
11605 # for reduce test_118* time (b=14842)
11606 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11607
11608 # Reset async IO behavior after error case
11609 reset_async() {
11610         FILE=$DIR/reset_async
11611
11612         # Ensure all OSCs are cleared
11613         $LFS setstripe -c -1 $FILE
11614         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11615         sync
11616         rm $FILE
11617 }
11618
11619 test_118a() #bug 11710
11620 {
11621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11622
11623         reset_async
11624
11625         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11626         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11627         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11628
11629         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11630                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11631                 return 1;
11632         fi
11633         rm -f $DIR/$tfile
11634 }
11635 run_test 118a "verify O_SYNC works =========="
11636
11637 test_118b()
11638 {
11639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11640         remote_ost_nodsh && skip "remote OST with nodsh"
11641
11642         reset_async
11643
11644         #define OBD_FAIL_SRV_ENOENT 0x217
11645         set_nodes_failloc "$(osts_nodes)" 0x217
11646         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11647         RC=$?
11648         set_nodes_failloc "$(osts_nodes)" 0
11649         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11650         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11651                     grep -c writeback)
11652
11653         if [[ $RC -eq 0 ]]; then
11654                 error "Must return error due to dropped pages, rc=$RC"
11655                 return 1;
11656         fi
11657
11658         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11659                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11660                 return 1;
11661         fi
11662
11663         echo "Dirty pages not leaked on ENOENT"
11664
11665         # Due to the above error the OSC will issue all RPCs syncronously
11666         # until a subsequent RPC completes successfully without error.
11667         $MULTIOP $DIR/$tfile Ow4096yc
11668         rm -f $DIR/$tfile
11669
11670         return 0
11671 }
11672 run_test 118b "Reclaim dirty pages on fatal error =========="
11673
11674 test_118c()
11675 {
11676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11677
11678         # for 118c, restore the original resend count, LU-1940
11679         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11680                                 set_resend_count $OLD_RESENDCOUNT
11681         remote_ost_nodsh && skip "remote OST with nodsh"
11682
11683         reset_async
11684
11685         #define OBD_FAIL_OST_EROFS               0x216
11686         set_nodes_failloc "$(osts_nodes)" 0x216
11687
11688         # multiop should block due to fsync until pages are written
11689         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11690         MULTIPID=$!
11691         sleep 1
11692
11693         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11694                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11695         fi
11696
11697         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11698                     grep -c writeback)
11699         if [[ $WRITEBACK -eq 0 ]]; then
11700                 error "No page in writeback, writeback=$WRITEBACK"
11701         fi
11702
11703         set_nodes_failloc "$(osts_nodes)" 0
11704         wait $MULTIPID
11705         RC=$?
11706         if [[ $RC -ne 0 ]]; then
11707                 error "Multiop fsync failed, rc=$RC"
11708         fi
11709
11710         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11711         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11712                     grep -c writeback)
11713         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11714                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11715         fi
11716
11717         rm -f $DIR/$tfile
11718         echo "Dirty pages flushed via fsync on EROFS"
11719         return 0
11720 }
11721 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11722
11723 # continue to use small resend count to reduce test_118* time (b=14842)
11724 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11725
11726 test_118d()
11727 {
11728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11729         remote_ost_nodsh && skip "remote OST with nodsh"
11730
11731         reset_async
11732
11733         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11734         set_nodes_failloc "$(osts_nodes)" 0x214
11735         # multiop should block due to fsync until pages are written
11736         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11737         MULTIPID=$!
11738         sleep 1
11739
11740         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11741                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11742         fi
11743
11744         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11745                     grep -c writeback)
11746         if [[ $WRITEBACK -eq 0 ]]; then
11747                 error "No page in writeback, writeback=$WRITEBACK"
11748         fi
11749
11750         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11751         set_nodes_failloc "$(osts_nodes)" 0
11752
11753         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11754         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11755                     grep -c writeback)
11756         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11757                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11758         fi
11759
11760         rm -f $DIR/$tfile
11761         echo "Dirty pages gaurenteed flushed via fsync"
11762         return 0
11763 }
11764 run_test 118d "Fsync validation inject a delay of the bulk =========="
11765
11766 test_118f() {
11767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11768
11769         reset_async
11770
11771         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11772         lctl set_param fail_loc=0x8000040a
11773
11774         # Should simulate EINVAL error which is fatal
11775         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11776         RC=$?
11777         if [[ $RC -eq 0 ]]; then
11778                 error "Must return error due to dropped pages, rc=$RC"
11779         fi
11780
11781         lctl set_param fail_loc=0x0
11782
11783         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11784         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11785         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11786                     grep -c writeback)
11787         if [[ $LOCKED -ne 0 ]]; then
11788                 error "Locked pages remain in cache, locked=$LOCKED"
11789         fi
11790
11791         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11792                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11793         fi
11794
11795         rm -f $DIR/$tfile
11796         echo "No pages locked after fsync"
11797
11798         reset_async
11799         return 0
11800 }
11801 run_test 118f "Simulate unrecoverable OSC side error =========="
11802
11803 test_118g() {
11804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11805
11806         reset_async
11807
11808         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11809         lctl set_param fail_loc=0x406
11810
11811         # simulate local -ENOMEM
11812         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11813         RC=$?
11814
11815         lctl set_param fail_loc=0
11816         if [[ $RC -eq 0 ]]; then
11817                 error "Must return error due to dropped pages, rc=$RC"
11818         fi
11819
11820         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11821         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11822         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11823                         grep -c writeback)
11824         if [[ $LOCKED -ne 0 ]]; then
11825                 error "Locked pages remain in cache, locked=$LOCKED"
11826         fi
11827
11828         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11829                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11830         fi
11831
11832         rm -f $DIR/$tfile
11833         echo "No pages locked after fsync"
11834
11835         reset_async
11836         return 0
11837 }
11838 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11839
11840 test_118h() {
11841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11842         remote_ost_nodsh && skip "remote OST with nodsh"
11843
11844         reset_async
11845
11846         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11847         set_nodes_failloc "$(osts_nodes)" 0x20e
11848         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11849         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11850         RC=$?
11851
11852         set_nodes_failloc "$(osts_nodes)" 0
11853         if [[ $RC -eq 0 ]]; then
11854                 error "Must return error due to dropped pages, rc=$RC"
11855         fi
11856
11857         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11858         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11859         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11860                     grep -c writeback)
11861         if [[ $LOCKED -ne 0 ]]; then
11862                 error "Locked pages remain in cache, locked=$LOCKED"
11863         fi
11864
11865         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11866                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11867         fi
11868
11869         rm -f $DIR/$tfile
11870         echo "No pages locked after fsync"
11871
11872         return 0
11873 }
11874 run_test 118h "Verify timeout in handling recoverables errors  =========="
11875
11876 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11877
11878 test_118i() {
11879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11880         remote_ost_nodsh && skip "remote OST with nodsh"
11881
11882         reset_async
11883
11884         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11885         set_nodes_failloc "$(osts_nodes)" 0x20e
11886
11887         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11888         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11889         PID=$!
11890         sleep 5
11891         set_nodes_failloc "$(osts_nodes)" 0
11892
11893         wait $PID
11894         RC=$?
11895         if [[ $RC -ne 0 ]]; then
11896                 error "got error, but should be not, rc=$RC"
11897         fi
11898
11899         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11900         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11901         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11902         if [[ $LOCKED -ne 0 ]]; then
11903                 error "Locked pages remain in cache, locked=$LOCKED"
11904         fi
11905
11906         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11907                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11908         fi
11909
11910         rm -f $DIR/$tfile
11911         echo "No pages locked after fsync"
11912
11913         return 0
11914 }
11915 run_test 118i "Fix error before timeout in recoverable error  =========="
11916
11917 [ "$SLOW" = "no" ] && set_resend_count 4
11918
11919 test_118j() {
11920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11921         remote_ost_nodsh && skip "remote OST with nodsh"
11922
11923         reset_async
11924
11925         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11926         set_nodes_failloc "$(osts_nodes)" 0x220
11927
11928         # return -EIO from OST
11929         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11930         RC=$?
11931         set_nodes_failloc "$(osts_nodes)" 0x0
11932         if [[ $RC -eq 0 ]]; then
11933                 error "Must return error due to dropped pages, rc=$RC"
11934         fi
11935
11936         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11937         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11938         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11939         if [[ $LOCKED -ne 0 ]]; then
11940                 error "Locked pages remain in cache, locked=$LOCKED"
11941         fi
11942
11943         # in recoverable error on OST we want resend and stay until it finished
11944         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11945                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11946         fi
11947
11948         rm -f $DIR/$tfile
11949         echo "No pages locked after fsync"
11950
11951         return 0
11952 }
11953 run_test 118j "Simulate unrecoverable OST side error =========="
11954
11955 test_118k()
11956 {
11957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11958         remote_ost_nodsh && skip "remote OSTs with nodsh"
11959
11960         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11961         set_nodes_failloc "$(osts_nodes)" 0x20e
11962         test_mkdir $DIR/$tdir
11963
11964         for ((i=0;i<10;i++)); do
11965                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11966                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11967                 SLEEPPID=$!
11968                 sleep 0.500s
11969                 kill $SLEEPPID
11970                 wait $SLEEPPID
11971         done
11972
11973         set_nodes_failloc "$(osts_nodes)" 0
11974         rm -rf $DIR/$tdir
11975 }
11976 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11977
11978 test_118l() # LU-646
11979 {
11980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11981
11982         test_mkdir $DIR/$tdir
11983         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11984         rm -rf $DIR/$tdir
11985 }
11986 run_test 118l "fsync dir"
11987
11988 test_118m() # LU-3066
11989 {
11990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11991
11992         test_mkdir $DIR/$tdir
11993         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11994         rm -rf $DIR/$tdir
11995 }
11996 run_test 118m "fdatasync dir ========="
11997
11998 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11999
12000 test_118n()
12001 {
12002         local begin
12003         local end
12004
12005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12006         remote_ost_nodsh && skip "remote OSTs with nodsh"
12007
12008         # Sleep to avoid a cached response.
12009         #define OBD_STATFS_CACHE_SECONDS 1
12010         sleep 2
12011
12012         # Inject a 10 second delay in the OST_STATFS handler.
12013         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12014         set_nodes_failloc "$(osts_nodes)" 0x242
12015
12016         begin=$SECONDS
12017         stat --file-system $MOUNT > /dev/null
12018         end=$SECONDS
12019
12020         set_nodes_failloc "$(osts_nodes)" 0
12021
12022         if ((end - begin > 20)); then
12023             error "statfs took $((end - begin)) seconds, expected 10"
12024         fi
12025 }
12026 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12027
12028 test_119a() # bug 11737
12029 {
12030         BSIZE=$((512 * 1024))
12031         directio write $DIR/$tfile 0 1 $BSIZE
12032         # We ask to read two blocks, which is more than a file size.
12033         # directio will indicate an error when requested and actual
12034         # sizes aren't equeal (a normal situation in this case) and
12035         # print actual read amount.
12036         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12037         if [ "$NOB" != "$BSIZE" ]; then
12038                 error "read $NOB bytes instead of $BSIZE"
12039         fi
12040         rm -f $DIR/$tfile
12041 }
12042 run_test 119a "Short directIO read must return actual read amount"
12043
12044 test_119b() # bug 11737
12045 {
12046         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12047
12048         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12049         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12050         sync
12051         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12052                 error "direct read failed"
12053         rm -f $DIR/$tfile
12054 }
12055 run_test 119b "Sparse directIO read must return actual read amount"
12056
12057 test_119c() # bug 13099
12058 {
12059         BSIZE=1048576
12060         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12061         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12062         rm -f $DIR/$tfile
12063 }
12064 run_test 119c "Testing for direct read hitting hole"
12065
12066 test_119d() # bug 15950
12067 {
12068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12069
12070         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12071         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12072         BSIZE=1048576
12073         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12074         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12075         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12076         lctl set_param fail_loc=0x40d
12077         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12078         pid_dio=$!
12079         sleep 1
12080         cat $DIR/$tfile > /dev/null &
12081         lctl set_param fail_loc=0
12082         pid_reads=$!
12083         wait $pid_dio
12084         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12085         sleep 2
12086         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12087         error "the read rpcs have not completed in 2s"
12088         rm -f $DIR/$tfile
12089         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12090 }
12091 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12092
12093 test_120a() {
12094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12095         remote_mds_nodsh && skip "remote MDS with nodsh"
12096         test_mkdir -i0 -c1 $DIR/$tdir
12097         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12098                 skip_env "no early lock cancel on server"
12099
12100         lru_resize_disable mdc
12101         lru_resize_disable osc
12102         cancel_lru_locks mdc
12103         # asynchronous object destroy at MDT could cause bl ast to client
12104         cancel_lru_locks osc
12105
12106         stat $DIR/$tdir > /dev/null
12107         can1=$(do_facet mds1 \
12108                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12109                awk '/ldlm_cancel/ {print $2}')
12110         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12111                awk '/ldlm_bl_callback/ {print $2}')
12112         test_mkdir -i0 -c1 $DIR/$tdir/d1
12113         can2=$(do_facet mds1 \
12114                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12115                awk '/ldlm_cancel/ {print $2}')
12116         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12117                awk '/ldlm_bl_callback/ {print $2}')
12118         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12119         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12120         lru_resize_enable mdc
12121         lru_resize_enable osc
12122 }
12123 run_test 120a "Early Lock Cancel: mkdir test"
12124
12125 test_120b() {
12126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12127         remote_mds_nodsh && skip "remote MDS with nodsh"
12128         test_mkdir $DIR/$tdir
12129         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12130                 skip_env "no early lock cancel on server"
12131
12132         lru_resize_disable mdc
12133         lru_resize_disable osc
12134         cancel_lru_locks mdc
12135         stat $DIR/$tdir > /dev/null
12136         can1=$(do_facet $SINGLEMDS \
12137                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12138                awk '/ldlm_cancel/ {print $2}')
12139         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12140                awk '/ldlm_bl_callback/ {print $2}')
12141         touch $DIR/$tdir/f1
12142         can2=$(do_facet $SINGLEMDS \
12143                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12144                awk '/ldlm_cancel/ {print $2}')
12145         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12146                awk '/ldlm_bl_callback/ {print $2}')
12147         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12148         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12149         lru_resize_enable mdc
12150         lru_resize_enable osc
12151 }
12152 run_test 120b "Early Lock Cancel: create test"
12153
12154 test_120c() {
12155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12156         remote_mds_nodsh && skip "remote MDS with nodsh"
12157         test_mkdir -i0 -c1 $DIR/$tdir
12158         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12159                 skip "no early lock cancel on server"
12160
12161         lru_resize_disable mdc
12162         lru_resize_disable osc
12163         test_mkdir -i0 -c1 $DIR/$tdir/d1
12164         test_mkdir -i0 -c1 $DIR/$tdir/d2
12165         touch $DIR/$tdir/d1/f1
12166         cancel_lru_locks mdc
12167         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12168         can1=$(do_facet mds1 \
12169                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12170                awk '/ldlm_cancel/ {print $2}')
12171         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12172                awk '/ldlm_bl_callback/ {print $2}')
12173         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12174         can2=$(do_facet mds1 \
12175                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12176                awk '/ldlm_cancel/ {print $2}')
12177         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12178                awk '/ldlm_bl_callback/ {print $2}')
12179         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12180         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12181         lru_resize_enable mdc
12182         lru_resize_enable osc
12183 }
12184 run_test 120c "Early Lock Cancel: link test"
12185
12186 test_120d() {
12187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12188         remote_mds_nodsh && skip "remote MDS with nodsh"
12189         test_mkdir -i0 -c1 $DIR/$tdir
12190         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12191                 skip_env "no early lock cancel on server"
12192
12193         lru_resize_disable mdc
12194         lru_resize_disable osc
12195         touch $DIR/$tdir
12196         cancel_lru_locks mdc
12197         stat $DIR/$tdir > /dev/null
12198         can1=$(do_facet mds1 \
12199                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12200                awk '/ldlm_cancel/ {print $2}')
12201         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12202                awk '/ldlm_bl_callback/ {print $2}')
12203         chmod a+x $DIR/$tdir
12204         can2=$(do_facet mds1 \
12205                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12206                awk '/ldlm_cancel/ {print $2}')
12207         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12208                awk '/ldlm_bl_callback/ {print $2}')
12209         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12210         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12211         lru_resize_enable mdc
12212         lru_resize_enable osc
12213 }
12214 run_test 120d "Early Lock Cancel: setattr test"
12215
12216 test_120e() {
12217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12218         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12219                 skip_env "no early lock cancel on server"
12220         remote_mds_nodsh && skip "remote MDS with nodsh"
12221
12222         local dlmtrace_set=false
12223
12224         test_mkdir -i0 -c1 $DIR/$tdir
12225         lru_resize_disable mdc
12226         lru_resize_disable osc
12227         ! $LCTL get_param debug | grep -q dlmtrace &&
12228                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12229         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12230         cancel_lru_locks mdc
12231         cancel_lru_locks osc
12232         dd if=$DIR/$tdir/f1 of=/dev/null
12233         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12234         # XXX client can not do early lock cancel of OST lock
12235         # during unlink (LU-4206), so cancel osc lock now.
12236         sleep 2
12237         cancel_lru_locks osc
12238         can1=$(do_facet mds1 \
12239                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12240                awk '/ldlm_cancel/ {print $2}')
12241         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12242                awk '/ldlm_bl_callback/ {print $2}')
12243         unlink $DIR/$tdir/f1
12244         sleep 5
12245         can2=$(do_facet mds1 \
12246                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12247                awk '/ldlm_cancel/ {print $2}')
12248         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12249                awk '/ldlm_bl_callback/ {print $2}')
12250         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12251                 $LCTL dk $TMP/cancel.debug.txt
12252         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12253                 $LCTL dk $TMP/blocking.debug.txt
12254         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12255         lru_resize_enable mdc
12256         lru_resize_enable osc
12257 }
12258 run_test 120e "Early Lock Cancel: unlink test"
12259
12260 test_120f() {
12261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12262         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12263                 skip_env "no early lock cancel on server"
12264         remote_mds_nodsh && skip "remote MDS with nodsh"
12265
12266         test_mkdir -i0 -c1 $DIR/$tdir
12267         lru_resize_disable mdc
12268         lru_resize_disable osc
12269         test_mkdir -i0 -c1 $DIR/$tdir/d1
12270         test_mkdir -i0 -c1 $DIR/$tdir/d2
12271         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12272         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12273         cancel_lru_locks mdc
12274         cancel_lru_locks osc
12275         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12276         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12277         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12278         # XXX client can not do early lock cancel of OST lock
12279         # during rename (LU-4206), so cancel osc lock now.
12280         sleep 2
12281         cancel_lru_locks osc
12282         can1=$(do_facet mds1 \
12283                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12284                awk '/ldlm_cancel/ {print $2}')
12285         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12286                awk '/ldlm_bl_callback/ {print $2}')
12287         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12288         sleep 5
12289         can2=$(do_facet mds1 \
12290                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12291                awk '/ldlm_cancel/ {print $2}')
12292         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12293                awk '/ldlm_bl_callback/ {print $2}')
12294         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12295         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12296         lru_resize_enable mdc
12297         lru_resize_enable osc
12298 }
12299 run_test 120f "Early Lock Cancel: rename test"
12300
12301 test_120g() {
12302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12303         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12304                 skip_env "no early lock cancel on server"
12305         remote_mds_nodsh && skip "remote MDS with nodsh"
12306
12307         lru_resize_disable mdc
12308         lru_resize_disable osc
12309         count=10000
12310         echo create $count files
12311         test_mkdir $DIR/$tdir
12312         cancel_lru_locks mdc
12313         cancel_lru_locks osc
12314         t0=$(date +%s)
12315
12316         can0=$(do_facet $SINGLEMDS \
12317                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12318                awk '/ldlm_cancel/ {print $2}')
12319         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12320                awk '/ldlm_bl_callback/ {print $2}')
12321         createmany -o $DIR/$tdir/f $count
12322         sync
12323         can1=$(do_facet $SINGLEMDS \
12324                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12325                awk '/ldlm_cancel/ {print $2}')
12326         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12327                awk '/ldlm_bl_callback/ {print $2}')
12328         t1=$(date +%s)
12329         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12330         echo rm $count files
12331         rm -r $DIR/$tdir
12332         sync
12333         can2=$(do_facet $SINGLEMDS \
12334                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12335                awk '/ldlm_cancel/ {print $2}')
12336         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12337                awk '/ldlm_bl_callback/ {print $2}')
12338         t2=$(date +%s)
12339         echo total: $count removes in $((t2-t1))
12340         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12341         sleep 2
12342         # wait for commitment of removal
12343         lru_resize_enable mdc
12344         lru_resize_enable osc
12345 }
12346 run_test 120g "Early Lock Cancel: performance test"
12347
12348 test_121() { #bug #10589
12349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12350
12351         rm -rf $DIR/$tfile
12352         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12353 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12354         lctl set_param fail_loc=0x310
12355         cancel_lru_locks osc > /dev/null
12356         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12357         lctl set_param fail_loc=0
12358         [[ $reads -eq $writes ]] ||
12359                 error "read $reads blocks, must be $writes blocks"
12360 }
12361 run_test 121 "read cancel race ========="
12362
12363 test_123a_base() { # was test 123, statahead(bug 11401)
12364         local lsx="$1"
12365
12366         SLOWOK=0
12367         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12368                 log "testing UP system. Performance may be lower than expected."
12369                 SLOWOK=1
12370         fi
12371
12372         rm -rf $DIR/$tdir
12373         test_mkdir $DIR/$tdir
12374         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12375         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12376         MULT=10
12377         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12378                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12379
12380                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12381                 lctl set_param -n llite.*.statahead_max 0
12382                 lctl get_param llite.*.statahead_max
12383                 cancel_lru_locks mdc
12384                 cancel_lru_locks osc
12385                 stime=$(date +%s)
12386                 time $lsx $DIR/$tdir | wc -l
12387                 etime=$(date +%s)
12388                 delta=$((etime - stime))
12389                 log "$lsx $i files without statahead: $delta sec"
12390                 lctl set_param llite.*.statahead_max=$max
12391
12392                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12393                         grep "statahead wrong:" | awk '{print $3}')
12394                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12395                 cancel_lru_locks mdc
12396                 cancel_lru_locks osc
12397                 stime=$(date +%s)
12398                 time $lsx $DIR/$tdir | wc -l
12399                 etime=$(date +%s)
12400                 delta_sa=$((etime - stime))
12401                 log "$lsx $i files with statahead: $delta_sa sec"
12402                 lctl get_param -n llite.*.statahead_stats
12403                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12404                         grep "statahead wrong:" | awk '{print $3}')
12405
12406                 [[ $swrong -lt $ewrong ]] &&
12407                         log "statahead was stopped, maybe too many locks held!"
12408                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12409
12410                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12411                         max=$(lctl get_param -n llite.*.statahead_max |
12412                                 head -n 1)
12413                         lctl set_param -n llite.*.statahead_max 0
12414                         lctl get_param llite.*.statahead_max
12415                         cancel_lru_locks mdc
12416                         cancel_lru_locks osc
12417                         stime=$(date +%s)
12418                         time $lsx $DIR/$tdir | wc -l
12419                         etime=$(date +%s)
12420                         delta=$((etime - stime))
12421                         log "$lsx $i files again without statahead: $delta sec"
12422                         lctl set_param llite.*.statahead_max=$max
12423                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12424                                 if [  $SLOWOK -eq 0 ]; then
12425                                         error "$lsx $i files is slower with statahead!"
12426                                 else
12427                                         log "$lsx $i files is slower with statahead!"
12428                                 fi
12429                                 break
12430                         fi
12431                 fi
12432
12433                 [ $delta -gt 20 ] && break
12434                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12435                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12436         done
12437         log "$lsx done"
12438
12439         stime=$(date +%s)
12440         rm -r $DIR/$tdir
12441         sync
12442         etime=$(date +%s)
12443         delta=$((etime - stime))
12444         log "rm -r $DIR/$tdir/: $delta seconds"
12445         log "rm done"
12446         lctl get_param -n llite.*.statahead_stats
12447 }
12448
12449 test_123aa() {
12450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12451
12452         test_123a_base "ls -l"
12453 }
12454 run_test 123aa "verify statahead work"
12455
12456 test_123ab() {
12457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12458
12459         statx_supported || skip_env "Test must be statx() syscall supported"
12460
12461         test_123a_base "$STATX -l"
12462 }
12463 run_test 123ab "verify statahead work by using statx"
12464
12465 test_123ac() {
12466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12467
12468         statx_supported || skip_env "Test must be statx() syscall supported"
12469
12470         local rpcs_before
12471         local rpcs_after
12472         local agl_before
12473         local agl_after
12474
12475         cancel_lru_locks $OSC
12476         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12477         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12478                 awk '/agl.total:/ {print $3}')
12479         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12480         test_123a_base "$STATX --cached=always -D"
12481         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12482                 awk '/agl.total:/ {print $3}')
12483         [ $agl_before -eq $agl_after ] ||
12484                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12485         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12486         [ $rpcs_after -eq $rpcs_before ] ||
12487                 error "$STATX should not send glimpse RPCs to $OSC"
12488 }
12489 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12490
12491 test_123b () { # statahead(bug 15027)
12492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12493
12494         test_mkdir $DIR/$tdir
12495         createmany -o $DIR/$tdir/$tfile-%d 1000
12496
12497         cancel_lru_locks mdc
12498         cancel_lru_locks osc
12499
12500 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12501         lctl set_param fail_loc=0x80000803
12502         ls -lR $DIR/$tdir > /dev/null
12503         log "ls done"
12504         lctl set_param fail_loc=0x0
12505         lctl get_param -n llite.*.statahead_stats
12506         rm -r $DIR/$tdir
12507         sync
12508
12509 }
12510 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12511
12512 test_123c() {
12513         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12514
12515         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12516         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12517         touch $DIR/$tdir.1/{1..3}
12518         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12519
12520         remount_client $MOUNT
12521
12522         $MULTIOP $DIR/$tdir.0 Q
12523
12524         # let statahead to complete
12525         ls -l $DIR/$tdir.0 > /dev/null
12526
12527         testid=$(echo $TESTNAME | tr '_' ' ')
12528         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12529                 error "statahead warning" || true
12530 }
12531 run_test 123c "Can not initialize inode warning on DNE statahead"
12532
12533 test_124a() {
12534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12535         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12536                 skip_env "no lru resize on server"
12537
12538         local NR=2000
12539
12540         test_mkdir $DIR/$tdir
12541
12542         log "create $NR files at $DIR/$tdir"
12543         createmany -o $DIR/$tdir/f $NR ||
12544                 error "failed to create $NR files in $DIR/$tdir"
12545
12546         cancel_lru_locks mdc
12547         ls -l $DIR/$tdir > /dev/null
12548
12549         local NSDIR=""
12550         local LRU_SIZE=0
12551         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12552                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12553                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12554                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12555                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12556                         log "NSDIR=$NSDIR"
12557                         log "NS=$(basename $NSDIR)"
12558                         break
12559                 fi
12560         done
12561
12562         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12563                 skip "Not enough cached locks created!"
12564         fi
12565         log "LRU=$LRU_SIZE"
12566
12567         local SLEEP=30
12568
12569         # We know that lru resize allows one client to hold $LIMIT locks
12570         # for 10h. After that locks begin to be killed by client.
12571         local MAX_HRS=10
12572         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12573         log "LIMIT=$LIMIT"
12574         if [ $LIMIT -lt $LRU_SIZE ]; then
12575                 skip "Limit is too small $LIMIT"
12576         fi
12577
12578         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12579         # killing locks. Some time was spent for creating locks. This means
12580         # that up to the moment of sleep finish we must have killed some of
12581         # them (10-100 locks). This depends on how fast ther were created.
12582         # Many of them were touched in almost the same moment and thus will
12583         # be killed in groups.
12584         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12585
12586         # Use $LRU_SIZE_B here to take into account real number of locks
12587         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12588         local LRU_SIZE_B=$LRU_SIZE
12589         log "LVF=$LVF"
12590         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12591         log "OLD_LVF=$OLD_LVF"
12592         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12593
12594         # Let's make sure that we really have some margin. Client checks
12595         # cached locks every 10 sec.
12596         SLEEP=$((SLEEP+20))
12597         log "Sleep ${SLEEP} sec"
12598         local SEC=0
12599         while ((SEC<$SLEEP)); do
12600                 echo -n "..."
12601                 sleep 5
12602                 SEC=$((SEC+5))
12603                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12604                 echo -n "$LRU_SIZE"
12605         done
12606         echo ""
12607         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12608         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12609
12610         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12611                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12612                 unlinkmany $DIR/$tdir/f $NR
12613                 return
12614         }
12615
12616         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12617         log "unlink $NR files at $DIR/$tdir"
12618         unlinkmany $DIR/$tdir/f $NR
12619 }
12620 run_test 124a "lru resize ======================================="
12621
12622 get_max_pool_limit()
12623 {
12624         local limit=$($LCTL get_param \
12625                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12626         local max=0
12627         for l in $limit; do
12628                 if [[ $l -gt $max ]]; then
12629                         max=$l
12630                 fi
12631         done
12632         echo $max
12633 }
12634
12635 test_124b() {
12636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12637         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12638                 skip_env "no lru resize on server"
12639
12640         LIMIT=$(get_max_pool_limit)
12641
12642         NR=$(($(default_lru_size)*20))
12643         if [[ $NR -gt $LIMIT ]]; then
12644                 log "Limit lock number by $LIMIT locks"
12645                 NR=$LIMIT
12646         fi
12647
12648         IFree=$(mdsrate_inodes_available)
12649         if [ $IFree -lt $NR ]; then
12650                 log "Limit lock number by $IFree inodes"
12651                 NR=$IFree
12652         fi
12653
12654         lru_resize_disable mdc
12655         test_mkdir -p $DIR/$tdir/disable_lru_resize
12656
12657         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12658         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12659         cancel_lru_locks mdc
12660         stime=`date +%s`
12661         PID=""
12662         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12663         PID="$PID $!"
12664         sleep 2
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         wait $PID
12671         etime=`date +%s`
12672         nolruresize_delta=$((etime-stime))
12673         log "ls -la time: $nolruresize_delta seconds"
12674         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12675         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12676
12677         lru_resize_enable mdc
12678         test_mkdir -p $DIR/$tdir/enable_lru_resize
12679
12680         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12681         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12682         cancel_lru_locks mdc
12683         stime=`date +%s`
12684         PID=""
12685         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12686         PID="$PID $!"
12687         sleep 2
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         wait $PID
12694         etime=`date +%s`
12695         lruresize_delta=$((etime-stime))
12696         log "ls -la time: $lruresize_delta seconds"
12697         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12698
12699         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12700                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12701         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12702                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12703         else
12704                 log "lru resize performs the same with no lru resize"
12705         fi
12706         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12707 }
12708 run_test 124b "lru resize (performance test) ======================="
12709
12710 test_124c() {
12711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12712         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12713                 skip_env "no lru resize on server"
12714
12715         # cache ununsed locks on client
12716         local nr=100
12717         cancel_lru_locks mdc
12718         test_mkdir $DIR/$tdir
12719         createmany -o $DIR/$tdir/f $nr ||
12720                 error "failed to create $nr files in $DIR/$tdir"
12721         ls -l $DIR/$tdir > /dev/null
12722
12723         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12724         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12725         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12726         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12727         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12728
12729         # set lru_max_age to 1 sec
12730         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12731         echo "sleep $((recalc_p * 2)) seconds..."
12732         sleep $((recalc_p * 2))
12733
12734         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12735         # restore lru_max_age
12736         $LCTL set_param -n $nsdir.lru_max_age $max_age
12737         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12738         unlinkmany $DIR/$tdir/f $nr
12739 }
12740 run_test 124c "LRUR cancel very aged locks"
12741
12742 test_124d() {
12743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12744         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12745                 skip_env "no lru resize on server"
12746
12747         # cache ununsed locks on client
12748         local nr=100
12749
12750         lru_resize_disable mdc
12751         stack_trap "lru_resize_enable mdc" EXIT
12752
12753         cancel_lru_locks mdc
12754
12755         # asynchronous object destroy at MDT could cause bl ast to client
12756         test_mkdir $DIR/$tdir
12757         createmany -o $DIR/$tdir/f $nr ||
12758                 error "failed to create $nr files in $DIR/$tdir"
12759         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12760
12761         ls -l $DIR/$tdir > /dev/null
12762
12763         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12764         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12765         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12766         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12767
12768         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12769
12770         # set lru_max_age to 1 sec
12771         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12772         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12773
12774         echo "sleep $((recalc_p * 2)) seconds..."
12775         sleep $((recalc_p * 2))
12776
12777         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12778
12779         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12780 }
12781 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12782
12783 test_125() { # 13358
12784         $LCTL get_param -n llite.*.client_type | grep -q local ||
12785                 skip "must run as local client"
12786         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12787                 skip_env "must have acl enabled"
12788         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12789
12790         test_mkdir $DIR/$tdir
12791         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12792         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12793         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12794 }
12795 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12796
12797 test_126() { # bug 12829/13455
12798         $GSS && skip_env "must run as gss disabled"
12799         $LCTL get_param -n llite.*.client_type | grep -q local ||
12800                 skip "must run as local client"
12801         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12802
12803         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12804         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12805         rm -f $DIR/$tfile
12806         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12807 }
12808 run_test 126 "check that the fsgid provided by the client is taken into account"
12809
12810 test_127a() { # bug 15521
12811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12812         local name count samp unit min max sum sumsq
12813
12814         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12815         echo "stats before reset"
12816         $LCTL get_param osc.*.stats
12817         $LCTL set_param osc.*.stats=0
12818         local fsize=$((2048 * 1024))
12819
12820         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12821         cancel_lru_locks osc
12822         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12823
12824         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12825         stack_trap "rm -f $TMP/$tfile.tmp"
12826         while read name count samp unit min max sum sumsq; do
12827                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12828                 [ ! $min ] && error "Missing min value for $name proc entry"
12829                 eval $name=$count || error "Wrong proc format"
12830
12831                 case $name in
12832                 read_bytes|write_bytes)
12833                         [[ "$unit" =~ "bytes" ]] ||
12834                                 error "unit is not 'bytes': $unit"
12835                         (( $min >= 4096 )) || error "min is too small: $min"
12836                         (( $min <= $fsize )) || error "min is too big: $min"
12837                         (( $max >= 4096 )) || error "max is too small: $max"
12838                         (( $max <= $fsize )) || error "max is too big: $max"
12839                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12840                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12841                                 error "sumsquare is too small: $sumsq"
12842                         (( $sumsq <= $fsize * $fsize )) ||
12843                                 error "sumsquare is too big: $sumsq"
12844                         ;;
12845                 ost_read|ost_write)
12846                         [[ "$unit" =~ "usec" ]] ||
12847                                 error "unit is not 'usec': $unit"
12848                         ;;
12849                 *)      ;;
12850                 esac
12851         done < $DIR/$tfile.tmp
12852
12853         #check that we actually got some stats
12854         [ "$read_bytes" ] || error "Missing read_bytes stats"
12855         [ "$write_bytes" ] || error "Missing write_bytes stats"
12856         [ "$read_bytes" != 0 ] || error "no read done"
12857         [ "$write_bytes" != 0 ] || error "no write done"
12858 }
12859 run_test 127a "verify the client stats are sane"
12860
12861 test_127b() { # bug LU-333
12862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12863         local name count samp unit min max sum sumsq
12864
12865         echo "stats before reset"
12866         $LCTL get_param llite.*.stats
12867         $LCTL set_param llite.*.stats=0
12868
12869         # perform 2 reads and writes so MAX is different from SUM.
12870         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12871         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12872         cancel_lru_locks osc
12873         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12874         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12875
12876         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12877         stack_trap "rm -f $TMP/$tfile.tmp"
12878         while read name count samp unit min max sum sumsq; do
12879                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12880                 eval $name=$count || error "Wrong proc format"
12881
12882                 case $name in
12883                 read_bytes|write_bytes)
12884                         [[ "$unit" =~ "bytes" ]] ||
12885                                 error "unit is not 'bytes': $unit"
12886                         (( $count == 2 )) || error "count is not 2: $count"
12887                         (( $min == $PAGE_SIZE )) ||
12888                                 error "min is not $PAGE_SIZE: $min"
12889                         (( $max == $PAGE_SIZE )) ||
12890                                 error "max is not $PAGE_SIZE: $max"
12891                         (( $sum == $PAGE_SIZE * 2 )) ||
12892                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12893                         ;;
12894                 read|write)
12895                         [[ "$unit" =~ "usec" ]] ||
12896                                 error "unit is not 'usec': $unit"
12897                         ;;
12898                 *)      ;;
12899                 esac
12900         done < $TMP/$tfile.tmp
12901
12902         #check that we actually got some stats
12903         [ "$read_bytes" ] || error "Missing read_bytes stats"
12904         [ "$write_bytes" ] || error "Missing write_bytes stats"
12905         [ "$read_bytes" != 0 ] || error "no read done"
12906         [ "$write_bytes" != 0 ] || error "no write done"
12907 }
12908 run_test 127b "verify the llite client stats are sane"
12909
12910 test_127c() { # LU-12394
12911         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12912         local size
12913         local bsize
12914         local reads
12915         local writes
12916         local count
12917
12918         $LCTL set_param llite.*.extents_stats=1
12919         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12920
12921         # Use two stripes so there is enough space in default config
12922         $LFS setstripe -c 2 $DIR/$tfile
12923
12924         # Extent stats start at 0-4K and go in power of two buckets
12925         # LL_HIST_START = 12 --> 2^12 = 4K
12926         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12927         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12928         # small configs
12929         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12930                 do
12931                 # Write and read, 2x each, second time at a non-zero offset
12932                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12933                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12934                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12935                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12936                 rm -f $DIR/$tfile
12937         done
12938
12939         $LCTL get_param llite.*.extents_stats
12940
12941         count=2
12942         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12943                 do
12944                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12945                                 grep -m 1 $bsize)
12946                 reads=$(echo $bucket | awk '{print $5}')
12947                 writes=$(echo $bucket | awk '{print $9}')
12948                 [ "$reads" -eq $count ] ||
12949                         error "$reads reads in < $bsize bucket, expect $count"
12950                 [ "$writes" -eq $count ] ||
12951                         error "$writes writes in < $bsize bucket, expect $count"
12952         done
12953
12954         # Test mmap write and read
12955         $LCTL set_param llite.*.extents_stats=c
12956         size=512
12957         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12958         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12959         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12960
12961         $LCTL get_param llite.*.extents_stats
12962
12963         count=$(((size*1024) / PAGE_SIZE))
12964
12965         bsize=$((2 * PAGE_SIZE / 1024))K
12966
12967         bucket=$($LCTL get_param -n llite.*.extents_stats |
12968                         grep -m 1 $bsize)
12969         reads=$(echo $bucket | awk '{print $5}')
12970         writes=$(echo $bucket | awk '{print $9}')
12971         # mmap writes fault in the page first, creating an additonal read
12972         [ "$reads" -eq $((2 * count)) ] ||
12973                 error "$reads reads in < $bsize bucket, expect $count"
12974         [ "$writes" -eq $count ] ||
12975                 error "$writes writes in < $bsize bucket, expect $count"
12976 }
12977 run_test 127c "test llite extent stats with regular & mmap i/o"
12978
12979 test_128() { # bug 15212
12980         touch $DIR/$tfile
12981         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12982                 find $DIR/$tfile
12983                 find $DIR/$tfile
12984         EOF
12985
12986         result=$(grep error $TMP/$tfile.log)
12987         rm -f $DIR/$tfile $TMP/$tfile.log
12988         [ -z "$result" ] ||
12989                 error "consecutive find's under interactive lfs failed"
12990 }
12991 run_test 128 "interactive lfs for 2 consecutive find's"
12992
12993 set_dir_limits () {
12994         local mntdev
12995         local canondev
12996         local node
12997
12998         local ldproc=/proc/fs/ldiskfs
12999         local facets=$(get_facets MDS)
13000
13001         for facet in ${facets//,/ }; do
13002                 canondev=$(ldiskfs_canon \
13003                            *.$(convert_facet2label $facet).mntdev $facet)
13004                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13005                         ldproc=/sys/fs/ldiskfs
13006                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13007                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13008         done
13009 }
13010
13011 check_mds_dmesg() {
13012         local facets=$(get_facets MDS)
13013         for facet in ${facets//,/ }; do
13014                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13015         done
13016         return 1
13017 }
13018
13019 test_129() {
13020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13021         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13022                 skip "Need MDS version with at least 2.5.56"
13023         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13024                 skip_env "ldiskfs only test"
13025         fi
13026         remote_mds_nodsh && skip "remote MDS with nodsh"
13027
13028         local ENOSPC=28
13029         local has_warning=false
13030
13031         rm -rf $DIR/$tdir
13032         mkdir -p $DIR/$tdir
13033
13034         # block size of mds1
13035         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13036         set_dir_limits $maxsize $((maxsize * 6 / 8))
13037         stack_trap "set_dir_limits 0 0"
13038         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13039         local dirsize=$(stat -c%s "$DIR/$tdir")
13040         local nfiles=0
13041         while (( $dirsize <= $maxsize )); do
13042                 $MCREATE $DIR/$tdir/file_base_$nfiles
13043                 rc=$?
13044                 # check two errors:
13045                 # ENOSPC for ext4 max_dir_size, which has been used since
13046                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13047                 if (( rc == ENOSPC )); then
13048                         set_dir_limits 0 0
13049                         echo "rc=$rc returned as expected after $nfiles files"
13050
13051                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13052                                 error "create failed w/o dir size limit"
13053
13054                         # messages may be rate limited if test is run repeatedly
13055                         check_mds_dmesg '"is approaching max"' ||
13056                                 echo "warning message should be output"
13057                         check_mds_dmesg '"has reached max"' ||
13058                                 echo "reached message should be output"
13059
13060                         dirsize=$(stat -c%s "$DIR/$tdir")
13061
13062                         [[ $dirsize -ge $maxsize ]] && return 0
13063                         error "dirsize $dirsize < $maxsize after $nfiles files"
13064                 elif (( rc != 0 )); then
13065                         break
13066                 fi
13067                 nfiles=$((nfiles + 1))
13068                 dirsize=$(stat -c%s "$DIR/$tdir")
13069         done
13070
13071         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13072 }
13073 run_test 129 "test directory size limit ========================"
13074
13075 OLDIFS="$IFS"
13076 cleanup_130() {
13077         trap 0
13078         IFS="$OLDIFS"
13079 }
13080
13081 test_130a() {
13082         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13083         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13084
13085         trap cleanup_130 EXIT RETURN
13086
13087         local fm_file=$DIR/$tfile
13088         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13089         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13090                 error "dd failed for $fm_file"
13091
13092         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13093         filefrag -ves $fm_file
13094         RC=$?
13095         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13096                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13097         [ $RC != 0 ] && error "filefrag $fm_file failed"
13098
13099         filefrag_op=$(filefrag -ve -k $fm_file |
13100                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13101         lun=$($LFS getstripe -i $fm_file)
13102
13103         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13104         IFS=$'\n'
13105         tot_len=0
13106         for line in $filefrag_op
13107         do
13108                 frag_lun=`echo $line | cut -d: -f5`
13109                 ext_len=`echo $line | cut -d: -f4`
13110                 if (( $frag_lun != $lun )); then
13111                         cleanup_130
13112                         error "FIEMAP on 1-stripe file($fm_file) failed"
13113                         return
13114                 fi
13115                 (( tot_len += ext_len ))
13116         done
13117
13118         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13119                 cleanup_130
13120                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13121                 return
13122         fi
13123
13124         cleanup_130
13125
13126         echo "FIEMAP on single striped file succeeded"
13127 }
13128 run_test 130a "FIEMAP (1-stripe file)"
13129
13130 test_130b() {
13131         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13132
13133         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13134         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13135
13136         trap cleanup_130 EXIT RETURN
13137
13138         local fm_file=$DIR/$tfile
13139         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13140                         error "setstripe on $fm_file"
13141         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13142                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13143
13144         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13145                 error "dd failed on $fm_file"
13146
13147         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13148         filefrag_op=$(filefrag -ve -k $fm_file |
13149                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13150
13151         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13152                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13153
13154         IFS=$'\n'
13155         tot_len=0
13156         num_luns=1
13157         for line in $filefrag_op
13158         do
13159                 frag_lun=$(echo $line | cut -d: -f5 |
13160                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13161                 ext_len=$(echo $line | cut -d: -f4)
13162                 if (( $frag_lun != $last_lun )); then
13163                         if (( tot_len != 1024 )); then
13164                                 cleanup_130
13165                                 error "FIEMAP on $fm_file failed; returned " \
13166                                 "len $tot_len for OST $last_lun instead of 1024"
13167                                 return
13168                         else
13169                                 (( num_luns += 1 ))
13170                                 tot_len=0
13171                         fi
13172                 fi
13173                 (( tot_len += ext_len ))
13174                 last_lun=$frag_lun
13175         done
13176         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13177                 cleanup_130
13178                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13179                         "luns or wrong len for OST $last_lun"
13180                 return
13181         fi
13182
13183         cleanup_130
13184
13185         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13186 }
13187 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13188
13189 test_130c() {
13190         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13191
13192         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13193         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13194
13195         trap cleanup_130 EXIT RETURN
13196
13197         local fm_file=$DIR/$tfile
13198         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13199         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13200                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13201
13202         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13203                         error "dd failed on $fm_file"
13204
13205         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13206         filefrag_op=$(filefrag -ve -k $fm_file |
13207                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13208
13209         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13210                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13211
13212         IFS=$'\n'
13213         tot_len=0
13214         num_luns=1
13215         for line in $filefrag_op
13216         do
13217                 frag_lun=$(echo $line | cut -d: -f5 |
13218                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13219                 ext_len=$(echo $line | cut -d: -f4)
13220                 if (( $frag_lun != $last_lun )); then
13221                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13222                         if (( logical != 512 )); then
13223                                 cleanup_130
13224                                 error "FIEMAP on $fm_file failed; returned " \
13225                                 "logical start for lun $logical instead of 512"
13226                                 return
13227                         fi
13228                         if (( tot_len != 512 )); then
13229                                 cleanup_130
13230                                 error "FIEMAP on $fm_file failed; returned " \
13231                                 "len $tot_len for OST $last_lun instead of 1024"
13232                                 return
13233                         else
13234                                 (( num_luns += 1 ))
13235                                 tot_len=0
13236                         fi
13237                 fi
13238                 (( tot_len += ext_len ))
13239                 last_lun=$frag_lun
13240         done
13241         if (( num_luns != 2 || tot_len != 512 )); then
13242                 cleanup_130
13243                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13244                         "luns or wrong len for OST $last_lun"
13245                 return
13246         fi
13247
13248         cleanup_130
13249
13250         echo "FIEMAP on 2-stripe file with hole succeeded"
13251 }
13252 run_test 130c "FIEMAP (2-stripe file with hole)"
13253
13254 test_130d() {
13255         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13256
13257         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13258         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13259
13260         trap cleanup_130 EXIT RETURN
13261
13262         local fm_file=$DIR/$tfile
13263         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13264                         error "setstripe on $fm_file"
13265         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13266                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13267
13268         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13269         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13270                 error "dd failed on $fm_file"
13271
13272         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13273         filefrag_op=$(filefrag -ve -k $fm_file |
13274                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13275
13276         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13277                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13278
13279         IFS=$'\n'
13280         tot_len=0
13281         num_luns=1
13282         for line in $filefrag_op
13283         do
13284                 frag_lun=$(echo $line | cut -d: -f5 |
13285                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13286                 ext_len=$(echo $line | cut -d: -f4)
13287                 if (( $frag_lun != $last_lun )); then
13288                         if (( tot_len != 1024 )); then
13289                                 cleanup_130
13290                                 error "FIEMAP on $fm_file failed; returned " \
13291                                 "len $tot_len for OST $last_lun instead of 1024"
13292                                 return
13293                         else
13294                                 (( num_luns += 1 ))
13295                                 tot_len=0
13296                         fi
13297                 fi
13298                 (( tot_len += ext_len ))
13299                 last_lun=$frag_lun
13300         done
13301         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13302                 cleanup_130
13303                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13304                         "luns or wrong len for OST $last_lun"
13305                 return
13306         fi
13307
13308         cleanup_130
13309
13310         echo "FIEMAP on N-stripe file succeeded"
13311 }
13312 run_test 130d "FIEMAP (N-stripe file)"
13313
13314 test_130e() {
13315         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13316
13317         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13318         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13319
13320         trap cleanup_130 EXIT RETURN
13321
13322         local fm_file=$DIR/$tfile
13323         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13324
13325         NUM_BLKS=512
13326         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13327         for ((i = 0; i < $NUM_BLKS; i++)); do
13328                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13329                         conv=notrunc > /dev/null 2>&1
13330         done
13331
13332         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13333         filefrag_op=$(filefrag -ve -k $fm_file |
13334                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13335
13336         last_lun=$(echo $filefrag_op | cut -d: -f5)
13337
13338         IFS=$'\n'
13339         tot_len=0
13340         num_luns=1
13341         for line in $filefrag_op; do
13342                 frag_lun=$(echo $line | cut -d: -f5)
13343                 ext_len=$(echo $line | cut -d: -f4)
13344                 if [[ "$frag_lun" != "$last_lun" ]]; then
13345                         if (( tot_len != $EXPECTED_LEN )); then
13346                                 cleanup_130
13347                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13348                         else
13349                                 (( num_luns += 1 ))
13350                                 tot_len=0
13351                         fi
13352                 fi
13353                 (( tot_len += ext_len ))
13354                 last_lun=$frag_lun
13355         done
13356         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13357                 cleanup_130
13358                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13359         fi
13360
13361         echo "FIEMAP with continuation calls succeeded"
13362 }
13363 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13364
13365 test_130f() {
13366         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13367         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13368
13369         local fm_file=$DIR/$tfile
13370         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13371                 error "multiop create with lov_delay_create on $fm_file"
13372
13373         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13374         filefrag_extents=$(filefrag -vek $fm_file |
13375                            awk '/extents? found/ { print $2 }')
13376         if [[ "$filefrag_extents" != "0" ]]; then
13377                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13378         fi
13379
13380         rm -f $fm_file
13381 }
13382 run_test 130f "FIEMAP (unstriped file)"
13383
13384 test_130g() {
13385         local file=$DIR/$tfile
13386         local nr=$((OSTCOUNT * 100))
13387
13388         $LFS setstripe -C $nr $file ||
13389                 error "failed to setstripe -C $nr $file"
13390
13391         dd if=/dev/zero of=$file count=$nr bs=1M
13392         sync
13393         nr=$($LFS getstripe -c $file)
13394
13395         local extents=$(filefrag -v $file |
13396                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13397
13398         echo "filefrag list $extents extents in file with stripecount $nr"
13399         if (( extents < nr )); then
13400                 $LFS getstripe $file
13401                 filefrag -v $file
13402                 error "filefrag printed $extents < $nr extents"
13403         fi
13404
13405         rm -f $file
13406 }
13407 run_test 130g "FIEMAP (overstripe file)"
13408
13409 # Test for writev/readv
13410 test_131a() {
13411         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13412                 error "writev test failed"
13413         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13414                 error "readv failed"
13415         rm -f $DIR/$tfile
13416 }
13417 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13418
13419 test_131b() {
13420         local fsize=$((524288 + 1048576 + 1572864))
13421         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13422                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13423                         error "append writev test failed"
13424
13425         ((fsize += 1572864 + 1048576))
13426         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13427                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13428                         error "append writev test failed"
13429         rm -f $DIR/$tfile
13430 }
13431 run_test 131b "test append writev"
13432
13433 test_131c() {
13434         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13435         error "NOT PASS"
13436 }
13437 run_test 131c "test read/write on file w/o objects"
13438
13439 test_131d() {
13440         rwv -f $DIR/$tfile -w -n 1 1572864
13441         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13442         if [ "$NOB" != 1572864 ]; then
13443                 error "Short read filed: read $NOB bytes instead of 1572864"
13444         fi
13445         rm -f $DIR/$tfile
13446 }
13447 run_test 131d "test short read"
13448
13449 test_131e() {
13450         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13451         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13452         error "read hitting hole failed"
13453         rm -f $DIR/$tfile
13454 }
13455 run_test 131e "test read hitting hole"
13456
13457 check_stats() {
13458         local facet=$1
13459         local op=$2
13460         local want=${3:-0}
13461         local res
13462
13463         case $facet in
13464         mds*) res=$(do_facet $facet \
13465                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13466                  ;;
13467         ost*) res=$(do_facet $facet \
13468                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13469                  ;;
13470         *) error "Wrong facet '$facet'" ;;
13471         esac
13472         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13473         # if the argument $3 is zero, it means any stat increment is ok.
13474         if [[ $want -gt 0 ]]; then
13475                 local count=$(echo $res | awk '{ print $2 }')
13476                 [[ $count -ne $want ]] &&
13477                         error "The $op counter on $facet is $count, not $want"
13478         fi
13479 }
13480
13481 test_133a() {
13482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13483         remote_ost_nodsh && skip "remote OST with nodsh"
13484         remote_mds_nodsh && skip "remote MDS with nodsh"
13485         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13486                 skip_env "MDS doesn't support rename stats"
13487
13488         local testdir=$DIR/${tdir}/stats_testdir
13489
13490         mkdir -p $DIR/${tdir}
13491
13492         # clear stats.
13493         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13494         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13495
13496         # verify mdt stats first.
13497         mkdir ${testdir} || error "mkdir failed"
13498         check_stats $SINGLEMDS "mkdir" 1
13499         touch ${testdir}/${tfile} || error "touch failed"
13500         check_stats $SINGLEMDS "open" 1
13501         check_stats $SINGLEMDS "close" 1
13502         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13503                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13504                 check_stats $SINGLEMDS "mknod" 2
13505         }
13506         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13507         check_stats $SINGLEMDS "unlink" 1
13508         rm -f ${testdir}/${tfile} || error "file remove failed"
13509         check_stats $SINGLEMDS "unlink" 2
13510
13511         # remove working dir and check mdt stats again.
13512         rmdir ${testdir} || error "rmdir failed"
13513         check_stats $SINGLEMDS "rmdir" 1
13514
13515         local testdir1=$DIR/${tdir}/stats_testdir1
13516         mkdir -p ${testdir}
13517         mkdir -p ${testdir1}
13518         touch ${testdir1}/test1
13519         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13520         check_stats $SINGLEMDS "crossdir_rename" 1
13521
13522         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13523         check_stats $SINGLEMDS "samedir_rename" 1
13524
13525         rm -rf $DIR/${tdir}
13526 }
13527 run_test 133a "Verifying MDT stats ========================================"
13528
13529 test_133b() {
13530         local res
13531
13532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13533         remote_ost_nodsh && skip "remote OST with nodsh"
13534         remote_mds_nodsh && skip "remote MDS with nodsh"
13535
13536         local testdir=$DIR/${tdir}/stats_testdir
13537
13538         mkdir -p ${testdir} || error "mkdir failed"
13539         touch ${testdir}/${tfile} || error "touch failed"
13540         cancel_lru_locks mdc
13541
13542         # clear stats.
13543         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13544         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13545
13546         # extra mdt stats verification.
13547         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13548         check_stats $SINGLEMDS "setattr" 1
13549         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13550         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13551         then            # LU-1740
13552                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13553                 check_stats $SINGLEMDS "getattr" 1
13554         fi
13555         rm -rf $DIR/${tdir}
13556
13557         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13558         # so the check below is not reliable
13559         [ $MDSCOUNT -eq 1 ] || return 0
13560
13561         # Sleep to avoid a cached response.
13562         #define OBD_STATFS_CACHE_SECONDS 1
13563         sleep 2
13564         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13565         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13566         $LFS df || error "lfs failed"
13567         check_stats $SINGLEMDS "statfs" 1
13568
13569         # check aggregated statfs (LU-10018)
13570         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13571                 return 0
13572         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13573                 return 0
13574         sleep 2
13575         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13576         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13577         df $DIR
13578         check_stats $SINGLEMDS "statfs" 1
13579
13580         # We want to check that the client didn't send OST_STATFS to
13581         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13582         # extra care is needed here.
13583         if remote_mds; then
13584                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13585                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13586
13587                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13588                 [ "$res" ] && error "OST got STATFS"
13589         fi
13590
13591         return 0
13592 }
13593 run_test 133b "Verifying extra MDT stats =================================="
13594
13595 test_133c() {
13596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13597         remote_ost_nodsh && skip "remote OST with nodsh"
13598         remote_mds_nodsh && skip "remote MDS with nodsh"
13599
13600         local testdir=$DIR/$tdir/stats_testdir
13601
13602         test_mkdir -p $testdir
13603
13604         # verify obdfilter stats.
13605         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13606         sync
13607         cancel_lru_locks osc
13608         wait_delete_completed
13609
13610         # clear stats.
13611         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13612         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13613
13614         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13615                 error "dd failed"
13616         sync
13617         cancel_lru_locks osc
13618         check_stats ost1 "write" 1
13619
13620         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13621         check_stats ost1 "read" 1
13622
13623         > $testdir/$tfile || error "truncate failed"
13624         check_stats ost1 "punch" 1
13625
13626         rm -f $testdir/$tfile || error "file remove failed"
13627         wait_delete_completed
13628         check_stats ost1 "destroy" 1
13629
13630         rm -rf $DIR/$tdir
13631 }
13632 run_test 133c "Verifying OST stats ========================================"
13633
13634 order_2() {
13635         local value=$1
13636         local orig=$value
13637         local order=1
13638
13639         while [ $value -ge 2 ]; do
13640                 order=$((order*2))
13641                 value=$((value/2))
13642         done
13643
13644         if [ $orig -gt $order ]; then
13645                 order=$((order*2))
13646         fi
13647         echo $order
13648 }
13649
13650 size_in_KMGT() {
13651     local value=$1
13652     local size=('K' 'M' 'G' 'T');
13653     local i=0
13654     local size_string=$value
13655
13656     while [ $value -ge 1024 ]; do
13657         if [ $i -gt 3 ]; then
13658             #T is the biggest unit we get here, if that is bigger,
13659             #just return XXXT
13660             size_string=${value}T
13661             break
13662         fi
13663         value=$((value >> 10))
13664         if [ $value -lt 1024 ]; then
13665             size_string=${value}${size[$i]}
13666             break
13667         fi
13668         i=$((i + 1))
13669     done
13670
13671     echo $size_string
13672 }
13673
13674 get_rename_size() {
13675         local size=$1
13676         local context=${2:-.}
13677         local sample=$(do_facet $SINGLEMDS $LCTL \
13678                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13679                 grep -A1 $context |
13680                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13681         echo $sample
13682 }
13683
13684 test_133d() {
13685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13686         remote_ost_nodsh && skip "remote OST with nodsh"
13687         remote_mds_nodsh && skip "remote MDS with nodsh"
13688         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13689                 skip_env "MDS doesn't support rename stats"
13690
13691         local testdir1=$DIR/${tdir}/stats_testdir1
13692         local testdir2=$DIR/${tdir}/stats_testdir2
13693         mkdir -p $DIR/${tdir}
13694
13695         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13696
13697         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13698         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13699
13700         createmany -o $testdir1/test 512 || error "createmany failed"
13701
13702         # check samedir rename size
13703         mv ${testdir1}/test0 ${testdir1}/test_0
13704
13705         local testdir1_size=$(ls -l $DIR/${tdir} |
13706                 awk '/stats_testdir1/ {print $5}')
13707         local testdir2_size=$(ls -l $DIR/${tdir} |
13708                 awk '/stats_testdir2/ {print $5}')
13709
13710         testdir1_size=$(order_2 $testdir1_size)
13711         testdir2_size=$(order_2 $testdir2_size)
13712
13713         testdir1_size=$(size_in_KMGT $testdir1_size)
13714         testdir2_size=$(size_in_KMGT $testdir2_size)
13715
13716         echo "source rename dir size: ${testdir1_size}"
13717         echo "target rename dir size: ${testdir2_size}"
13718
13719         local cmd="do_facet $SINGLEMDS $LCTL "
13720         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13721
13722         eval $cmd || error "$cmd failed"
13723         local samedir=$($cmd | grep 'same_dir')
13724         local same_sample=$(get_rename_size $testdir1_size)
13725         [ -z "$samedir" ] && error "samedir_rename_size count error"
13726         [[ $same_sample -eq 1 ]] ||
13727                 error "samedir_rename_size error $same_sample"
13728         echo "Check same dir rename stats success"
13729
13730         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13731
13732         # check crossdir rename size
13733         mv ${testdir1}/test_0 ${testdir2}/test_0
13734
13735         testdir1_size=$(ls -l $DIR/${tdir} |
13736                 awk '/stats_testdir1/ {print $5}')
13737         testdir2_size=$(ls -l $DIR/${tdir} |
13738                 awk '/stats_testdir2/ {print $5}')
13739
13740         testdir1_size=$(order_2 $testdir1_size)
13741         testdir2_size=$(order_2 $testdir2_size)
13742
13743         testdir1_size=$(size_in_KMGT $testdir1_size)
13744         testdir2_size=$(size_in_KMGT $testdir2_size)
13745
13746         echo "source rename dir size: ${testdir1_size}"
13747         echo "target rename dir size: ${testdir2_size}"
13748
13749         eval $cmd || error "$cmd failed"
13750         local crossdir=$($cmd | grep 'crossdir')
13751         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13752         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13753         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13754         [[ $src_sample -eq 1 ]] ||
13755                 error "crossdir_rename_size error $src_sample"
13756         [[ $tgt_sample -eq 1 ]] ||
13757                 error "crossdir_rename_size error $tgt_sample"
13758         echo "Check cross dir rename stats success"
13759         rm -rf $DIR/${tdir}
13760 }
13761 run_test 133d "Verifying rename_stats ========================================"
13762
13763 test_133e() {
13764         remote_mds_nodsh && skip "remote MDS with nodsh"
13765         remote_ost_nodsh && skip "remote OST with nodsh"
13766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13767
13768         local testdir=$DIR/${tdir}/stats_testdir
13769         local ctr f0 f1 bs=32768 count=42 sum
13770
13771         mkdir -p ${testdir} || error "mkdir failed"
13772
13773         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13774
13775         for ctr in {write,read}_bytes; do
13776                 sync
13777                 cancel_lru_locks osc
13778
13779                 do_facet ost1 $LCTL set_param -n \
13780                         "obdfilter.*.exports.clear=clear"
13781
13782                 if [ $ctr = write_bytes ]; then
13783                         f0=/dev/zero
13784                         f1=${testdir}/${tfile}
13785                 else
13786                         f0=${testdir}/${tfile}
13787                         f1=/dev/null
13788                 fi
13789
13790                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13791                         error "dd failed"
13792                 sync
13793                 cancel_lru_locks osc
13794
13795                 sum=$(do_facet ost1 $LCTL get_param \
13796                         "obdfilter.*.exports.*.stats" |
13797                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13798                                 $1 == ctr { sum += $7 }
13799                                 END { printf("%0.0f", sum) }')
13800
13801                 if ((sum != bs * count)); then
13802                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13803                 fi
13804         done
13805
13806         rm -rf $DIR/${tdir}
13807 }
13808 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13809
13810 test_133f() {
13811         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13812                 skip "too old lustre for get_param -R ($facet_ver)"
13813
13814         # verifying readability.
13815         $LCTL get_param -R '*' &> /dev/null
13816
13817         # Verifing writability with badarea_io.
13818         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13819                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13820                 error "client badarea_io failed"
13821
13822         # remount the FS in case writes/reads /proc break the FS
13823         cleanup || error "failed to unmount"
13824         setup || error "failed to setup"
13825 }
13826 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13827
13828 test_133g() {
13829         remote_mds_nodsh && skip "remote MDS with nodsh"
13830         remote_ost_nodsh && skip "remote OST with nodsh"
13831
13832         local facet
13833         for facet in mds1 ost1; do
13834                 local facet_ver=$(lustre_version_code $facet)
13835                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13836                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13837                 else
13838                         log "$facet: too old lustre for get_param -R"
13839                 fi
13840                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13841                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13842                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13843                                 xargs badarea_io" ||
13844                                         error "$facet badarea_io failed"
13845                 else
13846                         skip_noexit "$facet: too old lustre for get_param -R"
13847                 fi
13848         done
13849
13850         # remount the FS in case writes/reads /proc break the FS
13851         cleanup || error "failed to unmount"
13852         setup || error "failed to setup"
13853 }
13854 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13855
13856 test_133h() {
13857         remote_mds_nodsh && skip "remote MDS with nodsh"
13858         remote_ost_nodsh && skip "remote OST with nodsh"
13859         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13860                 skip "Need MDS version at least 2.9.54"
13861
13862         local facet
13863         for facet in client mds1 ost1; do
13864                 # Get the list of files that are missing the terminating newline
13865                 local plist=$(do_facet $facet
13866                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13867                 local ent
13868                 for ent in $plist; do
13869                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13870                                 awk -v FS='\v' -v RS='\v\v' \
13871                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13872                                         print FILENAME}'" 2>/dev/null)
13873                         [ -z $missing ] || {
13874                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13875                                 error "file does not end with newline: $facet-$ent"
13876                         }
13877                 done
13878         done
13879 }
13880 run_test 133h "Proc files should end with newlines"
13881
13882 test_134a() {
13883         remote_mds_nodsh && skip "remote MDS with nodsh"
13884         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13885                 skip "Need MDS version at least 2.7.54"
13886
13887         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13888         cancel_lru_locks mdc
13889
13890         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13891         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13892         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13893
13894         local nr=1000
13895         createmany -o $DIR/$tdir/f $nr ||
13896                 error "failed to create $nr files in $DIR/$tdir"
13897         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13898
13899         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13900         do_facet mds1 $LCTL set_param fail_loc=0x327
13901         do_facet mds1 $LCTL set_param fail_val=500
13902         touch $DIR/$tdir/m
13903
13904         echo "sleep 10 seconds ..."
13905         sleep 10
13906         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13907
13908         do_facet mds1 $LCTL set_param fail_loc=0
13909         do_facet mds1 $LCTL set_param fail_val=0
13910         [ $lck_cnt -lt $unused ] ||
13911                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13912
13913         rm $DIR/$tdir/m
13914         unlinkmany $DIR/$tdir/f $nr
13915 }
13916 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13917
13918 test_134b() {
13919         remote_mds_nodsh && skip "remote MDS with nodsh"
13920         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13921                 skip "Need MDS version at least 2.7.54"
13922
13923         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13924         cancel_lru_locks mdc
13925
13926         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13927                         ldlm.lock_reclaim_threshold_mb)
13928         # disable reclaim temporarily
13929         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13930
13931         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13932         do_facet mds1 $LCTL set_param fail_loc=0x328
13933         do_facet mds1 $LCTL set_param fail_val=500
13934
13935         $LCTL set_param debug=+trace
13936
13937         local nr=600
13938         createmany -o $DIR/$tdir/f $nr &
13939         local create_pid=$!
13940
13941         echo "Sleep $TIMEOUT seconds ..."
13942         sleep $TIMEOUT
13943         if ! ps -p $create_pid  > /dev/null 2>&1; then
13944                 do_facet mds1 $LCTL set_param fail_loc=0
13945                 do_facet mds1 $LCTL set_param fail_val=0
13946                 do_facet mds1 $LCTL set_param \
13947                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13948                 error "createmany finished incorrectly!"
13949         fi
13950         do_facet mds1 $LCTL set_param fail_loc=0
13951         do_facet mds1 $LCTL set_param fail_val=0
13952         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13953         wait $create_pid || return 1
13954
13955         unlinkmany $DIR/$tdir/f $nr
13956 }
13957 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13958
13959 test_135() {
13960         remote_mds_nodsh && skip "remote MDS with nodsh"
13961         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13962                 skip "Need MDS version at least 2.13.50"
13963         local fname
13964
13965         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13966
13967 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13968         #set only one record at plain llog
13969         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13970
13971         #fill already existed plain llog each 64767
13972         #wrapping whole catalog
13973         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13974
13975         createmany -o $DIR/$tdir/$tfile_ 64700
13976         for (( i = 0; i < 64700; i = i + 2 ))
13977         do
13978                 rm $DIR/$tdir/$tfile_$i &
13979                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13980                 local pid=$!
13981                 wait $pid
13982         done
13983
13984         #waiting osp synchronization
13985         wait_delete_completed
13986 }
13987 run_test 135 "Race catalog processing"
13988
13989 test_136() {
13990         remote_mds_nodsh && skip "remote MDS with nodsh"
13991         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13992                 skip "Need MDS version at least 2.13.50"
13993         local fname
13994
13995         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13996         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13997         #set only one record at plain llog
13998 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13999         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14000
14001         #fill already existed 2 plain llogs each 64767
14002         #wrapping whole catalog
14003         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14004         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14005         wait_delete_completed
14006
14007         createmany -o $DIR/$tdir/$tfile_ 10
14008         sleep 25
14009
14010         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14011         for (( i = 0; i < 10; i = i + 3 ))
14012         do
14013                 rm $DIR/$tdir/$tfile_$i &
14014                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14015                 local pid=$!
14016                 wait $pid
14017                 sleep 7
14018                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14019         done
14020
14021         #waiting osp synchronization
14022         wait_delete_completed
14023 }
14024 run_test 136 "Race catalog processing 2"
14025
14026 test_140() { #bug-17379
14027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14028
14029         test_mkdir $DIR/$tdir
14030         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14031         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14032
14033         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14034         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14035         local i=0
14036         while i=$((i + 1)); do
14037                 test_mkdir $i
14038                 cd $i || error "Changing to $i"
14039                 ln -s ../stat stat || error "Creating stat symlink"
14040                 # Read the symlink until ELOOP present,
14041                 # not LBUGing the system is considered success,
14042                 # we didn't overrun the stack.
14043                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14044                 if [ $ret -ne 0 ]; then
14045                         if [ $ret -eq 40 ]; then
14046                                 break  # -ELOOP
14047                         else
14048                                 error "Open stat symlink"
14049                                         return
14050                         fi
14051                 fi
14052         done
14053         i=$((i - 1))
14054         echo "The symlink depth = $i"
14055         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14056                 error "Invalid symlink depth"
14057
14058         # Test recursive symlink
14059         ln -s symlink_self symlink_self
14060         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14061         echo "open symlink_self returns $ret"
14062         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14063 }
14064 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14065
14066 test_150a() {
14067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14068
14069         local TF="$TMP/$tfile"
14070
14071         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14072         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14073         cp $TF $DIR/$tfile
14074         cancel_lru_locks $OSC
14075         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14076         remount_client $MOUNT
14077         df -P $MOUNT
14078         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14079
14080         $TRUNCATE $TF 6000
14081         $TRUNCATE $DIR/$tfile 6000
14082         cancel_lru_locks $OSC
14083         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14084
14085         echo "12345" >>$TF
14086         echo "12345" >>$DIR/$tfile
14087         cancel_lru_locks $OSC
14088         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14089
14090         echo "12345" >>$TF
14091         echo "12345" >>$DIR/$tfile
14092         cancel_lru_locks $OSC
14093         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14094 }
14095 run_test 150a "truncate/append tests"
14096
14097 test_150b() {
14098         check_set_fallocate_or_skip
14099
14100         touch $DIR/$tfile
14101         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14102         check_fallocate $DIR/$tfile || error "fallocate failed"
14103 }
14104 run_test 150b "Verify fallocate (prealloc) functionality"
14105
14106 test_150bb() {
14107         check_set_fallocate_or_skip
14108
14109         touch $DIR/$tfile
14110         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14111         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14112         > $DIR/$tfile
14113         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14114         # precomputed md5sum for 20MB of zeroes
14115         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14116         local sum=($(md5sum $DIR/$tfile))
14117
14118         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14119
14120         check_set_fallocate 1
14121
14122         > $DIR/$tfile
14123         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14124         sum=($(md5sum $DIR/$tfile))
14125
14126         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14127 }
14128 run_test 150bb "Verify fallocate modes both zero space"
14129
14130 test_150c() {
14131         check_set_fallocate_or_skip
14132
14133         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14134         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14135         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14136         sync; sync_all_data
14137         cancel_lru_locks $OSC
14138         sleep 5
14139         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14140         want=$((OSTCOUNT * 1048576))
14141
14142         # Must allocate all requested space, not more than 5% extra
14143         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14144                 error "bytes $bytes is not $want"
14145
14146         rm -f $DIR/$tfile
14147         # verify fallocate on PFL file
14148         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14149                 error "Create $DIR/$tfile failed"
14150         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
14151                         error "fallocate failed"
14152         sync; sync_all_data
14153         cancel_lru_locks $OSC
14154         sleep 5
14155         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14156         local want=$((1024 * 1048576))
14157
14158         # Must allocate all requested space, not more than 5% extra
14159         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14160                 error "bytes $bytes is not $want"
14161 }
14162 run_test 150c "Verify fallocate Size and Blocks"
14163
14164 test_150d() {
14165         check_set_fallocate_or_skip
14166
14167         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14168         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
14169         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14170         sync; sync_all_data
14171         cancel_lru_locks $OSC
14172         sleep 5
14173         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14174         local want=$((OSTCOUNT * 1048576))
14175
14176         # Must allocate all requested space, not more than 5% extra
14177         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14178                 error "bytes $bytes is not $want"
14179 }
14180 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14181
14182 test_150e() {
14183         check_set_fallocate_or_skip
14184
14185         echo "df before:"
14186         $LFS df
14187         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14188         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14189                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14190
14191         # Find OST with Minimum Size
14192         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14193                        sort -un | head -1)
14194
14195         # Get 100MB per OST of the available space to reduce run time
14196         # else 60% of the available space if we are running SLOW tests
14197         if [ $SLOW == "no" ]; then
14198                 local space=$((1024 * 100 * OSTCOUNT))
14199         else
14200                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14201         fi
14202
14203         fallocate -l${space}k $DIR/$tfile ||
14204                 error "fallocate ${space}k $DIR/$tfile failed"
14205         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14206
14207         # get size immediately after fallocate. This should be correctly
14208         # updated
14209         local size=$(stat -c '%s' $DIR/$tfile)
14210         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14211
14212         # Sleep for a while for statfs to get updated. And not pull from cache.
14213         sleep 2
14214
14215         echo "df after fallocate:"
14216         $LFS df
14217
14218         (( size / 1024 == space )) || error "size $size != requested $space"
14219         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14220                 error "used $used < space $space"
14221
14222         rm $DIR/$tfile || error "rm failed"
14223         sync
14224         wait_delete_completed
14225
14226         echo "df after unlink:"
14227         $LFS df
14228 }
14229 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14230
14231 test_150f() {
14232         local size
14233         local blocks
14234         local want_size_before=20480 # in bytes
14235         local want_blocks_before=40 # 512 sized blocks
14236         local want_blocks_after=24  # 512 sized blocks
14237         local length=$(((want_blocks_before - want_blocks_after) * 512))
14238
14239         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14240                 skip "need at least 2.14.0 for fallocate punch"
14241
14242         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14243                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14244         fi
14245
14246         check_set_fallocate_or_skip
14247         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14248
14249         echo "Verify fallocate punch: Range within the file range"
14250         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14251                 error "dd failed for bs 4096 and count 5"
14252
14253         # Call fallocate with punch range which is within the file range
14254         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14255                 error "fallocate failed: offset 4096 and length $length"
14256         # client must see changes immediately after fallocate
14257         size=$(stat -c '%s' $DIR/$tfile)
14258         blocks=$(stat -c '%b' $DIR/$tfile)
14259
14260         # Verify punch worked.
14261         (( blocks == want_blocks_after )) ||
14262                 error "punch failed: blocks $blocks != $want_blocks_after"
14263
14264         (( size == want_size_before )) ||
14265                 error "punch failed: size $size != $want_size_before"
14266
14267         # Verify there is hole in file
14268         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14269         # precomputed md5sum
14270         local expect="4a9a834a2db02452929c0a348273b4aa"
14271
14272         cksum=($(md5sum $DIR/$tfile))
14273         [[ "${cksum[0]}" == "$expect" ]] ||
14274                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14275
14276         # Start second sub-case for fallocate punch.
14277         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14278         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14279                 error "dd failed for bs 4096 and count 5"
14280
14281         # Punch range less than block size will have no change in block count
14282         want_blocks_after=40  # 512 sized blocks
14283
14284         # Punch overlaps two blocks and less than blocksize
14285         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14286                 error "fallocate failed: offset 4000 length 3000"
14287         size=$(stat -c '%s' $DIR/$tfile)
14288         blocks=$(stat -c '%b' $DIR/$tfile)
14289
14290         # Verify punch worked.
14291         (( blocks == want_blocks_after )) ||
14292                 error "punch failed: blocks $blocks != $want_blocks_after"
14293
14294         (( size == want_size_before )) ||
14295                 error "punch failed: size $size != $want_size_before"
14296
14297         # Verify if range is really zero'ed out. We expect Zeros.
14298         # precomputed md5sum
14299         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14300         cksum=($(md5sum $DIR/$tfile))
14301         [[ "${cksum[0]}" == "$expect" ]] ||
14302                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14303 }
14304 run_test 150f "Verify fallocate punch functionality"
14305
14306 test_150g() {
14307         local space
14308         local size
14309         local blocks
14310         local blocks_after
14311         local size_after
14312         local BS=4096 # Block size in bytes
14313
14314         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14315                 skip "need at least 2.14.0 for fallocate punch"
14316
14317         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14318                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14319         fi
14320
14321         check_set_fallocate_or_skip
14322         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14323
14324         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14325                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14326
14327         # Get 100MB per OST of the available space to reduce run time
14328         # else 60% of the available space if we are running SLOW tests
14329         if [ $SLOW == "no" ]; then
14330                 space=$((1024 * 100 * OSTCOUNT))
14331         else
14332                 # Find OST with Minimum Size
14333                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14334                         sort -un | head -1)
14335                 echo "min size OST: $space"
14336                 space=$(((space * 60)/100 * OSTCOUNT))
14337         fi
14338         # space in 1k units, round to 4k blocks
14339         local blkcount=$((space * 1024 / $BS))
14340
14341         echo "Verify fallocate punch: Very large Range"
14342         fallocate -l${space}k $DIR/$tfile ||
14343                 error "fallocate ${space}k $DIR/$tfile failed"
14344         # write 1M at the end, start and in the middle
14345         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14346                 error "dd failed: bs $BS count 256"
14347         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14348                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14349         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14350                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14351
14352         # Gather stats.
14353         size=$(stat -c '%s' $DIR/$tfile)
14354
14355         # gather punch length.
14356         local punch_size=$((size - (BS * 2)))
14357
14358         echo "punch_size = $punch_size"
14359         echo "size - punch_size: $((size - punch_size))"
14360         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14361
14362         # Call fallocate to punch all except 2 blocks. We leave the
14363         # first and the last block
14364         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14365         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14366                 error "fallocate failed: offset $BS length $punch_size"
14367
14368         size_after=$(stat -c '%s' $DIR/$tfile)
14369         blocks_after=$(stat -c '%b' $DIR/$tfile)
14370
14371         # Verify punch worked.
14372         # Size should be kept
14373         (( size == size_after )) ||
14374                 error "punch failed: size $size != $size_after"
14375
14376         # two 4k data blocks to remain plus possible 1 extra extent block
14377         (( blocks_after <= ((BS / 512) * 3) )) ||
14378                 error "too many blocks remains: $blocks_after"
14379
14380         # Verify that file has hole between the first and the last blocks
14381         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14382         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14383
14384         echo "Hole at [$hole_start, $hole_end)"
14385         (( hole_start == BS )) ||
14386                 error "no hole at offset $BS after punch"
14387
14388         (( hole_end == BS + punch_size )) ||
14389                 error "data at offset $hole_end < $((BS + punch_size))"
14390 }
14391 run_test 150g "Verify fallocate punch on large range"
14392
14393 #LU-2902 roc_hit was not able to read all values from lproc
14394 function roc_hit_init() {
14395         local list=$(comma_list $(osts_nodes))
14396         local dir=$DIR/$tdir-check
14397         local file=$dir/$tfile
14398         local BEFORE
14399         local AFTER
14400         local idx
14401
14402         test_mkdir $dir
14403         #use setstripe to do a write to every ost
14404         for i in $(seq 0 $((OSTCOUNT-1))); do
14405                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14406                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14407                 idx=$(printf %04x $i)
14408                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14409                         awk '$1 == "cache_access" {sum += $7}
14410                                 END { printf("%0.0f", sum) }')
14411
14412                 cancel_lru_locks osc
14413                 cat $file >/dev/null
14414
14415                 AFTER=$(get_osd_param $list *OST*$idx stats |
14416                         awk '$1 == "cache_access" {sum += $7}
14417                                 END { printf("%0.0f", sum) }')
14418
14419                 echo BEFORE:$BEFORE AFTER:$AFTER
14420                 if ! let "AFTER - BEFORE == 4"; then
14421                         rm -rf $dir
14422                         error "roc_hit is not safe to use"
14423                 fi
14424                 rm $file
14425         done
14426
14427         rm -rf $dir
14428 }
14429
14430 function roc_hit() {
14431         local list=$(comma_list $(osts_nodes))
14432         echo $(get_osd_param $list '' stats |
14433                 awk '$1 == "cache_hit" {sum += $7}
14434                         END { printf("%0.0f", sum) }')
14435 }
14436
14437 function set_cache() {
14438         local on=1
14439
14440         if [ "$2" == "off" ]; then
14441                 on=0;
14442         fi
14443         local list=$(comma_list $(osts_nodes))
14444         set_osd_param $list '' $1_cache_enable $on
14445
14446         cancel_lru_locks osc
14447 }
14448
14449 test_151() {
14450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14451         remote_ost_nodsh && skip "remote OST with nodsh"
14452
14453         local CPAGES=3
14454         local list=$(comma_list $(osts_nodes))
14455
14456         # check whether obdfilter is cache capable at all
14457         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14458                 skip "not cache-capable obdfilter"
14459         fi
14460
14461         # check cache is enabled on all obdfilters
14462         if get_osd_param $list '' read_cache_enable | grep 0; then
14463                 skip "oss cache is disabled"
14464         fi
14465
14466         set_osd_param $list '' writethrough_cache_enable 1
14467
14468         # check write cache is enabled on all obdfilters
14469         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14470                 skip "oss write cache is NOT enabled"
14471         fi
14472
14473         roc_hit_init
14474
14475         #define OBD_FAIL_OBD_NO_LRU  0x609
14476         do_nodes $list $LCTL set_param fail_loc=0x609
14477
14478         # pages should be in the case right after write
14479         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14480                 error "dd failed"
14481
14482         local BEFORE=$(roc_hit)
14483         cancel_lru_locks osc
14484         cat $DIR/$tfile >/dev/null
14485         local AFTER=$(roc_hit)
14486
14487         do_nodes $list $LCTL set_param fail_loc=0
14488
14489         if ! let "AFTER - BEFORE == CPAGES"; then
14490                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14491         fi
14492
14493         cancel_lru_locks osc
14494         # invalidates OST cache
14495         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14496         set_osd_param $list '' read_cache_enable 0
14497         cat $DIR/$tfile >/dev/null
14498
14499         # now data shouldn't be found in the cache
14500         BEFORE=$(roc_hit)
14501         cancel_lru_locks osc
14502         cat $DIR/$tfile >/dev/null
14503         AFTER=$(roc_hit)
14504         if let "AFTER - BEFORE != 0"; then
14505                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14506         fi
14507
14508         set_osd_param $list '' read_cache_enable 1
14509         rm -f $DIR/$tfile
14510 }
14511 run_test 151 "test cache on oss and controls ==============================="
14512
14513 test_152() {
14514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14515
14516         local TF="$TMP/$tfile"
14517
14518         # simulate ENOMEM during write
14519 #define OBD_FAIL_OST_NOMEM      0x226
14520         lctl set_param fail_loc=0x80000226
14521         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14522         cp $TF $DIR/$tfile
14523         sync || error "sync failed"
14524         lctl set_param fail_loc=0
14525
14526         # discard client's cache
14527         cancel_lru_locks osc
14528
14529         # simulate ENOMEM during read
14530         lctl set_param fail_loc=0x80000226
14531         cmp $TF $DIR/$tfile || error "cmp failed"
14532         lctl set_param fail_loc=0
14533
14534         rm -f $TF
14535 }
14536 run_test 152 "test read/write with enomem ============================"
14537
14538 test_153() {
14539         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14540 }
14541 run_test 153 "test if fdatasync does not crash ======================="
14542
14543 dot_lustre_fid_permission_check() {
14544         local fid=$1
14545         local ffid=$MOUNT/.lustre/fid/$fid
14546         local test_dir=$2
14547
14548         echo "stat fid $fid"
14549         stat $ffid > /dev/null || error "stat $ffid failed."
14550         echo "touch fid $fid"
14551         touch $ffid || error "touch $ffid failed."
14552         echo "write to fid $fid"
14553         cat /etc/hosts > $ffid || error "write $ffid failed."
14554         echo "read fid $fid"
14555         diff /etc/hosts $ffid || error "read $ffid failed."
14556         echo "append write to fid $fid"
14557         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14558         echo "rename fid $fid"
14559         mv $ffid $test_dir/$tfile.1 &&
14560                 error "rename $ffid to $tfile.1 should fail."
14561         touch $test_dir/$tfile.1
14562         mv $test_dir/$tfile.1 $ffid &&
14563                 error "rename $tfile.1 to $ffid should fail."
14564         rm -f $test_dir/$tfile.1
14565         echo "truncate fid $fid"
14566         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14567         echo "link fid $fid"
14568         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14569         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14570                 echo "setfacl fid $fid"
14571                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14572                 echo "getfacl fid $fid"
14573                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14574         fi
14575         echo "unlink fid $fid"
14576         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14577         echo "mknod fid $fid"
14578         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14579
14580         fid=[0xf00000400:0x1:0x0]
14581         ffid=$MOUNT/.lustre/fid/$fid
14582
14583         echo "stat non-exist fid $fid"
14584         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14585         echo "write to non-exist fid $fid"
14586         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14587         echo "link new fid $fid"
14588         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14589
14590         mkdir -p $test_dir/$tdir
14591         touch $test_dir/$tdir/$tfile
14592         fid=$($LFS path2fid $test_dir/$tdir)
14593         rc=$?
14594         [ $rc -ne 0 ] &&
14595                 error "error: could not get fid for $test_dir/$dir/$tfile."
14596
14597         ffid=$MOUNT/.lustre/fid/$fid
14598
14599         echo "ls $fid"
14600         ls $ffid > /dev/null || error "ls $ffid failed."
14601         echo "touch $fid/$tfile.1"
14602         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14603
14604         echo "touch $MOUNT/.lustre/fid/$tfile"
14605         touch $MOUNT/.lustre/fid/$tfile && \
14606                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14607
14608         echo "setxattr to $MOUNT/.lustre/fid"
14609         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14610
14611         echo "listxattr for $MOUNT/.lustre/fid"
14612         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14613
14614         echo "delxattr from $MOUNT/.lustre/fid"
14615         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14616
14617         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14618         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14619                 error "touch invalid fid should fail."
14620
14621         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14622         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14623                 error "touch non-normal fid should fail."
14624
14625         echo "rename $tdir to $MOUNT/.lustre/fid"
14626         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14627                 error "rename to $MOUNT/.lustre/fid should fail."
14628
14629         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14630         then            # LU-3547
14631                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14632                 local new_obf_mode=777
14633
14634                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14635                 chmod $new_obf_mode $DIR/.lustre/fid ||
14636                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14637
14638                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14639                 [ $obf_mode -eq $new_obf_mode ] ||
14640                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14641
14642                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14643                 chmod $old_obf_mode $DIR/.lustre/fid ||
14644                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14645         fi
14646
14647         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14648         fid=$($LFS path2fid $test_dir/$tfile-2)
14649
14650         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14651         then # LU-5424
14652                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14653                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14654                         error "create lov data thru .lustre failed"
14655         fi
14656         echo "cp /etc/passwd $test_dir/$tfile-2"
14657         cp /etc/passwd $test_dir/$tfile-2 ||
14658                 error "copy to $test_dir/$tfile-2 failed."
14659         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14660         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14661                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14662
14663         rm -rf $test_dir/tfile.lnk
14664         rm -rf $test_dir/$tfile-2
14665 }
14666
14667 test_154A() {
14668         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14669                 skip "Need MDS version at least 2.4.1"
14670
14671         local tf=$DIR/$tfile
14672         touch $tf
14673
14674         local fid=$($LFS path2fid $tf)
14675         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14676
14677         # check that we get the same pathname back
14678         local rootpath
14679         local found
14680         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14681                 echo "$rootpath $fid"
14682                 found=$($LFS fid2path $rootpath "$fid")
14683                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14684                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14685         done
14686
14687         # check wrong root path format
14688         rootpath=$MOUNT"_wrong"
14689         found=$($LFS fid2path $rootpath "$fid")
14690         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14691 }
14692 run_test 154A "lfs path2fid and fid2path basic checks"
14693
14694 test_154B() {
14695         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14696                 skip "Need MDS version at least 2.4.1"
14697
14698         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14699         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14700         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14701         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14702
14703         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14704         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14705
14706         # check that we get the same pathname
14707         echo "PFID: $PFID, name: $name"
14708         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14709         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14710         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14711                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14712
14713         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14714 }
14715 run_test 154B "verify the ll_decode_linkea tool"
14716
14717 test_154a() {
14718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14719         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14720         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14721                 skip "Need MDS version at least 2.2.51"
14722         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14723
14724         cp /etc/hosts $DIR/$tfile
14725
14726         fid=$($LFS path2fid $DIR/$tfile)
14727         rc=$?
14728         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14729
14730         dot_lustre_fid_permission_check "$fid" $DIR ||
14731                 error "dot lustre permission check $fid failed"
14732
14733         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14734
14735         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14736
14737         touch $MOUNT/.lustre/file &&
14738                 error "creation is not allowed under .lustre"
14739
14740         mkdir $MOUNT/.lustre/dir &&
14741                 error "mkdir is not allowed under .lustre"
14742
14743         rm -rf $DIR/$tfile
14744 }
14745 run_test 154a "Open-by-FID"
14746
14747 test_154b() {
14748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14749         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14750         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14751         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14752                 skip "Need MDS version at least 2.2.51"
14753
14754         local remote_dir=$DIR/$tdir/remote_dir
14755         local MDTIDX=1
14756         local rc=0
14757
14758         mkdir -p $DIR/$tdir
14759         $LFS mkdir -i $MDTIDX $remote_dir ||
14760                 error "create remote directory failed"
14761
14762         cp /etc/hosts $remote_dir/$tfile
14763
14764         fid=$($LFS path2fid $remote_dir/$tfile)
14765         rc=$?
14766         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14767
14768         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14769                 error "dot lustre permission check $fid failed"
14770         rm -rf $DIR/$tdir
14771 }
14772 run_test 154b "Open-by-FID for remote directory"
14773
14774 test_154c() {
14775         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14776                 skip "Need MDS version at least 2.4.1"
14777
14778         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14779         local FID1=$($LFS path2fid $DIR/$tfile.1)
14780         local FID2=$($LFS path2fid $DIR/$tfile.2)
14781         local FID3=$($LFS path2fid $DIR/$tfile.3)
14782
14783         local N=1
14784         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14785                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14786                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14787                 local want=FID$N
14788                 [ "$FID" = "${!want}" ] ||
14789                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14790                 N=$((N + 1))
14791         done
14792
14793         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14794         do
14795                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14796                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14797                 N=$((N + 1))
14798         done
14799 }
14800 run_test 154c "lfs path2fid and fid2path multiple arguments"
14801
14802 test_154d() {
14803         remote_mds_nodsh && skip "remote MDS with nodsh"
14804         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14805                 skip "Need MDS version at least 2.5.53"
14806
14807         if remote_mds; then
14808                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14809         else
14810                 nid="0@lo"
14811         fi
14812         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14813         local fd
14814         local cmd
14815
14816         rm -f $DIR/$tfile
14817         touch $DIR/$tfile
14818
14819         local fid=$($LFS path2fid $DIR/$tfile)
14820         # Open the file
14821         fd=$(free_fd)
14822         cmd="exec $fd<$DIR/$tfile"
14823         eval $cmd
14824         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14825         echo "$fid_list" | grep "$fid"
14826         rc=$?
14827
14828         cmd="exec $fd>/dev/null"
14829         eval $cmd
14830         if [ $rc -ne 0 ]; then
14831                 error "FID $fid not found in open files list $fid_list"
14832         fi
14833 }
14834 run_test 154d "Verify open file fid"
14835
14836 test_154e()
14837 {
14838         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14839                 skip "Need MDS version at least 2.6.50"
14840
14841         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14842                 error ".lustre returned by readdir"
14843         fi
14844 }
14845 run_test 154e ".lustre is not returned by readdir"
14846
14847 test_154f() {
14848         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14849
14850         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14851         test_mkdir -p -c1 $DIR/$tdir/d
14852         # test dirs inherit from its stripe
14853         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14854         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14855         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14856         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14857         touch $DIR/f
14858
14859         # get fid of parents
14860         local FID0=$($LFS path2fid $DIR/$tdir/d)
14861         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14862         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14863         local FID3=$($LFS path2fid $DIR)
14864
14865         # check that path2fid --parents returns expected <parent_fid>/name
14866         # 1) test for a directory (single parent)
14867         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14868         [ "$parent" == "$FID0/foo1" ] ||
14869                 error "expected parent: $FID0/foo1, got: $parent"
14870
14871         # 2) test for a file with nlink > 1 (multiple parents)
14872         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14873         echo "$parent" | grep -F "$FID1/$tfile" ||
14874                 error "$FID1/$tfile not returned in parent list"
14875         echo "$parent" | grep -F "$FID2/link" ||
14876                 error "$FID2/link not returned in parent list"
14877
14878         # 3) get parent by fid
14879         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14880         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14881         echo "$parent" | grep -F "$FID1/$tfile" ||
14882                 error "$FID1/$tfile not returned in parent list (by fid)"
14883         echo "$parent" | grep -F "$FID2/link" ||
14884                 error "$FID2/link not returned in parent list (by fid)"
14885
14886         # 4) test for entry in root directory
14887         parent=$($LFS path2fid --parents $DIR/f)
14888         echo "$parent" | grep -F "$FID3/f" ||
14889                 error "$FID3/f not returned in parent list"
14890
14891         # 5) test it on root directory
14892         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14893                 error "$MOUNT should not have parents"
14894
14895         # enable xattr caching and check that linkea is correctly updated
14896         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14897         save_lustre_params client "llite.*.xattr_cache" > $save
14898         lctl set_param llite.*.xattr_cache 1
14899
14900         # 6.1) linkea update on rename
14901         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14902
14903         # get parents by fid
14904         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14905         # foo1 should no longer be returned in parent list
14906         echo "$parent" | grep -F "$FID1" &&
14907                 error "$FID1 should no longer be in parent list"
14908         # the new path should appear
14909         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14910                 error "$FID2/$tfile.moved is not in parent list"
14911
14912         # 6.2) linkea update on unlink
14913         rm -f $DIR/$tdir/d/foo2/link
14914         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14915         # foo2/link should no longer be returned in parent list
14916         echo "$parent" | grep -F "$FID2/link" &&
14917                 error "$FID2/link should no longer be in parent list"
14918         true
14919
14920         rm -f $DIR/f
14921         restore_lustre_params < $save
14922         rm -f $save
14923 }
14924 run_test 154f "get parent fids by reading link ea"
14925
14926 test_154g()
14927 {
14928         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14929         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14930            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14931                 skip "Need MDS version at least 2.6.92"
14932
14933         mkdir -p $DIR/$tdir
14934         llapi_fid_test -d $DIR/$tdir
14935 }
14936 run_test 154g "various llapi FID tests"
14937
14938 test_155_small_load() {
14939     local temp=$TMP/$tfile
14940     local file=$DIR/$tfile
14941
14942     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14943         error "dd of=$temp bs=6096 count=1 failed"
14944     cp $temp $file
14945     cancel_lru_locks $OSC
14946     cmp $temp $file || error "$temp $file differ"
14947
14948     $TRUNCATE $temp 6000
14949     $TRUNCATE $file 6000
14950     cmp $temp $file || error "$temp $file differ (truncate1)"
14951
14952     echo "12345" >>$temp
14953     echo "12345" >>$file
14954     cmp $temp $file || error "$temp $file differ (append1)"
14955
14956     echo "12345" >>$temp
14957     echo "12345" >>$file
14958     cmp $temp $file || error "$temp $file differ (append2)"
14959
14960     rm -f $temp $file
14961     true
14962 }
14963
14964 test_155_big_load() {
14965         remote_ost_nodsh && skip "remote OST with nodsh"
14966
14967         local temp=$TMP/$tfile
14968         local file=$DIR/$tfile
14969
14970         free_min_max
14971         local cache_size=$(do_facet ost$((MAXI+1)) \
14972                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14973         local large_file_size=$((cache_size * 2))
14974
14975         echo "OSS cache size: $cache_size KB"
14976         echo "Large file size: $large_file_size KB"
14977
14978         [ $MAXV -le $large_file_size ] &&
14979                 skip_env "max available OST size needs > $large_file_size KB"
14980
14981         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14982
14983         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14984                 error "dd of=$temp bs=$large_file_size count=1k failed"
14985         cp $temp $file
14986         ls -lh $temp $file
14987         cancel_lru_locks osc
14988         cmp $temp $file || error "$temp $file differ"
14989
14990         rm -f $temp $file
14991         true
14992 }
14993
14994 save_writethrough() {
14995         local facets=$(get_facets OST)
14996
14997         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14998 }
14999
15000 test_155a() {
15001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15002
15003         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15004
15005         save_writethrough $p
15006
15007         set_cache read on
15008         set_cache writethrough on
15009         test_155_small_load
15010         restore_lustre_params < $p
15011         rm -f $p
15012 }
15013 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15014
15015 test_155b() {
15016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15017
15018         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15019
15020         save_writethrough $p
15021
15022         set_cache read on
15023         set_cache writethrough off
15024         test_155_small_load
15025         restore_lustre_params < $p
15026         rm -f $p
15027 }
15028 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15029
15030 test_155c() {
15031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15032
15033         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15034
15035         save_writethrough $p
15036
15037         set_cache read off
15038         set_cache writethrough on
15039         test_155_small_load
15040         restore_lustre_params < $p
15041         rm -f $p
15042 }
15043 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15044
15045 test_155d() {
15046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15047
15048         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15049
15050         save_writethrough $p
15051
15052         set_cache read off
15053         set_cache writethrough off
15054         test_155_small_load
15055         restore_lustre_params < $p
15056         rm -f $p
15057 }
15058 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15059
15060 test_155e() {
15061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15062
15063         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15064
15065         save_writethrough $p
15066
15067         set_cache read on
15068         set_cache writethrough on
15069         test_155_big_load
15070         restore_lustre_params < $p
15071         rm -f $p
15072 }
15073 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15074
15075 test_155f() {
15076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15077
15078         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15079
15080         save_writethrough $p
15081
15082         set_cache read on
15083         set_cache writethrough off
15084         test_155_big_load
15085         restore_lustre_params < $p
15086         rm -f $p
15087 }
15088 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15089
15090 test_155g() {
15091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15092
15093         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15094
15095         save_writethrough $p
15096
15097         set_cache read off
15098         set_cache writethrough on
15099         test_155_big_load
15100         restore_lustre_params < $p
15101         rm -f $p
15102 }
15103 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15104
15105 test_155h() {
15106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15107
15108         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15109
15110         save_writethrough $p
15111
15112         set_cache read off
15113         set_cache writethrough off
15114         test_155_big_load
15115         restore_lustre_params < $p
15116         rm -f $p
15117 }
15118 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15119
15120 test_156() {
15121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15122         remote_ost_nodsh && skip "remote OST with nodsh"
15123         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15124                 skip "stats not implemented on old servers"
15125         [ "$ost1_FSTYPE" = "zfs" ] &&
15126                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15127
15128         local CPAGES=3
15129         local BEFORE
15130         local AFTER
15131         local file="$DIR/$tfile"
15132         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15133
15134         save_writethrough $p
15135         roc_hit_init
15136
15137         log "Turn on read and write cache"
15138         set_cache read on
15139         set_cache writethrough on
15140
15141         log "Write data and read it back."
15142         log "Read should be satisfied from the cache."
15143         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15144         BEFORE=$(roc_hit)
15145         cancel_lru_locks osc
15146         cat $file >/dev/null
15147         AFTER=$(roc_hit)
15148         if ! let "AFTER - BEFORE == CPAGES"; then
15149                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15150         else
15151                 log "cache hits: before: $BEFORE, after: $AFTER"
15152         fi
15153
15154         log "Read again; it should be satisfied from the cache."
15155         BEFORE=$AFTER
15156         cancel_lru_locks osc
15157         cat $file >/dev/null
15158         AFTER=$(roc_hit)
15159         if ! let "AFTER - BEFORE == CPAGES"; then
15160                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15161         else
15162                 log "cache hits:: before: $BEFORE, after: $AFTER"
15163         fi
15164
15165         log "Turn off the read cache and turn on the write cache"
15166         set_cache read off
15167         set_cache writethrough on
15168
15169         log "Read again; it should be satisfied from the cache."
15170         BEFORE=$(roc_hit)
15171         cancel_lru_locks osc
15172         cat $file >/dev/null
15173         AFTER=$(roc_hit)
15174         if ! let "AFTER - BEFORE == CPAGES"; then
15175                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15176         else
15177                 log "cache hits:: before: $BEFORE, after: $AFTER"
15178         fi
15179
15180         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15181                 # > 2.12.56 uses pagecache if cached
15182                 log "Read again; it should not be satisfied from the cache."
15183                 BEFORE=$AFTER
15184                 cancel_lru_locks osc
15185                 cat $file >/dev/null
15186                 AFTER=$(roc_hit)
15187                 if ! let "AFTER - BEFORE == 0"; then
15188                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15189                 else
15190                         log "cache hits:: before: $BEFORE, after: $AFTER"
15191                 fi
15192         fi
15193
15194         log "Write data and read it back."
15195         log "Read should be satisfied from the cache."
15196         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15197         BEFORE=$(roc_hit)
15198         cancel_lru_locks osc
15199         cat $file >/dev/null
15200         AFTER=$(roc_hit)
15201         if ! let "AFTER - BEFORE == CPAGES"; then
15202                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15203         else
15204                 log "cache hits:: before: $BEFORE, after: $AFTER"
15205         fi
15206
15207         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15208                 # > 2.12.56 uses pagecache if cached
15209                 log "Read again; it should not be satisfied from the cache."
15210                 BEFORE=$AFTER
15211                 cancel_lru_locks osc
15212                 cat $file >/dev/null
15213                 AFTER=$(roc_hit)
15214                 if ! let "AFTER - BEFORE == 0"; then
15215                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15216                 else
15217                         log "cache hits:: before: $BEFORE, after: $AFTER"
15218                 fi
15219         fi
15220
15221         log "Turn off read and write cache"
15222         set_cache read off
15223         set_cache writethrough off
15224
15225         log "Write data and read it back"
15226         log "It should not be satisfied from the cache."
15227         rm -f $file
15228         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15229         cancel_lru_locks osc
15230         BEFORE=$(roc_hit)
15231         cat $file >/dev/null
15232         AFTER=$(roc_hit)
15233         if ! let "AFTER - BEFORE == 0"; then
15234                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15235         else
15236                 log "cache hits:: before: $BEFORE, after: $AFTER"
15237         fi
15238
15239         log "Turn on the read cache and turn off the write cache"
15240         set_cache read on
15241         set_cache writethrough off
15242
15243         log "Write data and read it back"
15244         log "It should not be satisfied from the cache."
15245         rm -f $file
15246         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15247         BEFORE=$(roc_hit)
15248         cancel_lru_locks osc
15249         cat $file >/dev/null
15250         AFTER=$(roc_hit)
15251         if ! let "AFTER - BEFORE == 0"; then
15252                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15253         else
15254                 log "cache hits:: before: $BEFORE, after: $AFTER"
15255         fi
15256
15257         log "Read again; it should be satisfied from the cache."
15258         BEFORE=$(roc_hit)
15259         cancel_lru_locks osc
15260         cat $file >/dev/null
15261         AFTER=$(roc_hit)
15262         if ! let "AFTER - BEFORE == CPAGES"; then
15263                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15264         else
15265                 log "cache hits:: before: $BEFORE, after: $AFTER"
15266         fi
15267
15268         restore_lustre_params < $p
15269         rm -f $p $file
15270 }
15271 run_test 156 "Verification of tunables"
15272
15273 test_160a() {
15274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15275         remote_mds_nodsh && skip "remote MDS with nodsh"
15276         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15277                 skip "Need MDS version at least 2.2.0"
15278
15279         changelog_register || error "changelog_register failed"
15280         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15281         changelog_users $SINGLEMDS | grep -q $cl_user ||
15282                 error "User $cl_user not found in changelog_users"
15283
15284         # change something
15285         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15286         changelog_clear 0 || error "changelog_clear failed"
15287         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15288         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15289         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15290         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15291         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15292         rm $DIR/$tdir/pics/desktop.jpg
15293
15294         changelog_dump | tail -10
15295
15296         echo "verifying changelog mask"
15297         changelog_chmask "-MKDIR"
15298         changelog_chmask "-CLOSE"
15299
15300         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15301         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15302
15303         changelog_chmask "+MKDIR"
15304         changelog_chmask "+CLOSE"
15305
15306         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15307         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15308
15309         changelog_dump | tail -10
15310         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15311         CLOSES=$(changelog_dump | grep -c "CLOSE")
15312         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15313         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15314
15315         # verify contents
15316         echo "verifying target fid"
15317         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15318         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15319         [ "$fidc" == "$fidf" ] ||
15320                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15321         echo "verifying parent fid"
15322         # The FID returned from the Changelog may be the directory shard on
15323         # a different MDT, and not the FID returned by path2fid on the parent.
15324         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15325         # since this is what will matter when recreating this file in the tree.
15326         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15327         local pathp=$($LFS fid2path $MOUNT "$fidp")
15328         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15329                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15330
15331         echo "getting records for $cl_user"
15332         changelog_users $SINGLEMDS
15333         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15334         local nclr=3
15335         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15336                 error "changelog_clear failed"
15337         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15338         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15339         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15340                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15341
15342         local min0_rec=$(changelog_users $SINGLEMDS |
15343                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15344         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15345                           awk '{ print $1; exit; }')
15346
15347         changelog_dump | tail -n 5
15348         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15349         [ $first_rec == $((min0_rec + 1)) ] ||
15350                 error "first index should be $min0_rec + 1 not $first_rec"
15351
15352         # LU-3446 changelog index reset on MDT restart
15353         local cur_rec1=$(changelog_users $SINGLEMDS |
15354                          awk '/^current.index:/ { print $NF }')
15355         changelog_clear 0 ||
15356                 error "clear all changelog records for $cl_user failed"
15357         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15358         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15359                 error "Fail to start $SINGLEMDS"
15360         local cur_rec2=$(changelog_users $SINGLEMDS |
15361                          awk '/^current.index:/ { print $NF }')
15362         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15363         [ $cur_rec1 == $cur_rec2 ] ||
15364                 error "current index should be $cur_rec1 not $cur_rec2"
15365
15366         echo "verifying users from this test are deregistered"
15367         changelog_deregister || error "changelog_deregister failed"
15368         changelog_users $SINGLEMDS | grep -q $cl_user &&
15369                 error "User '$cl_user' still in changelog_users"
15370
15371         # lctl get_param -n mdd.*.changelog_users
15372         # current index: 144
15373         # ID    index (idle seconds)
15374         # cl3   144 (2)
15375         if ! changelog_users $SINGLEMDS | grep "^cl"; then
15376                 # this is the normal case where all users were deregistered
15377                 # make sure no new records are added when no users are present
15378                 local last_rec1=$(changelog_users $SINGLEMDS |
15379                                   awk '/^current.index:/ { print $NF }')
15380                 touch $DIR/$tdir/chloe
15381                 local last_rec2=$(changelog_users $SINGLEMDS |
15382                                   awk '/^current.index:/ { print $NF }')
15383                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15384                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15385         else
15386                 # any changelog users must be leftovers from a previous test
15387                 changelog_users $SINGLEMDS
15388                 echo "other changelog users; can't verify off"
15389         fi
15390 }
15391 run_test 160a "changelog sanity"
15392
15393 test_160b() { # LU-3587
15394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15395         remote_mds_nodsh && skip "remote MDS with nodsh"
15396         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15397                 skip "Need MDS version at least 2.2.0"
15398
15399         changelog_register || error "changelog_register failed"
15400         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15401         changelog_users $SINGLEMDS | grep -q $cl_user ||
15402                 error "User '$cl_user' not found in changelog_users"
15403
15404         local longname1=$(str_repeat a 255)
15405         local longname2=$(str_repeat b 255)
15406
15407         cd $DIR
15408         echo "creating very long named file"
15409         touch $longname1 || error "create of '$longname1' failed"
15410         echo "renaming very long named file"
15411         mv $longname1 $longname2
15412
15413         changelog_dump | grep RENME | tail -n 5
15414         rm -f $longname2
15415 }
15416 run_test 160b "Verify that very long rename doesn't crash in changelog"
15417
15418 test_160c() {
15419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15420         remote_mds_nodsh && skip "remote MDS with nodsh"
15421
15422         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15423                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15424                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15425                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15426
15427         local rc=0
15428
15429         # Registration step
15430         changelog_register || error "changelog_register failed"
15431
15432         rm -rf $DIR/$tdir
15433         mkdir -p $DIR/$tdir
15434         $MCREATE $DIR/$tdir/foo_160c
15435         changelog_chmask "-TRUNC"
15436         $TRUNCATE $DIR/$tdir/foo_160c 200
15437         changelog_chmask "+TRUNC"
15438         $TRUNCATE $DIR/$tdir/foo_160c 199
15439         changelog_dump | tail -n 5
15440         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15441         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15442 }
15443 run_test 160c "verify that changelog log catch the truncate event"
15444
15445 test_160d() {
15446         remote_mds_nodsh && skip "remote MDS with nodsh"
15447         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15449         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15450                 skip "Need MDS version at least 2.7.60"
15451
15452         # Registration step
15453         changelog_register || error "changelog_register failed"
15454
15455         mkdir -p $DIR/$tdir/migrate_dir
15456         changelog_clear 0 || error "changelog_clear failed"
15457
15458         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15459         changelog_dump | tail -n 5
15460         local migrates=$(changelog_dump | grep -c "MIGRT")
15461         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15462 }
15463 run_test 160d "verify that changelog log catch the migrate event"
15464
15465 test_160e() {
15466         remote_mds_nodsh && skip "remote MDS with nodsh"
15467
15468         # Create a user
15469         changelog_register || error "changelog_register failed"
15470
15471         # Delete a future user (expect fail)
15472         local MDT0=$(facet_svc $SINGLEMDS)
15473         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15474         local rc=$?
15475
15476         if [ $rc -eq 0 ]; then
15477                 error "Deleted non-existant user cl77"
15478         elif [ $rc -ne 2 ]; then
15479                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15480         fi
15481
15482         # Clear to a bad index (1 billion should be safe)
15483         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15484         rc=$?
15485
15486         if [ $rc -eq 0 ]; then
15487                 error "Successfully cleared to invalid CL index"
15488         elif [ $rc -ne 22 ]; then
15489                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15490         fi
15491 }
15492 run_test 160e "changelog negative testing (should return errors)"
15493
15494 test_160f() {
15495         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15496         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15497                 skip "Need MDS version at least 2.10.56"
15498
15499         local mdts=$(comma_list $(mdts_nodes))
15500
15501         # Create a user
15502         changelog_register || error "first changelog_register failed"
15503         changelog_register || error "second changelog_register failed"
15504         local cl_users
15505         declare -A cl_user1
15506         declare -A cl_user2
15507         local user_rec1
15508         local user_rec2
15509         local i
15510
15511         # generate some changelog records to accumulate on each MDT
15512         # use all_char because created files should be evenly distributed
15513         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15514                 error "test_mkdir $tdir failed"
15515         log "$(date +%s): creating first files"
15516         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15517                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15518                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15519         done
15520
15521         # check changelogs have been generated
15522         local start=$SECONDS
15523         local idle_time=$((MDSCOUNT * 5 + 5))
15524         local nbcl=$(changelog_dump | wc -l)
15525         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15526
15527         for param in "changelog_max_idle_time=$idle_time" \
15528                      "changelog_gc=1" \
15529                      "changelog_min_gc_interval=2" \
15530                      "changelog_min_free_cat_entries=3"; do
15531                 local MDT0=$(facet_svc $SINGLEMDS)
15532                 local var="${param%=*}"
15533                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15534
15535                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15536                 do_nodes $mdts $LCTL set_param mdd.*.$param
15537         done
15538
15539         # force cl_user2 to be idle (1st part), but also cancel the
15540         # cl_user1 records so that it is not evicted later in the test.
15541         local sleep1=$((idle_time / 2))
15542         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15543         sleep $sleep1
15544
15545         # simulate changelog catalog almost full
15546         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15547         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15548
15549         for i in $(seq $MDSCOUNT); do
15550                 cl_users=(${CL_USERS[mds$i]})
15551                 cl_user1[mds$i]="${cl_users[0]}"
15552                 cl_user2[mds$i]="${cl_users[1]}"
15553
15554                 [ -n "${cl_user1[mds$i]}" ] ||
15555                         error "mds$i: no user registered"
15556                 [ -n "${cl_user2[mds$i]}" ] ||
15557                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15558
15559                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15560                 [ -n "$user_rec1" ] ||
15561                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15562                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15563                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15564                 [ -n "$user_rec2" ] ||
15565                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15566                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15567                      "$user_rec1 + 2 == $user_rec2"
15568                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15569                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15570                               "$user_rec1 + 2, but is $user_rec2"
15571                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15572                 [ -n "$user_rec2" ] ||
15573                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15574                 [ $user_rec1 == $user_rec2 ] ||
15575                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15576                               "$user_rec1, but is $user_rec2"
15577         done
15578
15579         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15580         local sleep2=$((idle_time - (SECONDS - start) + 1))
15581         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15582         sleep $sleep2
15583
15584         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15585         # cl_user1 should be OK because it recently processed records.
15586         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15587         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15588                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15589                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15590         done
15591
15592         # ensure gc thread is done
15593         for i in $(mdts_nodes); do
15594                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15595                         error "$i: GC-thread not done"
15596         done
15597
15598         local first_rec
15599         for (( i = 1; i <= MDSCOUNT; i++ )); do
15600                 # check cl_user1 still registered
15601                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15602                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15603                 # check cl_user2 unregistered
15604                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15605                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15606
15607                 # check changelogs are present and starting at $user_rec1 + 1
15608                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15609                 [ -n "$user_rec1" ] ||
15610                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15611                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15612                             awk '{ print $1; exit; }')
15613
15614                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15615                 [ $((user_rec1 + 1)) == $first_rec ] ||
15616                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15617         done
15618 }
15619 run_test 160f "changelog garbage collect (timestamped users)"
15620
15621 test_160g() {
15622         remote_mds_nodsh && skip "remote MDS with nodsh"
15623         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15624                 skip "Need MDS version at least 2.10.56"
15625
15626         local mdts=$(comma_list $(mdts_nodes))
15627
15628         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15629         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15630
15631         # Create a user
15632         changelog_register || error "first changelog_register failed"
15633         changelog_register || error "second changelog_register failed"
15634         local cl_users
15635         declare -A cl_user1
15636         declare -A cl_user2
15637         local user_rec1
15638         local user_rec2
15639         local i
15640
15641         # generate some changelog records to accumulate on each MDT
15642         # use all_char because created files should be evenly distributed
15643         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15644                 error "test_mkdir $tdir failed"
15645         for ((i = 0; i < MDSCOUNT; i++)); do
15646                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15647                         error "create $DIR/$tdir/d$i.1 failed"
15648         done
15649
15650         # check changelogs have been generated
15651         local nbcl=$(changelog_dump | wc -l)
15652         (( $nbcl > 0 )) || error "no changelogs found"
15653
15654         # reduce the max_idle_indexes value to make sure we exceed it
15655         for param in "changelog_max_idle_indexes=1" \
15656                      "changelog_gc=1" \
15657                      "changelog_min_gc_interval=2" \
15658                      "changelog_min_free_cat_entries=3"; do
15659                 local MDT0=$(facet_svc $SINGLEMDS)
15660                 local var="${param%=*}"
15661                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15662
15663                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15664                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15665                         error "unable to set mdd.*.$param"
15666         done
15667
15668         # simulate changelog catalog almost full
15669         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15670         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15671
15672         local start=$SECONDS
15673         for i in $(seq $MDSCOUNT); do
15674                 cl_users=(${CL_USERS[mds$i]})
15675                 cl_user1[mds$i]="${cl_users[0]}"
15676                 cl_user2[mds$i]="${cl_users[1]}"
15677
15678                 [ -n "${cl_user1[mds$i]}" ] ||
15679                         error "mds$i: no user registered"
15680                 [ -n "${cl_user2[mds$i]}" ] ||
15681                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15682
15683                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15684                 [ -n "$user_rec1" ] ||
15685                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15686                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15687                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15688                 [ -n "$user_rec2" ] ||
15689                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15690                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15691                      "$user_rec1 + 2 == $user_rec2"
15692                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15693                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15694                               "$user_rec1 + 2, but is $user_rec2"
15695                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15696                 [ -n "$user_rec2" ] ||
15697                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15698                 [ $user_rec1 == $user_rec2 ] ||
15699                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15700                               "$user_rec1, but is $user_rec2"
15701         done
15702
15703         # ensure we are past the previous changelog_min_gc_interval set above
15704         local sleep2=$((start + 2 - SECONDS))
15705         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15706
15707         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15708         # cl_user1 should be OK because it recently processed records.
15709         for ((i = 0; i < MDSCOUNT; i++)); do
15710                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15711                         error "create $DIR/$tdir/d$i.3 failed"
15712         done
15713
15714         # ensure gc thread is done
15715         for i in $(mdts_nodes); do
15716                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15717                         error "$i: GC-thread not done"
15718         done
15719
15720         local first_rec
15721         for (( i = 1; i <= MDSCOUNT; i++ )); do
15722                 # check cl_user1 still registered
15723                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15724                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15725                 # check cl_user2 unregistered
15726                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15727                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15728
15729                 # check changelogs are present and starting at $user_rec1 + 1
15730                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15731                 [ -n "$user_rec1" ] ||
15732                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15733                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15734                             awk '{ print $1; exit; }')
15735
15736                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15737                 [ $((user_rec1 + 1)) == $first_rec ] ||
15738                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15739         done
15740 }
15741 run_test 160g "changelog garbage collect (old users)"
15742
15743 test_160h() {
15744         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15745         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15746                 skip "Need MDS version at least 2.10.56"
15747
15748         local mdts=$(comma_list $(mdts_nodes))
15749
15750         # Create a user
15751         changelog_register || error "first changelog_register failed"
15752         changelog_register || error "second changelog_register failed"
15753         local cl_users
15754         declare -A cl_user1
15755         declare -A cl_user2
15756         local user_rec1
15757         local user_rec2
15758         local i
15759
15760         # generate some changelog records to accumulate on each MDT
15761         # use all_char because created files should be evenly distributed
15762         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15763                 error "test_mkdir $tdir failed"
15764         for ((i = 0; i < MDSCOUNT; i++)); do
15765                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15766                         error "create $DIR/$tdir/d$i.1 failed"
15767         done
15768
15769         # check changelogs have been generated
15770         local nbcl=$(changelog_dump | wc -l)
15771         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15772
15773         for param in "changelog_max_idle_time=10" \
15774                      "changelog_gc=1" \
15775                      "changelog_min_gc_interval=2"; do
15776                 local MDT0=$(facet_svc $SINGLEMDS)
15777                 local var="${param%=*}"
15778                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15779
15780                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15781                 do_nodes $mdts $LCTL set_param mdd.*.$param
15782         done
15783
15784         # force cl_user2 to be idle (1st part)
15785         sleep 9
15786
15787         for i in $(seq $MDSCOUNT); do
15788                 cl_users=(${CL_USERS[mds$i]})
15789                 cl_user1[mds$i]="${cl_users[0]}"
15790                 cl_user2[mds$i]="${cl_users[1]}"
15791
15792                 [ -n "${cl_user1[mds$i]}" ] ||
15793                         error "mds$i: no user registered"
15794                 [ -n "${cl_user2[mds$i]}" ] ||
15795                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15796
15797                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15798                 [ -n "$user_rec1" ] ||
15799                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15800                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15801                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15802                 [ -n "$user_rec2" ] ||
15803                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15804                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15805                      "$user_rec1 + 2 == $user_rec2"
15806                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15807                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15808                               "$user_rec1 + 2, but is $user_rec2"
15809                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15810                 [ -n "$user_rec2" ] ||
15811                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15812                 [ $user_rec1 == $user_rec2 ] ||
15813                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15814                               "$user_rec1, but is $user_rec2"
15815         done
15816
15817         # force cl_user2 to be idle (2nd part) and to reach
15818         # changelog_max_idle_time
15819         sleep 2
15820
15821         # force each GC-thread start and block then
15822         # one per MDT/MDD, set fail_val accordingly
15823         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15824         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15825
15826         # generate more changelogs to trigger fail_loc
15827         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15828                 error "create $DIR/$tdir/${tfile}bis failed"
15829
15830         # stop MDT to stop GC-thread, should be done in back-ground as it will
15831         # block waiting for the thread to be released and exit
15832         declare -A stop_pids
15833         for i in $(seq $MDSCOUNT); do
15834                 stop mds$i &
15835                 stop_pids[mds$i]=$!
15836         done
15837
15838         for i in $(mdts_nodes); do
15839                 local facet
15840                 local nb=0
15841                 local facets=$(facets_up_on_host $i)
15842
15843                 for facet in ${facets//,/ }; do
15844                         if [[ $facet == mds* ]]; then
15845                                 nb=$((nb + 1))
15846                         fi
15847                 done
15848                 # ensure each MDS's gc threads are still present and all in "R"
15849                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15850                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15851                         error "$i: expected $nb GC-thread"
15852                 wait_update $i \
15853                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15854                         "R" 20 ||
15855                         error "$i: GC-thread not found in R-state"
15856                 # check umounts of each MDT on MDS have reached kthread_stop()
15857                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15858                         error "$i: expected $nb umount"
15859                 wait_update $i \
15860                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15861                         error "$i: umount not found in D-state"
15862         done
15863
15864         # release all GC-threads
15865         do_nodes $mdts $LCTL set_param fail_loc=0
15866
15867         # wait for MDT stop to complete
15868         for i in $(seq $MDSCOUNT); do
15869                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15870         done
15871
15872         # XXX
15873         # may try to check if any orphan changelog records are present
15874         # via ldiskfs/zfs and llog_reader...
15875
15876         # re-start/mount MDTs
15877         for i in $(seq $MDSCOUNT); do
15878                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15879                         error "Fail to start mds$i"
15880         done
15881
15882         local first_rec
15883         for i in $(seq $MDSCOUNT); do
15884                 # check cl_user1 still registered
15885                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15886                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15887                 # check cl_user2 unregistered
15888                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15889                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15890
15891                 # check changelogs are present and starting at $user_rec1 + 1
15892                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15893                 [ -n "$user_rec1" ] ||
15894                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15895                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15896                             awk '{ print $1; exit; }')
15897
15898                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15899                 [ $((user_rec1 + 1)) == $first_rec ] ||
15900                         error "mds$i: first index should be $user_rec1 + 1, " \
15901                               "but is $first_rec"
15902         done
15903 }
15904 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15905               "during mount"
15906
15907 test_160i() {
15908
15909         local mdts=$(comma_list $(mdts_nodes))
15910
15911         changelog_register || error "first changelog_register failed"
15912
15913         # generate some changelog records to accumulate on each MDT
15914         # use all_char because created files should be evenly distributed
15915         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15916                 error "test_mkdir $tdir failed"
15917         for ((i = 0; i < MDSCOUNT; i++)); do
15918                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15919                         error "create $DIR/$tdir/d$i.1 failed"
15920         done
15921
15922         # check changelogs have been generated
15923         local nbcl=$(changelog_dump | wc -l)
15924         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15925
15926         # simulate race between register and unregister
15927         # XXX as fail_loc is set per-MDS, with DNE configs the race
15928         # simulation will only occur for one MDT per MDS and for the
15929         # others the normal race scenario will take place
15930         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15931         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15932         do_nodes $mdts $LCTL set_param fail_val=1
15933
15934         # unregister 1st user
15935         changelog_deregister &
15936         local pid1=$!
15937         # wait some time for deregister work to reach race rdv
15938         sleep 2
15939         # register 2nd user
15940         changelog_register || error "2nd user register failed"
15941
15942         wait $pid1 || error "1st user deregister failed"
15943
15944         local i
15945         local last_rec
15946         declare -A LAST_REC
15947         for i in $(seq $MDSCOUNT); do
15948                 if changelog_users mds$i | grep "^cl"; then
15949                         # make sure new records are added with one user present
15950                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15951                                           awk '/^current.index:/ { print $NF }')
15952                 else
15953                         error "mds$i has no user registered"
15954                 fi
15955         done
15956
15957         # generate more changelog records to accumulate on each MDT
15958         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15959                 error "create $DIR/$tdir/${tfile}bis failed"
15960
15961         for i in $(seq $MDSCOUNT); do
15962                 last_rec=$(changelog_users $SINGLEMDS |
15963                            awk '/^current.index:/ { print $NF }')
15964                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15965                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15966                         error "changelogs are off on mds$i"
15967         done
15968 }
15969 run_test 160i "changelog user register/unregister race"
15970
15971 test_160j() {
15972         remote_mds_nodsh && skip "remote MDS with nodsh"
15973         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15974                 skip "Need MDS version at least 2.12.56"
15975
15976         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15977         stack_trap "umount $MOUNT2" EXIT
15978
15979         changelog_register || error "first changelog_register failed"
15980         stack_trap "changelog_deregister" EXIT
15981
15982         # generate some changelog
15983         # use all_char because created files should be evenly distributed
15984         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15985                 error "mkdir $tdir failed"
15986         for ((i = 0; i < MDSCOUNT; i++)); do
15987                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15988                         error "create $DIR/$tdir/d$i.1 failed"
15989         done
15990
15991         # open the changelog device
15992         exec 3>/dev/changelog-$FSNAME-MDT0000
15993         stack_trap "exec 3>&-" EXIT
15994         exec 4</dev/changelog-$FSNAME-MDT0000
15995         stack_trap "exec 4<&-" EXIT
15996
15997         # umount the first lustre mount
15998         umount $MOUNT
15999         stack_trap "mount_client $MOUNT" EXIT
16000
16001         # read changelog, which may or may not fail, but should not crash
16002         cat <&4 >/dev/null
16003
16004         # clear changelog
16005         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16006         changelog_users $SINGLEMDS | grep -q $cl_user ||
16007                 error "User $cl_user not found in changelog_users"
16008
16009         printf 'clear:'$cl_user':0' >&3
16010 }
16011 run_test 160j "client can be umounted while its chanangelog is being used"
16012
16013 test_160k() {
16014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16015         remote_mds_nodsh && skip "remote MDS with nodsh"
16016
16017         mkdir -p $DIR/$tdir/1/1
16018
16019         changelog_register || error "changelog_register failed"
16020         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16021
16022         changelog_users $SINGLEMDS | grep -q $cl_user ||
16023                 error "User '$cl_user' not found in changelog_users"
16024 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16025         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16026         rmdir $DIR/$tdir/1/1 & sleep 1
16027         mkdir $DIR/$tdir/2
16028         touch $DIR/$tdir/2/2
16029         rm -rf $DIR/$tdir/2
16030
16031         wait
16032         sleep 4
16033
16034         changelog_dump | grep rmdir || error "rmdir not recorded"
16035 }
16036 run_test 160k "Verify that changelog records are not lost"
16037
16038 # Verifies that a file passed as a parameter has recently had an operation
16039 # performed on it that has generated an MTIME changelog which contains the
16040 # correct parent FID. As files might reside on a different MDT from the
16041 # parent directory in DNE configurations, the FIDs are translated to paths
16042 # before being compared, which should be identical
16043 compare_mtime_changelog() {
16044         local file="${1}"
16045         local mdtidx
16046         local mtime
16047         local cl_fid
16048         local pdir
16049         local dir
16050
16051         mdtidx=$($LFS getstripe --mdt-index $file)
16052         mdtidx=$(printf "%04x" $mdtidx)
16053
16054         # Obtain the parent FID from the MTIME changelog
16055         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16056         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16057
16058         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16059         [ -z "$cl_fid" ] && error "parent FID not present"
16060
16061         # Verify that the path for the parent FID is the same as the path for
16062         # the test directory
16063         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16064
16065         dir=$(dirname $1)
16066
16067         [[ "${pdir%/}" == "$dir" ]] ||
16068                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16069 }
16070
16071 test_160l() {
16072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16073
16074         remote_mds_nodsh && skip "remote MDS with nodsh"
16075         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16076                 skip "Need MDS version at least 2.13.55"
16077
16078         local cl_user
16079
16080         changelog_register || error "changelog_register failed"
16081         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16082
16083         changelog_users $SINGLEMDS | grep -q $cl_user ||
16084                 error "User '$cl_user' not found in changelog_users"
16085
16086         # Clear some types so that MTIME changelogs are generated
16087         changelog_chmask "-CREAT"
16088         changelog_chmask "-CLOSE"
16089
16090         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16091
16092         # Test CL_MTIME during setattr
16093         touch $DIR/$tdir/$tfile
16094         compare_mtime_changelog $DIR/$tdir/$tfile
16095
16096         # Test CL_MTIME during close
16097         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16098         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16099 }
16100 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16101
16102 test_160m() {
16103         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16104         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16105                 skip "Need MDS version at least 2.14.51"
16106         local cl_users
16107         local cl_user1
16108         local cl_user2
16109         local pid1
16110
16111         # Create a user
16112         changelog_register || error "first changelog_register failed"
16113         changelog_register || error "second changelog_register failed"
16114
16115         cl_users=(${CL_USERS[mds1]})
16116         cl_user1="${cl_users[0]}"
16117         cl_user2="${cl_users[1]}"
16118         # generate some changelog records to accumulate on MDT0
16119         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16120         createmany -m $DIR/$tdir/$tfile 50 ||
16121                 error "create $DIR/$tdir/$tfile failed"
16122         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16123         rm -f $DIR/$tdir
16124
16125         # check changelogs have been generated
16126         local nbcl=$(changelog_dump | wc -l)
16127         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16128
16129 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16130         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16131
16132         __changelog_clear mds1 $cl_user1 +10
16133         __changelog_clear mds1 $cl_user2 0 &
16134         pid1=$!
16135         sleep 2
16136         __changelog_clear mds1 $cl_user1 0 ||
16137                 error "fail to cancel record for $cl_user1"
16138         wait $pid1
16139         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16140 }
16141 run_test 160m "Changelog clear race"
16142
16143 test_160n() {
16144         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16145         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16146                 skip "Need MDS version at least 2.14.51"
16147         local cl_users
16148         local cl_user1
16149         local cl_user2
16150         local pid1
16151         local first_rec
16152         local last_rec=0
16153
16154         # Create a user
16155         changelog_register || error "first changelog_register failed"
16156
16157         cl_users=(${CL_USERS[mds1]})
16158         cl_user1="${cl_users[0]}"
16159
16160         # generate some changelog records to accumulate on MDT0
16161         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16162         first_rec=$(changelog_users $SINGLEMDS |
16163                         awk '/^current.index:/ { print $NF }')
16164         while (( last_rec < (( first_rec + 65000)) )); do
16165                 createmany -m $DIR/$tdir/$tfile 10000 ||
16166                         error "create $DIR/$tdir/$tfile failed"
16167
16168                 for i in $(seq 0 10000); do
16169                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16170                                 > /dev/null
16171                 done
16172
16173                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16174                         error "unlinkmany failed unlink"
16175                 last_rec=$(changelog_users $SINGLEMDS |
16176                         awk '/^current.index:/ { print $NF }')
16177                 echo last record $last_rec
16178                 (( last_rec == 0 )) && error "no changelog found"
16179         done
16180
16181 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16182         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16183
16184         __changelog_clear mds1 $cl_user1 0 &
16185         pid1=$!
16186         sleep 2
16187         __changelog_clear mds1 $cl_user1 0 ||
16188                 error "fail to cancel record for $cl_user1"
16189         wait $pid1
16190         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16191 }
16192 run_test 160n "Changelog destroy race"
16193
16194 test_161a() {
16195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16196
16197         test_mkdir -c1 $DIR/$tdir
16198         cp /etc/hosts $DIR/$tdir/$tfile
16199         test_mkdir -c1 $DIR/$tdir/foo1
16200         test_mkdir -c1 $DIR/$tdir/foo2
16201         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16202         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16203         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16204         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16205         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16206         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16207                 $LFS fid2path $DIR $FID
16208                 error "bad link ea"
16209         fi
16210         # middle
16211         rm $DIR/$tdir/foo2/zachary
16212         # last
16213         rm $DIR/$tdir/foo2/thor
16214         # first
16215         rm $DIR/$tdir/$tfile
16216         # rename
16217         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16218         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16219                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16220         rm $DIR/$tdir/foo2/maggie
16221
16222         # overflow the EA
16223         local longname=$tfile.avg_len_is_thirty_two_
16224         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16225                 error_noexit 'failed to unlink many hardlinks'" EXIT
16226         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16227                 error "failed to hardlink many files"
16228         links=$($LFS fid2path $DIR $FID | wc -l)
16229         echo -n "${links}/1000 links in link EA"
16230         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16231 }
16232 run_test 161a "link ea sanity"
16233
16234 test_161b() {
16235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16236         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16237
16238         local MDTIDX=1
16239         local remote_dir=$DIR/$tdir/remote_dir
16240
16241         mkdir -p $DIR/$tdir
16242         $LFS mkdir -i $MDTIDX $remote_dir ||
16243                 error "create remote directory failed"
16244
16245         cp /etc/hosts $remote_dir/$tfile
16246         mkdir -p $remote_dir/foo1
16247         mkdir -p $remote_dir/foo2
16248         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16249         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16250         ln $remote_dir/$tfile $remote_dir/foo1/luna
16251         ln $remote_dir/$tfile $remote_dir/foo2/thor
16252
16253         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16254                      tr -d ']')
16255         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16256                 $LFS fid2path $DIR $FID
16257                 error "bad link ea"
16258         fi
16259         # middle
16260         rm $remote_dir/foo2/zachary
16261         # last
16262         rm $remote_dir/foo2/thor
16263         # first
16264         rm $remote_dir/$tfile
16265         # rename
16266         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16267         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16268         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16269                 $LFS fid2path $DIR $FID
16270                 error "bad link rename"
16271         fi
16272         rm $remote_dir/foo2/maggie
16273
16274         # overflow the EA
16275         local longname=filename_avg_len_is_thirty_two_
16276         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16277                 error "failed to hardlink many files"
16278         links=$($LFS fid2path $DIR $FID | wc -l)
16279         echo -n "${links}/1000 links in link EA"
16280         [[ ${links} -gt 60 ]] ||
16281                 error "expected at least 60 links in link EA"
16282         unlinkmany $remote_dir/foo2/$longname 1000 ||
16283         error "failed to unlink many hardlinks"
16284 }
16285 run_test 161b "link ea sanity under remote directory"
16286
16287 test_161c() {
16288         remote_mds_nodsh && skip "remote MDS with nodsh"
16289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16290         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16291                 skip "Need MDS version at least 2.1.5"
16292
16293         # define CLF_RENAME_LAST 0x0001
16294         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16295         changelog_register || error "changelog_register failed"
16296
16297         rm -rf $DIR/$tdir
16298         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16299         touch $DIR/$tdir/foo_161c
16300         touch $DIR/$tdir/bar_161c
16301         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16302         changelog_dump | grep RENME | tail -n 5
16303         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16304         changelog_clear 0 || error "changelog_clear failed"
16305         if [ x$flags != "x0x1" ]; then
16306                 error "flag $flags is not 0x1"
16307         fi
16308
16309         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16310         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16311         touch $DIR/$tdir/foo_161c
16312         touch $DIR/$tdir/bar_161c
16313         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16314         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16315         changelog_dump | grep RENME | tail -n 5
16316         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16317         changelog_clear 0 || error "changelog_clear failed"
16318         if [ x$flags != "x0x0" ]; then
16319                 error "flag $flags is not 0x0"
16320         fi
16321         echo "rename overwrite a target having nlink > 1," \
16322                 "changelog record has flags of $flags"
16323
16324         # rename doesn't overwrite a target (changelog flag 0x0)
16325         touch $DIR/$tdir/foo_161c
16326         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16327         changelog_dump | grep RENME | tail -n 5
16328         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16329         changelog_clear 0 || error "changelog_clear failed"
16330         if [ x$flags != "x0x0" ]; then
16331                 error "flag $flags is not 0x0"
16332         fi
16333         echo "rename doesn't overwrite a target," \
16334                 "changelog record has flags of $flags"
16335
16336         # define CLF_UNLINK_LAST 0x0001
16337         # unlink a file having nlink = 1 (changelog flag 0x1)
16338         rm -f $DIR/$tdir/foo2_161c
16339         changelog_dump | grep UNLNK | tail -n 5
16340         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16341         changelog_clear 0 || error "changelog_clear failed"
16342         if [ x$flags != "x0x1" ]; then
16343                 error "flag $flags is not 0x1"
16344         fi
16345         echo "unlink a file having nlink = 1," \
16346                 "changelog record has flags of $flags"
16347
16348         # unlink a file having nlink > 1 (changelog flag 0x0)
16349         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16350         rm -f $DIR/$tdir/foobar_161c
16351         changelog_dump | grep UNLNK | tail -n 5
16352         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16353         changelog_clear 0 || error "changelog_clear failed"
16354         if [ x$flags != "x0x0" ]; then
16355                 error "flag $flags is not 0x0"
16356         fi
16357         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16358 }
16359 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16360
16361 test_161d() {
16362         remote_mds_nodsh && skip "remote MDS with nodsh"
16363         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16364
16365         local pid
16366         local fid
16367
16368         changelog_register || error "changelog_register failed"
16369
16370         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16371         # interfer with $MOUNT/.lustre/fid/ access
16372         mkdir $DIR/$tdir
16373         [[ $? -eq 0 ]] || error "mkdir failed"
16374
16375         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16376         $LCTL set_param fail_loc=0x8000140c
16377         # 5s pause
16378         $LCTL set_param fail_val=5
16379
16380         # create file
16381         echo foofoo > $DIR/$tdir/$tfile &
16382         pid=$!
16383
16384         # wait for create to be delayed
16385         sleep 2
16386
16387         ps -p $pid
16388         [[ $? -eq 0 ]] || error "create should be blocked"
16389
16390         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16391         stack_trap "rm -f $tempfile"
16392         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16393         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16394         # some delay may occur during ChangeLog publishing and file read just
16395         # above, that could allow file write to happen finally
16396         [[ -s $tempfile ]] && echo "file should be empty"
16397
16398         $LCTL set_param fail_loc=0
16399
16400         wait $pid
16401         [[ $? -eq 0 ]] || error "create failed"
16402 }
16403 run_test 161d "create with concurrent .lustre/fid access"
16404
16405 check_path() {
16406         local expected="$1"
16407         shift
16408         local fid="$2"
16409
16410         local path
16411         path=$($LFS fid2path "$@")
16412         local rc=$?
16413
16414         if [ $rc -ne 0 ]; then
16415                 error "path looked up of '$expected' failed: rc=$rc"
16416         elif [ "$path" != "$expected" ]; then
16417                 error "path looked up '$path' instead of '$expected'"
16418         else
16419                 echo "FID '$fid' resolves to path '$path' as expected"
16420         fi
16421 }
16422
16423 test_162a() { # was test_162
16424         test_mkdir -p -c1 $DIR/$tdir/d2
16425         touch $DIR/$tdir/d2/$tfile
16426         touch $DIR/$tdir/d2/x1
16427         touch $DIR/$tdir/d2/x2
16428         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16429         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16430         # regular file
16431         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16432         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16433
16434         # softlink
16435         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16436         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16437         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16438
16439         # softlink to wrong file
16440         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16441         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16442         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16443
16444         # hardlink
16445         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16446         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16447         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16448         # fid2path dir/fsname should both work
16449         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16450         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16451
16452         # hardlink count: check that there are 2 links
16453         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16454         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16455
16456         # hardlink indexing: remove the first link
16457         rm $DIR/$tdir/d2/p/q/r/hlink
16458         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16459 }
16460 run_test 162a "path lookup sanity"
16461
16462 test_162b() {
16463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16464         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16465
16466         mkdir $DIR/$tdir
16467         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16468                                 error "create striped dir failed"
16469
16470         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16471                                         tail -n 1 | awk '{print $2}')
16472         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16473
16474         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16475         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16476
16477         # regular file
16478         for ((i=0;i<5;i++)); do
16479                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16480                         error "get fid for f$i failed"
16481                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16482
16483                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16484                         error "get fid for d$i failed"
16485                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16486         done
16487
16488         return 0
16489 }
16490 run_test 162b "striped directory path lookup sanity"
16491
16492 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16493 test_162c() {
16494         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16495                 skip "Need MDS version at least 2.7.51"
16496
16497         local lpath=$tdir.local
16498         local rpath=$tdir.remote
16499
16500         test_mkdir $DIR/$lpath
16501         test_mkdir $DIR/$rpath
16502
16503         for ((i = 0; i <= 101; i++)); do
16504                 lpath="$lpath/$i"
16505                 mkdir $DIR/$lpath
16506                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16507                         error "get fid for local directory $DIR/$lpath failed"
16508                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16509
16510                 rpath="$rpath/$i"
16511                 test_mkdir $DIR/$rpath
16512                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16513                         error "get fid for remote directory $DIR/$rpath failed"
16514                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16515         done
16516
16517         return 0
16518 }
16519 run_test 162c "fid2path works with paths 100 or more directories deep"
16520
16521 oalr_event_count() {
16522         local event="${1}"
16523         local trace="${2}"
16524
16525         awk -v name="${FSNAME}-OST0000" \
16526             -v event="${event}" \
16527             '$1 == "TRACE" && $2 == event && $3 == name' \
16528             "${trace}" |
16529         wc -l
16530 }
16531
16532 oalr_expect_event_count() {
16533         local event="${1}"
16534         local trace="${2}"
16535         local expect="${3}"
16536         local count
16537
16538         count=$(oalr_event_count "${event}" "${trace}")
16539         if ((count == expect)); then
16540                 return 0
16541         fi
16542
16543         error_noexit "${event} event count was '${count}', expected ${expect}"
16544         cat "${trace}" >&2
16545         exit 1
16546 }
16547
16548 cleanup_165() {
16549         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16550         stop ost1
16551         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16552 }
16553
16554 setup_165() {
16555         sync # Flush previous IOs so we can count log entries.
16556         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16557         stack_trap cleanup_165 EXIT
16558 }
16559
16560 test_165a() {
16561         local trace="/tmp/${tfile}.trace"
16562         local rc
16563         local count
16564
16565         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16566                 skip "OFD access log unsupported"
16567
16568         setup_165
16569         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16570         sleep 5
16571
16572         do_facet ost1 ofd_access_log_reader --list
16573         stop ost1
16574
16575         do_facet ost1 killall -TERM ofd_access_log_reader
16576         wait
16577         rc=$?
16578
16579         if ((rc != 0)); then
16580                 error "ofd_access_log_reader exited with rc = '${rc}'"
16581         fi
16582
16583         # Parse trace file for discovery events:
16584         oalr_expect_event_count alr_log_add "${trace}" 1
16585         oalr_expect_event_count alr_log_eof "${trace}" 1
16586         oalr_expect_event_count alr_log_free "${trace}" 1
16587 }
16588 run_test 165a "ofd access log discovery"
16589
16590 test_165b() {
16591         local trace="/tmp/${tfile}.trace"
16592         local file="${DIR}/${tfile}"
16593         local pfid1
16594         local pfid2
16595         local -a entry
16596         local rc
16597         local count
16598         local size
16599         local flags
16600
16601         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16602                 skip "OFD access log unsupported"
16603
16604         setup_165
16605         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16606         sleep 5
16607
16608         do_facet ost1 ofd_access_log_reader --list
16609
16610         lfs setstripe -c 1 -i 0 "${file}"
16611         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16612                 error "cannot create '${file}'"
16613
16614         sleep 5
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         oalr_expect_event_count alr_log_entry "${trace}" 1
16624
16625         pfid1=$($LFS path2fid "${file}")
16626
16627         # 1     2             3   4    5     6   7    8    9     10
16628         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16629         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16630
16631         echo "entry = '${entry[*]}'" >&2
16632
16633         pfid2=${entry[4]}
16634         if [[ "${pfid1}" != "${pfid2}" ]]; then
16635                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16636         fi
16637
16638         size=${entry[8]}
16639         if ((size != 1048576)); then
16640                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16641         fi
16642
16643         flags=${entry[10]}
16644         if [[ "${flags}" != "w" ]]; then
16645                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16646         fi
16647
16648         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16649         sleep 5
16650
16651         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16652                 error "cannot read '${file}'"
16653         sleep 5
16654
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         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16666         echo "entry = '${entry[*]}'" >&2
16667
16668         pfid2=${entry[4]}
16669         if [[ "${pfid1}" != "${pfid2}" ]]; then
16670                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16671         fi
16672
16673         size=${entry[8]}
16674         if ((size != 524288)); then
16675                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16676         fi
16677
16678         flags=${entry[10]}
16679         if [[ "${flags}" != "r" ]]; then
16680                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16681         fi
16682 }
16683 run_test 165b "ofd access log entries are produced and consumed"
16684
16685 test_165c() {
16686         local trace="/tmp/${tfile}.trace"
16687         local file="${DIR}/${tdir}/${tfile}"
16688
16689         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16690                 skip "OFD access log unsupported"
16691
16692         test_mkdir "${DIR}/${tdir}"
16693
16694         setup_165
16695         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16696         sleep 5
16697
16698         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16699
16700         # 4096 / 64 = 64. Create twice as many entries.
16701         for ((i = 0; i < 128; i++)); do
16702                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16703                         error "cannot create file"
16704         done
16705
16706         sync
16707
16708         do_facet ost1 killall -TERM ofd_access_log_reader
16709         wait
16710         rc=$?
16711         if ((rc != 0)); then
16712                 error "ofd_access_log_reader exited with rc = '${rc}'"
16713         fi
16714
16715         unlinkmany  "${file}-%d" 128
16716 }
16717 run_test 165c "full ofd access logs do not block IOs"
16718
16719 oal_get_read_count() {
16720         local stats="$1"
16721
16722         # STATS lustre-OST0001 alr_read_count 1
16723
16724         do_facet ost1 cat "${stats}" |
16725         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16726              END { print count; }'
16727 }
16728
16729 oal_expect_read_count() {
16730         local stats="$1"
16731         local count
16732         local expect="$2"
16733
16734         # Ask ofd_access_log_reader to write stats.
16735         do_facet ost1 killall -USR1 ofd_access_log_reader
16736
16737         # Allow some time for things to happen.
16738         sleep 1
16739
16740         count=$(oal_get_read_count "${stats}")
16741         if ((count == expect)); then
16742                 return 0
16743         fi
16744
16745         error_noexit "bad read count, got ${count}, expected ${expect}"
16746         do_facet ost1 cat "${stats}" >&2
16747         exit 1
16748 }
16749
16750 test_165d() {
16751         local stats="/tmp/${tfile}.stats"
16752         local file="${DIR}/${tdir}/${tfile}"
16753         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16754
16755         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16756                 skip "OFD access log unsupported"
16757
16758         test_mkdir "${DIR}/${tdir}"
16759
16760         setup_165
16761         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16762         sleep 5
16763
16764         lfs setstripe -c 1 -i 0 "${file}"
16765
16766         do_facet ost1 lctl set_param "${param}=rw"
16767         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16768                 error "cannot create '${file}'"
16769         oal_expect_read_count "${stats}" 1
16770
16771         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16772                 error "cannot read '${file}'"
16773         oal_expect_read_count "${stats}" 2
16774
16775         do_facet ost1 lctl set_param "${param}=r"
16776         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16777                 error "cannot create '${file}'"
16778         oal_expect_read_count "${stats}" 2
16779
16780         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16781                 error "cannot read '${file}'"
16782         oal_expect_read_count "${stats}" 3
16783
16784         do_facet ost1 lctl set_param "${param}=w"
16785         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16786                 error "cannot create '${file}'"
16787         oal_expect_read_count "${stats}" 4
16788
16789         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16790                 error "cannot read '${file}'"
16791         oal_expect_read_count "${stats}" 4
16792
16793         do_facet ost1 lctl set_param "${param}=0"
16794         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16795                 error "cannot create '${file}'"
16796         oal_expect_read_count "${stats}" 4
16797
16798         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16799                 error "cannot read '${file}'"
16800         oal_expect_read_count "${stats}" 4
16801
16802         do_facet ost1 killall -TERM ofd_access_log_reader
16803         wait
16804         rc=$?
16805         if ((rc != 0)); then
16806                 error "ofd_access_log_reader exited with rc = '${rc}'"
16807         fi
16808 }
16809 run_test 165d "ofd_access_log mask works"
16810
16811 test_165e() {
16812         local stats="/tmp/${tfile}.stats"
16813         local file0="${DIR}/${tdir}-0/${tfile}"
16814         local file1="${DIR}/${tdir}-1/${tfile}"
16815
16816         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16817                 skip "OFD access log unsupported"
16818
16819         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16820
16821         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16822         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16823
16824         lfs setstripe -c 1 -i 0 "${file0}"
16825         lfs setstripe -c 1 -i 0 "${file1}"
16826
16827         setup_165
16828         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16829         sleep 5
16830
16831         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16832                 error "cannot create '${file0}'"
16833         sync
16834         oal_expect_read_count "${stats}" 0
16835
16836         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16837                 error "cannot create '${file1}'"
16838         sync
16839         oal_expect_read_count "${stats}" 1
16840
16841         do_facet ost1 killall -TERM ofd_access_log_reader
16842         wait
16843         rc=$?
16844         if ((rc != 0)); then
16845                 error "ofd_access_log_reader exited with rc = '${rc}'"
16846         fi
16847 }
16848 run_test 165e "ofd_access_log MDT index filter works"
16849
16850 test_165f() {
16851         local trace="/tmp/${tfile}.trace"
16852         local rc
16853         local count
16854
16855         setup_165
16856         do_facet ost1 timeout 60 ofd_access_log_reader \
16857                 --exit-on-close --debug=- --trace=- > "${trace}" &
16858         sleep 5
16859         stop ost1
16860
16861         wait
16862         rc=$?
16863
16864         if ((rc != 0)); then
16865                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16866                 cat "${trace}"
16867                 exit 1
16868         fi
16869 }
16870 run_test 165f "ofd_access_log_reader --exit-on-close works"
16871
16872 test_169() {
16873         # do directio so as not to populate the page cache
16874         log "creating a 10 Mb file"
16875         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16876                 error "multiop failed while creating a file"
16877         log "starting reads"
16878         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16879         log "truncating the file"
16880         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16881                 error "multiop failed while truncating the file"
16882         log "killing dd"
16883         kill %+ || true # reads might have finished
16884         echo "wait until dd is finished"
16885         wait
16886         log "removing the temporary file"
16887         rm -rf $DIR/$tfile || error "tmp file removal failed"
16888 }
16889 run_test 169 "parallel read and truncate should not deadlock"
16890
16891 test_170() {
16892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16893
16894         $LCTL clear     # bug 18514
16895         $LCTL debug_daemon start $TMP/${tfile}_log_good
16896         touch $DIR/$tfile
16897         $LCTL debug_daemon stop
16898         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16899                 error "sed failed to read log_good"
16900
16901         $LCTL debug_daemon start $TMP/${tfile}_log_good
16902         rm -rf $DIR/$tfile
16903         $LCTL debug_daemon stop
16904
16905         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16906                error "lctl df log_bad failed"
16907
16908         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16909         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16910
16911         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16912         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16913
16914         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16915                 error "bad_line good_line1 good_line2 are empty"
16916
16917         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16918         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16919         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16920
16921         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16922         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16923         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16924
16925         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16926                 error "bad_line_new good_line_new are empty"
16927
16928         local expected_good=$((good_line1 + good_line2*2))
16929
16930         rm -f $TMP/${tfile}*
16931         # LU-231, short malformed line may not be counted into bad lines
16932         if [ $bad_line -ne $bad_line_new ] &&
16933                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16934                 error "expected $bad_line bad lines, but got $bad_line_new"
16935                 return 1
16936         fi
16937
16938         if [ $expected_good -ne $good_line_new ]; then
16939                 error "expected $expected_good good lines, but got $good_line_new"
16940                 return 2
16941         fi
16942         true
16943 }
16944 run_test 170 "test lctl df to handle corrupted log ====================="
16945
16946 test_171() { # bug20592
16947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16948
16949         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16950         $LCTL set_param fail_loc=0x50e
16951         $LCTL set_param fail_val=3000
16952         multiop_bg_pause $DIR/$tfile O_s || true
16953         local MULTIPID=$!
16954         kill -USR1 $MULTIPID
16955         # cause log dump
16956         sleep 3
16957         wait $MULTIPID
16958         if dmesg | grep "recursive fault"; then
16959                 error "caught a recursive fault"
16960         fi
16961         $LCTL set_param fail_loc=0
16962         true
16963 }
16964 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16965
16966 # it would be good to share it with obdfilter-survey/iokit-libecho code
16967 setup_obdecho_osc () {
16968         local rc=0
16969         local ost_nid=$1
16970         local obdfilter_name=$2
16971         echo "Creating new osc for $obdfilter_name on $ost_nid"
16972         # make sure we can find loopback nid
16973         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16974
16975         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16976                            ${obdfilter_name}_osc_UUID || rc=2; }
16977         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16978                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16979         return $rc
16980 }
16981
16982 cleanup_obdecho_osc () {
16983         local obdfilter_name=$1
16984         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16985         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16986         return 0
16987 }
16988
16989 obdecho_test() {
16990         local OBD=$1
16991         local node=$2
16992         local pages=${3:-64}
16993         local rc=0
16994         local id
16995
16996         local count=10
16997         local obd_size=$(get_obd_size $node $OBD)
16998         local page_size=$(get_page_size $node)
16999         if [[ -n "$obd_size" ]]; then
17000                 local new_count=$((obd_size / (pages * page_size / 1024)))
17001                 [[ $new_count -ge $count ]] || count=$new_count
17002         fi
17003
17004         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17005         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17006                            rc=2; }
17007         if [ $rc -eq 0 ]; then
17008             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17009             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17010         fi
17011         echo "New object id is $id"
17012         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17013                            rc=4; }
17014         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17015                            "test_brw $count w v $pages $id" || rc=4; }
17016         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17017                            rc=4; }
17018         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17019                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17020         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17021                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17022         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17023         return $rc
17024 }
17025
17026 test_180a() {
17027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17028
17029         if ! [ -d /sys/fs/lustre/echo_client ] &&
17030            ! module_loaded obdecho; then
17031                 load_module obdecho/obdecho &&
17032                         stack_trap "rmmod obdecho" EXIT ||
17033                         error "unable to load obdecho on client"
17034         fi
17035
17036         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17037         local host=$($LCTL get_param -n osc.$osc.import |
17038                      awk '/current_connection:/ { print $2 }' )
17039         local target=$($LCTL get_param -n osc.$osc.import |
17040                        awk '/target:/ { print $2 }' )
17041         target=${target%_UUID}
17042
17043         if [ -n "$target" ]; then
17044                 setup_obdecho_osc $host $target &&
17045                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17046                         { error "obdecho setup failed with $?"; return; }
17047
17048                 obdecho_test ${target}_osc client ||
17049                         error "obdecho_test failed on ${target}_osc"
17050         else
17051                 $LCTL get_param osc.$osc.import
17052                 error "there is no osc.$osc.import target"
17053         fi
17054 }
17055 run_test 180a "test obdecho on osc"
17056
17057 test_180b() {
17058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17059         remote_ost_nodsh && skip "remote OST with nodsh"
17060
17061         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17062                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17063                 error "failed to load module obdecho"
17064
17065         local target=$(do_facet ost1 $LCTL dl |
17066                        awk '/obdfilter/ { print $4; exit; }')
17067
17068         if [ -n "$target" ]; then
17069                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17070         else
17071                 do_facet ost1 $LCTL dl
17072                 error "there is no obdfilter target on ost1"
17073         fi
17074 }
17075 run_test 180b "test obdecho directly on obdfilter"
17076
17077 test_180c() { # LU-2598
17078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17079         remote_ost_nodsh && skip "remote OST with nodsh"
17080         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17081                 skip "Need MDS version at least 2.4.0"
17082
17083         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17084                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17085                 error "failed to load module obdecho"
17086
17087         local target=$(do_facet ost1 $LCTL dl |
17088                        awk '/obdfilter/ { print $4; exit; }')
17089
17090         if [ -n "$target" ]; then
17091                 local pages=16384 # 64MB bulk I/O RPC size
17092
17093                 obdecho_test "$target" ost1 "$pages" ||
17094                         error "obdecho_test with pages=$pages failed with $?"
17095         else
17096                 do_facet ost1 $LCTL dl
17097                 error "there is no obdfilter target on ost1"
17098         fi
17099 }
17100 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17101
17102 test_181() { # bug 22177
17103         test_mkdir $DIR/$tdir
17104         # create enough files to index the directory
17105         createmany -o $DIR/$tdir/foobar 4000
17106         # print attributes for debug purpose
17107         lsattr -d .
17108         # open dir
17109         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17110         MULTIPID=$!
17111         # remove the files & current working dir
17112         unlinkmany $DIR/$tdir/foobar 4000
17113         rmdir $DIR/$tdir
17114         kill -USR1 $MULTIPID
17115         wait $MULTIPID
17116         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17117         return 0
17118 }
17119 run_test 181 "Test open-unlinked dir ========================"
17120
17121 test_182() {
17122         local fcount=1000
17123         local tcount=10
17124
17125         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17126
17127         $LCTL set_param mdc.*.rpc_stats=clear
17128
17129         for (( i = 0; i < $tcount; i++ )) ; do
17130                 mkdir $DIR/$tdir/$i
17131         done
17132
17133         for (( i = 0; i < $tcount; i++ )) ; do
17134                 createmany -o $DIR/$tdir/$i/f- $fcount &
17135         done
17136         wait
17137
17138         for (( i = 0; i < $tcount; i++ )) ; do
17139                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17140         done
17141         wait
17142
17143         $LCTL get_param mdc.*.rpc_stats
17144
17145         rm -rf $DIR/$tdir
17146 }
17147 run_test 182 "Test parallel modify metadata operations ================"
17148
17149 test_183() { # LU-2275
17150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17151         remote_mds_nodsh && skip "remote MDS with nodsh"
17152         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17153                 skip "Need MDS version at least 2.3.56"
17154
17155         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17156         echo aaa > $DIR/$tdir/$tfile
17157
17158 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17159         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17160
17161         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17162         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17163
17164         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17165
17166         # Flush negative dentry cache
17167         touch $DIR/$tdir/$tfile
17168
17169         # We are not checking for any leaked references here, they'll
17170         # become evident next time we do cleanup with module unload.
17171         rm -rf $DIR/$tdir
17172 }
17173 run_test 183 "No crash or request leak in case of strange dispositions ========"
17174
17175 # test suite 184 is for LU-2016, LU-2017
17176 test_184a() {
17177         check_swap_layouts_support
17178
17179         dir0=$DIR/$tdir/$testnum
17180         test_mkdir -p -c1 $dir0
17181         ref1=/etc/passwd
17182         ref2=/etc/group
17183         file1=$dir0/f1
17184         file2=$dir0/f2
17185         $LFS setstripe -c1 $file1
17186         cp $ref1 $file1
17187         $LFS setstripe -c2 $file2
17188         cp $ref2 $file2
17189         gen1=$($LFS getstripe -g $file1)
17190         gen2=$($LFS getstripe -g $file2)
17191
17192         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17193         gen=$($LFS getstripe -g $file1)
17194         [[ $gen1 != $gen ]] ||
17195                 "Layout generation on $file1 does not change"
17196         gen=$($LFS getstripe -g $file2)
17197         [[ $gen2 != $gen ]] ||
17198                 "Layout generation on $file2 does not change"
17199
17200         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17201         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17202
17203         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17204 }
17205 run_test 184a "Basic layout swap"
17206
17207 test_184b() {
17208         check_swap_layouts_support
17209
17210         dir0=$DIR/$tdir/$testnum
17211         mkdir -p $dir0 || error "creating dir $dir0"
17212         file1=$dir0/f1
17213         file2=$dir0/f2
17214         file3=$dir0/f3
17215         dir1=$dir0/d1
17216         dir2=$dir0/d2
17217         mkdir $dir1 $dir2
17218         $LFS setstripe -c1 $file1
17219         $LFS setstripe -c2 $file2
17220         $LFS setstripe -c1 $file3
17221         chown $RUNAS_ID $file3
17222         gen1=$($LFS getstripe -g $file1)
17223         gen2=$($LFS getstripe -g $file2)
17224
17225         $LFS swap_layouts $dir1 $dir2 &&
17226                 error "swap of directories layouts should fail"
17227         $LFS swap_layouts $dir1 $file1 &&
17228                 error "swap of directory and file layouts should fail"
17229         $RUNAS $LFS swap_layouts $file1 $file2 &&
17230                 error "swap of file we cannot write should fail"
17231         $LFS swap_layouts $file1 $file3 &&
17232                 error "swap of file with different owner should fail"
17233         /bin/true # to clear error code
17234 }
17235 run_test 184b "Forbidden layout swap (will generate errors)"
17236
17237 test_184c() {
17238         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17239         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17240         check_swap_layouts_support
17241         check_swap_layout_no_dom $DIR
17242
17243         local dir0=$DIR/$tdir/$testnum
17244         mkdir -p $dir0 || error "creating dir $dir0"
17245
17246         local ref1=$dir0/ref1
17247         local ref2=$dir0/ref2
17248         local file1=$dir0/file1
17249         local file2=$dir0/file2
17250         # create a file large enough for the concurrent test
17251         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17252         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17253         echo "ref file size: ref1($(stat -c %s $ref1))," \
17254              "ref2($(stat -c %s $ref2))"
17255
17256         cp $ref2 $file2
17257         dd if=$ref1 of=$file1 bs=16k &
17258         local DD_PID=$!
17259
17260         # Make sure dd starts to copy file, but wait at most 5 seconds
17261         local loops=0
17262         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17263
17264         $LFS swap_layouts $file1 $file2
17265         local rc=$?
17266         wait $DD_PID
17267         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17268         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17269
17270         # how many bytes copied before swapping layout
17271         local copied=$(stat -c %s $file2)
17272         local remaining=$(stat -c %s $ref1)
17273         remaining=$((remaining - copied))
17274         echo "Copied $copied bytes before swapping layout..."
17275
17276         cmp -n $copied $file1 $ref2 | grep differ &&
17277                 error "Content mismatch [0, $copied) of ref2 and file1"
17278         cmp -n $copied $file2 $ref1 ||
17279                 error "Content mismatch [0, $copied) of ref1 and file2"
17280         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17281                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17282
17283         # clean up
17284         rm -f $ref1 $ref2 $file1 $file2
17285 }
17286 run_test 184c "Concurrent write and layout swap"
17287
17288 test_184d() {
17289         check_swap_layouts_support
17290         check_swap_layout_no_dom $DIR
17291         [ -z "$(which getfattr 2>/dev/null)" ] &&
17292                 skip_env "no getfattr command"
17293
17294         local file1=$DIR/$tdir/$tfile-1
17295         local file2=$DIR/$tdir/$tfile-2
17296         local file3=$DIR/$tdir/$tfile-3
17297         local lovea1
17298         local lovea2
17299
17300         mkdir -p $DIR/$tdir
17301         touch $file1 || error "create $file1 failed"
17302         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17303                 error "create $file2 failed"
17304         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17305                 error "create $file3 failed"
17306         lovea1=$(get_layout_param $file1)
17307
17308         $LFS swap_layouts $file2 $file3 ||
17309                 error "swap $file2 $file3 layouts failed"
17310         $LFS swap_layouts $file1 $file2 ||
17311                 error "swap $file1 $file2 layouts failed"
17312
17313         lovea2=$(get_layout_param $file2)
17314         echo "$lovea1"
17315         echo "$lovea2"
17316         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17317
17318         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17319         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17320 }
17321 run_test 184d "allow stripeless layouts swap"
17322
17323 test_184e() {
17324         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17325                 skip "Need MDS version at least 2.6.94"
17326         check_swap_layouts_support
17327         check_swap_layout_no_dom $DIR
17328         [ -z "$(which getfattr 2>/dev/null)" ] &&
17329                 skip_env "no getfattr command"
17330
17331         local file1=$DIR/$tdir/$tfile-1
17332         local file2=$DIR/$tdir/$tfile-2
17333         local file3=$DIR/$tdir/$tfile-3
17334         local lovea
17335
17336         mkdir -p $DIR/$tdir
17337         touch $file1 || error "create $file1 failed"
17338         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17339                 error "create $file2 failed"
17340         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17341                 error "create $file3 failed"
17342
17343         $LFS swap_layouts $file1 $file2 ||
17344                 error "swap $file1 $file2 layouts failed"
17345
17346         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17347         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17348
17349         echo 123 > $file1 || error "Should be able to write into $file1"
17350
17351         $LFS swap_layouts $file1 $file3 ||
17352                 error "swap $file1 $file3 layouts failed"
17353
17354         echo 123 > $file1 || error "Should be able to write into $file1"
17355
17356         rm -rf $file1 $file2 $file3
17357 }
17358 run_test 184e "Recreate layout after stripeless layout swaps"
17359
17360 test_184f() {
17361         # Create a file with name longer than sizeof(struct stat) ==
17362         # 144 to see if we can get chars from the file name to appear
17363         # in the returned striping. Note that 'f' == 0x66.
17364         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17365
17366         mkdir -p $DIR/$tdir
17367         mcreate $DIR/$tdir/$file
17368         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17369                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17370         fi
17371 }
17372 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17373
17374 test_185() { # LU-2441
17375         # LU-3553 - no volatile file support in old servers
17376         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17377                 skip "Need MDS version at least 2.3.60"
17378
17379         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17380         touch $DIR/$tdir/spoo
17381         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17382         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17383                 error "cannot create/write a volatile file"
17384         [ "$FILESET" == "" ] &&
17385         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17386                 error "FID is still valid after close"
17387
17388         multiop_bg_pause $DIR/$tdir vVw4096_c
17389         local multi_pid=$!
17390
17391         local OLD_IFS=$IFS
17392         IFS=":"
17393         local fidv=($fid)
17394         IFS=$OLD_IFS
17395         # assume that the next FID for this client is sequential, since stdout
17396         # is unfortunately eaten by multiop_bg_pause
17397         local n=$((${fidv[1]} + 1))
17398         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17399         if [ "$FILESET" == "" ]; then
17400                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17401                         error "FID is missing before close"
17402         fi
17403         kill -USR1 $multi_pid
17404         # 1 second delay, so if mtime change we will see it
17405         sleep 1
17406         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17407         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17408 }
17409 run_test 185 "Volatile file support"
17410
17411 function create_check_volatile() {
17412         local idx=$1
17413         local tgt
17414
17415         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17416         local PID=$!
17417         sleep 1
17418         local FID=$(cat /tmp/${tfile}.fid)
17419         [ "$FID" == "" ] && error "can't get FID for volatile"
17420         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17421         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17422         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17423         kill -USR1 $PID
17424         wait
17425         sleep 1
17426         cancel_lru_locks mdc # flush opencache
17427         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17428         return 0
17429 }
17430
17431 test_185a(){
17432         # LU-12516 - volatile creation via .lustre
17433         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17434                 skip "Need MDS version at least 2.3.55"
17435
17436         create_check_volatile 0
17437         [ $MDSCOUNT -lt 2 ] && return 0
17438
17439         # DNE case
17440         create_check_volatile 1
17441
17442         return 0
17443 }
17444 run_test 185a "Volatile file creation in .lustre/fid/"
17445
17446 test_187a() {
17447         remote_mds_nodsh && skip "remote MDS with nodsh"
17448         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17449                 skip "Need MDS version at least 2.3.0"
17450
17451         local dir0=$DIR/$tdir/$testnum
17452         mkdir -p $dir0 || error "creating dir $dir0"
17453
17454         local file=$dir0/file1
17455         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17456         local dv1=$($LFS data_version $file)
17457         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17458         local dv2=$($LFS data_version $file)
17459         [[ $dv1 != $dv2 ]] ||
17460                 error "data version did not change on write $dv1 == $dv2"
17461
17462         # clean up
17463         rm -f $file1
17464 }
17465 run_test 187a "Test data version change"
17466
17467 test_187b() {
17468         remote_mds_nodsh && skip "remote MDS with nodsh"
17469         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17470                 skip "Need MDS version at least 2.3.0"
17471
17472         local dir0=$DIR/$tdir/$testnum
17473         mkdir -p $dir0 || error "creating dir $dir0"
17474
17475         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17476         [[ ${DV[0]} != ${DV[1]} ]] ||
17477                 error "data version did not change on write"\
17478                       " ${DV[0]} == ${DV[1]}"
17479
17480         # clean up
17481         rm -f $file1
17482 }
17483 run_test 187b "Test data version change on volatile file"
17484
17485 test_200() {
17486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17487         remote_mgs_nodsh && skip "remote MGS with nodsh"
17488         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17489
17490         local POOL=${POOL:-cea1}
17491         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17492         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17493         # Pool OST targets
17494         local first_ost=0
17495         local last_ost=$(($OSTCOUNT - 1))
17496         local ost_step=2
17497         local ost_list=$(seq $first_ost $ost_step $last_ost)
17498         local ost_range="$first_ost $last_ost $ost_step"
17499         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17500         local file_dir=$POOL_ROOT/file_tst
17501         local subdir=$test_path/subdir
17502         local rc=0
17503
17504         while : ; do
17505                 # former test_200a test_200b
17506                 pool_add $POOL                          || { rc=$? ; break; }
17507                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17508                 # former test_200c test_200d
17509                 mkdir -p $test_path
17510                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17511                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17512                 mkdir -p $subdir
17513                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17514                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17515                                                         || { rc=$? ; break; }
17516                 # former test_200e test_200f
17517                 local files=$((OSTCOUNT*3))
17518                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17519                                                         || { rc=$? ; break; }
17520                 pool_create_files $POOL $file_dir $files "$ost_list" \
17521                                                         || { rc=$? ; break; }
17522                 # former test_200g test_200h
17523                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17524                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17525
17526                 # former test_201a test_201b test_201c
17527                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17528
17529                 local f=$test_path/$tfile
17530                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17531                 pool_remove $POOL $f                    || { rc=$? ; break; }
17532                 break
17533         done
17534
17535         destroy_test_pools
17536
17537         return $rc
17538 }
17539 run_test 200 "OST pools"
17540
17541 # usage: default_attr <count | size | offset>
17542 default_attr() {
17543         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17544 }
17545
17546 # usage: check_default_stripe_attr
17547 check_default_stripe_attr() {
17548         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17549         case $1 in
17550         --stripe-count|-c)
17551                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17552         --stripe-size|-S)
17553                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17554         --stripe-index|-i)
17555                 EXPECTED=-1;;
17556         *)
17557                 error "unknown getstripe attr '$1'"
17558         esac
17559
17560         [ $ACTUAL == $EXPECTED ] ||
17561                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17562 }
17563
17564 test_204a() {
17565         test_mkdir $DIR/$tdir
17566         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17567
17568         check_default_stripe_attr --stripe-count
17569         check_default_stripe_attr --stripe-size
17570         check_default_stripe_attr --stripe-index
17571 }
17572 run_test 204a "Print default stripe attributes"
17573
17574 test_204b() {
17575         test_mkdir $DIR/$tdir
17576         $LFS setstripe --stripe-count 1 $DIR/$tdir
17577
17578         check_default_stripe_attr --stripe-size
17579         check_default_stripe_attr --stripe-index
17580 }
17581 run_test 204b "Print default stripe size and offset"
17582
17583 test_204c() {
17584         test_mkdir $DIR/$tdir
17585         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17586
17587         check_default_stripe_attr --stripe-count
17588         check_default_stripe_attr --stripe-index
17589 }
17590 run_test 204c "Print default stripe count and offset"
17591
17592 test_204d() {
17593         test_mkdir $DIR/$tdir
17594         $LFS setstripe --stripe-index 0 $DIR/$tdir
17595
17596         check_default_stripe_attr --stripe-count
17597         check_default_stripe_attr --stripe-size
17598 }
17599 run_test 204d "Print default stripe count and size"
17600
17601 test_204e() {
17602         test_mkdir $DIR/$tdir
17603         $LFS setstripe -d $DIR/$tdir
17604
17605         check_default_stripe_attr --stripe-count --raw
17606         check_default_stripe_attr --stripe-size --raw
17607         check_default_stripe_attr --stripe-index --raw
17608 }
17609 run_test 204e "Print raw stripe attributes"
17610
17611 test_204f() {
17612         test_mkdir $DIR/$tdir
17613         $LFS setstripe --stripe-count 1 $DIR/$tdir
17614
17615         check_default_stripe_attr --stripe-size --raw
17616         check_default_stripe_attr --stripe-index --raw
17617 }
17618 run_test 204f "Print raw stripe size and offset"
17619
17620 test_204g() {
17621         test_mkdir $DIR/$tdir
17622         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17623
17624         check_default_stripe_attr --stripe-count --raw
17625         check_default_stripe_attr --stripe-index --raw
17626 }
17627 run_test 204g "Print raw stripe count and offset"
17628
17629 test_204h() {
17630         test_mkdir $DIR/$tdir
17631         $LFS setstripe --stripe-index 0 $DIR/$tdir
17632
17633         check_default_stripe_attr --stripe-count --raw
17634         check_default_stripe_attr --stripe-size --raw
17635 }
17636 run_test 204h "Print raw stripe count and size"
17637
17638 # Figure out which job scheduler is being used, if any,
17639 # or use a fake one
17640 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17641         JOBENV=SLURM_JOB_ID
17642 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17643         JOBENV=LSB_JOBID
17644 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17645         JOBENV=PBS_JOBID
17646 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17647         JOBENV=LOADL_STEP_ID
17648 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17649         JOBENV=JOB_ID
17650 else
17651         $LCTL list_param jobid_name > /dev/null 2>&1
17652         if [ $? -eq 0 ]; then
17653                 JOBENV=nodelocal
17654         else
17655                 JOBENV=FAKE_JOBID
17656         fi
17657 fi
17658 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17659
17660 verify_jobstats() {
17661         local cmd=($1)
17662         shift
17663         local facets="$@"
17664
17665 # we don't really need to clear the stats for this test to work, since each
17666 # command has a unique jobid, but it makes debugging easier if needed.
17667 #       for facet in $facets; do
17668 #               local dev=$(convert_facet2label $facet)
17669 #               # clear old jobstats
17670 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17671 #       done
17672
17673         # use a new JobID for each test, or we might see an old one
17674         [ "$JOBENV" = "FAKE_JOBID" ] &&
17675                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17676
17677         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17678
17679         [ "$JOBENV" = "nodelocal" ] && {
17680                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17681                 $LCTL set_param jobid_name=$FAKE_JOBID
17682                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17683         }
17684
17685         log "Test: ${cmd[*]}"
17686         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17687
17688         if [ $JOBENV = "FAKE_JOBID" ]; then
17689                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17690         else
17691                 ${cmd[*]}
17692         fi
17693
17694         # all files are created on OST0000
17695         for facet in $facets; do
17696                 local stats="*.$(convert_facet2label $facet).job_stats"
17697
17698                 # strip out libtool wrappers for in-tree executables
17699                 if [ $(do_facet $facet lctl get_param $stats |
17700                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17701                         do_facet $facet lctl get_param $stats
17702                         error "No jobstats for $JOBVAL found on $facet::$stats"
17703                 fi
17704         done
17705 }
17706
17707 jobstats_set() {
17708         local new_jobenv=$1
17709
17710         set_persistent_param_and_check client "jobid_var" \
17711                 "$FSNAME.sys.jobid_var" $new_jobenv
17712 }
17713
17714 test_205a() { # Job stats
17715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17716         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17717                 skip "Need MDS version with at least 2.7.1"
17718         remote_mgs_nodsh && skip "remote MGS with nodsh"
17719         remote_mds_nodsh && skip "remote MDS with nodsh"
17720         remote_ost_nodsh && skip "remote OST with nodsh"
17721         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17722                 skip "Server doesn't support jobstats"
17723         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17724
17725         local old_jobenv=$($LCTL get_param -n jobid_var)
17726         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17727
17728         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17729                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17730         else
17731                 stack_trap "do_facet mgs $PERM_CMD \
17732                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17733         fi
17734         changelog_register
17735
17736         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17737                                 mdt.*.job_cleanup_interval | head -n 1)
17738         local new_interval=5
17739         do_facet $SINGLEMDS \
17740                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17741         stack_trap "do_facet $SINGLEMDS \
17742                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17743         local start=$SECONDS
17744
17745         local cmd
17746         # mkdir
17747         cmd="mkdir $DIR/$tdir"
17748         verify_jobstats "$cmd" "$SINGLEMDS"
17749         # rmdir
17750         cmd="rmdir $DIR/$tdir"
17751         verify_jobstats "$cmd" "$SINGLEMDS"
17752         # mkdir on secondary MDT
17753         if [ $MDSCOUNT -gt 1 ]; then
17754                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17755                 verify_jobstats "$cmd" "mds2"
17756         fi
17757         # mknod
17758         cmd="mknod $DIR/$tfile c 1 3"
17759         verify_jobstats "$cmd" "$SINGLEMDS"
17760         # unlink
17761         cmd="rm -f $DIR/$tfile"
17762         verify_jobstats "$cmd" "$SINGLEMDS"
17763         # create all files on OST0000 so verify_jobstats can find OST stats
17764         # open & close
17765         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17766         verify_jobstats "$cmd" "$SINGLEMDS"
17767         # setattr
17768         cmd="touch $DIR/$tfile"
17769         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17770         # write
17771         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17772         verify_jobstats "$cmd" "ost1"
17773         # read
17774         cancel_lru_locks osc
17775         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17776         verify_jobstats "$cmd" "ost1"
17777         # truncate
17778         cmd="$TRUNCATE $DIR/$tfile 0"
17779         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17780         # rename
17781         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17782         verify_jobstats "$cmd" "$SINGLEMDS"
17783         # jobstats expiry - sleep until old stats should be expired
17784         local left=$((new_interval + 5 - (SECONDS - start)))
17785         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17786                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17787                         "0" $left
17788         cmd="mkdir $DIR/$tdir.expire"
17789         verify_jobstats "$cmd" "$SINGLEMDS"
17790         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17791             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17792
17793         # Ensure that jobid are present in changelog (if supported by MDS)
17794         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17795                 changelog_dump | tail -10
17796                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17797                 [ $jobids -eq 9 ] ||
17798                         error "Wrong changelog jobid count $jobids != 9"
17799
17800                 # LU-5862
17801                 JOBENV="disable"
17802                 jobstats_set $JOBENV
17803                 touch $DIR/$tfile
17804                 changelog_dump | grep $tfile
17805                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17806                 [ $jobids -eq 0 ] ||
17807                         error "Unexpected jobids when jobid_var=$JOBENV"
17808         fi
17809
17810         # test '%j' access to environment variable - if supported
17811         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17812                 JOBENV="JOBCOMPLEX"
17813                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17814
17815                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17816         fi
17817
17818         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17819                 JOBENV="JOBCOMPLEX"
17820                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17821
17822                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17823         fi
17824
17825         # test '%j' access to per-session jobid - if supported
17826         if lctl list_param jobid_this_session > /dev/null 2>&1
17827         then
17828                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17829                 lctl set_param jobid_this_session=$USER
17830
17831                 JOBENV="JOBCOMPLEX"
17832                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17833
17834                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17835         fi
17836 }
17837 run_test 205a "Verify job stats"
17838
17839 # LU-13117, LU-13597
17840 test_205b() {
17841         job_stats="mdt.*.job_stats"
17842         $LCTL set_param $job_stats=clear
17843         # Setting jobid_var to USER might not be supported
17844         $LCTL set_param jobid_var=USER || true
17845         $LCTL set_param jobid_name="%e.%u"
17846         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17847         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17848                 grep "job_id:.*foolish" &&
17849                         error "Unexpected jobid found"
17850         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17851                 grep "open:.*min.*max.*sum" ||
17852                         error "wrong job_stats format found"
17853 }
17854 run_test 205b "Verify job stats jobid and output format"
17855
17856 # LU-13733
17857 test_205c() {
17858         $LCTL set_param llite.*.stats=0
17859         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17860         $LCTL get_param llite.*.stats
17861         $LCTL get_param llite.*.stats | grep \
17862                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17863                         error "wrong client stats format found"
17864 }
17865 run_test 205c "Verify client stats format"
17866
17867 # LU-1480, LU-1773 and LU-1657
17868 test_206() {
17869         mkdir -p $DIR/$tdir
17870         $LFS setstripe -c -1 $DIR/$tdir
17871 #define OBD_FAIL_LOV_INIT 0x1403
17872         $LCTL set_param fail_loc=0xa0001403
17873         $LCTL set_param fail_val=1
17874         touch $DIR/$tdir/$tfile || true
17875 }
17876 run_test 206 "fail lov_init_raid0() doesn't lbug"
17877
17878 test_207a() {
17879         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17880         local fsz=`stat -c %s $DIR/$tfile`
17881         cancel_lru_locks mdc
17882
17883         # do not return layout in getattr intent
17884 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17885         $LCTL set_param fail_loc=0x170
17886         local sz=`stat -c %s $DIR/$tfile`
17887
17888         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17889
17890         rm -rf $DIR/$tfile
17891 }
17892 run_test 207a "can refresh layout at glimpse"
17893
17894 test_207b() {
17895         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17896         local cksum=`md5sum $DIR/$tfile`
17897         local fsz=`stat -c %s $DIR/$tfile`
17898         cancel_lru_locks mdc
17899         cancel_lru_locks osc
17900
17901         # do not return layout in getattr intent
17902 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17903         $LCTL set_param fail_loc=0x171
17904
17905         # it will refresh layout after the file is opened but before read issues
17906         echo checksum is "$cksum"
17907         echo "$cksum" |md5sum -c --quiet || error "file differs"
17908
17909         rm -rf $DIR/$tfile
17910 }
17911 run_test 207b "can refresh layout at open"
17912
17913 test_208() {
17914         # FIXME: in this test suite, only RD lease is used. This is okay
17915         # for now as only exclusive open is supported. After generic lease
17916         # is done, this test suite should be revised. - Jinshan
17917
17918         remote_mds_nodsh && skip "remote MDS with nodsh"
17919         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17920                 skip "Need MDS version at least 2.4.52"
17921
17922         echo "==== test 1: verify get lease work"
17923         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17924
17925         echo "==== test 2: verify lease can be broken by upcoming open"
17926         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17927         local PID=$!
17928         sleep 1
17929
17930         $MULTIOP $DIR/$tfile oO_RDONLY:c
17931         kill -USR1 $PID && wait $PID || error "break lease error"
17932
17933         echo "==== test 3: verify lease can't be granted if an open already exists"
17934         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17935         local PID=$!
17936         sleep 1
17937
17938         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17939         kill -USR1 $PID && wait $PID || error "open file error"
17940
17941         echo "==== test 4: lease can sustain over recovery"
17942         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17943         PID=$!
17944         sleep 1
17945
17946         fail mds1
17947
17948         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17949
17950         echo "==== test 5: lease broken can't be regained by replay"
17951         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17952         PID=$!
17953         sleep 1
17954
17955         # open file to break lease and then recovery
17956         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17957         fail mds1
17958
17959         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17960
17961         rm -f $DIR/$tfile
17962 }
17963 run_test 208 "Exclusive open"
17964
17965 test_209() {
17966         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17967                 skip_env "must have disp_stripe"
17968
17969         touch $DIR/$tfile
17970         sync; sleep 5; sync;
17971
17972         echo 3 > /proc/sys/vm/drop_caches
17973         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17974                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17975         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17976
17977         # open/close 500 times
17978         for i in $(seq 500); do
17979                 cat $DIR/$tfile
17980         done
17981
17982         echo 3 > /proc/sys/vm/drop_caches
17983         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17984                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17985         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17986
17987         echo "before: $req_before, after: $req_after"
17988         [ $((req_after - req_before)) -ge 300 ] &&
17989                 error "open/close requests are not freed"
17990         return 0
17991 }
17992 run_test 209 "read-only open/close requests should be freed promptly"
17993
17994 test_210() {
17995         local pid
17996
17997         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17998         pid=$!
17999         sleep 1
18000
18001         $LFS getstripe $DIR/$tfile
18002         kill -USR1 $pid
18003         wait $pid || error "multiop failed"
18004
18005         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18006         pid=$!
18007         sleep 1
18008
18009         $LFS getstripe $DIR/$tfile
18010         kill -USR1 $pid
18011         wait $pid || error "multiop failed"
18012 }
18013 run_test 210 "lfs getstripe does not break leases"
18014
18015 test_212() {
18016         size=`date +%s`
18017         size=$((size % 8192 + 1))
18018         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18019         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18020         rm -f $DIR/f212 $DIR/f212.xyz
18021 }
18022 run_test 212 "Sendfile test ============================================"
18023
18024 test_213() {
18025         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18026         cancel_lru_locks osc
18027         lctl set_param fail_loc=0x8000040f
18028         # generate a read lock
18029         cat $DIR/$tfile > /dev/null
18030         # write to the file, it will try to cancel the above read lock.
18031         cat /etc/hosts >> $DIR/$tfile
18032 }
18033 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18034
18035 test_214() { # for bug 20133
18036         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18037         for (( i=0; i < 340; i++ )) ; do
18038                 touch $DIR/$tdir/d214c/a$i
18039         done
18040
18041         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18042         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18043         ls $DIR/d214c || error "ls $DIR/d214c failed"
18044         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18045         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18046 }
18047 run_test 214 "hash-indexed directory test - bug 20133"
18048
18049 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18050 create_lnet_proc_files() {
18051         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18052 }
18053
18054 # counterpart of create_lnet_proc_files
18055 remove_lnet_proc_files() {
18056         rm -f $TMP/lnet_$1.sys
18057 }
18058
18059 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18060 # 3rd arg as regexp for body
18061 check_lnet_proc_stats() {
18062         local l=$(cat "$TMP/lnet_$1" |wc -l)
18063         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18064
18065         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18066 }
18067
18068 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18069 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18070 # optional and can be regexp for 2nd line (lnet.routes case)
18071 check_lnet_proc_entry() {
18072         local blp=2          # blp stands for 'position of 1st line of body'
18073         [ -z "$5" ] || blp=3 # lnet.routes case
18074
18075         local l=$(cat "$TMP/lnet_$1" |wc -l)
18076         # subtracting one from $blp because the body can be empty
18077         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18078
18079         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18080                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18081
18082         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18083                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18084
18085         # bail out if any unexpected line happened
18086         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18087         [ "$?" != 0 ] || error "$2 misformatted"
18088 }
18089
18090 test_215() { # for bugs 18102, 21079, 21517
18091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18092
18093         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18094         local P='[1-9][0-9]*'           # positive numeric
18095         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18096         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18097         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18098         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18099
18100         local L1 # regexp for 1st line
18101         local L2 # regexp for 2nd line (optional)
18102         local BR # regexp for the rest (body)
18103
18104         # lnet.stats should look as 11 space-separated non-negative numerics
18105         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18106         create_lnet_proc_files "stats"
18107         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18108         remove_lnet_proc_files "stats"
18109
18110         # lnet.routes should look like this:
18111         # Routing disabled/enabled
18112         # net hops priority state router
18113         # where net is a string like tcp0, hops > 0, priority >= 0,
18114         # state is up/down,
18115         # router is a string like 192.168.1.1@tcp2
18116         L1="^Routing (disabled|enabled)$"
18117         L2="^net +hops +priority +state +router$"
18118         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18119         create_lnet_proc_files "routes"
18120         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18121         remove_lnet_proc_files "routes"
18122
18123         # lnet.routers should look like this:
18124         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18125         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18126         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18127         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18128         L1="^ref +rtr_ref +alive +router$"
18129         BR="^$P +$P +(up|down) +$NID$"
18130         create_lnet_proc_files "routers"
18131         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18132         remove_lnet_proc_files "routers"
18133
18134         # lnet.peers should look like this:
18135         # nid refs state last max rtr min tx min queue
18136         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18137         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18138         # numeric (0 or >0 or <0), queue >= 0.
18139         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18140         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18141         create_lnet_proc_files "peers"
18142         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18143         remove_lnet_proc_files "peers"
18144
18145         # lnet.buffers  should look like this:
18146         # pages count credits min
18147         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18148         L1="^pages +count +credits +min$"
18149         BR="^ +$N +$N +$I +$I$"
18150         create_lnet_proc_files "buffers"
18151         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18152         remove_lnet_proc_files "buffers"
18153
18154         # lnet.nis should look like this:
18155         # nid status alive refs peer rtr max tx min
18156         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18157         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18158         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18159         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18160         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18161         create_lnet_proc_files "nis"
18162         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18163         remove_lnet_proc_files "nis"
18164
18165         # can we successfully write to lnet.stats?
18166         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18167 }
18168 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18169
18170 test_216() { # bug 20317
18171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18172         remote_ost_nodsh && skip "remote OST with nodsh"
18173
18174         local node
18175         local facets=$(get_facets OST)
18176         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18177
18178         save_lustre_params client "osc.*.contention_seconds" > $p
18179         save_lustre_params $facets \
18180                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18181         save_lustre_params $facets \
18182                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18183         save_lustre_params $facets \
18184                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18185         clear_stats osc.*.osc_stats
18186
18187         # agressive lockless i/o settings
18188         do_nodes $(comma_list $(osts_nodes)) \
18189                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18190                         ldlm.namespaces.filter-*.contended_locks=0 \
18191                         ldlm.namespaces.filter-*.contention_seconds=60"
18192         lctl set_param -n osc.*.contention_seconds=60
18193
18194         $DIRECTIO write $DIR/$tfile 0 10 4096
18195         $CHECKSTAT -s 40960 $DIR/$tfile
18196
18197         # disable lockless i/o
18198         do_nodes $(comma_list $(osts_nodes)) \
18199                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18200                         ldlm.namespaces.filter-*.contended_locks=32 \
18201                         ldlm.namespaces.filter-*.contention_seconds=0"
18202         lctl set_param -n osc.*.contention_seconds=0
18203         clear_stats osc.*.osc_stats
18204
18205         dd if=/dev/zero of=$DIR/$tfile count=0
18206         $CHECKSTAT -s 0 $DIR/$tfile
18207
18208         restore_lustre_params <$p
18209         rm -f $p
18210         rm $DIR/$tfile
18211 }
18212 run_test 216 "check lockless direct write updates file size and kms correctly"
18213
18214 test_217() { # bug 22430
18215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18216
18217         local node
18218         local nid
18219
18220         for node in $(nodes_list); do
18221                 nid=$(host_nids_address $node $NETTYPE)
18222                 if [[ $nid = *-* ]] ; then
18223                         echo "lctl ping $(h2nettype $nid)"
18224                         lctl ping $(h2nettype $nid)
18225                 else
18226                         echo "skipping $node (no hyphen detected)"
18227                 fi
18228         done
18229 }
18230 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18231
18232 test_218() {
18233        # do directio so as not to populate the page cache
18234        log "creating a 10 Mb file"
18235        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18236        log "starting reads"
18237        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18238        log "truncating the file"
18239        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18240        log "killing dd"
18241        kill %+ || true # reads might have finished
18242        echo "wait until dd is finished"
18243        wait
18244        log "removing the temporary file"
18245        rm -rf $DIR/$tfile || error "tmp file removal failed"
18246 }
18247 run_test 218 "parallel read and truncate should not deadlock"
18248
18249 test_219() {
18250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18251
18252         # write one partial page
18253         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18254         # set no grant so vvp_io_commit_write will do sync write
18255         $LCTL set_param fail_loc=0x411
18256         # write a full page at the end of file
18257         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18258
18259         $LCTL set_param fail_loc=0
18260         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18261         $LCTL set_param fail_loc=0x411
18262         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18263
18264         # LU-4201
18265         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18266         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18267 }
18268 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18269
18270 test_220() { #LU-325
18271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18272         remote_ost_nodsh && skip "remote OST with nodsh"
18273         remote_mds_nodsh && skip "remote MDS with nodsh"
18274         remote_mgs_nodsh && skip "remote MGS with nodsh"
18275
18276         local OSTIDX=0
18277
18278         # create on MDT0000 so the last_id and next_id are correct
18279         mkdir $DIR/$tdir
18280         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18281         OST=${OST%_UUID}
18282
18283         # on the mdt's osc
18284         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18285         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18286                         osp.$mdtosc_proc1.prealloc_last_id)
18287         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18288                         osp.$mdtosc_proc1.prealloc_next_id)
18289
18290         $LFS df -i
18291
18292         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18293         #define OBD_FAIL_OST_ENOINO              0x229
18294         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18295         create_pool $FSNAME.$TESTNAME || return 1
18296         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18297
18298         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18299
18300         MDSOBJS=$((last_id - next_id))
18301         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18302
18303         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18304         echo "OST still has $count kbytes free"
18305
18306         echo "create $MDSOBJS files @next_id..."
18307         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18308
18309         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18310                         osp.$mdtosc_proc1.prealloc_last_id)
18311         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18312                         osp.$mdtosc_proc1.prealloc_next_id)
18313
18314         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18315         $LFS df -i
18316
18317         echo "cleanup..."
18318
18319         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18320         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18321
18322         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18323                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18324         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18325                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18326         echo "unlink $MDSOBJS files @$next_id..."
18327         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18328 }
18329 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18330
18331 test_221() {
18332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18333
18334         dd if=`which date` of=$MOUNT/date oflag=sync
18335         chmod +x $MOUNT/date
18336
18337         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18338         $LCTL set_param fail_loc=0x80001401
18339
18340         $MOUNT/date > /dev/null
18341         rm -f $MOUNT/date
18342 }
18343 run_test 221 "make sure fault and truncate race to not cause OOM"
18344
18345 test_222a () {
18346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18347
18348         rm -rf $DIR/$tdir
18349         test_mkdir $DIR/$tdir
18350         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18351         createmany -o $DIR/$tdir/$tfile 10
18352         cancel_lru_locks mdc
18353         cancel_lru_locks osc
18354         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18355         $LCTL set_param fail_loc=0x31a
18356         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18357         $LCTL set_param fail_loc=0
18358         rm -r $DIR/$tdir
18359 }
18360 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18361
18362 test_222b () {
18363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18364
18365         rm -rf $DIR/$tdir
18366         test_mkdir $DIR/$tdir
18367         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18368         createmany -o $DIR/$tdir/$tfile 10
18369         cancel_lru_locks mdc
18370         cancel_lru_locks osc
18371         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18372         $LCTL set_param fail_loc=0x31a
18373         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18374         $LCTL set_param fail_loc=0
18375 }
18376 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18377
18378 test_223 () {
18379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18380
18381         rm -rf $DIR/$tdir
18382         test_mkdir $DIR/$tdir
18383         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18384         createmany -o $DIR/$tdir/$tfile 10
18385         cancel_lru_locks mdc
18386         cancel_lru_locks osc
18387         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18388         $LCTL set_param fail_loc=0x31b
18389         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18390         $LCTL set_param fail_loc=0
18391         rm -r $DIR/$tdir
18392 }
18393 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18394
18395 test_224a() { # LU-1039, MRP-303
18396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18397
18398         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18399         $LCTL set_param fail_loc=0x508
18400         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18401         $LCTL set_param fail_loc=0
18402         df $DIR
18403 }
18404 run_test 224a "Don't panic on bulk IO failure"
18405
18406 test_224b() { # LU-1039, MRP-303
18407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18408
18409         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18410         cancel_lru_locks osc
18411         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18412         $LCTL set_param fail_loc=0x515
18413         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18414         $LCTL set_param fail_loc=0
18415         df $DIR
18416 }
18417 run_test 224b "Don't panic on bulk IO failure"
18418
18419 test_224c() { # LU-6441
18420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18421         remote_mds_nodsh && skip "remote MDS with nodsh"
18422
18423         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18424         save_writethrough $p
18425         set_cache writethrough on
18426
18427         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18428         local at_max=$($LCTL get_param -n at_max)
18429         local timeout=$($LCTL get_param -n timeout)
18430         local test_at="at_max"
18431         local param_at="$FSNAME.sys.at_max"
18432         local test_timeout="timeout"
18433         local param_timeout="$FSNAME.sys.timeout"
18434
18435         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18436
18437         set_persistent_param_and_check client "$test_at" "$param_at" 0
18438         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18439
18440         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18441         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18442         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18443         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18444         sync
18445         do_facet ost1 "$LCTL set_param fail_loc=0"
18446
18447         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18448         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18449                 $timeout
18450
18451         $LCTL set_param -n $pages_per_rpc
18452         restore_lustre_params < $p
18453         rm -f $p
18454 }
18455 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18456
18457 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18458 test_225a () {
18459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18460         if [ -z ${MDSSURVEY} ]; then
18461                 skip_env "mds-survey not found"
18462         fi
18463         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18464                 skip "Need MDS version at least 2.2.51"
18465
18466         local mds=$(facet_host $SINGLEMDS)
18467         local target=$(do_nodes $mds 'lctl dl' |
18468                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18469
18470         local cmd1="file_count=1000 thrhi=4"
18471         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18472         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18473         local cmd="$cmd1 $cmd2 $cmd3"
18474
18475         rm -f ${TMP}/mds_survey*
18476         echo + $cmd
18477         eval $cmd || error "mds-survey with zero-stripe failed"
18478         cat ${TMP}/mds_survey*
18479         rm -f ${TMP}/mds_survey*
18480 }
18481 run_test 225a "Metadata survey sanity with zero-stripe"
18482
18483 test_225b () {
18484         if [ -z ${MDSSURVEY} ]; then
18485                 skip_env "mds-survey not found"
18486         fi
18487         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18488                 skip "Need MDS version at least 2.2.51"
18489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18490         remote_mds_nodsh && skip "remote MDS with nodsh"
18491         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18492                 skip_env "Need to mount OST to test"
18493         fi
18494
18495         local mds=$(facet_host $SINGLEMDS)
18496         local target=$(do_nodes $mds 'lctl dl' |
18497                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18498
18499         local cmd1="file_count=1000 thrhi=4"
18500         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18501         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18502         local cmd="$cmd1 $cmd2 $cmd3"
18503
18504         rm -f ${TMP}/mds_survey*
18505         echo + $cmd
18506         eval $cmd || error "mds-survey with stripe_count failed"
18507         cat ${TMP}/mds_survey*
18508         rm -f ${TMP}/mds_survey*
18509 }
18510 run_test 225b "Metadata survey sanity with stripe_count = 1"
18511
18512 mcreate_path2fid () {
18513         local mode=$1
18514         local major=$2
18515         local minor=$3
18516         local name=$4
18517         local desc=$5
18518         local path=$DIR/$tdir/$name
18519         local fid
18520         local rc
18521         local fid_path
18522
18523         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18524                 error "cannot create $desc"
18525
18526         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18527         rc=$?
18528         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18529
18530         fid_path=$($LFS fid2path $MOUNT $fid)
18531         rc=$?
18532         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18533
18534         [ "$path" == "$fid_path" ] ||
18535                 error "fid2path returned $fid_path, expected $path"
18536
18537         echo "pass with $path and $fid"
18538 }
18539
18540 test_226a () {
18541         rm -rf $DIR/$tdir
18542         mkdir -p $DIR/$tdir
18543
18544         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18545         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18546         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18547         mcreate_path2fid 0040666 0 0 dir "directory"
18548         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18549         mcreate_path2fid 0100666 0 0 file "regular file"
18550         mcreate_path2fid 0120666 0 0 link "symbolic link"
18551         mcreate_path2fid 0140666 0 0 sock "socket"
18552 }
18553 run_test 226a "call path2fid and fid2path on files of all type"
18554
18555 test_226b () {
18556         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18557
18558         local MDTIDX=1
18559
18560         rm -rf $DIR/$tdir
18561         mkdir -p $DIR/$tdir
18562         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18563                 error "create remote directory failed"
18564         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18565         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18566                                 "character special file (null)"
18567         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18568                                 "character special file (no device)"
18569         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18570         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18571                                 "block special file (loop)"
18572         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18573         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18574         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18575 }
18576 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18577
18578 test_226c () {
18579         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18580         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18581                 skip "Need MDS version at least 2.13.55"
18582
18583         local submnt=/mnt/submnt
18584         local srcfile=/etc/passwd
18585         local dstfile=$submnt/passwd
18586         local path
18587         local fid
18588
18589         rm -rf $DIR/$tdir
18590         rm -rf $submnt
18591         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18592                 error "create remote directory failed"
18593         mkdir -p $submnt || error "create $submnt failed"
18594         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18595                 error "mount $submnt failed"
18596         stack_trap "umount $submnt" EXIT
18597
18598         cp $srcfile $dstfile
18599         fid=$($LFS path2fid $dstfile)
18600         path=$($LFS fid2path $submnt "$fid")
18601         [ "$path" = "$dstfile" ] ||
18602                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18603 }
18604 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18605
18606 # LU-1299 Executing or running ldd on a truncated executable does not
18607 # cause an out-of-memory condition.
18608 test_227() {
18609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18610         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18611
18612         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18613         chmod +x $MOUNT/date
18614
18615         $MOUNT/date > /dev/null
18616         ldd $MOUNT/date > /dev/null
18617         rm -f $MOUNT/date
18618 }
18619 run_test 227 "running truncated executable does not cause OOM"
18620
18621 # LU-1512 try to reuse idle OI blocks
18622 test_228a() {
18623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18624         remote_mds_nodsh && skip "remote MDS with nodsh"
18625         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18626
18627         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18628         local myDIR=$DIR/$tdir
18629
18630         mkdir -p $myDIR
18631         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18632         $LCTL set_param fail_loc=0x80001002
18633         createmany -o $myDIR/t- 10000
18634         $LCTL set_param fail_loc=0
18635         # The guard is current the largest FID holder
18636         touch $myDIR/guard
18637         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18638                     tr -d '[')
18639         local IDX=$(($SEQ % 64))
18640
18641         do_facet $SINGLEMDS sync
18642         # Make sure journal flushed.
18643         sleep 6
18644         local blk1=$(do_facet $SINGLEMDS \
18645                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18646                      grep Blockcount | awk '{print $4}')
18647
18648         # Remove old files, some OI blocks will become idle.
18649         unlinkmany $myDIR/t- 10000
18650         # Create new files, idle OI blocks should be reused.
18651         createmany -o $myDIR/t- 2000
18652         do_facet $SINGLEMDS sync
18653         # Make sure journal flushed.
18654         sleep 6
18655         local blk2=$(do_facet $SINGLEMDS \
18656                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18657                      grep Blockcount | awk '{print $4}')
18658
18659         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18660 }
18661 run_test 228a "try to reuse idle OI blocks"
18662
18663 test_228b() {
18664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18665         remote_mds_nodsh && skip "remote MDS with nodsh"
18666         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18667
18668         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18669         local myDIR=$DIR/$tdir
18670
18671         mkdir -p $myDIR
18672         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18673         $LCTL set_param fail_loc=0x80001002
18674         createmany -o $myDIR/t- 10000
18675         $LCTL set_param fail_loc=0
18676         # The guard is current the largest FID holder
18677         touch $myDIR/guard
18678         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18679                     tr -d '[')
18680         local IDX=$(($SEQ % 64))
18681
18682         do_facet $SINGLEMDS sync
18683         # Make sure journal flushed.
18684         sleep 6
18685         local blk1=$(do_facet $SINGLEMDS \
18686                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18687                      grep Blockcount | awk '{print $4}')
18688
18689         # Remove old files, some OI blocks will become idle.
18690         unlinkmany $myDIR/t- 10000
18691
18692         # stop the MDT
18693         stop $SINGLEMDS || error "Fail to stop MDT."
18694         # remount the MDT
18695         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18696
18697         df $MOUNT || error "Fail to df."
18698         # Create new files, idle OI blocks should be reused.
18699         createmany -o $myDIR/t- 2000
18700         do_facet $SINGLEMDS sync
18701         # Make sure journal flushed.
18702         sleep 6
18703         local blk2=$(do_facet $SINGLEMDS \
18704                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18705                      grep Blockcount | awk '{print $4}')
18706
18707         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18708 }
18709 run_test 228b "idle OI blocks can be reused after MDT restart"
18710
18711 #LU-1881
18712 test_228c() {
18713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18714         remote_mds_nodsh && skip "remote MDS with nodsh"
18715         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18716
18717         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18718         local myDIR=$DIR/$tdir
18719
18720         mkdir -p $myDIR
18721         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18722         $LCTL set_param fail_loc=0x80001002
18723         # 20000 files can guarantee there are index nodes in the OI file
18724         createmany -o $myDIR/t- 20000
18725         $LCTL set_param fail_loc=0
18726         # The guard is current the largest FID holder
18727         touch $myDIR/guard
18728         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18729                     tr -d '[')
18730         local IDX=$(($SEQ % 64))
18731
18732         do_facet $SINGLEMDS sync
18733         # Make sure journal flushed.
18734         sleep 6
18735         local blk1=$(do_facet $SINGLEMDS \
18736                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18737                      grep Blockcount | awk '{print $4}')
18738
18739         # Remove old files, some OI blocks will become idle.
18740         unlinkmany $myDIR/t- 20000
18741         rm -f $myDIR/guard
18742         # The OI file should become empty now
18743
18744         # Create new files, idle OI blocks should be reused.
18745         createmany -o $myDIR/t- 2000
18746         do_facet $SINGLEMDS sync
18747         # Make sure journal flushed.
18748         sleep 6
18749         local blk2=$(do_facet $SINGLEMDS \
18750                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18751                      grep Blockcount | awk '{print $4}')
18752
18753         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18754 }
18755 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18756
18757 test_229() { # LU-2482, LU-3448
18758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18759         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18760         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18761                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18762
18763         rm -f $DIR/$tfile
18764
18765         # Create a file with a released layout and stripe count 2.
18766         $MULTIOP $DIR/$tfile H2c ||
18767                 error "failed to create file with released layout"
18768
18769         $LFS getstripe -v $DIR/$tfile
18770
18771         local pattern=$($LFS getstripe -L $DIR/$tfile)
18772         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18773
18774         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18775                 error "getstripe"
18776         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18777         stat $DIR/$tfile || error "failed to stat released file"
18778
18779         chown $RUNAS_ID $DIR/$tfile ||
18780                 error "chown $RUNAS_ID $DIR/$tfile failed"
18781
18782         chgrp $RUNAS_ID $DIR/$tfile ||
18783                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18784
18785         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18786         rm $DIR/$tfile || error "failed to remove released file"
18787 }
18788 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18789
18790 test_230a() {
18791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18792         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18793         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18794                 skip "Need MDS version at least 2.11.52"
18795
18796         local MDTIDX=1
18797
18798         test_mkdir $DIR/$tdir
18799         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18800         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18801         [ $mdt_idx -ne 0 ] &&
18802                 error "create local directory on wrong MDT $mdt_idx"
18803
18804         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18805                         error "create remote directory failed"
18806         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18807         [ $mdt_idx -ne $MDTIDX ] &&
18808                 error "create remote directory on wrong MDT $mdt_idx"
18809
18810         createmany -o $DIR/$tdir/test_230/t- 10 ||
18811                 error "create files on remote directory failed"
18812         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18813         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18814         rm -r $DIR/$tdir || error "unlink remote directory failed"
18815 }
18816 run_test 230a "Create remote directory and files under the remote directory"
18817
18818 test_230b() {
18819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18820         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18821         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18822                 skip "Need MDS version at least 2.11.52"
18823
18824         local MDTIDX=1
18825         local mdt_index
18826         local i
18827         local file
18828         local pid
18829         local stripe_count
18830         local migrate_dir=$DIR/$tdir/migrate_dir
18831         local other_dir=$DIR/$tdir/other_dir
18832
18833         test_mkdir $DIR/$tdir
18834         test_mkdir -i0 -c1 $migrate_dir
18835         test_mkdir -i0 -c1 $other_dir
18836         for ((i=0; i<10; i++)); do
18837                 mkdir -p $migrate_dir/dir_${i}
18838                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18839                         error "create files under remote dir failed $i"
18840         done
18841
18842         cp /etc/passwd $migrate_dir/$tfile
18843         cp /etc/passwd $other_dir/$tfile
18844         chattr +SAD $migrate_dir
18845         chattr +SAD $migrate_dir/$tfile
18846
18847         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18848         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18849         local old_dir_mode=$(stat -c%f $migrate_dir)
18850         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18851
18852         mkdir -p $migrate_dir/dir_default_stripe2
18853         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18854         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18855
18856         mkdir -p $other_dir
18857         ln $migrate_dir/$tfile $other_dir/luna
18858         ln $migrate_dir/$tfile $migrate_dir/sofia
18859         ln $other_dir/$tfile $migrate_dir/david
18860         ln -s $migrate_dir/$tfile $other_dir/zachary
18861         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18862         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18863
18864         local len
18865         local lnktgt
18866
18867         # inline symlink
18868         for len in 58 59 60; do
18869                 lnktgt=$(str_repeat 'l' $len)
18870                 touch $migrate_dir/$lnktgt
18871                 ln -s $lnktgt $migrate_dir/${len}char_ln
18872         done
18873
18874         # PATH_MAX
18875         for len in 4094 4095; do
18876                 lnktgt=$(str_repeat 'l' $len)
18877                 ln -s $lnktgt $migrate_dir/${len}char_ln
18878         done
18879
18880         # NAME_MAX
18881         for len in 254 255; do
18882                 touch $migrate_dir/$(str_repeat 'l' $len)
18883         done
18884
18885         $LFS migrate -m $MDTIDX $migrate_dir ||
18886                 error "fails on migrating remote dir to MDT1"
18887
18888         echo "migratate to MDT1, then checking.."
18889         for ((i = 0; i < 10; i++)); do
18890                 for file in $(find $migrate_dir/dir_${i}); do
18891                         mdt_index=$($LFS getstripe -m $file)
18892                         # broken symlink getstripe will fail
18893                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18894                                 error "$file is not on MDT${MDTIDX}"
18895                 done
18896         done
18897
18898         # the multiple link file should still in MDT0
18899         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18900         [ $mdt_index == 0 ] ||
18901                 error "$file is not on MDT${MDTIDX}"
18902
18903         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18904         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18905                 error " expect $old_dir_flag get $new_dir_flag"
18906
18907         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18908         [ "$old_file_flag" = "$new_file_flag" ] ||
18909                 error " expect $old_file_flag get $new_file_flag"
18910
18911         local new_dir_mode=$(stat -c%f $migrate_dir)
18912         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18913                 error "expect mode $old_dir_mode get $new_dir_mode"
18914
18915         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18916         [ "$old_file_mode" = "$new_file_mode" ] ||
18917                 error "expect mode $old_file_mode get $new_file_mode"
18918
18919         diff /etc/passwd $migrate_dir/$tfile ||
18920                 error "$tfile different after migration"
18921
18922         diff /etc/passwd $other_dir/luna ||
18923                 error "luna different after migration"
18924
18925         diff /etc/passwd $migrate_dir/sofia ||
18926                 error "sofia different after migration"
18927
18928         diff /etc/passwd $migrate_dir/david ||
18929                 error "david different after migration"
18930
18931         diff /etc/passwd $other_dir/zachary ||
18932                 error "zachary different after migration"
18933
18934         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18935                 error "${tfile}_ln different after migration"
18936
18937         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18938                 error "${tfile}_ln_other different after migration"
18939
18940         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18941         [ $stripe_count = 2 ] ||
18942                 error "dir strpe_count $d != 2 after migration."
18943
18944         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18945         [ $stripe_count = 2 ] ||
18946                 error "file strpe_count $d != 2 after migration."
18947
18948         #migrate back to MDT0
18949         MDTIDX=0
18950
18951         $LFS migrate -m $MDTIDX $migrate_dir ||
18952                 error "fails on migrating remote dir to MDT0"
18953
18954         echo "migrate back to MDT0, checking.."
18955         for file in $(find $migrate_dir); do
18956                 mdt_index=$($LFS getstripe -m $file)
18957                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18958                         error "$file is not on MDT${MDTIDX}"
18959         done
18960
18961         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18962         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18963                 error " expect $old_dir_flag get $new_dir_flag"
18964
18965         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18966         [ "$old_file_flag" = "$new_file_flag" ] ||
18967                 error " expect $old_file_flag get $new_file_flag"
18968
18969         local new_dir_mode=$(stat -c%f $migrate_dir)
18970         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18971                 error "expect mode $old_dir_mode get $new_dir_mode"
18972
18973         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18974         [ "$old_file_mode" = "$new_file_mode" ] ||
18975                 error "expect mode $old_file_mode get $new_file_mode"
18976
18977         diff /etc/passwd ${migrate_dir}/$tfile ||
18978                 error "$tfile different after migration"
18979
18980         diff /etc/passwd ${other_dir}/luna ||
18981                 error "luna different after migration"
18982
18983         diff /etc/passwd ${migrate_dir}/sofia ||
18984                 error "sofia different after migration"
18985
18986         diff /etc/passwd ${other_dir}/zachary ||
18987                 error "zachary different after migration"
18988
18989         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18990                 error "${tfile}_ln different after migration"
18991
18992         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18993                 error "${tfile}_ln_other different after migration"
18994
18995         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18996         [ $stripe_count = 2 ] ||
18997                 error "dir strpe_count $d != 2 after migration."
18998
18999         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19000         [ $stripe_count = 2 ] ||
19001                 error "file strpe_count $d != 2 after migration."
19002
19003         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19004 }
19005 run_test 230b "migrate directory"
19006
19007 test_230c() {
19008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19009         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19010         remote_mds_nodsh && skip "remote MDS with nodsh"
19011         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19012                 skip "Need MDS version at least 2.11.52"
19013
19014         local MDTIDX=1
19015         local total=3
19016         local mdt_index
19017         local file
19018         local migrate_dir=$DIR/$tdir/migrate_dir
19019
19020         #If migrating directory fails in the middle, all entries of
19021         #the directory is still accessiable.
19022         test_mkdir $DIR/$tdir
19023         test_mkdir -i0 -c1 $migrate_dir
19024         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19025         stat $migrate_dir
19026         createmany -o $migrate_dir/f $total ||
19027                 error "create files under ${migrate_dir} failed"
19028
19029         # fail after migrating top dir, and this will fail only once, so the
19030         # first sub file migration will fail (currently f3), others succeed.
19031         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19032         do_facet mds1 lctl set_param fail_loc=0x1801
19033         local t=$(ls $migrate_dir | wc -l)
19034         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19035                 error "migrate should fail"
19036         local u=$(ls $migrate_dir | wc -l)
19037         [ "$u" == "$t" ] || error "$u != $t during migration"
19038
19039         # add new dir/file should succeed
19040         mkdir $migrate_dir/dir ||
19041                 error "mkdir failed under migrating directory"
19042         touch $migrate_dir/file ||
19043                 error "create file failed under migrating directory"
19044
19045         # add file with existing name should fail
19046         for file in $migrate_dir/f*; do
19047                 stat $file > /dev/null || error "stat $file failed"
19048                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19049                         error "open(O_CREAT|O_EXCL) $file should fail"
19050                 $MULTIOP $file m && error "create $file should fail"
19051                 touch $DIR/$tdir/remote_dir/$tfile ||
19052                         error "touch $tfile failed"
19053                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19054                         error "link $file should fail"
19055                 mdt_index=$($LFS getstripe -m $file)
19056                 if [ $mdt_index == 0 ]; then
19057                         # file failed to migrate is not allowed to rename to
19058                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19059                                 error "rename to $file should fail"
19060                 else
19061                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19062                                 error "rename to $file failed"
19063                 fi
19064                 echo hello >> $file || error "write $file failed"
19065         done
19066
19067         # resume migration with different options should fail
19068         $LFS migrate -m 0 $migrate_dir &&
19069                 error "migrate -m 0 $migrate_dir should fail"
19070
19071         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19072                 error "migrate -c 2 $migrate_dir should fail"
19073
19074         # resume migration should succeed
19075         $LFS migrate -m $MDTIDX $migrate_dir ||
19076                 error "migrate $migrate_dir failed"
19077
19078         echo "Finish migration, then checking.."
19079         for file in $(find $migrate_dir); do
19080                 mdt_index=$($LFS getstripe -m $file)
19081                 [ $mdt_index == $MDTIDX ] ||
19082                         error "$file is not on MDT${MDTIDX}"
19083         done
19084
19085         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19086 }
19087 run_test 230c "check directory accessiblity if migration failed"
19088
19089 test_230d() {
19090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19091         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19092         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19093                 skip "Need MDS version at least 2.11.52"
19094         # LU-11235
19095         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19096
19097         local migrate_dir=$DIR/$tdir/migrate_dir
19098         local old_index
19099         local new_index
19100         local old_count
19101         local new_count
19102         local new_hash
19103         local mdt_index
19104         local i
19105         local j
19106
19107         old_index=$((RANDOM % MDSCOUNT))
19108         old_count=$((MDSCOUNT - old_index))
19109         new_index=$((RANDOM % MDSCOUNT))
19110         new_count=$((MDSCOUNT - new_index))
19111         new_hash=1 # for all_char
19112
19113         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19114         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19115
19116         test_mkdir $DIR/$tdir
19117         test_mkdir -i $old_index -c $old_count $migrate_dir
19118
19119         for ((i=0; i<100; i++)); do
19120                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19121                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19122                         error "create files under remote dir failed $i"
19123         done
19124
19125         echo -n "Migrate from MDT$old_index "
19126         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19127         echo -n "to MDT$new_index"
19128         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19129         echo
19130
19131         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19132         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19133                 error "migrate remote dir error"
19134
19135         echo "Finish migration, then checking.."
19136         for file in $(find $migrate_dir); do
19137                 mdt_index=$($LFS getstripe -m $file)
19138                 if [ $mdt_index -lt $new_index ] ||
19139                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19140                         error "$file is on MDT$mdt_index"
19141                 fi
19142         done
19143
19144         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19145 }
19146 run_test 230d "check migrate big directory"
19147
19148 test_230e() {
19149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19150         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19151         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19152                 skip "Need MDS version at least 2.11.52"
19153
19154         local i
19155         local j
19156         local a_fid
19157         local b_fid
19158
19159         mkdir -p $DIR/$tdir
19160         mkdir $DIR/$tdir/migrate_dir
19161         mkdir $DIR/$tdir/other_dir
19162         touch $DIR/$tdir/migrate_dir/a
19163         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19164         ls $DIR/$tdir/other_dir
19165
19166         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19167                 error "migrate dir fails"
19168
19169         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19170         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19171
19172         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19173         [ $mdt_index == 0 ] || error "a is not on MDT0"
19174
19175         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19176                 error "migrate dir fails"
19177
19178         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19179         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19180
19181         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19182         [ $mdt_index == 1 ] || error "a is not on MDT1"
19183
19184         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19185         [ $mdt_index == 1 ] || error "b is not on MDT1"
19186
19187         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19188         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19189
19190         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19191
19192         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19193 }
19194 run_test 230e "migrate mulitple local link files"
19195
19196 test_230f() {
19197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19198         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19199         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19200                 skip "Need MDS version at least 2.11.52"
19201
19202         local a_fid
19203         local ln_fid
19204
19205         mkdir -p $DIR/$tdir
19206         mkdir $DIR/$tdir/migrate_dir
19207         $LFS mkdir -i1 $DIR/$tdir/other_dir
19208         touch $DIR/$tdir/migrate_dir/a
19209         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19210         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19211         ls $DIR/$tdir/other_dir
19212
19213         # a should be migrated to MDT1, since no other links on MDT0
19214         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19215                 error "#1 migrate dir fails"
19216         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19217         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19218         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19219         [ $mdt_index == 1 ] || error "a is not on MDT1"
19220
19221         # a should stay on MDT1, because it is a mulitple link file
19222         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19223                 error "#2 migrate dir fails"
19224         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19225         [ $mdt_index == 1 ] || error "a is not on MDT1"
19226
19227         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19228                 error "#3 migrate dir fails"
19229
19230         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19231         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19232         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19233
19234         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19235         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19236
19237         # a should be migrated to MDT0, since no other links on MDT1
19238         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19239                 error "#4 migrate dir fails"
19240         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19241         [ $mdt_index == 0 ] || error "a is not on MDT0"
19242
19243         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19244 }
19245 run_test 230f "migrate mulitple remote link files"
19246
19247 test_230g() {
19248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19249         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19250         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19251                 skip "Need MDS version at least 2.11.52"
19252
19253         mkdir -p $DIR/$tdir/migrate_dir
19254
19255         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19256                 error "migrating dir to non-exist MDT succeeds"
19257         true
19258 }
19259 run_test 230g "migrate dir to non-exist MDT"
19260
19261 test_230h() {
19262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19263         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19264         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19265                 skip "Need MDS version at least 2.11.52"
19266
19267         local mdt_index
19268
19269         mkdir -p $DIR/$tdir/migrate_dir
19270
19271         $LFS migrate -m1 $DIR &&
19272                 error "migrating mountpoint1 should fail"
19273
19274         $LFS migrate -m1 $DIR/$tdir/.. &&
19275                 error "migrating mountpoint2 should fail"
19276
19277         # same as mv
19278         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19279                 error "migrating $tdir/migrate_dir/.. should fail"
19280
19281         true
19282 }
19283 run_test 230h "migrate .. and root"
19284
19285 test_230i() {
19286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19287         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19288         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19289                 skip "Need MDS version at least 2.11.52"
19290
19291         mkdir -p $DIR/$tdir/migrate_dir
19292
19293         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19294                 error "migration fails with a tailing slash"
19295
19296         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19297                 error "migration fails with two tailing slashes"
19298 }
19299 run_test 230i "lfs migrate -m tolerates trailing slashes"
19300
19301 test_230j() {
19302         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19303         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19304                 skip "Need MDS version at least 2.11.52"
19305
19306         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19307         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19308                 error "create $tfile failed"
19309         cat /etc/passwd > $DIR/$tdir/$tfile
19310
19311         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19312
19313         cmp /etc/passwd $DIR/$tdir/$tfile ||
19314                 error "DoM file mismatch after migration"
19315 }
19316 run_test 230j "DoM file data not changed after dir migration"
19317
19318 test_230k() {
19319         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19320         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19321                 skip "Need MDS version at least 2.11.56"
19322
19323         local total=20
19324         local files_on_starting_mdt=0
19325
19326         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19327         $LFS getdirstripe $DIR/$tdir
19328         for i in $(seq $total); do
19329                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19330                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19331                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19332         done
19333
19334         echo "$files_on_starting_mdt files on MDT0"
19335
19336         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19337         $LFS getdirstripe $DIR/$tdir
19338
19339         files_on_starting_mdt=0
19340         for i in $(seq $total); do
19341                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19342                         error "file $tfile.$i mismatch after migration"
19343                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19344                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19345         done
19346
19347         echo "$files_on_starting_mdt files on MDT1 after migration"
19348         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19349
19350         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19351         $LFS getdirstripe $DIR/$tdir
19352
19353         files_on_starting_mdt=0
19354         for i in $(seq $total); do
19355                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19356                         error "file $tfile.$i mismatch after 2nd migration"
19357                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19358                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19359         done
19360
19361         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19362         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19363
19364         true
19365 }
19366 run_test 230k "file data not changed after dir migration"
19367
19368 test_230l() {
19369         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19370         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19371                 skip "Need MDS version at least 2.11.56"
19372
19373         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19374         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19375                 error "create files under remote dir failed $i"
19376         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19377 }
19378 run_test 230l "readdir between MDTs won't crash"
19379
19380 test_230m() {
19381         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19382         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19383                 skip "Need MDS version at least 2.11.56"
19384
19385         local MDTIDX=1
19386         local mig_dir=$DIR/$tdir/migrate_dir
19387         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19388         local shortstr="b"
19389         local val
19390
19391         echo "Creating files and dirs with xattrs"
19392         test_mkdir $DIR/$tdir
19393         test_mkdir -i0 -c1 $mig_dir
19394         mkdir $mig_dir/dir
19395         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19396                 error "cannot set xattr attr1 on dir"
19397         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19398                 error "cannot set xattr attr2 on dir"
19399         touch $mig_dir/dir/f0
19400         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19401                 error "cannot set xattr attr1 on file"
19402         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19403                 error "cannot set xattr attr2 on file"
19404         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19405         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19406         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19407         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19408         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19409         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19410         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19411         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19412         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19413
19414         echo "Migrating to MDT1"
19415         $LFS migrate -m $MDTIDX $mig_dir ||
19416                 error "fails on migrating dir to MDT1"
19417
19418         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19419         echo "Checking xattrs"
19420         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19421         [ "$val" = $longstr ] ||
19422                 error "expecting xattr1 $longstr on dir, found $val"
19423         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19424         [ "$val" = $shortstr ] ||
19425                 error "expecting xattr2 $shortstr on dir, found $val"
19426         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19427         [ "$val" = $longstr ] ||
19428                 error "expecting xattr1 $longstr on file, found $val"
19429         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19430         [ "$val" = $shortstr ] ||
19431                 error "expecting xattr2 $shortstr on file, found $val"
19432 }
19433 run_test 230m "xattrs not changed after dir migration"
19434
19435 test_230n() {
19436         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19437         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19438                 skip "Need MDS version at least 2.13.53"
19439
19440         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19441         cat /etc/hosts > $DIR/$tdir/$tfile
19442         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19443         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19444
19445         cmp /etc/hosts $DIR/$tdir/$tfile ||
19446                 error "File data mismatch after migration"
19447 }
19448 run_test 230n "Dir migration with mirrored file"
19449
19450 test_230o() {
19451         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19452         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19453                 skip "Need MDS version at least 2.13.52"
19454
19455         local mdts=$(comma_list $(mdts_nodes))
19456         local timeout=100
19457         local restripe_status
19458         local delta
19459         local i
19460
19461         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19462
19463         # in case "crush" hash type is not set
19464         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19465
19466         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19467                            mdt.*MDT0000.enable_dir_restripe)
19468         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19469         stack_trap "do_nodes $mdts $LCTL set_param \
19470                     mdt.*.enable_dir_restripe=$restripe_status"
19471
19472         mkdir $DIR/$tdir
19473         createmany -m $DIR/$tdir/f 100 ||
19474                 error "create files under remote dir failed $i"
19475         createmany -d $DIR/$tdir/d 100 ||
19476                 error "create dirs under remote dir failed $i"
19477
19478         for i in $(seq 2 $MDSCOUNT); do
19479                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19480                 $LFS setdirstripe -c $i $DIR/$tdir ||
19481                         error "split -c $i $tdir failed"
19482                 wait_update $HOSTNAME \
19483                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19484                         error "dir split not finished"
19485                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19486                         awk '/migrate/ {sum += $2} END { print sum }')
19487                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19488                 # delta is around total_files/stripe_count
19489                 (( $delta < 200 / (i - 1) + 4 )) ||
19490                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19491         done
19492 }
19493 run_test 230o "dir split"
19494
19495 test_230p() {
19496         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19497         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19498                 skip "Need MDS version at least 2.13.52"
19499
19500         local mdts=$(comma_list $(mdts_nodes))
19501         local timeout=100
19502         local restripe_status
19503         local delta
19504         local i
19505
19506         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19507
19508         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19509
19510         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19511                            mdt.*MDT0000.enable_dir_restripe)
19512         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19513         stack_trap "do_nodes $mdts $LCTL set_param \
19514                     mdt.*.enable_dir_restripe=$restripe_status"
19515
19516         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19517         createmany -m $DIR/$tdir/f 100 ||
19518                 error "create files under remote dir failed $i"
19519         createmany -d $DIR/$tdir/d 100 ||
19520                 error "create dirs under remote dir failed $i"
19521
19522         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19523                 local mdt_hash="crush"
19524
19525                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19526                 $LFS setdirstripe -c $i $DIR/$tdir ||
19527                         error "split -c $i $tdir failed"
19528                 [ $i -eq 1 ] && mdt_hash="none"
19529                 wait_update $HOSTNAME \
19530                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19531                         error "dir merge not finished"
19532                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19533                         awk '/migrate/ {sum += $2} END { print sum }')
19534                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19535                 # delta is around total_files/stripe_count
19536                 (( $delta < 200 / i + 4 )) ||
19537                         error "$delta files migrated >= $((200 / i + 4))"
19538         done
19539 }
19540 run_test 230p "dir merge"
19541
19542 test_230q() {
19543         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19544         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19545                 skip "Need MDS version at least 2.13.52"
19546
19547         local mdts=$(comma_list $(mdts_nodes))
19548         local saved_threshold=$(do_facet mds1 \
19549                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19550         local saved_delta=$(do_facet mds1 \
19551                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19552         local threshold=100
19553         local delta=2
19554         local total=0
19555         local stripe_count=0
19556         local stripe_index
19557         local nr_files
19558         local create
19559
19560         # test with fewer files on ZFS
19561         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19562
19563         stack_trap "do_nodes $mdts $LCTL set_param \
19564                     mdt.*.dir_split_count=$saved_threshold"
19565         stack_trap "do_nodes $mdts $LCTL set_param \
19566                     mdt.*.dir_split_delta=$saved_delta"
19567         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19568         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19569         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19570         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19571         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19572         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19573
19574         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19575         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19576
19577         create=$((threshold * 3 / 2))
19578         while [ $stripe_count -lt $MDSCOUNT ]; do
19579                 createmany -m $DIR/$tdir/f $total $create ||
19580                         error "create sub files failed"
19581                 stat $DIR/$tdir > /dev/null
19582                 total=$((total + create))
19583                 stripe_count=$((stripe_count + delta))
19584                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19585
19586                 wait_update $HOSTNAME \
19587                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19588                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19589
19590                 wait_update $HOSTNAME \
19591                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19592                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19593
19594                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19595                 echo "$nr_files/$total files on MDT$stripe_index after split"
19596                 # allow 10% margin of imbalance with crush hash
19597                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19598                         error "$nr_files files on MDT$stripe_index after split"
19599
19600                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19601                 [ $nr_files -eq $total ] ||
19602                         error "total sub files $nr_files != $total"
19603         done
19604 }
19605 run_test 230q "dir auto split"
19606
19607 test_230r() {
19608         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19609         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19610         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19611                 skip "Need MDS version at least 2.13.54"
19612
19613         # maximum amount of local locks:
19614         # parent striped dir - 2 locks
19615         # new stripe in parent to migrate to - 1 lock
19616         # source and target - 2 locks
19617         # Total 5 locks for regular file
19618         mkdir -p $DIR/$tdir
19619         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19620         touch $DIR/$tdir/dir1/eee
19621
19622         # create 4 hardlink for 4 more locks
19623         # Total: 9 locks > RS_MAX_LOCKS (8)
19624         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19625         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19626         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19627         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19628         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19629         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19630         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19631         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19632
19633         cancel_lru_locks mdc
19634
19635         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19636                 error "migrate dir fails"
19637
19638         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19639 }
19640 run_test 230r "migrate with too many local locks"
19641
19642 test_230s() {
19643         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19644                 skip "Need MDS version at least 2.13.57"
19645
19646         local mdts=$(comma_list $(mdts_nodes))
19647         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19648                                 mdt.*MDT0000.enable_dir_restripe)
19649
19650         stack_trap "do_nodes $mdts $LCTL set_param \
19651                     mdt.*.enable_dir_restripe=$restripe_status"
19652
19653         local st
19654         for st in 0 1; do
19655                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19656                 test_mkdir $DIR/$tdir
19657                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19658                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19659                 rmdir $DIR/$tdir
19660         done
19661 }
19662 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19663
19664 test_230t()
19665 {
19666         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19667         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19668                 skip "Need MDS version at least 2.14.50"
19669
19670         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19671         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19672         $LFS project -p 1 -s $DIR/$tdir ||
19673                 error "set $tdir project id failed"
19674         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19675                 error "set subdir project id failed"
19676         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19677 }
19678 run_test 230t "migrate directory with project ID set"
19679
19680 test_231a()
19681 {
19682         # For simplicity this test assumes that max_pages_per_rpc
19683         # is the same across all OSCs
19684         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19685         local bulk_size=$((max_pages * PAGE_SIZE))
19686         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19687                                        head -n 1)
19688
19689         mkdir -p $DIR/$tdir
19690         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19691                 error "failed to set stripe with -S ${brw_size}M option"
19692
19693         # clear the OSC stats
19694         $LCTL set_param osc.*.stats=0 &>/dev/null
19695         stop_writeback
19696
19697         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19698         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19699                 oflag=direct &>/dev/null || error "dd failed"
19700
19701         sync; sleep 1; sync # just to be safe
19702         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19703         if [ x$nrpcs != "x1" ]; then
19704                 $LCTL get_param osc.*.stats
19705                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19706         fi
19707
19708         start_writeback
19709         # Drop the OSC cache, otherwise we will read from it
19710         cancel_lru_locks osc
19711
19712         # clear the OSC stats
19713         $LCTL set_param osc.*.stats=0 &>/dev/null
19714
19715         # Client reads $bulk_size.
19716         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19717                 iflag=direct &>/dev/null || error "dd failed"
19718
19719         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19720         if [ x$nrpcs != "x1" ]; then
19721                 $LCTL get_param osc.*.stats
19722                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19723         fi
19724 }
19725 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19726
19727 test_231b() {
19728         mkdir -p $DIR/$tdir
19729         local i
19730         for i in {0..1023}; do
19731                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19732                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19733                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19734         done
19735         sync
19736 }
19737 run_test 231b "must not assert on fully utilized OST request buffer"
19738
19739 test_232a() {
19740         mkdir -p $DIR/$tdir
19741         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19742
19743         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19744         do_facet ost1 $LCTL set_param fail_loc=0x31c
19745
19746         # ignore dd failure
19747         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19748
19749         do_facet ost1 $LCTL set_param fail_loc=0
19750         umount_client $MOUNT || error "umount failed"
19751         mount_client $MOUNT || error "mount failed"
19752         stop ost1 || error "cannot stop ost1"
19753         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19754 }
19755 run_test 232a "failed lock should not block umount"
19756
19757 test_232b() {
19758         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19759                 skip "Need MDS version at least 2.10.58"
19760
19761         mkdir -p $DIR/$tdir
19762         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19763         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19764         sync
19765         cancel_lru_locks osc
19766
19767         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19768         do_facet ost1 $LCTL set_param fail_loc=0x31c
19769
19770         # ignore failure
19771         $LFS data_version $DIR/$tdir/$tfile || true
19772
19773         do_facet ost1 $LCTL set_param fail_loc=0
19774         umount_client $MOUNT || error "umount failed"
19775         mount_client $MOUNT || error "mount failed"
19776         stop ost1 || error "cannot stop ost1"
19777         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19778 }
19779 run_test 232b "failed data version lock should not block umount"
19780
19781 test_233a() {
19782         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19783                 skip "Need MDS version at least 2.3.64"
19784         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19785
19786         local fid=$($LFS path2fid $MOUNT)
19787
19788         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19789                 error "cannot access $MOUNT using its FID '$fid'"
19790 }
19791 run_test 233a "checking that OBF of the FS root succeeds"
19792
19793 test_233b() {
19794         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19795                 skip "Need MDS version at least 2.5.90"
19796         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19797
19798         local fid=$($LFS path2fid $MOUNT/.lustre)
19799
19800         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19801                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19802
19803         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19804         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19805                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19806 }
19807 run_test 233b "checking that OBF of the FS .lustre succeeds"
19808
19809 test_234() {
19810         local p="$TMP/sanityN-$TESTNAME.parameters"
19811         save_lustre_params client "llite.*.xattr_cache" > $p
19812         lctl set_param llite.*.xattr_cache 1 ||
19813                 skip_env "xattr cache is not supported"
19814
19815         mkdir -p $DIR/$tdir || error "mkdir failed"
19816         touch $DIR/$tdir/$tfile || error "touch failed"
19817         # OBD_FAIL_LLITE_XATTR_ENOMEM
19818         $LCTL set_param fail_loc=0x1405
19819         getfattr -n user.attr $DIR/$tdir/$tfile &&
19820                 error "getfattr should have failed with ENOMEM"
19821         $LCTL set_param fail_loc=0x0
19822         rm -rf $DIR/$tdir
19823
19824         restore_lustre_params < $p
19825         rm -f $p
19826 }
19827 run_test 234 "xattr cache should not crash on ENOMEM"
19828
19829 test_235() {
19830         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19831                 skip "Need MDS version at least 2.4.52"
19832
19833         flock_deadlock $DIR/$tfile
19834         local RC=$?
19835         case $RC in
19836                 0)
19837                 ;;
19838                 124) error "process hangs on a deadlock"
19839                 ;;
19840                 *) error "error executing flock_deadlock $DIR/$tfile"
19841                 ;;
19842         esac
19843 }
19844 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19845
19846 #LU-2935
19847 test_236() {
19848         check_swap_layouts_support
19849
19850         local ref1=/etc/passwd
19851         local ref2=/etc/group
19852         local file1=$DIR/$tdir/f1
19853         local file2=$DIR/$tdir/f2
19854
19855         test_mkdir -c1 $DIR/$tdir
19856         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19857         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19858         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19859         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19860         local fd=$(free_fd)
19861         local cmd="exec $fd<>$file2"
19862         eval $cmd
19863         rm $file2
19864         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19865                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19866         cmd="exec $fd>&-"
19867         eval $cmd
19868         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19869
19870         #cleanup
19871         rm -rf $DIR/$tdir
19872 }
19873 run_test 236 "Layout swap on open unlinked file"
19874
19875 # LU-4659 linkea consistency
19876 test_238() {
19877         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19878                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19879                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19880                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19881
19882         touch $DIR/$tfile
19883         ln $DIR/$tfile $DIR/$tfile.lnk
19884         touch $DIR/$tfile.new
19885         mv $DIR/$tfile.new $DIR/$tfile
19886         local fid1=$($LFS path2fid $DIR/$tfile)
19887         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19888         local path1=$($LFS fid2path $FSNAME "$fid1")
19889         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19890         local path2=$($LFS fid2path $FSNAME "$fid2")
19891         [ $tfile.lnk == $path2 ] ||
19892                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19893         rm -f $DIR/$tfile*
19894 }
19895 run_test 238 "Verify linkea consistency"
19896
19897 test_239A() { # was test_239
19898         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19899                 skip "Need MDS version at least 2.5.60"
19900
19901         local list=$(comma_list $(mdts_nodes))
19902
19903         mkdir -p $DIR/$tdir
19904         createmany -o $DIR/$tdir/f- 5000
19905         unlinkmany $DIR/$tdir/f- 5000
19906         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19907                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19908         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19909                         osp.*MDT*.sync_in_flight" | calc_sum)
19910         [ "$changes" -eq 0 ] || error "$changes not synced"
19911 }
19912 run_test 239A "osp_sync test"
19913
19914 test_239a() { #LU-5297
19915         remote_mds_nodsh && skip "remote MDS with nodsh"
19916
19917         touch $DIR/$tfile
19918         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19919         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19920         chgrp $RUNAS_GID $DIR/$tfile
19921         wait_delete_completed
19922 }
19923 run_test 239a "process invalid osp sync record correctly"
19924
19925 test_239b() { #LU-5297
19926         remote_mds_nodsh && skip "remote MDS with nodsh"
19927
19928         touch $DIR/$tfile1
19929         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19930         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19931         chgrp $RUNAS_GID $DIR/$tfile1
19932         wait_delete_completed
19933         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19934         touch $DIR/$tfile2
19935         chgrp $RUNAS_GID $DIR/$tfile2
19936         wait_delete_completed
19937 }
19938 run_test 239b "process osp sync record with ENOMEM error correctly"
19939
19940 test_240() {
19941         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19942         remote_mds_nodsh && skip "remote MDS with nodsh"
19943
19944         mkdir -p $DIR/$tdir
19945
19946         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19947                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19948         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19949                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19950
19951         umount_client $MOUNT || error "umount failed"
19952         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19953         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19954         mount_client $MOUNT || error "failed to mount client"
19955
19956         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19957         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19958 }
19959 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19960
19961 test_241_bio() {
19962         local count=$1
19963         local bsize=$2
19964
19965         for LOOP in $(seq $count); do
19966                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19967                 cancel_lru_locks $OSC || true
19968         done
19969 }
19970
19971 test_241_dio() {
19972         local count=$1
19973         local bsize=$2
19974
19975         for LOOP in $(seq $1); do
19976                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19977                         2>/dev/null
19978         done
19979 }
19980
19981 test_241a() { # was test_241
19982         local bsize=$PAGE_SIZE
19983
19984         (( bsize < 40960 )) && bsize=40960
19985         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19986         ls -la $DIR/$tfile
19987         cancel_lru_locks $OSC
19988         test_241_bio 1000 $bsize &
19989         PID=$!
19990         test_241_dio 1000 $bsize
19991         wait $PID
19992 }
19993 run_test 241a "bio vs dio"
19994
19995 test_241b() {
19996         local bsize=$PAGE_SIZE
19997
19998         (( bsize < 40960 )) && bsize=40960
19999         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20000         ls -la $DIR/$tfile
20001         test_241_dio 1000 $bsize &
20002         PID=$!
20003         test_241_dio 1000 $bsize
20004         wait $PID
20005 }
20006 run_test 241b "dio vs dio"
20007
20008 test_242() {
20009         remote_mds_nodsh && skip "remote MDS with nodsh"
20010
20011         mkdir -p $DIR/$tdir
20012         touch $DIR/$tdir/$tfile
20013
20014         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20015         do_facet mds1 lctl set_param fail_loc=0x105
20016         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20017
20018         do_facet mds1 lctl set_param fail_loc=0
20019         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20020 }
20021 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20022
20023 test_243()
20024 {
20025         test_mkdir $DIR/$tdir
20026         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20027 }
20028 run_test 243 "various group lock tests"
20029
20030 test_244a()
20031 {
20032         test_mkdir $DIR/$tdir
20033         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20034         sendfile_grouplock $DIR/$tdir/$tfile || \
20035                 error "sendfile+grouplock failed"
20036         rm -rf $DIR/$tdir
20037 }
20038 run_test 244a "sendfile with group lock tests"
20039
20040 test_244b()
20041 {
20042         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20043
20044         local threads=50
20045         local size=$((1024*1024))
20046
20047         test_mkdir $DIR/$tdir
20048         for i in $(seq 1 $threads); do
20049                 local file=$DIR/$tdir/file_$((i / 10))
20050                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20051                 local pids[$i]=$!
20052         done
20053         for i in $(seq 1 $threads); do
20054                 wait ${pids[$i]}
20055         done
20056 }
20057 run_test 244b "multi-threaded write with group lock"
20058
20059 test_245() {
20060         local flagname="multi_mod_rpcs"
20061         local connect_data_name="max_mod_rpcs"
20062         local out
20063
20064         # check if multiple modify RPCs flag is set
20065         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20066                 grep "connect_flags:")
20067         echo "$out"
20068
20069         echo "$out" | grep -qw $flagname
20070         if [ $? -ne 0 ]; then
20071                 echo "connect flag $flagname is not set"
20072                 return
20073         fi
20074
20075         # check if multiple modify RPCs data is set
20076         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20077         echo "$out"
20078
20079         echo "$out" | grep -qw $connect_data_name ||
20080                 error "import should have connect data $connect_data_name"
20081 }
20082 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20083
20084 cleanup_247() {
20085         local submount=$1
20086
20087         trap 0
20088         umount_client $submount
20089         rmdir $submount
20090 }
20091
20092 test_247a() {
20093         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20094                 grep -q subtree ||
20095                 skip_env "Fileset feature is not supported"
20096
20097         local submount=${MOUNT}_$tdir
20098
20099         mkdir $MOUNT/$tdir
20100         mkdir -p $submount || error "mkdir $submount failed"
20101         FILESET="$FILESET/$tdir" mount_client $submount ||
20102                 error "mount $submount failed"
20103         trap "cleanup_247 $submount" EXIT
20104         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20105         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20106                 error "read $MOUNT/$tdir/$tfile failed"
20107         cleanup_247 $submount
20108 }
20109 run_test 247a "mount subdir as fileset"
20110
20111 test_247b() {
20112         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20113                 skip_env "Fileset feature is not supported"
20114
20115         local submount=${MOUNT}_$tdir
20116
20117         rm -rf $MOUNT/$tdir
20118         mkdir -p $submount || error "mkdir $submount failed"
20119         SKIP_FILESET=1
20120         FILESET="$FILESET/$tdir" mount_client $submount &&
20121                 error "mount $submount should fail"
20122         rmdir $submount
20123 }
20124 run_test 247b "mount subdir that dose not exist"
20125
20126 test_247c() {
20127         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20128                 skip_env "Fileset feature is not supported"
20129
20130         local submount=${MOUNT}_$tdir
20131
20132         mkdir -p $MOUNT/$tdir/dir1
20133         mkdir -p $submount || error "mkdir $submount failed"
20134         trap "cleanup_247 $submount" EXIT
20135         FILESET="$FILESET/$tdir" mount_client $submount ||
20136                 error "mount $submount failed"
20137         local fid=$($LFS path2fid $MOUNT/)
20138         $LFS fid2path $submount $fid && error "fid2path should fail"
20139         cleanup_247 $submount
20140 }
20141 run_test 247c "running fid2path outside subdirectory root"
20142
20143 test_247d() {
20144         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20145                 skip "Fileset feature is not supported"
20146
20147         local submount=${MOUNT}_$tdir
20148
20149         mkdir -p $MOUNT/$tdir/dir1
20150         mkdir -p $submount || error "mkdir $submount failed"
20151         FILESET="$FILESET/$tdir" mount_client $submount ||
20152                 error "mount $submount failed"
20153         trap "cleanup_247 $submount" EXIT
20154
20155         local td=$submount/dir1
20156         local fid=$($LFS path2fid $td)
20157         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20158
20159         # check that we get the same pathname back
20160         local rootpath
20161         local found
20162         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20163                 echo "$rootpath $fid"
20164                 found=$($LFS fid2path $rootpath "$fid")
20165                 [ -n "found" ] || error "fid2path should succeed"
20166                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20167         done
20168         # check wrong root path format
20169         rootpath=$submount"_wrong"
20170         found=$($LFS fid2path $rootpath "$fid")
20171         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20172
20173         cleanup_247 $submount
20174 }
20175 run_test 247d "running fid2path inside subdirectory root"
20176
20177 # LU-8037
20178 test_247e() {
20179         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20180                 grep -q subtree ||
20181                 skip "Fileset feature is not supported"
20182
20183         local submount=${MOUNT}_$tdir
20184
20185         mkdir $MOUNT/$tdir
20186         mkdir -p $submount || error "mkdir $submount failed"
20187         FILESET="$FILESET/.." mount_client $submount &&
20188                 error "mount $submount should fail"
20189         rmdir $submount
20190 }
20191 run_test 247e "mount .. as fileset"
20192
20193 test_247f() {
20194         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20195         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20196                 skip "Need at least version 2.13.52"
20197         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20198                 skip "Need at least version 2.14.50"
20199         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20200                 grep -q subtree ||
20201                 skip "Fileset feature is not supported"
20202
20203         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20204         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20205                 error "mkdir remote failed"
20206         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
20207         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20208                 error "mkdir striped failed"
20209         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20210
20211         local submount=${MOUNT}_$tdir
20212
20213         mkdir -p $submount || error "mkdir $submount failed"
20214         stack_trap "rmdir $submount"
20215
20216         local dir
20217         local stat
20218         local fileset=$FILESET
20219         local mdts=$(comma_list $(mdts_nodes))
20220
20221         stat=$(do_facet mds1 $LCTL get_param -n \
20222                 mdt.*MDT0000.enable_remote_subdir_mount)
20223         stack_trap "do_nodes $mdts $LCTL set_param \
20224                 mdt.*.enable_remote_subdir_mount=$stat"
20225
20226         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20227         stack_trap "umount_client $submount"
20228         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20229                 error "mount remote dir $dir should fail"
20230
20231         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20232                 $tdir/striped/. ; do
20233                 FILESET="$fileset/$dir" mount_client $submount ||
20234                         error "mount $dir failed"
20235                 umount_client $submount
20236         done
20237
20238         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20239         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20240                 error "mount $tdir/remote failed"
20241 }
20242 run_test 247f "mount striped or remote directory as fileset"
20243
20244 test_247g() {
20245         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20246         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20247                 skip "Need at least version 2.14.50"
20248
20249         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20250                 error "mkdir $tdir failed"
20251         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20252
20253         local submount=${MOUNT}_$tdir
20254
20255         mkdir -p $submount || error "mkdir $submount failed"
20256         stack_trap "rmdir $submount"
20257
20258         FILESET="$fileset/$tdir" mount_client $submount ||
20259                 error "mount $dir failed"
20260         stack_trap "umount $submount"
20261
20262         local mdts=$(comma_list $(mdts_nodes))
20263
20264         local nrpcs
20265
20266         stat $submount > /dev/null
20267         cancel_lru_locks $MDC
20268         stat $submount > /dev/null
20269         stat $submount/$tfile > /dev/null
20270         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20271         stat $submount/$tfile > /dev/null
20272         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20273                 awk '/getattr/ {sum += $2} END {print sum}')
20274
20275         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20276 }
20277 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20278
20279 test_248a() {
20280         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20281         [ -z "$fast_read_sav" ] && skip "no fast read support"
20282
20283         # create a large file for fast read verification
20284         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20285
20286         # make sure the file is created correctly
20287         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20288                 { rm -f $DIR/$tfile; skip "file creation error"; }
20289
20290         echo "Test 1: verify that fast read is 4 times faster on cache read"
20291
20292         # small read with fast read enabled
20293         $LCTL set_param -n llite.*.fast_read=1
20294         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20295                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20296                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20297         # small read with fast read disabled
20298         $LCTL set_param -n llite.*.fast_read=0
20299         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20300                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20301                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20302
20303         # verify that fast read is 4 times faster for cache read
20304         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20305                 error_not_in_vm "fast read was not 4 times faster: " \
20306                            "$t_fast vs $t_slow"
20307
20308         echo "Test 2: verify the performance between big and small read"
20309         $LCTL set_param -n llite.*.fast_read=1
20310
20311         # 1k non-cache read
20312         cancel_lru_locks osc
20313         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20314                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20315                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20316
20317         # 1M non-cache read
20318         cancel_lru_locks osc
20319         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20320                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20321                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20322
20323         # verify that big IO is not 4 times faster than small IO
20324         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20325                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20326
20327         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20328         rm -f $DIR/$tfile
20329 }
20330 run_test 248a "fast read verification"
20331
20332 test_248b() {
20333         # Default short_io_bytes=16384, try both smaller and larger sizes.
20334         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20335         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20336         echo "bs=53248 count=113 normal buffered write"
20337         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20338                 error "dd of initial data file failed"
20339         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20340
20341         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20342         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20343                 error "dd with sync normal writes failed"
20344         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20345
20346         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20347         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20348                 error "dd with sync small writes failed"
20349         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20350
20351         cancel_lru_locks osc
20352
20353         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20354         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20355         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20356         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20357                 iflag=direct || error "dd with O_DIRECT small read failed"
20358         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20359         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20360                 error "compare $TMP/$tfile.1 failed"
20361
20362         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20363         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20364
20365         # just to see what the maximum tunable value is, and test parsing
20366         echo "test invalid parameter 2MB"
20367         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20368                 error "too-large short_io_bytes allowed"
20369         echo "test maximum parameter 512KB"
20370         # if we can set a larger short_io_bytes, run test regardless of version
20371         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20372                 # older clients may not allow setting it this large, that's OK
20373                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20374                         skip "Need at least client version 2.13.50"
20375                 error "medium short_io_bytes failed"
20376         fi
20377         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20378         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20379
20380         echo "test large parameter 64KB"
20381         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20382         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20383
20384         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20385         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20386                 error "dd with sync large writes failed"
20387         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20388
20389         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20390         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20391         num=$((113 * 4096 / PAGE_SIZE))
20392         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20393         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20394                 error "dd with O_DIRECT large writes failed"
20395         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20396                 error "compare $DIR/$tfile.3 failed"
20397
20398         cancel_lru_locks osc
20399
20400         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20401         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20402                 error "dd with O_DIRECT large read failed"
20403         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20404                 error "compare $TMP/$tfile.2 failed"
20405
20406         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20407         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20408                 error "dd with O_DIRECT large read failed"
20409         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20410                 error "compare $TMP/$tfile.3 failed"
20411 }
20412 run_test 248b "test short_io read and write for both small and large sizes"
20413
20414 test_249() { # LU-7890
20415         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20416                 skip "Need at least version 2.8.54"
20417
20418         rm -f $DIR/$tfile
20419         $LFS setstripe -c 1 $DIR/$tfile
20420         # Offset 2T == 4k * 512M
20421         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20422                 error "dd to 2T offset failed"
20423 }
20424 run_test 249 "Write above 2T file size"
20425
20426 test_250() {
20427         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20428          && skip "no 16TB file size limit on ZFS"
20429
20430         $LFS setstripe -c 1 $DIR/$tfile
20431         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20432         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20433         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20434         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20435                 conv=notrunc,fsync && error "append succeeded"
20436         return 0
20437 }
20438 run_test 250 "Write above 16T limit"
20439
20440 test_251() {
20441         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20442
20443         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20444         #Skip once - writing the first stripe will succeed
20445         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20446         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20447                 error "short write happened"
20448
20449         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20450         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20451                 error "short read happened"
20452
20453         rm -f $DIR/$tfile
20454 }
20455 run_test 251 "Handling short read and write correctly"
20456
20457 test_252() {
20458         remote_mds_nodsh && skip "remote MDS with nodsh"
20459         remote_ost_nodsh && skip "remote OST with nodsh"
20460         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20461                 skip_env "ldiskfs only test"
20462         fi
20463
20464         local tgt
20465         local dev
20466         local out
20467         local uuid
20468         local num
20469         local gen
20470
20471         # check lr_reader on OST0000
20472         tgt=ost1
20473         dev=$(facet_device $tgt)
20474         out=$(do_facet $tgt $LR_READER $dev)
20475         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20476         echo "$out"
20477         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20478         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20479                 error "Invalid uuid returned by $LR_READER on target $tgt"
20480         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20481
20482         # check lr_reader -c on MDT0000
20483         tgt=mds1
20484         dev=$(facet_device $tgt)
20485         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20486                 skip "$LR_READER does not support additional options"
20487         fi
20488         out=$(do_facet $tgt $LR_READER -c $dev)
20489         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20490         echo "$out"
20491         num=$(echo "$out" | grep -c "mdtlov")
20492         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20493                 error "Invalid number of mdtlov clients returned by $LR_READER"
20494         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20495
20496         # check lr_reader -cr on MDT0000
20497         out=$(do_facet $tgt $LR_READER -cr $dev)
20498         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20499         echo "$out"
20500         echo "$out" | grep -q "^reply_data:$" ||
20501                 error "$LR_READER should have returned 'reply_data' section"
20502         num=$(echo "$out" | grep -c "client_generation")
20503         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20504 }
20505 run_test 252 "check lr_reader tool"
20506
20507 test_253() {
20508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20509         remote_mds_nodsh && skip "remote MDS with nodsh"
20510         remote_mgs_nodsh && skip "remote MGS with nodsh"
20511
20512         local ostidx=0
20513         local rc=0
20514         local ost_name=$(ostname_from_index $ostidx)
20515
20516         # on the mdt's osc
20517         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20518         do_facet $SINGLEMDS $LCTL get_param -n \
20519                 osp.$mdtosc_proc1.reserved_mb_high ||
20520                 skip  "remote MDS does not support reserved_mb_high"
20521
20522         rm -rf $DIR/$tdir
20523         wait_mds_ost_sync
20524         wait_delete_completed
20525         mkdir $DIR/$tdir
20526
20527         pool_add $TESTNAME || error "Pool creation failed"
20528         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20529
20530         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20531                 error "Setstripe failed"
20532
20533         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20534
20535         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20536                     grep "watermarks")
20537         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20538
20539         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20540                         osp.$mdtosc_proc1.prealloc_status)
20541         echo "prealloc_status $oa_status"
20542
20543         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20544                 error "File creation should fail"
20545
20546         #object allocation was stopped, but we still able to append files
20547         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20548                 oflag=append || error "Append failed"
20549
20550         rm -f $DIR/$tdir/$tfile.0
20551
20552         # For this test, we want to delete the files we created to go out of
20553         # space but leave the watermark, so we remain nearly out of space
20554         ost_watermarks_enospc_delete_files $tfile $ostidx
20555
20556         wait_delete_completed
20557
20558         sleep_maxage
20559
20560         for i in $(seq 10 12); do
20561                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20562                         2>/dev/null || error "File creation failed after rm"
20563         done
20564
20565         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20566                         osp.$mdtosc_proc1.prealloc_status)
20567         echo "prealloc_status $oa_status"
20568
20569         if (( oa_status != 0 )); then
20570                 error "Object allocation still disable after rm"
20571         fi
20572 }
20573 run_test 253 "Check object allocation limit"
20574
20575 test_254() {
20576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20577         remote_mds_nodsh && skip "remote MDS with nodsh"
20578         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20579                 skip "MDS does not support changelog_size"
20580
20581         local cl_user
20582         local MDT0=$(facet_svc $SINGLEMDS)
20583
20584         changelog_register || error "changelog_register failed"
20585
20586         changelog_clear 0 || error "changelog_clear failed"
20587
20588         local size1=$(do_facet $SINGLEMDS \
20589                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20590         echo "Changelog size $size1"
20591
20592         rm -rf $DIR/$tdir
20593         $LFS mkdir -i 0 $DIR/$tdir
20594         # change something
20595         mkdir -p $DIR/$tdir/pics/2008/zachy
20596         touch $DIR/$tdir/pics/2008/zachy/timestamp
20597         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20598         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20599         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20600         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20601         rm $DIR/$tdir/pics/desktop.jpg
20602
20603         local size2=$(do_facet $SINGLEMDS \
20604                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20605         echo "Changelog size after work $size2"
20606
20607         (( $size2 > $size1 )) ||
20608                 error "new Changelog size=$size2 less than old size=$size1"
20609 }
20610 run_test 254 "Check changelog size"
20611
20612 ladvise_no_type()
20613 {
20614         local type=$1
20615         local file=$2
20616
20617         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20618                 awk -F: '{print $2}' | grep $type > /dev/null
20619         if [ $? -ne 0 ]; then
20620                 return 0
20621         fi
20622         return 1
20623 }
20624
20625 ladvise_no_ioctl()
20626 {
20627         local file=$1
20628
20629         lfs ladvise -a willread $file > /dev/null 2>&1
20630         if [ $? -eq 0 ]; then
20631                 return 1
20632         fi
20633
20634         lfs ladvise -a willread $file 2>&1 |
20635                 grep "Inappropriate ioctl for device" > /dev/null
20636         if [ $? -eq 0 ]; then
20637                 return 0
20638         fi
20639         return 1
20640 }
20641
20642 percent() {
20643         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20644 }
20645
20646 # run a random read IO workload
20647 # usage: random_read_iops <filename> <filesize> <iosize>
20648 random_read_iops() {
20649         local file=$1
20650         local fsize=$2
20651         local iosize=${3:-4096}
20652
20653         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20654                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20655 }
20656
20657 drop_file_oss_cache() {
20658         local file="$1"
20659         local nodes="$2"
20660
20661         $LFS ladvise -a dontneed $file 2>/dev/null ||
20662                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20663 }
20664
20665 ladvise_willread_performance()
20666 {
20667         local repeat=10
20668         local average_origin=0
20669         local average_cache=0
20670         local average_ladvise=0
20671
20672         for ((i = 1; i <= $repeat; i++)); do
20673                 echo "Iter $i/$repeat: reading without willread hint"
20674                 cancel_lru_locks osc
20675                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20676                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20677                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20678                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20679
20680                 cancel_lru_locks osc
20681                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20682                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20683                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20684
20685                 cancel_lru_locks osc
20686                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20687                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20688                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20689                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20690                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20691         done
20692         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20693         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20694         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20695
20696         speedup_cache=$(percent $average_cache $average_origin)
20697         speedup_ladvise=$(percent $average_ladvise $average_origin)
20698
20699         echo "Average uncached read: $average_origin"
20700         echo "Average speedup with OSS cached read: " \
20701                 "$average_cache = +$speedup_cache%"
20702         echo "Average speedup with ladvise willread: " \
20703                 "$average_ladvise = +$speedup_ladvise%"
20704
20705         local lowest_speedup=20
20706         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20707                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20708                         "got $average_cache%. Skipping ladvise willread check."
20709                 return 0
20710         fi
20711
20712         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20713         # it is still good to run until then to exercise 'ladvise willread'
20714         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20715                 [ "$ost1_FSTYPE" = "zfs" ] &&
20716                 echo "osd-zfs does not support dontneed or drop_caches" &&
20717                 return 0
20718
20719         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20720         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20721                 error_not_in_vm "Speedup with willread is less than " \
20722                         "$lowest_speedup%, got $average_ladvise%"
20723 }
20724
20725 test_255a() {
20726         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20727                 skip "lustre < 2.8.54 does not support ladvise "
20728         remote_ost_nodsh && skip "remote OST with nodsh"
20729
20730         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20731
20732         ladvise_no_type willread $DIR/$tfile &&
20733                 skip "willread ladvise is not supported"
20734
20735         ladvise_no_ioctl $DIR/$tfile &&
20736                 skip "ladvise ioctl is not supported"
20737
20738         local size_mb=100
20739         local size=$((size_mb * 1048576))
20740         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20741                 error "dd to $DIR/$tfile failed"
20742
20743         lfs ladvise -a willread $DIR/$tfile ||
20744                 error "Ladvise failed with no range argument"
20745
20746         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20747                 error "Ladvise failed with no -l or -e argument"
20748
20749         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20750                 error "Ladvise failed with only -e argument"
20751
20752         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20753                 error "Ladvise failed with only -l argument"
20754
20755         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20756                 error "End offset should not be smaller than start offset"
20757
20758         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20759                 error "End offset should not be equal to start offset"
20760
20761         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20762                 error "Ladvise failed with overflowing -s argument"
20763
20764         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20765                 error "Ladvise failed with overflowing -e argument"
20766
20767         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20768                 error "Ladvise failed with overflowing -l argument"
20769
20770         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20771                 error "Ladvise succeeded with conflicting -l and -e arguments"
20772
20773         echo "Synchronous ladvise should wait"
20774         local delay=4
20775 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20776         do_nodes $(comma_list $(osts_nodes)) \
20777                 $LCTL set_param fail_val=$delay fail_loc=0x237
20778
20779         local start_ts=$SECONDS
20780         lfs ladvise -a willread $DIR/$tfile ||
20781                 error "Ladvise failed with no range argument"
20782         local end_ts=$SECONDS
20783         local inteval_ts=$((end_ts - start_ts))
20784
20785         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20786                 error "Synchronous advice didn't wait reply"
20787         fi
20788
20789         echo "Asynchronous ladvise shouldn't wait"
20790         local start_ts=$SECONDS
20791         lfs ladvise -a willread -b $DIR/$tfile ||
20792                 error "Ladvise failed with no range argument"
20793         local end_ts=$SECONDS
20794         local inteval_ts=$((end_ts - start_ts))
20795
20796         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20797                 error "Asynchronous advice blocked"
20798         fi
20799
20800         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20801         ladvise_willread_performance
20802 }
20803 run_test 255a "check 'lfs ladvise -a willread'"
20804
20805 facet_meminfo() {
20806         local facet=$1
20807         local info=$2
20808
20809         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20810 }
20811
20812 test_255b() {
20813         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20814                 skip "lustre < 2.8.54 does not support ladvise "
20815         remote_ost_nodsh && skip "remote OST with nodsh"
20816
20817         lfs setstripe -c 1 -i 0 $DIR/$tfile
20818
20819         ladvise_no_type dontneed $DIR/$tfile &&
20820                 skip "dontneed ladvise is not supported"
20821
20822         ladvise_no_ioctl $DIR/$tfile &&
20823                 skip "ladvise ioctl is not supported"
20824
20825         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20826                 [ "$ost1_FSTYPE" = "zfs" ] &&
20827                 skip "zfs-osd does not support 'ladvise dontneed'"
20828
20829         local size_mb=100
20830         local size=$((size_mb * 1048576))
20831         # In order to prevent disturbance of other processes, only check 3/4
20832         # of the memory usage
20833         local kibibytes=$((size_mb * 1024 * 3 / 4))
20834
20835         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20836                 error "dd to $DIR/$tfile failed"
20837
20838         #force write to complete before dropping OST cache & checking memory
20839         sync
20840
20841         local total=$(facet_meminfo ost1 MemTotal)
20842         echo "Total memory: $total KiB"
20843
20844         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20845         local before_read=$(facet_meminfo ost1 Cached)
20846         echo "Cache used before read: $before_read KiB"
20847
20848         lfs ladvise -a willread $DIR/$tfile ||
20849                 error "Ladvise willread failed"
20850         local after_read=$(facet_meminfo ost1 Cached)
20851         echo "Cache used after read: $after_read KiB"
20852
20853         lfs ladvise -a dontneed $DIR/$tfile ||
20854                 error "Ladvise dontneed again failed"
20855         local no_read=$(facet_meminfo ost1 Cached)
20856         echo "Cache used after dontneed ladvise: $no_read KiB"
20857
20858         if [ $total -lt $((before_read + kibibytes)) ]; then
20859                 echo "Memory is too small, abort checking"
20860                 return 0
20861         fi
20862
20863         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20864                 error "Ladvise willread should use more memory" \
20865                         "than $kibibytes KiB"
20866         fi
20867
20868         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20869                 error "Ladvise dontneed should release more memory" \
20870                         "than $kibibytes KiB"
20871         fi
20872 }
20873 run_test 255b "check 'lfs ladvise -a dontneed'"
20874
20875 test_255c() {
20876         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20877                 skip "lustre < 2.10.50 does not support lockahead"
20878
20879         local ost1_imp=$(get_osc_import_name client ost1)
20880         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20881                          cut -d'.' -f2)
20882         local count
20883         local new_count
20884         local difference
20885         local i
20886         local rc
20887
20888         test_mkdir -p $DIR/$tdir
20889         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20890
20891         #test 10 returns only success/failure
20892         i=10
20893         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20894         rc=$?
20895         if [ $rc -eq 255 ]; then
20896                 error "Ladvise test${i} failed, ${rc}"
20897         fi
20898
20899         #test 11 counts lock enqueue requests, all others count new locks
20900         i=11
20901         count=$(do_facet ost1 \
20902                 $LCTL get_param -n ost.OSS.ost.stats)
20903         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20904
20905         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20906         rc=$?
20907         if [ $rc -eq 255 ]; then
20908                 error "Ladvise test${i} failed, ${rc}"
20909         fi
20910
20911         new_count=$(do_facet ost1 \
20912                 $LCTL get_param -n ost.OSS.ost.stats)
20913         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20914                    awk '{ print $2 }')
20915
20916         difference="$((new_count - count))"
20917         if [ $difference -ne $rc ]; then
20918                 error "Ladvise test${i}, bad enqueue count, returned " \
20919                       "${rc}, actual ${difference}"
20920         fi
20921
20922         for i in $(seq 12 21); do
20923                 # If we do not do this, we run the risk of having too many
20924                 # locks and starting lock cancellation while we are checking
20925                 # lock counts.
20926                 cancel_lru_locks osc
20927
20928                 count=$($LCTL get_param -n \
20929                        ldlm.namespaces.$imp_name.lock_unused_count)
20930
20931                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20932                 rc=$?
20933                 if [ $rc -eq 255 ]; then
20934                         error "Ladvise test ${i} failed, ${rc}"
20935                 fi
20936
20937                 new_count=$($LCTL get_param -n \
20938                        ldlm.namespaces.$imp_name.lock_unused_count)
20939                 difference="$((new_count - count))"
20940
20941                 # Test 15 output is divided by 100 to map down to valid return
20942                 if [ $i -eq 15 ]; then
20943                         rc="$((rc * 100))"
20944                 fi
20945
20946                 if [ $difference -ne $rc ]; then
20947                         error "Ladvise test ${i}, bad lock count, returned " \
20948                               "${rc}, actual ${difference}"
20949                 fi
20950         done
20951
20952         #test 22 returns only success/failure
20953         i=22
20954         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20955         rc=$?
20956         if [ $rc -eq 255 ]; then
20957                 error "Ladvise test${i} failed, ${rc}"
20958         fi
20959 }
20960 run_test 255c "suite of ladvise lockahead tests"
20961
20962 test_256() {
20963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20964         remote_mds_nodsh && skip "remote MDS with nodsh"
20965         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20966         changelog_users $SINGLEMDS | grep "^cl" &&
20967                 skip "active changelog user"
20968
20969         local cl_user
20970         local cat_sl
20971         local mdt_dev
20972
20973         mdt_dev=$(mdsdevname 1)
20974         echo $mdt_dev
20975
20976         changelog_register || error "changelog_register failed"
20977
20978         rm -rf $DIR/$tdir
20979         mkdir -p $DIR/$tdir
20980
20981         changelog_clear 0 || error "changelog_clear failed"
20982
20983         # change something
20984         touch $DIR/$tdir/{1..10}
20985
20986         # stop the MDT
20987         stop $SINGLEMDS || error "Fail to stop MDT"
20988
20989         # remount the MDT
20990
20991         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20992
20993         #after mount new plainllog is used
20994         touch $DIR/$tdir/{11..19}
20995         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20996         stack_trap "rm -f $tmpfile"
20997         cat_sl=$(do_facet $SINGLEMDS "sync; \
20998                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20999                  llog_reader $tmpfile | grep -c type=1064553b")
21000         do_facet $SINGLEMDS llog_reader $tmpfile
21001
21002         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21003
21004         changelog_clear 0 || error "changelog_clear failed"
21005
21006         cat_sl=$(do_facet $SINGLEMDS "sync; \
21007                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21008                  llog_reader $tmpfile | grep -c type=1064553b")
21009
21010         if (( cat_sl == 2 )); then
21011                 error "Empty plain llog was not deleted from changelog catalog"
21012         elif (( cat_sl != 1 )); then
21013                 error "Active plain llog shouldn't be deleted from catalog"
21014         fi
21015 }
21016 run_test 256 "Check llog delete for empty and not full state"
21017
21018 test_257() {
21019         remote_mds_nodsh && skip "remote MDS with nodsh"
21020         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21021                 skip "Need MDS version at least 2.8.55"
21022
21023         test_mkdir $DIR/$tdir
21024
21025         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21026                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21027         stat $DIR/$tdir
21028
21029 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21030         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21031         local facet=mds$((mdtidx + 1))
21032         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21033         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21034
21035         stop $facet || error "stop MDS failed"
21036         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21037                 error "start MDS fail"
21038         wait_recovery_complete $facet
21039 }
21040 run_test 257 "xattr locks are not lost"
21041
21042 # Verify we take the i_mutex when security requires it
21043 test_258a() {
21044 #define OBD_FAIL_IMUTEX_SEC 0x141c
21045         $LCTL set_param fail_loc=0x141c
21046         touch $DIR/$tfile
21047         chmod u+s $DIR/$tfile
21048         chmod a+rwx $DIR/$tfile
21049         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21050         RC=$?
21051         if [ $RC -ne 0 ]; then
21052                 error "error, failed to take i_mutex, rc=$?"
21053         fi
21054         rm -f $DIR/$tfile
21055 }
21056 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21057
21058 # Verify we do NOT take the i_mutex in the normal case
21059 test_258b() {
21060 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21061         $LCTL set_param fail_loc=0x141d
21062         touch $DIR/$tfile
21063         chmod a+rwx $DIR
21064         chmod a+rw $DIR/$tfile
21065         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21066         RC=$?
21067         if [ $RC -ne 0 ]; then
21068                 error "error, took i_mutex unnecessarily, rc=$?"
21069         fi
21070         rm -f $DIR/$tfile
21071
21072 }
21073 run_test 258b "verify i_mutex security behavior"
21074
21075 test_259() {
21076         local file=$DIR/$tfile
21077         local before
21078         local after
21079
21080         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21081
21082         stack_trap "rm -f $file" EXIT
21083
21084         wait_delete_completed
21085         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21086         echo "before: $before"
21087
21088         $LFS setstripe -i 0 -c 1 $file
21089         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21090         sync_all_data
21091         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21092         echo "after write: $after"
21093
21094 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21095         do_facet ost1 $LCTL set_param fail_loc=0x2301
21096         $TRUNCATE $file 0
21097         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21098         echo "after truncate: $after"
21099
21100         stop ost1
21101         do_facet ost1 $LCTL set_param fail_loc=0
21102         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21103         sleep 2
21104         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21105         echo "after restart: $after"
21106         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21107                 error "missing truncate?"
21108
21109         return 0
21110 }
21111 run_test 259 "crash at delayed truncate"
21112
21113 test_260() {
21114 #define OBD_FAIL_MDC_CLOSE               0x806
21115         $LCTL set_param fail_loc=0x80000806
21116         touch $DIR/$tfile
21117
21118 }
21119 run_test 260 "Check mdc_close fail"
21120
21121 ### Data-on-MDT sanity tests ###
21122 test_270a() {
21123         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21124                 skip "Need MDS version at least 2.10.55 for DoM"
21125
21126         # create DoM file
21127         local dom=$DIR/$tdir/dom_file
21128         local tmp=$DIR/$tdir/tmp_file
21129
21130         mkdir -p $DIR/$tdir
21131
21132         # basic checks for DoM component creation
21133         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21134                 error "Can set MDT layout to non-first entry"
21135
21136         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21137                 error "Can define multiple entries as MDT layout"
21138
21139         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21140
21141         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21142         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21143         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21144
21145         local mdtidx=$($LFS getstripe -m $dom)
21146         local mdtname=MDT$(printf %04x $mdtidx)
21147         local facet=mds$((mdtidx + 1))
21148         local space_check=1
21149
21150         # Skip free space checks with ZFS
21151         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21152
21153         # write
21154         sync
21155         local size_tmp=$((65536 * 3))
21156         local mdtfree1=$(do_facet $facet \
21157                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21158
21159         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21160         # check also direct IO along write
21161         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21162         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21163         sync
21164         cmp $tmp $dom || error "file data is different"
21165         [ $(stat -c%s $dom) == $size_tmp ] ||
21166                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21167         if [ $space_check == 1 ]; then
21168                 local mdtfree2=$(do_facet $facet \
21169                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21170
21171                 # increase in usage from by $size_tmp
21172                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21173                         error "MDT free space wrong after write: " \
21174                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21175         fi
21176
21177         # truncate
21178         local size_dom=10000
21179
21180         $TRUNCATE $dom $size_dom
21181         [ $(stat -c%s $dom) == $size_dom ] ||
21182                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21183         if [ $space_check == 1 ]; then
21184                 mdtfree1=$(do_facet $facet \
21185                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21186                 # decrease in usage from $size_tmp to new $size_dom
21187                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21188                   $(((size_tmp - size_dom) / 1024)) ] ||
21189                         error "MDT free space is wrong after truncate: " \
21190                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21191         fi
21192
21193         # append
21194         cat $tmp >> $dom
21195         sync
21196         size_dom=$((size_dom + size_tmp))
21197         [ $(stat -c%s $dom) == $size_dom ] ||
21198                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21199         if [ $space_check == 1 ]; then
21200                 mdtfree2=$(do_facet $facet \
21201                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21202                 # increase in usage by $size_tmp from previous
21203                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21204                         error "MDT free space is wrong after append: " \
21205                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21206         fi
21207
21208         # delete
21209         rm $dom
21210         if [ $space_check == 1 ]; then
21211                 mdtfree1=$(do_facet $facet \
21212                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21213                 # decrease in usage by $size_dom from previous
21214                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21215                         error "MDT free space is wrong after removal: " \
21216                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21217         fi
21218
21219         # combined striping
21220         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21221                 error "Can't create DoM + OST striping"
21222
21223         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21224         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21225         # check also direct IO along write
21226         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21227         sync
21228         cmp $tmp $dom || error "file data is different"
21229         [ $(stat -c%s $dom) == $size_tmp ] ||
21230                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21231         rm $dom $tmp
21232
21233         return 0
21234 }
21235 run_test 270a "DoM: basic functionality tests"
21236
21237 test_270b() {
21238         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21239                 skip "Need MDS version at least 2.10.55"
21240
21241         local dom=$DIR/$tdir/dom_file
21242         local max_size=1048576
21243
21244         mkdir -p $DIR/$tdir
21245         $LFS setstripe -E $max_size -L mdt $dom
21246
21247         # truncate over the limit
21248         $TRUNCATE $dom $(($max_size + 1)) &&
21249                 error "successful truncate over the maximum size"
21250         # write over the limit
21251         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21252                 error "successful write over the maximum size"
21253         # append over the limit
21254         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21255         echo "12345" >> $dom && error "successful append over the maximum size"
21256         rm $dom
21257
21258         return 0
21259 }
21260 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21261
21262 test_270c() {
21263         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21264                 skip "Need MDS version at least 2.10.55"
21265
21266         mkdir -p $DIR/$tdir
21267         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21268
21269         # check files inherit DoM EA
21270         touch $DIR/$tdir/first
21271         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21272                 error "bad pattern"
21273         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21274                 error "bad stripe count"
21275         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21276                 error "bad stripe size"
21277
21278         # check directory inherits DoM EA and uses it as default
21279         mkdir $DIR/$tdir/subdir
21280         touch $DIR/$tdir/subdir/second
21281         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21282                 error "bad pattern in sub-directory"
21283         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21284                 error "bad stripe count in sub-directory"
21285         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21286                 error "bad stripe size in sub-directory"
21287         return 0
21288 }
21289 run_test 270c "DoM: DoM EA inheritance tests"
21290
21291 test_270d() {
21292         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21293                 skip "Need MDS version at least 2.10.55"
21294
21295         mkdir -p $DIR/$tdir
21296         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21297
21298         # inherit default DoM striping
21299         mkdir $DIR/$tdir/subdir
21300         touch $DIR/$tdir/subdir/f1
21301
21302         # change default directory striping
21303         $LFS setstripe -c 1 $DIR/$tdir/subdir
21304         touch $DIR/$tdir/subdir/f2
21305         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21306                 error "wrong default striping in file 2"
21307         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21308                 error "bad pattern in file 2"
21309         return 0
21310 }
21311 run_test 270d "DoM: change striping from DoM to RAID0"
21312
21313 test_270e() {
21314         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21315                 skip "Need MDS version at least 2.10.55"
21316
21317         mkdir -p $DIR/$tdir/dom
21318         mkdir -p $DIR/$tdir/norm
21319         DOMFILES=20
21320         NORMFILES=10
21321         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21322         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21323
21324         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21325         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21326
21327         # find DoM files by layout
21328         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21329         [ $NUM -eq  $DOMFILES ] ||
21330                 error "lfs find -L: found $NUM, expected $DOMFILES"
21331         echo "Test 1: lfs find 20 DOM files by layout: OK"
21332
21333         # there should be 1 dir with default DOM striping
21334         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21335         [ $NUM -eq  1 ] ||
21336                 error "lfs find -L: found $NUM, expected 1 dir"
21337         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21338
21339         # find DoM files by stripe size
21340         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21341         [ $NUM -eq  $DOMFILES ] ||
21342                 error "lfs find -S: found $NUM, expected $DOMFILES"
21343         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21344
21345         # find files by stripe offset except DoM files
21346         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21347         [ $NUM -eq  $NORMFILES ] ||
21348                 error "lfs find -i: found $NUM, expected $NORMFILES"
21349         echo "Test 5: lfs find no DOM files by stripe index: OK"
21350         return 0
21351 }
21352 run_test 270e "DoM: lfs find with DoM files test"
21353
21354 test_270f() {
21355         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21356                 skip "Need MDS version at least 2.10.55"
21357
21358         local mdtname=${FSNAME}-MDT0000-mdtlov
21359         local dom=$DIR/$tdir/dom_file
21360         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21361                                                 lod.$mdtname.dom_stripesize)
21362         local dom_limit=131072
21363
21364         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21365         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21366                                                 lod.$mdtname.dom_stripesize)
21367         [ ${dom_limit} -eq ${dom_current} ] ||
21368                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21369
21370         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21371         $LFS setstripe -d $DIR/$tdir
21372         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21373                 error "Can't set directory default striping"
21374
21375         # exceed maximum stripe size
21376         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21377                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21378         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21379                 error "Able to create DoM component size more than LOD limit"
21380
21381         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21382         dom_current=$(do_facet mds1 $LCTL get_param -n \
21383                                                 lod.$mdtname.dom_stripesize)
21384         [ 0 -eq ${dom_current} ] ||
21385                 error "Can't set zero DoM stripe limit"
21386         rm $dom
21387
21388         # attempt to create DoM file on server with disabled DoM should
21389         # remove DoM entry from layout and be succeed
21390         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21391                 error "Can't create DoM file (DoM is disabled)"
21392         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21393                 error "File has DoM component while DoM is disabled"
21394         rm $dom
21395
21396         # attempt to create DoM file with only DoM stripe should return error
21397         $LFS setstripe -E $dom_limit -L mdt $dom &&
21398                 error "Able to create DoM-only file while DoM is disabled"
21399
21400         # too low values to be aligned with smallest stripe size 64K
21401         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21402         dom_current=$(do_facet mds1 $LCTL get_param -n \
21403                                                 lod.$mdtname.dom_stripesize)
21404         [ 30000 -eq ${dom_current} ] &&
21405                 error "Can set too small DoM stripe limit"
21406
21407         # 64K is a minimal stripe size in Lustre, expect limit of that size
21408         [ 65536 -eq ${dom_current} ] ||
21409                 error "Limit is not set to 64K but ${dom_current}"
21410
21411         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21412         dom_current=$(do_facet mds1 $LCTL get_param -n \
21413                                                 lod.$mdtname.dom_stripesize)
21414         echo $dom_current
21415         [ 2147483648 -eq ${dom_current} ] &&
21416                 error "Can set too large DoM stripe limit"
21417
21418         do_facet mds1 $LCTL set_param -n \
21419                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21420         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21421                 error "Can't create DoM component size after limit change"
21422         do_facet mds1 $LCTL set_param -n \
21423                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21424         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21425                 error "Can't create DoM file after limit decrease"
21426         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21427                 error "Can create big DoM component after limit decrease"
21428         touch ${dom}_def ||
21429                 error "Can't create file with old default layout"
21430
21431         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21432         return 0
21433 }
21434 run_test 270f "DoM: maximum DoM stripe size checks"
21435
21436 test_270g() {
21437         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21438                 skip "Need MDS version at least 2.13.52"
21439         local dom=$DIR/$tdir/$tfile
21440
21441         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21442         local lodname=${FSNAME}-MDT0000-mdtlov
21443
21444         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21445         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21446         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21447         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21448
21449         local dom_limit=1024
21450         local dom_threshold="50%"
21451
21452         $LFS setstripe -d $DIR/$tdir
21453         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21454                 error "Can't set directory default striping"
21455
21456         do_facet mds1 $LCTL set_param -n \
21457                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21458         # set 0 threshold and create DOM file to change tunable stripesize
21459         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21460         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21461                 error "Failed to create $dom file"
21462         # now tunable dom_cur_stripesize should reach maximum
21463         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21464                                         lod.${lodname}.dom_stripesize_cur_kb)
21465         [[ $dom_current == $dom_limit ]] ||
21466                 error "Current DOM stripesize is not maximum"
21467         rm $dom
21468
21469         # set threshold for further tests
21470         do_facet mds1 $LCTL set_param -n \
21471                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21472         echo "DOM threshold is $dom_threshold free space"
21473         local dom_def
21474         local dom_set
21475         # Spoof bfree to exceed threshold
21476         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21477         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21478         for spfree in 40 20 0 15 30 55; do
21479                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21480                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21481                         error "Failed to create $dom file"
21482                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21483                                         lod.${lodname}.dom_stripesize_cur_kb)
21484                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21485                 [[ $dom_def != $dom_current ]] ||
21486                         error "Default stripe size was not changed"
21487                 if [[ $spfree > 0 ]] ; then
21488                         dom_set=$($LFS getstripe -S $dom)
21489                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21490                                 error "DOM component size is still old"
21491                 else
21492                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21493                                 error "DoM component is set with no free space"
21494                 fi
21495                 rm $dom
21496                 dom_current=$dom_def
21497         done
21498 }
21499 run_test 270g "DoM: default DoM stripe size depends on free space"
21500
21501 test_270h() {
21502         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21503                 skip "Need MDS version at least 2.13.53"
21504
21505         local mdtname=${FSNAME}-MDT0000-mdtlov
21506         local dom=$DIR/$tdir/$tfile
21507         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21508
21509         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21510         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21511
21512         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21513         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21514                 error "can't create OST file"
21515         # mirrored file with DOM entry in the second mirror
21516         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21517                 error "can't create mirror with DoM component"
21518
21519         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21520
21521         # DOM component in the middle and has other enries in the same mirror,
21522         # should succeed but lost DoM component
21523         $LFS setstripe --copy=${dom}_1 $dom ||
21524                 error "Can't create file from OST|DOM mirror layout"
21525         # check new file has no DoM layout after all
21526         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21527                 error "File has DoM component while DoM is disabled"
21528 }
21529 run_test 270h "DoM: DoM stripe removal when disabled on server"
21530
21531 test_271a() {
21532         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21533                 skip "Need MDS version at least 2.10.55"
21534
21535         local dom=$DIR/$tdir/dom
21536
21537         mkdir -p $DIR/$tdir
21538
21539         $LFS setstripe -E 1024K -L mdt $dom
21540
21541         lctl set_param -n mdc.*.stats=clear
21542         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21543         cat $dom > /dev/null
21544         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21545         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21546         ls $dom
21547         rm -f $dom
21548 }
21549 run_test 271a "DoM: data is cached for read after write"
21550
21551 test_271b() {
21552         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21553                 skip "Need MDS version at least 2.10.55"
21554
21555         local dom=$DIR/$tdir/dom
21556
21557         mkdir -p $DIR/$tdir
21558
21559         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21560
21561         lctl set_param -n mdc.*.stats=clear
21562         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21563         cancel_lru_locks mdc
21564         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21565         # second stat to check size is cached on client
21566         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21567         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21568         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21569         rm -f $dom
21570 }
21571 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21572
21573 test_271ba() {
21574         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21575                 skip "Need MDS version at least 2.10.55"
21576
21577         local dom=$DIR/$tdir/dom
21578
21579         mkdir -p $DIR/$tdir
21580
21581         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21582
21583         lctl set_param -n mdc.*.stats=clear
21584         lctl set_param -n osc.*.stats=clear
21585         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21586         cancel_lru_locks mdc
21587         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21588         # second stat to check size is cached on client
21589         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21590         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21591         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21592         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21593         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21594         rm -f $dom
21595 }
21596 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21597
21598
21599 get_mdc_stats() {
21600         local mdtidx=$1
21601         local param=$2
21602         local mdt=MDT$(printf %04x $mdtidx)
21603
21604         if [ -z $param ]; then
21605                 lctl get_param -n mdc.*$mdt*.stats
21606         else
21607                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21608         fi
21609 }
21610
21611 test_271c() {
21612         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21613                 skip "Need MDS version at least 2.10.55"
21614
21615         local dom=$DIR/$tdir/dom
21616
21617         mkdir -p $DIR/$tdir
21618
21619         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21620
21621         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21622         local facet=mds$((mdtidx + 1))
21623
21624         cancel_lru_locks mdc
21625         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21626         createmany -o $dom 1000
21627         lctl set_param -n mdc.*.stats=clear
21628         smalliomany -w $dom 1000 200
21629         get_mdc_stats $mdtidx
21630         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21631         # Each file has 1 open, 1 IO enqueues, total 2000
21632         # but now we have also +1 getxattr for security.capability, total 3000
21633         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21634         unlinkmany $dom 1000
21635
21636         cancel_lru_locks mdc
21637         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21638         createmany -o $dom 1000
21639         lctl set_param -n mdc.*.stats=clear
21640         smalliomany -w $dom 1000 200
21641         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21642         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21643         # for OPEN and IO lock.
21644         [ $((enq - enq_2)) -ge 1000 ] ||
21645                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21646         unlinkmany $dom 1000
21647         return 0
21648 }
21649 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21650
21651 cleanup_271def_tests() {
21652         trap 0
21653         rm -f $1
21654 }
21655
21656 test_271d() {
21657         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21658                 skip "Need MDS version at least 2.10.57"
21659
21660         local dom=$DIR/$tdir/dom
21661         local tmp=$TMP/$tfile
21662         trap "cleanup_271def_tests $tmp" EXIT
21663
21664         mkdir -p $DIR/$tdir
21665
21666         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21667
21668         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21669
21670         cancel_lru_locks mdc
21671         dd if=/dev/urandom of=$tmp bs=1000 count=1
21672         dd if=$tmp of=$dom bs=1000 count=1
21673         cancel_lru_locks mdc
21674
21675         cat /etc/hosts >> $tmp
21676         lctl set_param -n mdc.*.stats=clear
21677
21678         # append data to the same file it should update local page
21679         echo "Append to the same page"
21680         cat /etc/hosts >> $dom
21681         local num=$(get_mdc_stats $mdtidx ost_read)
21682         local ra=$(get_mdc_stats $mdtidx req_active)
21683         local rw=$(get_mdc_stats $mdtidx req_waittime)
21684
21685         [ -z $num ] || error "$num READ RPC occured"
21686         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21687         echo "... DONE"
21688
21689         # compare content
21690         cmp $tmp $dom || error "file miscompare"
21691
21692         cancel_lru_locks mdc
21693         lctl set_param -n mdc.*.stats=clear
21694
21695         echo "Open and read file"
21696         cat $dom > /dev/null
21697         local num=$(get_mdc_stats $mdtidx ost_read)
21698         local ra=$(get_mdc_stats $mdtidx req_active)
21699         local rw=$(get_mdc_stats $mdtidx req_waittime)
21700
21701         [ -z $num ] || error "$num READ RPC occured"
21702         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21703         echo "... DONE"
21704
21705         # compare content
21706         cmp $tmp $dom || error "file miscompare"
21707
21708         return 0
21709 }
21710 run_test 271d "DoM: read on open (1K file in reply buffer)"
21711
21712 test_271f() {
21713         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21714                 skip "Need MDS version at least 2.10.57"
21715
21716         local dom=$DIR/$tdir/dom
21717         local tmp=$TMP/$tfile
21718         trap "cleanup_271def_tests $tmp" EXIT
21719
21720         mkdir -p $DIR/$tdir
21721
21722         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21723
21724         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21725
21726         cancel_lru_locks mdc
21727         dd if=/dev/urandom of=$tmp bs=265000 count=1
21728         dd if=$tmp of=$dom bs=265000 count=1
21729         cancel_lru_locks mdc
21730         cat /etc/hosts >> $tmp
21731         lctl set_param -n mdc.*.stats=clear
21732
21733         echo "Append to the same page"
21734         cat /etc/hosts >> $dom
21735         local num=$(get_mdc_stats $mdtidx ost_read)
21736         local ra=$(get_mdc_stats $mdtidx req_active)
21737         local rw=$(get_mdc_stats $mdtidx req_waittime)
21738
21739         [ -z $num ] || error "$num READ RPC occured"
21740         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21741         echo "... DONE"
21742
21743         # compare content
21744         cmp $tmp $dom || error "file miscompare"
21745
21746         cancel_lru_locks mdc
21747         lctl set_param -n mdc.*.stats=clear
21748
21749         echo "Open and read file"
21750         cat $dom > /dev/null
21751         local num=$(get_mdc_stats $mdtidx ost_read)
21752         local ra=$(get_mdc_stats $mdtidx req_active)
21753         local rw=$(get_mdc_stats $mdtidx req_waittime)
21754
21755         [ -z $num ] && num=0
21756         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21757         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21758         echo "... DONE"
21759
21760         # compare content
21761         cmp $tmp $dom || error "file miscompare"
21762
21763         return 0
21764 }
21765 run_test 271f "DoM: read on open (200K file and read tail)"
21766
21767 test_271g() {
21768         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21769                 skip "Skipping due to old client or server version"
21770
21771         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21772         # to get layout
21773         $CHECKSTAT -t file $DIR1/$tfile
21774
21775         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21776         MULTIOP_PID=$!
21777         sleep 1
21778         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21779         $LCTL set_param fail_loc=0x80000314
21780         rm $DIR1/$tfile || error "Unlink fails"
21781         RC=$?
21782         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21783         [ $RC -eq 0 ] || error "Failed write to stale object"
21784 }
21785 run_test 271g "Discard DoM data vs client flush race"
21786
21787 test_272a() {
21788         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21789                 skip "Need MDS version at least 2.11.50"
21790
21791         local dom=$DIR/$tdir/dom
21792         mkdir -p $DIR/$tdir
21793
21794         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21795         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21796                 error "failed to write data into $dom"
21797         local old_md5=$(md5sum $dom)
21798
21799         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21800                 error "failed to migrate to the same DoM component"
21801
21802         local new_md5=$(md5sum $dom)
21803
21804         [ "$old_md5" == "$new_md5" ] ||
21805                 error "md5sum differ: $old_md5, $new_md5"
21806
21807         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21808                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21809 }
21810 run_test 272a "DoM migration: new layout with the same DOM component"
21811
21812 test_272b() {
21813         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21814                 skip "Need MDS version at least 2.11.50"
21815
21816         local dom=$DIR/$tdir/dom
21817         mkdir -p $DIR/$tdir
21818         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21819
21820         local mdtidx=$($LFS getstripe -m $dom)
21821         local mdtname=MDT$(printf %04x $mdtidx)
21822         local facet=mds$((mdtidx + 1))
21823
21824         local mdtfree1=$(do_facet $facet \
21825                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21826         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21827                 error "failed to write data into $dom"
21828         local old_md5=$(md5sum $dom)
21829         cancel_lru_locks mdc
21830         local mdtfree1=$(do_facet $facet \
21831                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21832
21833         $LFS migrate -c2 $dom ||
21834                 error "failed to migrate to the new composite layout"
21835         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21836                 error "MDT stripe was not removed"
21837
21838         cancel_lru_locks mdc
21839         local new_md5=$(md5sum $dom)
21840         [ "$old_md5" == "$new_md5" ] ||
21841                 error "$old_md5 != $new_md5"
21842
21843         # Skip free space checks with ZFS
21844         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21845                 local mdtfree2=$(do_facet $facet \
21846                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21847                 [ $mdtfree2 -gt $mdtfree1 ] ||
21848                         error "MDT space is not freed after migration"
21849         fi
21850         return 0
21851 }
21852 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21853
21854 test_272c() {
21855         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21856                 skip "Need MDS version at least 2.11.50"
21857
21858         local dom=$DIR/$tdir/$tfile
21859         mkdir -p $DIR/$tdir
21860         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21861
21862         local mdtidx=$($LFS getstripe -m $dom)
21863         local mdtname=MDT$(printf %04x $mdtidx)
21864         local facet=mds$((mdtidx + 1))
21865
21866         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21867                 error "failed to write data into $dom"
21868         local old_md5=$(md5sum $dom)
21869         cancel_lru_locks mdc
21870         local mdtfree1=$(do_facet $facet \
21871                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21872
21873         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21874                 error "failed to migrate to the new composite layout"
21875         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21876                 error "MDT stripe was not removed"
21877
21878         cancel_lru_locks mdc
21879         local new_md5=$(md5sum $dom)
21880         [ "$old_md5" == "$new_md5" ] ||
21881                 error "$old_md5 != $new_md5"
21882
21883         # Skip free space checks with ZFS
21884         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21885                 local mdtfree2=$(do_facet $facet \
21886                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21887                 [ $mdtfree2 -gt $mdtfree1 ] ||
21888                         error "MDS space is not freed after migration"
21889         fi
21890         return 0
21891 }
21892 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21893
21894 test_272d() {
21895         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21896                 skip "Need MDS version at least 2.12.55"
21897
21898         local dom=$DIR/$tdir/$tfile
21899         mkdir -p $DIR/$tdir
21900         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21901
21902         local mdtidx=$($LFS getstripe -m $dom)
21903         local mdtname=MDT$(printf %04x $mdtidx)
21904         local facet=mds$((mdtidx + 1))
21905
21906         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21907                 error "failed to write data into $dom"
21908         local old_md5=$(md5sum $dom)
21909         cancel_lru_locks mdc
21910         local mdtfree1=$(do_facet $facet \
21911                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21912
21913         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21914                 error "failed mirroring to the new composite layout"
21915         $LFS mirror resync $dom ||
21916                 error "failed mirror resync"
21917         $LFS mirror split --mirror-id 1 -d $dom ||
21918                 error "failed mirror split"
21919
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 DOM mirror deletion"
21934         fi
21935         return 0
21936 }
21937 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21938
21939 test_272e() {
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 -c 2 $dom
21946
21947         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21948                 error "failed to write data into $dom"
21949         local old_md5=$(md5sum $dom)
21950         cancel_lru_locks mdc
21951
21952         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21953                 error "failed mirroring to the DOM layout"
21954         $LFS mirror resync $dom ||
21955                 error "failed mirror resync"
21956         $LFS mirror split --mirror-id 1 -d $dom ||
21957                 error "failed mirror split"
21958
21959         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21960                 error "MDT stripe was not removed"
21961
21962         cancel_lru_locks mdc
21963         local new_md5=$(md5sum $dom)
21964         [ "$old_md5" == "$new_md5" ] ||
21965                 error "$old_md5 != $new_md5"
21966
21967         return 0
21968 }
21969 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21970
21971 test_272f() {
21972         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21973                 skip "Need MDS version at least 2.12.55"
21974
21975         local dom=$DIR/$tdir/$tfile
21976         mkdir -p $DIR/$tdir
21977         $LFS setstripe -c 2 $dom
21978
21979         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21980                 error "failed to write data into $dom"
21981         local old_md5=$(md5sum $dom)
21982         cancel_lru_locks mdc
21983
21984         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21985                 error "failed migrating to the DOM file"
21986
21987         cancel_lru_locks mdc
21988         local new_md5=$(md5sum $dom)
21989         [ "$old_md5" != "$new_md5" ] &&
21990                 error "$old_md5 != $new_md5"
21991
21992         return 0
21993 }
21994 run_test 272f "DoM migration: OST-striped file to DOM file"
21995
21996 test_273a() {
21997         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21998                 skip "Need MDS version at least 2.11.50"
21999
22000         # Layout swap cannot be done if either file has DOM component,
22001         # this will never be supported, migration should be used instead
22002
22003         local dom=$DIR/$tdir/$tfile
22004         mkdir -p $DIR/$tdir
22005
22006         $LFS setstripe -c2 ${dom}_plain
22007         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22008         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22009                 error "can swap layout with DoM component"
22010         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22011                 error "can swap layout with DoM component"
22012
22013         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22014         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22015                 error "can swap layout with DoM component"
22016         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22017                 error "can swap layout with DoM component"
22018         return 0
22019 }
22020 run_test 273a "DoM: layout swapping should fail with DOM"
22021
22022 test_273b() {
22023         mkdir -p $DIR/$tdir
22024         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22025
22026 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22027         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22028
22029         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22030 }
22031 run_test 273b "DoM: race writeback and object destroy"
22032
22033 test_275() {
22034         remote_ost_nodsh && skip "remote OST with nodsh"
22035         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22036                 skip "Need OST version >= 2.10.57"
22037
22038         local file=$DIR/$tfile
22039         local oss
22040
22041         oss=$(comma_list $(osts_nodes))
22042
22043         dd if=/dev/urandom of=$file bs=1M count=2 ||
22044                 error "failed to create a file"
22045         cancel_lru_locks osc
22046
22047         #lock 1
22048         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22049                 error "failed to read a file"
22050
22051 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22052         $LCTL set_param fail_loc=0x8000031f
22053
22054         cancel_lru_locks osc &
22055         sleep 1
22056
22057 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22058         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22059         #IO takes another lock, but matches the PENDING one
22060         #and places it to the IO RPC
22061         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22062                 error "failed to read a file with PENDING lock"
22063 }
22064 run_test 275 "Read on a canceled duplicate lock"
22065
22066 test_276() {
22067         remote_ost_nodsh && skip "remote OST with nodsh"
22068         local pid
22069
22070         do_facet ost1 "(while true; do \
22071                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22072                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22073         pid=$!
22074
22075         for LOOP in $(seq 20); do
22076                 stop ost1
22077                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22078         done
22079         kill -9 $pid
22080         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22081                 rm $TMP/sanity_276_pid"
22082 }
22083 run_test 276 "Race between mount and obd_statfs"
22084
22085 test_277() {
22086         $LCTL set_param ldlm.namespaces.*.lru_size=0
22087         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22088         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22089                         grep ^used_mb | awk '{print $2}')
22090         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22091         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22092                 oflag=direct conv=notrunc
22093         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22094                         grep ^used_mb | awk '{print $2}')
22095         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22096 }
22097 run_test 277 "Direct IO shall drop page cache"
22098
22099 test_278() {
22100         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22101         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22102         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22103                 skip "needs the same host for mdt1 mdt2" && return
22104
22105         local pid1
22106         local pid2
22107
22108 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22109         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22110         stop mds2 &
22111         pid2=$!
22112
22113         stop mds1
22114
22115         echo "Starting MDTs"
22116         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22117         wait $pid2
22118 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22119 #will return NULL
22120         do_facet mds2 $LCTL set_param fail_loc=0
22121
22122         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22123         wait_recovery_complete mds2
22124 }
22125 run_test 278 "Race starting MDS between MDTs stop/start"
22126
22127 test_280() {
22128         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22129                 skip "Need MGS version at least 2.13.52"
22130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22131         combined_mgs_mds || skip "needs combined MGS/MDT"
22132
22133         umount_client $MOUNT
22134 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22135         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22136
22137         mount_client $MOUNT &
22138         sleep 1
22139         stop mgs || error "stop mgs failed"
22140         #for a race mgs would crash
22141         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22142         # make sure we unmount client before remounting
22143         wait
22144         umount_client $MOUNT
22145         mount_client $MOUNT || error "mount client failed"
22146 }
22147 run_test 280 "Race between MGS umount and client llog processing"
22148
22149 cleanup_test_300() {
22150         trap 0
22151         umask $SAVE_UMASK
22152 }
22153 test_striped_dir() {
22154         local mdt_index=$1
22155         local stripe_count
22156         local stripe_index
22157
22158         mkdir -p $DIR/$tdir
22159
22160         SAVE_UMASK=$(umask)
22161         trap cleanup_test_300 RETURN EXIT
22162
22163         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22164                                                 $DIR/$tdir/striped_dir ||
22165                 error "set striped dir error"
22166
22167         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22168         [ "$mode" = "755" ] || error "expect 755 got $mode"
22169
22170         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22171                 error "getdirstripe failed"
22172         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22173         if [ "$stripe_count" != "2" ]; then
22174                 error "1:stripe_count is $stripe_count, expect 2"
22175         fi
22176         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22177         if [ "$stripe_count" != "2" ]; then
22178                 error "2:stripe_count is $stripe_count, expect 2"
22179         fi
22180
22181         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22182         if [ "$stripe_index" != "$mdt_index" ]; then
22183                 error "stripe_index is $stripe_index, expect $mdt_index"
22184         fi
22185
22186         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22187                 error "nlink error after create striped dir"
22188
22189         mkdir $DIR/$tdir/striped_dir/a
22190         mkdir $DIR/$tdir/striped_dir/b
22191
22192         stat $DIR/$tdir/striped_dir/a ||
22193                 error "create dir under striped dir failed"
22194         stat $DIR/$tdir/striped_dir/b ||
22195                 error "create dir under striped dir failed"
22196
22197         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22198                 error "nlink error after mkdir"
22199
22200         rmdir $DIR/$tdir/striped_dir/a
22201         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22202                 error "nlink error after rmdir"
22203
22204         rmdir $DIR/$tdir/striped_dir/b
22205         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22206                 error "nlink error after rmdir"
22207
22208         chattr +i $DIR/$tdir/striped_dir
22209         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22210                 error "immutable flags not working under striped dir!"
22211         chattr -i $DIR/$tdir/striped_dir
22212
22213         rmdir $DIR/$tdir/striped_dir ||
22214                 error "rmdir striped dir error"
22215
22216         cleanup_test_300
22217
22218         true
22219 }
22220
22221 test_300a() {
22222         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22223                 skip "skipped for lustre < 2.7.0"
22224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22225         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22226
22227         test_striped_dir 0 || error "failed on striped dir on MDT0"
22228         test_striped_dir 1 || error "failed on striped dir on MDT0"
22229 }
22230 run_test 300a "basic striped dir sanity test"
22231
22232 test_300b() {
22233         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22234                 skip "skipped for lustre < 2.7.0"
22235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22236         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22237
22238         local i
22239         local mtime1
22240         local mtime2
22241         local mtime3
22242
22243         test_mkdir $DIR/$tdir || error "mkdir fail"
22244         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22245                 error "set striped dir error"
22246         for i in {0..9}; do
22247                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22248                 sleep 1
22249                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22250                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22251                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22252                 sleep 1
22253                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22254                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22255                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22256         done
22257         true
22258 }
22259 run_test 300b "check ctime/mtime for striped dir"
22260
22261 test_300c() {
22262         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22263                 skip "skipped for lustre < 2.7.0"
22264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22265         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22266
22267         local file_count
22268
22269         mkdir -p $DIR/$tdir
22270         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22271                 error "set striped dir error"
22272
22273         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22274                 error "chown striped dir failed"
22275
22276         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22277                 error "create 5k files failed"
22278
22279         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22280
22281         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22282
22283         rm -rf $DIR/$tdir
22284 }
22285 run_test 300c "chown && check ls under striped directory"
22286
22287 test_300d() {
22288         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22289                 skip "skipped for lustre < 2.7.0"
22290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22291         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22292
22293         local stripe_count
22294         local file
22295
22296         mkdir -p $DIR/$tdir
22297         $LFS setstripe -c 2 $DIR/$tdir
22298
22299         #local striped directory
22300         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22301                 error "set striped dir error"
22302         #look at the directories for debug purposes
22303         ls -l $DIR/$tdir
22304         $LFS getdirstripe $DIR/$tdir
22305         ls -l $DIR/$tdir/striped_dir
22306         $LFS getdirstripe $DIR/$tdir/striped_dir
22307         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22308                 error "create 10 files failed"
22309
22310         #remote striped directory
22311         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22312                 error "set striped dir error"
22313         #look at the directories for debug purposes
22314         ls -l $DIR/$tdir
22315         $LFS getdirstripe $DIR/$tdir
22316         ls -l $DIR/$tdir/remote_striped_dir
22317         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22318         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22319                 error "create 10 files failed"
22320
22321         for file in $(find $DIR/$tdir); do
22322                 stripe_count=$($LFS getstripe -c $file)
22323                 [ $stripe_count -eq 2 ] ||
22324                         error "wrong stripe $stripe_count for $file"
22325         done
22326
22327         rm -rf $DIR/$tdir
22328 }
22329 run_test 300d "check default stripe under striped directory"
22330
22331 test_300e() {
22332         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22333                 skip "Need MDS version at least 2.7.55"
22334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22335         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22336
22337         local stripe_count
22338         local file
22339
22340         mkdir -p $DIR/$tdir
22341
22342         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22343                 error "set striped dir error"
22344
22345         touch $DIR/$tdir/striped_dir/a
22346         touch $DIR/$tdir/striped_dir/b
22347         touch $DIR/$tdir/striped_dir/c
22348
22349         mkdir $DIR/$tdir/striped_dir/dir_a
22350         mkdir $DIR/$tdir/striped_dir/dir_b
22351         mkdir $DIR/$tdir/striped_dir/dir_c
22352
22353         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22354                 error "set striped adir under striped dir error"
22355
22356         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22357                 error "set striped bdir under striped dir error"
22358
22359         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22360                 error "set striped cdir under striped dir error"
22361
22362         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22363                 error "rename dir under striped dir fails"
22364
22365         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22366                 error "rename dir under different stripes fails"
22367
22368         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22369                 error "rename file under striped dir should succeed"
22370
22371         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22372                 error "rename dir under striped dir should succeed"
22373
22374         rm -rf $DIR/$tdir
22375 }
22376 run_test 300e "check rename under striped directory"
22377
22378 test_300f() {
22379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22380         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22381         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22382                 skip "Need MDS version at least 2.7.55"
22383
22384         local stripe_count
22385         local file
22386
22387         rm -rf $DIR/$tdir
22388         mkdir -p $DIR/$tdir
22389
22390         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22391                 error "set striped dir error"
22392
22393         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22394                 error "set striped dir error"
22395
22396         touch $DIR/$tdir/striped_dir/a
22397         mkdir $DIR/$tdir/striped_dir/dir_a
22398         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22399                 error "create striped dir under striped dir fails"
22400
22401         touch $DIR/$tdir/striped_dir1/b
22402         mkdir $DIR/$tdir/striped_dir1/dir_b
22403         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22404                 error "create striped dir under striped dir fails"
22405
22406         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22407                 error "rename dir under different striped dir should fail"
22408
22409         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22410                 error "rename striped dir under diff striped dir should fail"
22411
22412         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22413                 error "rename file under diff striped dirs fails"
22414
22415         rm -rf $DIR/$tdir
22416 }
22417 run_test 300f "check rename cross striped directory"
22418
22419 test_300_check_default_striped_dir()
22420 {
22421         local dirname=$1
22422         local default_count=$2
22423         local default_index=$3
22424         local stripe_count
22425         local stripe_index
22426         local dir_stripe_index
22427         local dir
22428
22429         echo "checking $dirname $default_count $default_index"
22430         $LFS setdirstripe -D -c $default_count -i $default_index \
22431                                 -H all_char $DIR/$tdir/$dirname ||
22432                 error "set default stripe on striped dir error"
22433         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22434         [ $stripe_count -eq $default_count ] ||
22435                 error "expect $default_count get $stripe_count for $dirname"
22436
22437         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22438         [ $stripe_index -eq $default_index ] ||
22439                 error "expect $default_index get $stripe_index for $dirname"
22440
22441         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22442                                                 error "create dirs failed"
22443
22444         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22445         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22446         for dir in $(find $DIR/$tdir/$dirname/*); do
22447                 stripe_count=$($LFS getdirstripe -c $dir)
22448                 (( $stripe_count == $default_count )) ||
22449                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22450                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22451                 error "stripe count $default_count != $stripe_count for $dir"
22452
22453                 stripe_index=$($LFS getdirstripe -i $dir)
22454                 [ $default_index -eq -1 ] ||
22455                         [ $stripe_index -eq $default_index ] ||
22456                         error "$stripe_index != $default_index for $dir"
22457
22458                 #check default stripe
22459                 stripe_count=$($LFS getdirstripe -D -c $dir)
22460                 [ $stripe_count -eq $default_count ] ||
22461                 error "default count $default_count != $stripe_count for $dir"
22462
22463                 stripe_index=$($LFS getdirstripe -D -i $dir)
22464                 [ $stripe_index -eq $default_index ] ||
22465                 error "default index $default_index != $stripe_index for $dir"
22466         done
22467         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22468 }
22469
22470 test_300g() {
22471         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22472         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22473                 skip "Need MDS version at least 2.7.55"
22474
22475         local dir
22476         local stripe_count
22477         local stripe_index
22478
22479         mkdir $DIR/$tdir
22480         mkdir $DIR/$tdir/normal_dir
22481
22482         #Checking when client cache stripe index
22483         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22484         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22485                 error "create striped_dir failed"
22486
22487         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22488                 error "create dir0 fails"
22489         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22490         [ $stripe_index -eq 0 ] ||
22491                 error "dir0 expect index 0 got $stripe_index"
22492
22493         mkdir $DIR/$tdir/striped_dir/dir1 ||
22494                 error "create dir1 fails"
22495         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22496         [ $stripe_index -eq 1 ] ||
22497                 error "dir1 expect index 1 got $stripe_index"
22498
22499         #check default stripe count/stripe index
22500         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22501         test_300_check_default_striped_dir normal_dir 1 0
22502         test_300_check_default_striped_dir normal_dir -1 1
22503         test_300_check_default_striped_dir normal_dir 2 -1
22504
22505         #delete default stripe information
22506         echo "delete default stripeEA"
22507         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22508                 error "set default stripe on striped dir error"
22509
22510         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22511         for dir in $(find $DIR/$tdir/normal_dir/*); do
22512                 stripe_count=$($LFS getdirstripe -c $dir)
22513                 [ $stripe_count -eq 0 ] ||
22514                         error "expect 1 get $stripe_count for $dir"
22515                 stripe_index=$($LFS getdirstripe -i $dir)
22516                 [ $stripe_index -eq 0 ] ||
22517                         error "expect 0 get $stripe_index for $dir"
22518         done
22519 }
22520 run_test 300g "check default striped directory for normal directory"
22521
22522 test_300h() {
22523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22524         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22525                 skip "Need MDS version at least 2.7.55"
22526
22527         local dir
22528         local stripe_count
22529
22530         mkdir $DIR/$tdir
22531         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22532                 error "set striped dir error"
22533
22534         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22535         test_300_check_default_striped_dir striped_dir 1 0
22536         test_300_check_default_striped_dir striped_dir -1 1
22537         test_300_check_default_striped_dir striped_dir 2 -1
22538
22539         #delete default stripe information
22540         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22541                 error "set default stripe on striped dir error"
22542
22543         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22544         for dir in $(find $DIR/$tdir/striped_dir/*); do
22545                 stripe_count=$($LFS getdirstripe -c $dir)
22546                 [ $stripe_count -eq 0 ] ||
22547                         error "expect 1 get $stripe_count for $dir"
22548         done
22549 }
22550 run_test 300h "check default striped directory for striped directory"
22551
22552 test_300i() {
22553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22554         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22555         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22556                 skip "Need MDS version at least 2.7.55"
22557
22558         local stripe_count
22559         local file
22560
22561         mkdir $DIR/$tdir
22562
22563         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22564                 error "set striped dir error"
22565
22566         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22567                 error "create files under striped dir failed"
22568
22569         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22570                 error "set striped hashdir error"
22571
22572         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22573                 error "create dir0 under hash dir failed"
22574         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22575                 error "create dir1 under hash dir failed"
22576         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22577                 error "create dir2 under hash dir failed"
22578
22579         # unfortunately, we need to umount to clear dir layout cache for now
22580         # once we fully implement dir layout, we can drop this
22581         umount_client $MOUNT || error "umount failed"
22582         mount_client $MOUNT || error "mount failed"
22583
22584         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22585         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22586         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22587
22588         #set the stripe to be unknown hash type
22589         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22590         $LCTL set_param fail_loc=0x1901
22591         for ((i = 0; i < 10; i++)); do
22592                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22593                         error "stat f-$i failed"
22594                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22595         done
22596
22597         touch $DIR/$tdir/striped_dir/f0 &&
22598                 error "create under striped dir with unknown hash should fail"
22599
22600         $LCTL set_param fail_loc=0
22601
22602         umount_client $MOUNT || error "umount failed"
22603         mount_client $MOUNT || error "mount failed"
22604
22605         return 0
22606 }
22607 run_test 300i "client handle unknown hash type striped directory"
22608
22609 test_300j() {
22610         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22612         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22613                 skip "Need MDS version at least 2.7.55"
22614
22615         local stripe_count
22616         local file
22617
22618         mkdir $DIR/$tdir
22619
22620         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22621         $LCTL set_param fail_loc=0x1702
22622         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22623                 error "set striped dir error"
22624
22625         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22626                 error "create files under striped dir failed"
22627
22628         $LCTL set_param fail_loc=0
22629
22630         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22631
22632         return 0
22633 }
22634 run_test 300j "test large update record"
22635
22636 test_300k() {
22637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22638         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22639         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22640                 skip "Need MDS version at least 2.7.55"
22641
22642         # this test needs a huge transaction
22643         local kb
22644         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22645              osd*.$FSNAME-MDT0000.kbytestotal")
22646         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22647
22648         local stripe_count
22649         local file
22650
22651         mkdir $DIR/$tdir
22652
22653         #define OBD_FAIL_LARGE_STRIPE   0x1703
22654         $LCTL set_param fail_loc=0x1703
22655         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22656                 error "set striped dir error"
22657         $LCTL set_param fail_loc=0
22658
22659         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22660                 error "getstripeddir fails"
22661         rm -rf $DIR/$tdir/striped_dir ||
22662                 error "unlink striped dir fails"
22663
22664         return 0
22665 }
22666 run_test 300k "test large striped directory"
22667
22668 test_300l() {
22669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22670         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22671         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22672                 skip "Need MDS version at least 2.7.55"
22673
22674         local stripe_index
22675
22676         test_mkdir -p $DIR/$tdir/striped_dir
22677         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22678                         error "chown $RUNAS_ID failed"
22679         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22680                 error "set default striped dir failed"
22681
22682         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22683         $LCTL set_param fail_loc=0x80000158
22684         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22685
22686         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22687         [ $stripe_index -eq 1 ] ||
22688                 error "expect 1 get $stripe_index for $dir"
22689 }
22690 run_test 300l "non-root user to create dir under striped dir with stale layout"
22691
22692 test_300m() {
22693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22694         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22695         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22696                 skip "Need MDS version at least 2.7.55"
22697
22698         mkdir -p $DIR/$tdir/striped_dir
22699         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22700                 error "set default stripes dir error"
22701
22702         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22703
22704         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22705         [ $stripe_count -eq 0 ] ||
22706                         error "expect 0 get $stripe_count for a"
22707
22708         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22709                 error "set default stripes dir error"
22710
22711         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22712
22713         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22714         [ $stripe_count -eq 0 ] ||
22715                         error "expect 0 get $stripe_count for b"
22716
22717         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22718                 error "set default stripes dir error"
22719
22720         mkdir $DIR/$tdir/striped_dir/c &&
22721                 error "default stripe_index is invalid, mkdir c should fails"
22722
22723         rm -rf $DIR/$tdir || error "rmdir fails"
22724 }
22725 run_test 300m "setstriped directory on single MDT FS"
22726
22727 cleanup_300n() {
22728         local list=$(comma_list $(mdts_nodes))
22729
22730         trap 0
22731         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22732 }
22733
22734 test_300n() {
22735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22736         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22737         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22738                 skip "Need MDS version at least 2.7.55"
22739         remote_mds_nodsh && skip "remote MDS with nodsh"
22740
22741         local stripe_index
22742         local list=$(comma_list $(mdts_nodes))
22743
22744         trap cleanup_300n RETURN EXIT
22745         mkdir -p $DIR/$tdir
22746         chmod 777 $DIR/$tdir
22747         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22748                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22749                 error "create striped dir succeeds with gid=0"
22750
22751         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22752         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22753                 error "create striped dir fails with gid=-1"
22754
22755         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22756         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22757                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22758                 error "set default striped dir succeeds with gid=0"
22759
22760
22761         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22762         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22763                 error "set default striped dir fails with gid=-1"
22764
22765
22766         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22767         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22768                                         error "create test_dir fails"
22769         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22770                                         error "create test_dir1 fails"
22771         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22772                                         error "create test_dir2 fails"
22773         cleanup_300n
22774 }
22775 run_test 300n "non-root user to create dir under striped dir with default EA"
22776
22777 test_300o() {
22778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22779         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22780         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22781                 skip "Need MDS version at least 2.7.55"
22782
22783         local numfree1
22784         local numfree2
22785
22786         mkdir -p $DIR/$tdir
22787
22788         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22789         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22790         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22791                 skip "not enough free inodes $numfree1 $numfree2"
22792         fi
22793
22794         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22795         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22796         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22797                 skip "not enough free space $numfree1 $numfree2"
22798         fi
22799
22800         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22801                 error "setdirstripe fails"
22802
22803         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22804                 error "create dirs fails"
22805
22806         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22807         ls $DIR/$tdir/striped_dir > /dev/null ||
22808                 error "ls striped dir fails"
22809         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22810                 error "unlink big striped dir fails"
22811 }
22812 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22813
22814 test_300p() {
22815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22816         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22817         remote_mds_nodsh && skip "remote MDS with nodsh"
22818
22819         mkdir -p $DIR/$tdir
22820
22821         #define OBD_FAIL_OUT_ENOSPC     0x1704
22822         do_facet mds2 lctl set_param fail_loc=0x80001704
22823         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22824                  && error "create striped directory should fail"
22825
22826         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22827
22828         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22829         true
22830 }
22831 run_test 300p "create striped directory without space"
22832
22833 test_300q() {
22834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22835         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22836
22837         local fd=$(free_fd)
22838         local cmd="exec $fd<$tdir"
22839         cd $DIR
22840         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22841         eval $cmd
22842         cmd="exec $fd<&-"
22843         trap "eval $cmd" EXIT
22844         cd $tdir || error "cd $tdir fails"
22845         rmdir  ../$tdir || error "rmdir $tdir fails"
22846         mkdir local_dir && error "create dir succeeds"
22847         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22848         eval $cmd
22849         return 0
22850 }
22851 run_test 300q "create remote directory under orphan directory"
22852
22853 test_300r() {
22854         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22855                 skip "Need MDS version at least 2.7.55" && return
22856         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22857
22858         mkdir $DIR/$tdir
22859
22860         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22861                 error "set striped dir error"
22862
22863         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22864                 error "getstripeddir fails"
22865
22866         local stripe_count
22867         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22868                       awk '/lmv_stripe_count:/ { print $2 }')
22869
22870         [ $MDSCOUNT -ne $stripe_count ] &&
22871                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22872
22873         rm -rf $DIR/$tdir/striped_dir ||
22874                 error "unlink striped dir fails"
22875 }
22876 run_test 300r "test -1 striped directory"
22877
22878 test_300s_helper() {
22879         local count=$1
22880
22881         local stripe_dir=$DIR/$tdir/striped_dir.$count
22882
22883         $LFS mkdir -c $count $stripe_dir ||
22884                 error "lfs mkdir -c error"
22885
22886         $LFS getdirstripe $stripe_dir ||
22887                 error "lfs getdirstripe fails"
22888
22889         local stripe_count
22890         stripe_count=$($LFS getdirstripe $stripe_dir |
22891                       awk '/lmv_stripe_count:/ { print $2 }')
22892
22893         [ $count -ne $stripe_count ] &&
22894                 error_noexit "bad stripe count $stripe_count expected $count"
22895
22896         local dupe_stripes
22897         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22898                 awk '/0x/ {count[$1] += 1}; END {
22899                         for (idx in count) {
22900                                 if (count[idx]>1) {
22901                                         print "index " idx " count " count[idx]
22902                                 }
22903                         }
22904                 }')
22905
22906         if [[ -n "$dupe_stripes" ]] ; then
22907                 lfs getdirstripe $stripe_dir
22908                 error_noexit "Dupe MDT above: $dupe_stripes "
22909         fi
22910
22911         rm -rf $stripe_dir ||
22912                 error_noexit "unlink $stripe_dir fails"
22913 }
22914
22915 test_300s() {
22916         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22917                 skip "Need MDS version at least 2.7.55" && return
22918         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22919
22920         mkdir $DIR/$tdir
22921         for count in $(seq 2 $MDSCOUNT); do
22922                 test_300s_helper $count
22923         done
22924 }
22925 run_test 300s "test lfs mkdir -c without -i"
22926
22927
22928 prepare_remote_file() {
22929         mkdir $DIR/$tdir/src_dir ||
22930                 error "create remote source failed"
22931
22932         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22933                  error "cp to remote source failed"
22934         touch $DIR/$tdir/src_dir/a
22935
22936         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22937                 error "create remote target dir failed"
22938
22939         touch $DIR/$tdir/tgt_dir/b
22940
22941         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22942                 error "rename dir cross MDT failed!"
22943
22944         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22945                 error "src_child still exists after rename"
22946
22947         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22948                 error "missing file(a) after rename"
22949
22950         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22951                 error "diff after rename"
22952 }
22953
22954 test_310a() {
22955         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22957
22958         local remote_file=$DIR/$tdir/tgt_dir/b
22959
22960         mkdir -p $DIR/$tdir
22961
22962         prepare_remote_file || error "prepare remote file failed"
22963
22964         #open-unlink file
22965         $OPENUNLINK $remote_file $remote_file ||
22966                 error "openunlink $remote_file failed"
22967         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22968 }
22969 run_test 310a "open unlink remote file"
22970
22971 test_310b() {
22972         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22974
22975         local remote_file=$DIR/$tdir/tgt_dir/b
22976
22977         mkdir -p $DIR/$tdir
22978
22979         prepare_remote_file || error "prepare remote file failed"
22980
22981         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22982         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22983         $CHECKSTAT -t file $remote_file || error "check file failed"
22984 }
22985 run_test 310b "unlink remote file with multiple links while open"
22986
22987 test_310c() {
22988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22989         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22990
22991         local remote_file=$DIR/$tdir/tgt_dir/b
22992
22993         mkdir -p $DIR/$tdir
22994
22995         prepare_remote_file || error "prepare remote file failed"
22996
22997         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22998         multiop_bg_pause $remote_file O_uc ||
22999                         error "mulitop failed for remote file"
23000         MULTIPID=$!
23001         $MULTIOP $DIR/$tfile Ouc
23002         kill -USR1 $MULTIPID
23003         wait $MULTIPID
23004 }
23005 run_test 310c "open-unlink remote file with multiple links"
23006
23007 #LU-4825
23008 test_311() {
23009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23010         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23011         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23012                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23013         remote_mds_nodsh && skip "remote MDS with nodsh"
23014
23015         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23016         local mdts=$(comma_list $(mdts_nodes))
23017
23018         mkdir -p $DIR/$tdir
23019         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23020         createmany -o $DIR/$tdir/$tfile. 1000
23021
23022         # statfs data is not real time, let's just calculate it
23023         old_iused=$((old_iused + 1000))
23024
23025         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23026                         osp.*OST0000*MDT0000.create_count")
23027         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23028                                 osp.*OST0000*MDT0000.max_create_count")
23029         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23030
23031         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23032         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23033         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23034
23035         unlinkmany $DIR/$tdir/$tfile. 1000
23036
23037         do_nodes $mdts "$LCTL set_param -n \
23038                         osp.*OST0000*.max_create_count=$max_count"
23039         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23040                 do_nodes $mdts "$LCTL set_param -n \
23041                                 osp.*OST0000*.create_count=$count"
23042         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23043                         grep "=0" && error "create_count is zero"
23044
23045         local new_iused
23046         for i in $(seq 120); do
23047                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23048                 # system may be too busy to destroy all objs in time, use
23049                 # a somewhat small value to not fail autotest
23050                 [ $((old_iused - new_iused)) -gt 400 ] && break
23051                 sleep 1
23052         done
23053
23054         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23055         [ $((old_iused - new_iused)) -gt 400 ] ||
23056                 error "objs not destroyed after unlink"
23057 }
23058 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23059
23060 zfs_oid_to_objid()
23061 {
23062         local ost=$1
23063         local objid=$2
23064
23065         local vdevdir=$(dirname $(facet_vdevice $ost))
23066         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23067         local zfs_zapid=$(do_facet $ost $cmd |
23068                           grep -w "/O/0/d$((objid%32))" -C 5 |
23069                           awk '/Object/{getline; print $1}')
23070         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23071                           awk "/$objid = /"'{printf $3}')
23072
23073         echo $zfs_objid
23074 }
23075
23076 zfs_object_blksz() {
23077         local ost=$1
23078         local objid=$2
23079
23080         local vdevdir=$(dirname $(facet_vdevice $ost))
23081         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23082         local blksz=$(do_facet $ost $cmd $objid |
23083                       awk '/dblk/{getline; printf $4}')
23084
23085         case "${blksz: -1}" in
23086                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23087                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23088                 *) ;;
23089         esac
23090
23091         echo $blksz
23092 }
23093
23094 test_312() { # LU-4856
23095         remote_ost_nodsh && skip "remote OST with nodsh"
23096         [ "$ost1_FSTYPE" = "zfs" ] ||
23097                 skip_env "the test only applies to zfs"
23098
23099         local max_blksz=$(do_facet ost1 \
23100                           $ZFS get -p recordsize $(facet_device ost1) |
23101                           awk '!/VALUE/{print $3}')
23102
23103         # to make life a little bit easier
23104         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23105         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23106
23107         local tf=$DIR/$tdir/$tfile
23108         touch $tf
23109         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23110
23111         # Get ZFS object id
23112         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23113         # block size change by sequential overwrite
23114         local bs
23115
23116         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23117                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23118
23119                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23120                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23121         done
23122         rm -f $tf
23123
23124         # block size change by sequential append write
23125         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23126         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23127         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23128         local count
23129
23130         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23131                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23132                         oflag=sync conv=notrunc
23133
23134                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23135                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23136                         error "blksz error, actual $blksz, " \
23137                                 "expected: 2 * $count * $PAGE_SIZE"
23138         done
23139         rm -f $tf
23140
23141         # random write
23142         touch $tf
23143         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23144         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23145
23146         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23147         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23148         [ $blksz -eq $PAGE_SIZE ] ||
23149                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23150
23151         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23152         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23153         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23154
23155         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23156         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23157         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23158 }
23159 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23160
23161 test_313() {
23162         remote_ost_nodsh && skip "remote OST with nodsh"
23163
23164         local file=$DIR/$tfile
23165
23166         rm -f $file
23167         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23168
23169         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23170         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23171         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23172                 error "write should failed"
23173         do_facet ost1 "$LCTL set_param fail_loc=0"
23174         rm -f $file
23175 }
23176 run_test 313 "io should fail after last_rcvd update fail"
23177
23178 test_314() {
23179         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23180
23181         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23182         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23183         rm -f $DIR/$tfile
23184         wait_delete_completed
23185         do_facet ost1 "$LCTL set_param fail_loc=0"
23186 }
23187 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23188
23189 test_315() { # LU-618
23190         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23191
23192         local file=$DIR/$tfile
23193         rm -f $file
23194
23195         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23196                 error "multiop file write failed"
23197         $MULTIOP $file oO_RDONLY:r4063232_c &
23198         PID=$!
23199
23200         sleep 2
23201
23202         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23203         kill -USR1 $PID
23204
23205         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23206         rm -f $file
23207 }
23208 run_test 315 "read should be accounted"
23209
23210 test_316() {
23211         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23212         large_xattr_enabled || skip_env "ea_inode feature disabled"
23213
23214         rm -rf $DIR/$tdir/d
23215         mkdir -p $DIR/$tdir/d
23216         chown nobody $DIR/$tdir/d
23217         touch $DIR/$tdir/d/file
23218
23219         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23220 }
23221 run_test 316 "lfs mv"
23222
23223 test_317() {
23224         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23225                 skip "Need MDS version at least 2.11.53"
23226         if [ "$ost1_FSTYPE" == "zfs" ]; then
23227                 skip "LU-10370: no implementation for ZFS"
23228         fi
23229
23230         local trunc_sz
23231         local grant_blk_size
23232
23233         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23234                         awk '/grant_block_size:/ { print $2; exit; }')
23235         #
23236         # Create File of size 5M. Truncate it to below size's and verify
23237         # blocks count.
23238         #
23239         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23240                 error "Create file $DIR/$tfile failed"
23241         stack_trap "rm -f $DIR/$tfile" EXIT
23242
23243         for trunc_sz in 2097152 4097 4000 509 0; do
23244                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23245                         error "truncate $tfile to $trunc_sz failed"
23246                 local sz=$(stat --format=%s $DIR/$tfile)
23247                 local blk=$(stat --format=%b $DIR/$tfile)
23248                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23249                                      grant_blk_size) * 8))
23250
23251                 if [[ $blk -ne $trunc_blk ]]; then
23252                         $(which stat) $DIR/$tfile
23253                         error "Expected Block $trunc_blk got $blk for $tfile"
23254                 fi
23255
23256                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23257                         error "Expected Size $trunc_sz got $sz for $tfile"
23258         done
23259
23260         #
23261         # sparse file test
23262         # Create file with a hole and write actual two blocks. Block count
23263         # must be 16.
23264         #
23265         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23266                 conv=fsync || error "Create file : $DIR/$tfile"
23267
23268         # Calculate the final truncate size.
23269         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23270
23271         #
23272         # truncate to size $trunc_sz bytes. Strip the last block
23273         # The block count must drop to 8
23274         #
23275         $TRUNCATE $DIR/$tfile $trunc_sz ||
23276                 error "truncate $tfile to $trunc_sz failed"
23277
23278         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23279         sz=$(stat --format=%s $DIR/$tfile)
23280         blk=$(stat --format=%b $DIR/$tfile)
23281
23282         if [[ $blk -ne $trunc_bsz ]]; then
23283                 $(which stat) $DIR/$tfile
23284                 error "Expected Block $trunc_bsz got $blk for $tfile"
23285         fi
23286
23287         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23288                 error "Expected Size $trunc_sz got $sz for $tfile"
23289 }
23290 run_test 317 "Verify blocks get correctly update after truncate"
23291
23292 test_318() {
23293         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23294         local old_max_active=$($LCTL get_param -n \
23295                             ${llite_name}.max_read_ahead_async_active \
23296                             2>/dev/null)
23297
23298         $LCTL set_param llite.*.max_read_ahead_async_active=256
23299         local max_active=$($LCTL get_param -n \
23300                            ${llite_name}.max_read_ahead_async_active \
23301                            2>/dev/null)
23302         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23303
23304         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23305                 error "set max_read_ahead_async_active should succeed"
23306
23307         $LCTL set_param llite.*.max_read_ahead_async_active=512
23308         max_active=$($LCTL get_param -n \
23309                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23310         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23311
23312         # restore @max_active
23313         [ $old_max_active -ne 0 ] && $LCTL set_param \
23314                 llite.*.max_read_ahead_async_active=$old_max_active
23315
23316         local old_threshold=$($LCTL get_param -n \
23317                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23318         local max_per_file_mb=$($LCTL get_param -n \
23319                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23320
23321         local invalid=$(($max_per_file_mb + 1))
23322         $LCTL set_param \
23323                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23324                         && error "set $invalid should fail"
23325
23326         local valid=$(($invalid - 1))
23327         $LCTL set_param \
23328                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23329                         error "set $valid should succeed"
23330         local threshold=$($LCTL get_param -n \
23331                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23332         [ $threshold -eq $valid ] || error \
23333                 "expect threshold $valid got $threshold"
23334         $LCTL set_param \
23335                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23336 }
23337 run_test 318 "Verify async readahead tunables"
23338
23339 test_319() {
23340         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23341
23342         local before=$(date +%s)
23343         local evict
23344         local mdir=$DIR/$tdir
23345         local file=$mdir/xxx
23346
23347         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23348         touch $file
23349
23350 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23351         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23352         $LFS mv -m1 $file &
23353
23354         sleep 1
23355         dd if=$file of=/dev/null
23356         wait
23357         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23358           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23359
23360         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23361 }
23362 run_test 319 "lost lease lock on migrate error"
23363
23364 test_398a() { # LU-4198
23365         local ost1_imp=$(get_osc_import_name client ost1)
23366         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23367                          cut -d'.' -f2)
23368
23369         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23370         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23371
23372         # request a new lock on client
23373         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23374
23375         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23376         local lock_count=$($LCTL get_param -n \
23377                            ldlm.namespaces.$imp_name.lru_size)
23378         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23379
23380         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23381
23382         # no lock cached, should use lockless IO and not enqueue new lock
23383         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23384         lock_count=$($LCTL get_param -n \
23385                      ldlm.namespaces.$imp_name.lru_size)
23386         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23387 }
23388 run_test 398a "direct IO should cancel lock otherwise lockless"
23389
23390 test_398b() { # LU-4198
23391         which fio || skip_env "no fio installed"
23392         $LFS setstripe -c -1 $DIR/$tfile
23393
23394         local size=12
23395         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23396
23397         local njobs=4
23398         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23399         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23400                 --numjobs=$njobs --fallocate=none \
23401                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23402                 --filename=$DIR/$tfile &
23403         bg_pid=$!
23404
23405         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23406         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23407                 --numjobs=$njobs --fallocate=none \
23408                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23409                 --filename=$DIR/$tfile || true
23410         wait $bg_pid
23411
23412         rm -f $DIR/$tfile
23413 }
23414 run_test 398b "DIO and buffer IO race"
23415
23416 test_398c() { # LU-4198
23417         local ost1_imp=$(get_osc_import_name client ost1)
23418         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23419                          cut -d'.' -f2)
23420
23421         which fio || skip_env "no fio installed"
23422
23423         saved_debug=$($LCTL get_param -n debug)
23424         $LCTL set_param debug=0
23425
23426         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23427         ((size /= 1024)) # by megabytes
23428         ((size /= 2)) # write half of the OST at most
23429         [ $size -gt 40 ] && size=40 #reduce test time anyway
23430
23431         $LFS setstripe -c 1 $DIR/$tfile
23432
23433         # it seems like ldiskfs reserves more space than necessary if the
23434         # writing blocks are not mapped, so it extends the file firstly
23435         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23436         cancel_lru_locks osc
23437
23438         # clear and verify rpc_stats later
23439         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23440
23441         local njobs=4
23442         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23443         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23444                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23445                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23446                 --filename=$DIR/$tfile
23447         [ $? -eq 0 ] || error "fio write error"
23448
23449         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23450                 error "Locks were requested while doing AIO"
23451
23452         # get the percentage of 1-page I/O
23453         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23454                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23455                 awk '{print $7}')
23456         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23457
23458         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23459         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23460                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23461                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23462                 --filename=$DIR/$tfile
23463         [ $? -eq 0 ] || error "fio mixed read write error"
23464
23465         echo "AIO with large block size ${size}M"
23466         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23467                 --numjobs=1 --fallocate=none --ioengine=libaio \
23468                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23469                 --filename=$DIR/$tfile
23470         [ $? -eq 0 ] || error "fio large block size failed"
23471
23472         rm -f $DIR/$tfile
23473         $LCTL set_param debug="$saved_debug"
23474 }
23475 run_test 398c "run fio to test AIO"
23476
23477 test_398d() { #  LU-13846
23478         which aiocp || skip_env "no aiocp installed"
23479         local aio_file=$DIR/$tfile.aio
23480
23481         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23482
23483         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23484         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23485         stack_trap "rm -f $DIR/$tfile $aio_file"
23486
23487         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23488
23489         # make sure we don't crash and fail properly
23490         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23491                 error "aio not aligned with PAGE SIZE should fail"
23492
23493         rm -f $DIR/$tfile $aio_file
23494 }
23495 run_test 398d "run aiocp to verify block size > stripe size"
23496
23497 test_398e() {
23498         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23499         touch $DIR/$tfile.new
23500         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23501 }
23502 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23503
23504 test_398f() { #  LU-14687
23505         which aiocp || skip_env "no aiocp installed"
23506         local aio_file=$DIR/$tfile.aio
23507
23508         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23509
23510         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23511         stack_trap "rm -f $DIR/$tfile $aio_file"
23512
23513         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23514         $LCTL set_param fail_loc=0x1418
23515         # make sure we don't crash and fail properly
23516         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23517                 error "aio with page allocation failure succeeded"
23518         $LCTL set_param fail_loc=0
23519         diff $DIR/$tfile $aio_file
23520         [[ $? != 0 ]] || error "no diff after failed aiocp"
23521 }
23522 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23523
23524 test_fake_rw() {
23525         local read_write=$1
23526         if [ "$read_write" = "write" ]; then
23527                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23528         elif [ "$read_write" = "read" ]; then
23529                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23530         else
23531                 error "argument error"
23532         fi
23533
23534         # turn off debug for performance testing
23535         local saved_debug=$($LCTL get_param -n debug)
23536         $LCTL set_param debug=0
23537
23538         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23539
23540         # get ost1 size - $FSNAME-OST0000
23541         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23542         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23543         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23544
23545         if [ "$read_write" = "read" ]; then
23546                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23547         fi
23548
23549         local start_time=$(date +%s.%N)
23550         $dd_cmd bs=1M count=$blocks oflag=sync ||
23551                 error "real dd $read_write error"
23552         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23553
23554         if [ "$read_write" = "write" ]; then
23555                 rm -f $DIR/$tfile
23556         fi
23557
23558         # define OBD_FAIL_OST_FAKE_RW           0x238
23559         do_facet ost1 $LCTL set_param fail_loc=0x238
23560
23561         local start_time=$(date +%s.%N)
23562         $dd_cmd bs=1M count=$blocks oflag=sync ||
23563                 error "fake dd $read_write error"
23564         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23565
23566         if [ "$read_write" = "write" ]; then
23567                 # verify file size
23568                 cancel_lru_locks osc
23569                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23570                         error "$tfile size not $blocks MB"
23571         fi
23572         do_facet ost1 $LCTL set_param fail_loc=0
23573
23574         echo "fake $read_write $duration_fake vs. normal $read_write" \
23575                 "$duration in seconds"
23576         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23577                 error_not_in_vm "fake write is slower"
23578
23579         $LCTL set_param -n debug="$saved_debug"
23580         rm -f $DIR/$tfile
23581 }
23582 test_399a() { # LU-7655 for OST fake write
23583         remote_ost_nodsh && skip "remote OST with nodsh"
23584
23585         test_fake_rw write
23586 }
23587 run_test 399a "fake write should not be slower than normal write"
23588
23589 test_399b() { # LU-8726 for OST fake read
23590         remote_ost_nodsh && skip "remote OST with nodsh"
23591         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23592                 skip_env "ldiskfs only test"
23593         fi
23594
23595         test_fake_rw read
23596 }
23597 run_test 399b "fake read should not be slower than normal read"
23598
23599 test_400a() { # LU-1606, was conf-sanity test_74
23600         if ! which $CC > /dev/null 2>&1; then
23601                 skip_env "$CC is not installed"
23602         fi
23603
23604         local extra_flags=''
23605         local out=$TMP/$tfile
23606         local prefix=/usr/include/lustre
23607         local prog
23608
23609         # Oleg removes c files in his test rig so test if any c files exist
23610         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23611                 skip_env "Needed c test files are missing"
23612
23613         if ! [[ -d $prefix ]]; then
23614                 # Assume we're running in tree and fixup the include path.
23615                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23616                 extra_flags+=" -L$LUSTRE/utils/.lib"
23617         fi
23618
23619         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23620                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
23621                         error "client api broken"
23622         done
23623         rm -f $out
23624 }
23625 run_test 400a "Lustre client api program can compile and link"
23626
23627 test_400b() { # LU-1606, LU-5011
23628         local header
23629         local out=$TMP/$tfile
23630         local prefix=/usr/include/linux/lustre
23631
23632         # We use a hard coded prefix so that this test will not fail
23633         # when run in tree. There are headers in lustre/include/lustre/
23634         # that are not packaged (like lustre_idl.h) and have more
23635         # complicated include dependencies (like config.h and lnet/types.h).
23636         # Since this test about correct packaging we just skip them when
23637         # they don't exist (see below) rather than try to fixup cppflags.
23638
23639         if ! which $CC > /dev/null 2>&1; then
23640                 skip_env "$CC is not installed"
23641         fi
23642
23643         for header in $prefix/*.h; do
23644                 if ! [[ -f "$header" ]]; then
23645                         continue
23646                 fi
23647
23648                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
23649                         continue # lustre_ioctl.h is internal header
23650                 fi
23651
23652                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
23653                         error "cannot compile '$header'"
23654         done
23655         rm -f $out
23656 }
23657 run_test 400b "packaged headers can be compiled"
23658
23659 test_401a() { #LU-7437
23660         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23661         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23662
23663         #count the number of parameters by "list_param -R"
23664         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23665         #count the number of parameters by listing proc files
23666         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23667         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23668         echo "proc_dirs='$proc_dirs'"
23669         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23670         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23671                       sort -u | wc -l)
23672
23673         [ $params -eq $procs ] ||
23674                 error "found $params parameters vs. $procs proc files"
23675
23676         # test the list_param -D option only returns directories
23677         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23678         #count the number of parameters by listing proc directories
23679         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23680                 sort -u | wc -l)
23681
23682         [ $params -eq $procs ] ||
23683                 error "found $params parameters vs. $procs proc files"
23684 }
23685 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23686
23687 test_401b() {
23688         # jobid_var may not allow arbitrary values, so use jobid_name
23689         # if available
23690         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23691                 local testname=jobid_name tmp='testing%p'
23692         else
23693                 local testname=jobid_var tmp=testing
23694         fi
23695
23696         local save=$($LCTL get_param -n $testname)
23697
23698         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23699                 error "no error returned when setting bad parameters"
23700
23701         local jobid_new=$($LCTL get_param -n foe $testname baz)
23702         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23703
23704         $LCTL set_param -n fog=bam $testname=$save bat=fog
23705         local jobid_old=$($LCTL get_param -n foe $testname bag)
23706         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23707 }
23708 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23709
23710 test_401c() {
23711         # jobid_var may not allow arbitrary values, so use jobid_name
23712         # if available
23713         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23714                 local testname=jobid_name
23715         else
23716                 local testname=jobid_var
23717         fi
23718
23719         local jobid_var_old=$($LCTL get_param -n $testname)
23720         local jobid_var_new
23721
23722         $LCTL set_param $testname= &&
23723                 error "no error returned for 'set_param a='"
23724
23725         jobid_var_new=$($LCTL get_param -n $testname)
23726         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23727                 error "$testname was changed by setting without value"
23728
23729         $LCTL set_param $testname &&
23730                 error "no error returned for 'set_param a'"
23731
23732         jobid_var_new=$($LCTL get_param -n $testname)
23733         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23734                 error "$testname was changed by setting without value"
23735 }
23736 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23737
23738 test_401d() {
23739         # jobid_var may not allow arbitrary values, so use jobid_name
23740         # if available
23741         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23742                 local testname=jobid_name new_value='foo=bar%p'
23743         else
23744                 local testname=jobid_var new_valuie=foo=bar
23745         fi
23746
23747         local jobid_var_old=$($LCTL get_param -n $testname)
23748         local jobid_var_new
23749
23750         $LCTL set_param $testname=$new_value ||
23751                 error "'set_param a=b' did not accept a value containing '='"
23752
23753         jobid_var_new=$($LCTL get_param -n $testname)
23754         [[ "$jobid_var_new" == "$new_value" ]] ||
23755                 error "'set_param a=b' failed on a value containing '='"
23756
23757         # Reset the $testname to test the other format
23758         $LCTL set_param $testname=$jobid_var_old
23759         jobid_var_new=$($LCTL get_param -n $testname)
23760         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23761                 error "failed to reset $testname"
23762
23763         $LCTL set_param $testname $new_value ||
23764                 error "'set_param a b' did not accept a value containing '='"
23765
23766         jobid_var_new=$($LCTL get_param -n $testname)
23767         [[ "$jobid_var_new" == "$new_value" ]] ||
23768                 error "'set_param a b' failed on a value containing '='"
23769
23770         $LCTL set_param $testname $jobid_var_old
23771         jobid_var_new=$($LCTL get_param -n $testname)
23772         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23773                 error "failed to reset $testname"
23774 }
23775 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23776
23777 test_402() {
23778         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23779         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23780                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23781         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23782                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23783                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23784         remote_mds_nodsh && skip "remote MDS with nodsh"
23785
23786         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23787 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23788         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23789         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23790                 echo "Touch failed - OK"
23791 }
23792 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23793
23794 test_403() {
23795         local file1=$DIR/$tfile.1
23796         local file2=$DIR/$tfile.2
23797         local tfile=$TMP/$tfile
23798
23799         rm -f $file1 $file2 $tfile
23800
23801         touch $file1
23802         ln $file1 $file2
23803
23804         # 30 sec OBD_TIMEOUT in ll_getattr()
23805         # right before populating st_nlink
23806         $LCTL set_param fail_loc=0x80001409
23807         stat -c %h $file1 > $tfile &
23808
23809         # create an alias, drop all locks and reclaim the dentry
23810         < $file2
23811         cancel_lru_locks mdc
23812         cancel_lru_locks osc
23813         sysctl -w vm.drop_caches=2
23814
23815         wait
23816
23817         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23818
23819         rm -f $tfile $file1 $file2
23820 }
23821 run_test 403 "i_nlink should not drop to zero due to aliasing"
23822
23823 test_404() { # LU-6601
23824         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23825                 skip "Need server version newer than 2.8.52"
23826         remote_mds_nodsh && skip "remote MDS with nodsh"
23827
23828         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23829                 awk '/osp .*-osc-MDT/ { print $4}')
23830
23831         local osp
23832         for osp in $mosps; do
23833                 echo "Deactivate: " $osp
23834                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23835                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23836                         awk -vp=$osp '$4 == p { print $2 }')
23837                 [ $stat = IN ] || {
23838                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23839                         error "deactivate error"
23840                 }
23841                 echo "Activate: " $osp
23842                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23843                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23844                         awk -vp=$osp '$4 == p { print $2 }')
23845                 [ $stat = UP ] || {
23846                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23847                         error "activate error"
23848                 }
23849         done
23850 }
23851 run_test 404 "validate manual {de}activated works properly for OSPs"
23852
23853 test_405() {
23854         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23855         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23856                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23857                         skip "Layout swap lock is not supported"
23858
23859         check_swap_layouts_support
23860         check_swap_layout_no_dom $DIR
23861
23862         test_mkdir $DIR/$tdir
23863         swap_lock_test -d $DIR/$tdir ||
23864                 error "One layout swap locked test failed"
23865 }
23866 run_test 405 "Various layout swap lock tests"
23867
23868 test_406() {
23869         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23870         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23871         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23873         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23874                 skip "Need MDS version at least 2.8.50"
23875
23876         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23877         local test_pool=$TESTNAME
23878
23879         pool_add $test_pool || error "pool_add failed"
23880         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23881                 error "pool_add_targets failed"
23882
23883         save_layout_restore_at_exit $MOUNT
23884
23885         # parent set default stripe count only, child will stripe from both
23886         # parent and fs default
23887         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23888                 error "setstripe $MOUNT failed"
23889         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23890         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23891         for i in $(seq 10); do
23892                 local f=$DIR/$tdir/$tfile.$i
23893                 touch $f || error "touch failed"
23894                 local count=$($LFS getstripe -c $f)
23895                 [ $count -eq $OSTCOUNT ] ||
23896                         error "$f stripe count $count != $OSTCOUNT"
23897                 local offset=$($LFS getstripe -i $f)
23898                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23899                 local size=$($LFS getstripe -S $f)
23900                 [ $size -eq $((def_stripe_size * 2)) ] ||
23901                         error "$f stripe size $size != $((def_stripe_size * 2))"
23902                 local pool=$($LFS getstripe -p $f)
23903                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23904         done
23905
23906         # change fs default striping, delete parent default striping, now child
23907         # will stripe from new fs default striping only
23908         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23909                 error "change $MOUNT default stripe failed"
23910         $LFS setstripe -c 0 $DIR/$tdir ||
23911                 error "delete $tdir default stripe failed"
23912         for i in $(seq 11 20); do
23913                 local f=$DIR/$tdir/$tfile.$i
23914                 touch $f || error "touch $f failed"
23915                 local count=$($LFS getstripe -c $f)
23916                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23917                 local offset=$($LFS getstripe -i $f)
23918                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23919                 local size=$($LFS getstripe -S $f)
23920                 [ $size -eq $def_stripe_size ] ||
23921                         error "$f stripe size $size != $def_stripe_size"
23922                 local pool=$($LFS getstripe -p $f)
23923                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23924         done
23925
23926         unlinkmany $DIR/$tdir/$tfile. 1 20
23927
23928         local f=$DIR/$tdir/$tfile
23929         pool_remove_all_targets $test_pool $f
23930         pool_remove $test_pool $f
23931 }
23932 run_test 406 "DNE support fs default striping"
23933
23934 test_407() {
23935         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23936         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23937                 skip "Need MDS version at least 2.8.55"
23938         remote_mds_nodsh && skip "remote MDS with nodsh"
23939
23940         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23941                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23942         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23943                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23944         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23945
23946         #define OBD_FAIL_DT_TXN_STOP    0x2019
23947         for idx in $(seq $MDSCOUNT); do
23948                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23949         done
23950         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23951         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23952                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23953         true
23954 }
23955 run_test 407 "transaction fail should cause operation fail"
23956
23957 test_408() {
23958         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23959
23960         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23961         lctl set_param fail_loc=0x8000040a
23962         # let ll_prepare_partial_page() fail
23963         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23964
23965         rm -f $DIR/$tfile
23966
23967         # create at least 100 unused inodes so that
23968         # shrink_icache_memory(0) should not return 0
23969         touch $DIR/$tfile-{0..100}
23970         rm -f $DIR/$tfile-{0..100}
23971         sync
23972
23973         echo 2 > /proc/sys/vm/drop_caches
23974 }
23975 run_test 408 "drop_caches should not hang due to page leaks"
23976
23977 test_409()
23978 {
23979         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23980
23981         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23982         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23983         touch $DIR/$tdir/guard || error "(2) Fail to create"
23984
23985         local PREFIX=$(str_repeat 'A' 128)
23986         echo "Create 1K hard links start at $(date)"
23987         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23988                 error "(3) Fail to hard link"
23989
23990         echo "Links count should be right although linkEA overflow"
23991         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23992         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23993         [ $linkcount -eq 1001 ] ||
23994                 error "(5) Unexpected hard links count: $linkcount"
23995
23996         echo "List all links start at $(date)"
23997         ls -l $DIR/$tdir/foo > /dev/null ||
23998                 error "(6) Fail to list $DIR/$tdir/foo"
23999
24000         echo "Unlink hard links start at $(date)"
24001         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24002                 error "(7) Fail to unlink"
24003         echo "Unlink hard links finished at $(date)"
24004 }
24005 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24006
24007 test_410()
24008 {
24009         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24010                 skip "Need client version at least 2.9.59"
24011         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24012                 skip "Need MODULES build"
24013
24014         # Create a file, and stat it from the kernel
24015         local testfile=$DIR/$tfile
24016         touch $testfile
24017
24018         local run_id=$RANDOM
24019         local my_ino=$(stat --format "%i" $testfile)
24020
24021         # Try to insert the module. This will always fail as the
24022         # module is designed to not be inserted.
24023         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24024             &> /dev/null
24025
24026         # Anything but success is a test failure
24027         dmesg | grep -q \
24028             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24029             error "no inode match"
24030 }
24031 run_test 410 "Test inode number returned from kernel thread"
24032
24033 cleanup_test411_cgroup() {
24034         trap 0
24035         rmdir "$1"
24036 }
24037
24038 test_411() {
24039         local cg_basedir=/sys/fs/cgroup/memory
24040         # LU-9966
24041         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24042                 skip "no setup for cgroup"
24043
24044         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24045                 error "test file creation failed"
24046         cancel_lru_locks osc
24047
24048         # Create a very small memory cgroup to force a slab allocation error
24049         local cgdir=$cg_basedir/osc_slab_alloc
24050         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24051         trap "cleanup_test411_cgroup $cgdir" EXIT
24052         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24053         echo 1M > $cgdir/memory.limit_in_bytes
24054
24055         # Should not LBUG, just be killed by oom-killer
24056         # dd will return 0 even allocation failure in some environment.
24057         # So don't check return value
24058         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24059         cleanup_test411_cgroup $cgdir
24060
24061         return 0
24062 }
24063 run_test 411 "Slab allocation error with cgroup does not LBUG"
24064
24065 test_412() {
24066         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24067         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24068                 skip "Need server version at least 2.10.55"
24069         fi
24070
24071         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24072                 error "mkdir failed"
24073         $LFS getdirstripe $DIR/$tdir
24074         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24075         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24076                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24077         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24078         [ $stripe_count -eq 2 ] ||
24079                 error "expect 2 get $stripe_count"
24080 }
24081 run_test 412 "mkdir on specific MDTs"
24082
24083 test_qos_mkdir() {
24084         local mkdir_cmd=$1
24085         local stripe_count=$2
24086         local mdts=$(comma_list $(mdts_nodes))
24087
24088         local testdir
24089         local lmv_qos_prio_free
24090         local lmv_qos_threshold_rr
24091         local lmv_qos_maxage
24092         local lod_qos_prio_free
24093         local lod_qos_threshold_rr
24094         local lod_qos_maxage
24095         local count
24096         local i
24097
24098         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24099         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24100         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24101                 head -n1)
24102         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24103         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24104         stack_trap "$LCTL set_param \
24105                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
24106         stack_trap "$LCTL set_param \
24107                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
24108         stack_trap "$LCTL set_param \
24109                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
24110
24111         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24112                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24113         lod_qos_prio_free=${lod_qos_prio_free%%%}
24114         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24115                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24116         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24117         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24118                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24119         stack_trap "do_nodes $mdts $LCTL set_param \
24120                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
24121         stack_trap "do_nodes $mdts $LCTL set_param \
24122                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
24123                 EXIT
24124         stack_trap "do_nodes $mdts $LCTL set_param \
24125                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
24126
24127         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24128         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24129
24130         testdir=$DIR/$tdir-s$stripe_count/rr
24131
24132         local stripe_index=$($LFS getstripe -m $testdir)
24133         local test_mkdir_rr=true
24134
24135         getfattr -d -m dmv $testdir | grep dmv
24136         if [ $? -eq 0 ] && [ $MDS1_VERSION -ge $(version_code 2.14.51) ]; then
24137                 local inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
24138
24139                 (( $inherit_rr == 0 )) && test_mkdir_rr=false
24140         fi
24141
24142         echo
24143         $test_mkdir_rr &&
24144                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24145                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24146
24147         for i in $(seq $((100 * MDSCOUNT))); do
24148                 eval $mkdir_cmd $testdir/subdir$i ||
24149                         error "$mkdir_cmd subdir$i failed"
24150         done
24151
24152         for i in $(seq $MDSCOUNT); do
24153                 count=$($LFS getdirstripe -i $testdir/* |
24154                                 grep ^$((i - 1))$ | wc -l)
24155                 echo "$count directories created on MDT$((i - 1))"
24156                 if $test_mkdir_rr; then
24157                         (( $count == 100 )) ||
24158                                 error "subdirs are not evenly distributed"
24159                 elif [ $((i - 1)) -eq $stripe_index ]; then
24160                         (( $count == 100 * MDSCOUNT )) ||
24161                                 error "$count subdirs created on MDT$((i - 1))"
24162                 else
24163                         (( $count == 0 )) ||
24164                                 error "$count subdirs created on MDT$((i - 1))"
24165                 fi
24166
24167                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24168                         count=$($LFS getdirstripe $testdir/* |
24169                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24170                         echo "$count stripes created on MDT$((i - 1))"
24171                         # deviation should < 5% of average
24172                         (( $count < 95 * stripe_count )) ||
24173                         (( $count > 105 * stripe_count)) &&
24174                                 error "stripes are not evenly distributed"
24175                 fi
24176         done
24177
24178         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
24179         do_nodes $mdts $LCTL set_param \
24180                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
24181
24182         echo
24183         echo "Check for uneven MDTs: "
24184
24185         local ffree
24186         local bavail
24187         local max
24188         local min
24189         local max_index
24190         local min_index
24191         local tmp
24192
24193         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24194         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24195         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24196
24197         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24198         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24199         max_index=0
24200         min_index=0
24201         for ((i = 1; i < ${#ffree[@]}; i++)); do
24202                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24203                 if [ $tmp -gt $max ]; then
24204                         max=$tmp
24205                         max_index=$i
24206                 fi
24207                 if [ $tmp -lt $min ]; then
24208                         min=$tmp
24209                         min_index=$i
24210                 fi
24211         done
24212
24213         (( ${ffree[min_index]} == 0 )) &&
24214                 skip "no free files in MDT$min_index"
24215         (( ${ffree[min_index]} > 100000000 )) &&
24216                 skip "too many free files in MDT$min_index"
24217
24218         # Check if we need to generate uneven MDTs
24219         local threshold=50
24220         local diff=$(((max - min) * 100 / min))
24221         local value="$(generate_string 1024)"
24222
24223         while [ $diff -lt $threshold ]; do
24224                 # generate uneven MDTs, create till $threshold% diff
24225                 echo -n "weight diff=$diff% must be > $threshold% ..."
24226                 count=$((${ffree[min_index]} / 10))
24227                 # 50 sec per 10000 files in vm
24228                 (( $count < 100000 )) || [ "$SLOW" != "no" ] ||
24229                         skip "$count files to create"
24230                 echo "Fill MDT$min_index with $count files"
24231                 [ -d $DIR/$tdir-MDT$min_index ] ||
24232                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
24233                         error "mkdir $tdir-MDT$min_index failed"
24234                 createmany -d $DIR/$tdir-MDT$min_index/d $count ||
24235                         error "create d$count failed"
24236
24237                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24238                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24239                 max=$(((${ffree[max_index]} >> 8) * \
24240                         (${bavail[max_index]} * bsize >> 16)))
24241                 min=$(((${ffree[min_index]} >> 8) * \
24242                         (${bavail[min_index]} * bsize >> 16)))
24243                 diff=$(((max - min) * 100 / min))
24244         done
24245
24246         echo "MDT filesfree available: ${ffree[@]}"
24247         echo "MDT blocks available: ${bavail[@]}"
24248         echo "weight diff=$diff%"
24249
24250         echo
24251         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24252
24253         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24254         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24255         # decrease statfs age, so that it can be updated in time
24256         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24257         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24258
24259         sleep 1
24260
24261         testdir=$DIR/$tdir-s$stripe_count/qos
24262
24263         for i in $(seq $((100 * MDSCOUNT))); do
24264                 eval $mkdir_cmd $testdir/subdir$i ||
24265                         error "$mkdir_cmd subdir$i failed"
24266         done
24267
24268         for i in $(seq $MDSCOUNT); do
24269                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
24270                         wc -l)
24271                 echo "$count directories created on MDT$((i - 1))"
24272
24273                 if [ $stripe_count -gt 1 ]; then
24274                         count=$($LFS getdirstripe $testdir/* |
24275                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24276                         echo "$count stripes created on MDT$((i - 1))"
24277                 fi
24278         done
24279
24280         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
24281         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
24282
24283         # D-value should > 10% of averge
24284         (( $max - $min < 10 )) &&
24285                 error "subdirs shouldn't be evenly distributed"
24286
24287         # ditto
24288         if [ $stripe_count -gt 1 ]; then
24289                 max=$($LFS getdirstripe $testdir/* |
24290                         grep -P "^\s+$max_index\t" | wc -l)
24291                 min=$($LFS getdirstripe $testdir/* |
24292                         grep -P "^\s+$min_index\t" | wc -l)
24293                 (( $max - $min < 10 * $stripe_count )) &&
24294                         error "stripes shouldn't be evenly distributed"|| true
24295         fi
24296 }
24297
24298 test_413a() {
24299         [ $MDSCOUNT -lt 2 ] &&
24300                 skip "We need at least 2 MDTs for this test"
24301
24302         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24303                 skip "Need server version at least 2.12.52"
24304
24305         local stripe_count
24306
24307         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24308                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24309                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24310                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
24311                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
24312         done
24313 }
24314 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24315
24316 test_413b() {
24317         [ $MDSCOUNT -lt 2 ] &&
24318                 skip "We need at least 2 MDTs for this test"
24319
24320         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24321                 skip "Need server version at least 2.12.52"
24322
24323         local testdir
24324         local stripe_count
24325
24326         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24327                 testdir=$DIR/$tdir-s$stripe_count
24328                 mkdir $testdir || error "mkdir $testdir failed"
24329                 mkdir $testdir/rr || error "mkdir rr failed"
24330                 mkdir $testdir/qos || error "mkdir qos failed"
24331                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24332                         $testdir/rr || error "setdirstripe rr failed"
24333                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24334                         error "setdirstripe failed"
24335                 test_qos_mkdir "mkdir" $stripe_count
24336         done
24337 }
24338 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24339
24340 test_413c() {
24341         [ $MDSCOUNT -ge 2 ] ||
24342                 skip "We need at least 2 MDTs for this test"
24343
24344         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] ||
24345                 skip "Need server version at least 2.14.50"
24346
24347         local testdir
24348         local inherit
24349         local inherit_rr
24350
24351         testdir=$DIR/${tdir}-s1
24352         mkdir $testdir || error "mkdir $testdir failed"
24353         mkdir $testdir/rr || error "mkdir rr failed"
24354         mkdir $testdir/qos || error "mkdir qos failed"
24355         # default max_inherit is -1, default max_inherit_rr is 0
24356         $LFS setdirstripe -D -c 1 $testdir/rr ||
24357                 error "setdirstripe rr failed"
24358         $LFS setdirstripe -D -c 1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24359                 error "setdirstripe qos failed"
24360         test_qos_mkdir "mkdir" 1
24361
24362         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24363         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24364         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24365         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24366         (( $inherit_rr == 0 )) ||
24367                 error "rr/level1 inherit-rr $inherit_rr != 0"
24368
24369         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24370         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24371         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24372         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24373         (( $inherit_rr == 0 )) ||
24374                 error "qos/level1 inherit-rr $inherit_rr !=0"
24375         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24376         getfattr -d -m dmv $testdir/qos/level1/level2 | grep dmv &&
24377                 error "level2 shouldn't have default LMV" || true
24378 }
24379 run_test 413c "mkdir with default LMV max inherit rr"
24380
24381 test_414() {
24382 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24383         $LCTL set_param fail_loc=0x80000521
24384         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24385         rm -f $DIR/$tfile
24386 }
24387 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24388
24389 test_415() {
24390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24391         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24392                 skip "Need server version at least 2.11.52"
24393
24394         # LU-11102
24395         local total
24396         local setattr_pid
24397         local start_time
24398         local end_time
24399         local duration
24400
24401         total=500
24402         # this test may be slow on ZFS
24403         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24404
24405         # though this test is designed for striped directory, let's test normal
24406         # directory too since lock is always saved as CoS lock.
24407         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24408         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24409
24410         (
24411                 while true; do
24412                         touch $DIR/$tdir
24413                 done
24414         ) &
24415         setattr_pid=$!
24416
24417         start_time=$(date +%s)
24418         for i in $(seq $total); do
24419                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24420                         > /dev/null
24421         done
24422         end_time=$(date +%s)
24423         duration=$((end_time - start_time))
24424
24425         kill -9 $setattr_pid
24426
24427         echo "rename $total files took $duration sec"
24428         [ $duration -lt 100 ] || error "rename took $duration sec"
24429 }
24430 run_test 415 "lock revoke is not missing"
24431
24432 test_416() {
24433         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24434                 skip "Need server version at least 2.11.55"
24435
24436         # define OBD_FAIL_OSD_TXN_START    0x19a
24437         do_facet mds1 lctl set_param fail_loc=0x19a
24438
24439         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24440
24441         true
24442 }
24443 run_test 416 "transaction start failure won't cause system hung"
24444
24445 cleanup_417() {
24446         trap 0
24447         do_nodes $(comma_list $(mdts_nodes)) \
24448                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24449         do_nodes $(comma_list $(mdts_nodes)) \
24450                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24451         do_nodes $(comma_list $(mdts_nodes)) \
24452                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24453 }
24454
24455 test_417() {
24456         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24457         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24458                 skip "Need MDS version at least 2.11.56"
24459
24460         trap cleanup_417 RETURN EXIT
24461
24462         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24463         do_nodes $(comma_list $(mdts_nodes)) \
24464                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24465         $LFS migrate -m 0 $DIR/$tdir.1 &&
24466                 error "migrate dir $tdir.1 should fail"
24467
24468         do_nodes $(comma_list $(mdts_nodes)) \
24469                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24470         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24471                 error "create remote dir $tdir.2 should fail"
24472
24473         do_nodes $(comma_list $(mdts_nodes)) \
24474                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24475         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24476                 error "create striped dir $tdir.3 should fail"
24477         true
24478 }
24479 run_test 417 "disable remote dir, striped dir and dir migration"
24480
24481 # Checks that the outputs of df [-i] and lfs df [-i] match
24482 #
24483 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24484 check_lfs_df() {
24485         local dir=$2
24486         local inodes
24487         local df_out
24488         local lfs_df_out
24489         local count
24490         local passed=false
24491
24492         # blocks or inodes
24493         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24494
24495         for count in {1..100}; do
24496                 cancel_lru_locks
24497                 sync; sleep 0.2
24498
24499                 # read the lines of interest
24500                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24501                         error "df $inodes $dir | tail -n +2 failed"
24502                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24503                         error "lfs df $inodes $dir | grep summary: failed"
24504
24505                 # skip first substrings of each output as they are different
24506                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24507                 # compare the two outputs
24508                 passed=true
24509                 for i in {1..5}; do
24510                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24511                 done
24512                 $passed && break
24513         done
24514
24515         if ! $passed; then
24516                 df -P $inodes $dir
24517                 echo
24518                 lfs df $inodes $dir
24519                 error "df and lfs df $1 output mismatch: "      \
24520                       "df ${inodes}: ${df_out[*]}, "            \
24521                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24522         fi
24523 }
24524
24525 test_418() {
24526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24527
24528         local dir=$DIR/$tdir
24529         local numfiles=$((RANDOM % 4096 + 2))
24530         local numblocks=$((RANDOM % 256 + 1))
24531
24532         wait_delete_completed
24533         test_mkdir $dir
24534
24535         # check block output
24536         check_lfs_df blocks $dir
24537         # check inode output
24538         check_lfs_df inodes $dir
24539
24540         # create a single file and retest
24541         echo "Creating a single file and testing"
24542         createmany -o $dir/$tfile- 1 &>/dev/null ||
24543                 error "creating 1 file in $dir failed"
24544         check_lfs_df blocks $dir
24545         check_lfs_df inodes $dir
24546
24547         # create a random number of files
24548         echo "Creating $((numfiles - 1)) files and testing"
24549         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24550                 error "creating $((numfiles - 1)) files in $dir failed"
24551
24552         # write a random number of blocks to the first test file
24553         echo "Writing $numblocks 4K blocks and testing"
24554         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24555                 count=$numblocks &>/dev/null ||
24556                 error "dd to $dir/${tfile}-0 failed"
24557
24558         # retest
24559         check_lfs_df blocks $dir
24560         check_lfs_df inodes $dir
24561
24562         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24563                 error "unlinking $numfiles files in $dir failed"
24564 }
24565 run_test 418 "df and lfs df outputs match"
24566
24567 test_419()
24568 {
24569         local dir=$DIR/$tdir
24570
24571         mkdir -p $dir
24572         touch $dir/file
24573
24574         cancel_lru_locks mdc
24575
24576         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24577         $LCTL set_param fail_loc=0x1410
24578         cat $dir/file
24579         $LCTL set_param fail_loc=0
24580         rm -rf $dir
24581 }
24582 run_test 419 "Verify open file by name doesn't crash kernel"
24583
24584 test_420()
24585 {
24586         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24587                 skip "Need MDS version at least 2.12.53"
24588
24589         local SAVE_UMASK=$(umask)
24590         local dir=$DIR/$tdir
24591         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24592
24593         mkdir -p $dir
24594         umask 0000
24595         mkdir -m03777 $dir/testdir
24596         ls -dn $dir/testdir
24597         # Need to remove trailing '.' when SELinux is enabled
24598         local dirperms=$(ls -dn $dir/testdir |
24599                          awk '{ sub(/\.$/, "", $1); print $1}')
24600         [ $dirperms == "drwxrwsrwt" ] ||
24601                 error "incorrect perms on $dir/testdir"
24602
24603         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24604                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24605         ls -n $dir/testdir/testfile
24606         local fileperms=$(ls -n $dir/testdir/testfile |
24607                           awk '{ sub(/\.$/, "", $1); print $1}')
24608         [ $fileperms == "-rwxr-xr-x" ] ||
24609                 error "incorrect perms on $dir/testdir/testfile"
24610
24611         umask $SAVE_UMASK
24612 }
24613 run_test 420 "clear SGID bit on non-directories for non-members"
24614
24615 test_421a() {
24616         local cnt
24617         local fid1
24618         local fid2
24619
24620         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24621                 skip "Need MDS version at least 2.12.54"
24622
24623         test_mkdir $DIR/$tdir
24624         createmany -o $DIR/$tdir/f 3
24625         cnt=$(ls -1 $DIR/$tdir | wc -l)
24626         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24627
24628         fid1=$(lfs path2fid $DIR/$tdir/f1)
24629         fid2=$(lfs path2fid $DIR/$tdir/f2)
24630         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
24631
24632         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
24633         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
24634
24635         cnt=$(ls -1 $DIR/$tdir | wc -l)
24636         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24637
24638         rm -f $DIR/$tdir/f3 || error "can't remove f3"
24639         createmany -o $DIR/$tdir/f 3
24640         cnt=$(ls -1 $DIR/$tdir | wc -l)
24641         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24642
24643         fid1=$(lfs path2fid $DIR/$tdir/f1)
24644         fid2=$(lfs path2fid $DIR/$tdir/f2)
24645         echo "remove using fsname $FSNAME"
24646         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
24647
24648         cnt=$(ls -1 $DIR/$tdir | wc -l)
24649         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24650 }
24651 run_test 421a "simple rm by fid"
24652
24653 test_421b() {
24654         local cnt
24655         local FID1
24656         local FID2
24657
24658         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24659                 skip "Need MDS version at least 2.12.54"
24660
24661         test_mkdir $DIR/$tdir
24662         createmany -o $DIR/$tdir/f 3
24663         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
24664         MULTIPID=$!
24665
24666         FID1=$(lfs path2fid $DIR/$tdir/f1)
24667         FID2=$(lfs path2fid $DIR/$tdir/f2)
24668         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
24669
24670         kill -USR1 $MULTIPID
24671         wait
24672
24673         cnt=$(ls $DIR/$tdir | wc -l)
24674         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
24675 }
24676 run_test 421b "rm by fid on open file"
24677
24678 test_421c() {
24679         local cnt
24680         local FIDS
24681
24682         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24683                 skip "Need MDS version at least 2.12.54"
24684
24685         test_mkdir $DIR/$tdir
24686         createmany -o $DIR/$tdir/f 3
24687         touch $DIR/$tdir/$tfile
24688         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
24689         cnt=$(ls -1 $DIR/$tdir | wc -l)
24690         [ $cnt != 184 ] && error "unexpected #files: $cnt"
24691
24692         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
24693         $LFS rmfid $DIR $FID1 || error "rmfid failed"
24694
24695         cnt=$(ls $DIR/$tdir | wc -l)
24696         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
24697 }
24698 run_test 421c "rm by fid against hardlinked files"
24699
24700 test_421d() {
24701         local cnt
24702         local FIDS
24703
24704         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24705                 skip "Need MDS version at least 2.12.54"
24706
24707         test_mkdir $DIR/$tdir
24708         createmany -o $DIR/$tdir/f 4097
24709         cnt=$(ls -1 $DIR/$tdir | wc -l)
24710         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
24711
24712         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
24713         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24714
24715         cnt=$(ls $DIR/$tdir | wc -l)
24716         rm -rf $DIR/$tdir
24717         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24718 }
24719 run_test 421d "rmfid en masse"
24720
24721 test_421e() {
24722         local cnt
24723         local FID
24724
24725         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24726         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24727                 skip "Need MDS version at least 2.12.54"
24728
24729         mkdir -p $DIR/$tdir
24730         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24731         createmany -o $DIR/$tdir/striped_dir/f 512
24732         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24733         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24734
24735         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24736                 sed "s/[/][^:]*://g")
24737         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24738
24739         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24740         rm -rf $DIR/$tdir
24741         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24742 }
24743 run_test 421e "rmfid in DNE"
24744
24745 test_421f() {
24746         local cnt
24747         local FID
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         touch $DIR/$tdir/f
24754         cnt=$(ls -1 $DIR/$tdir | wc -l)
24755         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24756
24757         FID=$(lfs path2fid $DIR/$tdir/f)
24758         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24759         # rmfid should fail
24760         cnt=$(ls -1 $DIR/$tdir | wc -l)
24761         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24762
24763         chmod a+rw $DIR/$tdir
24764         ls -la $DIR/$tdir
24765         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24766         # rmfid should fail
24767         cnt=$(ls -1 $DIR/$tdir | wc -l)
24768         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24769
24770         rm -f $DIR/$tdir/f
24771         $RUNAS touch $DIR/$tdir/f
24772         FID=$(lfs path2fid $DIR/$tdir/f)
24773         echo "rmfid as root"
24774         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24775         cnt=$(ls -1 $DIR/$tdir | wc -l)
24776         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24777
24778         rm -f $DIR/$tdir/f
24779         $RUNAS touch $DIR/$tdir/f
24780         cnt=$(ls -1 $DIR/$tdir | wc -l)
24781         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24782         FID=$(lfs path2fid $DIR/$tdir/f)
24783         # rmfid w/o user_fid2path mount option should fail
24784         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24785         cnt=$(ls -1 $DIR/$tdir | wc -l)
24786         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24787
24788         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24789         stack_trap "rmdir $tmpdir"
24790         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24791                 error "failed to mount client'"
24792         stack_trap "umount_client $tmpdir"
24793
24794         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24795         # rmfid should succeed
24796         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24797         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24798
24799         # rmfid shouldn't allow to remove files due to dir's permission
24800         chmod a+rwx $tmpdir/$tdir
24801         touch $tmpdir/$tdir/f
24802         ls -la $tmpdir/$tdir
24803         FID=$(lfs path2fid $tmpdir/$tdir/f)
24804         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24805         return 0
24806 }
24807 run_test 421f "rmfid checks permissions"
24808
24809 test_421g() {
24810         local cnt
24811         local FIDS
24812
24813         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24814         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24815                 skip "Need MDS version at least 2.12.54"
24816
24817         mkdir -p $DIR/$tdir
24818         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24819         createmany -o $DIR/$tdir/striped_dir/f 512
24820         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24821         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24822
24823         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24824                 sed "s/[/][^:]*://g")
24825
24826         rm -f $DIR/$tdir/striped_dir/f1*
24827         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24828         removed=$((512 - cnt))
24829
24830         # few files have been just removed, so we expect
24831         # rmfid to fail on their fids
24832         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24833         [ $removed != $errors ] && error "$errors != $removed"
24834
24835         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24836         rm -rf $DIR/$tdir
24837         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24838 }
24839 run_test 421g "rmfid to return errors properly"
24840
24841 test_422() {
24842         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24843         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24844         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24845         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24846         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24847
24848         local amc=$(at_max_get client)
24849         local amo=$(at_max_get mds1)
24850         local timeout=`lctl get_param -n timeout`
24851
24852         at_max_set 0 client
24853         at_max_set 0 mds1
24854
24855 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24856         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24857                         fail_val=$(((2*timeout + 10)*1000))
24858         touch $DIR/$tdir/d3/file &
24859         sleep 2
24860 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24861         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24862                         fail_val=$((2*timeout + 5))
24863         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24864         local pid=$!
24865         sleep 1
24866         kill -9 $pid
24867         sleep $((2 * timeout))
24868         echo kill $pid
24869         kill -9 $pid
24870         lctl mark touch
24871         touch $DIR/$tdir/d2/file3
24872         touch $DIR/$tdir/d2/file4
24873         touch $DIR/$tdir/d2/file5
24874
24875         wait
24876         at_max_set $amc client
24877         at_max_set $amo mds1
24878
24879         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24880         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24881                 error "Watchdog is always throttled"
24882 }
24883 run_test 422 "kill a process with RPC in progress"
24884
24885 stat_test() {
24886     df -h $MOUNT &
24887     df -h $MOUNT &
24888     df -h $MOUNT &
24889     df -h $MOUNT &
24890     df -h $MOUNT &
24891     df -h $MOUNT &
24892 }
24893
24894 test_423() {
24895     local _stats
24896     # ensure statfs cache is expired
24897     sleep 2;
24898
24899     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24900     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24901
24902     return 0
24903 }
24904 run_test 423 "statfs should return a right data"
24905
24906 test_424() {
24907 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24908         $LCTL set_param fail_loc=0x80000522
24909         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24910         rm -f $DIR/$tfile
24911 }
24912 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24913
24914 test_425() {
24915         test_mkdir -c -1 $DIR/$tdir
24916         $LFS setstripe -c -1 $DIR/$tdir
24917
24918         lru_resize_disable "" 100
24919         stack_trap "lru_resize_enable" EXIT
24920
24921         sleep 5
24922
24923         for i in $(seq $((MDSCOUNT * 125))); do
24924                 local t=$DIR/$tdir/$tfile_$i
24925
24926                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24927                         error_noexit "Create file $t"
24928         done
24929         stack_trap "rm -rf $DIR/$tdir" EXIT
24930
24931         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24932                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24933                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24934
24935                 [ $lock_count -le $lru_size ] ||
24936                         error "osc lock count $lock_count > lru size $lru_size"
24937         done
24938
24939         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24940                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24941                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24942
24943                 [ $lock_count -le $lru_size ] ||
24944                         error "mdc lock count $lock_count > lru size $lru_size"
24945         done
24946 }
24947 run_test 425 "lock count should not exceed lru size"
24948
24949 test_426() {
24950         splice-test -r $DIR/$tfile
24951         splice-test -rd $DIR/$tfile
24952         splice-test $DIR/$tfile
24953         splice-test -d $DIR/$tfile
24954 }
24955 run_test 426 "splice test on Lustre"
24956
24957 test_427() {
24958         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24959         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24960                 skip "Need MDS version at least 2.12.4"
24961         local log
24962
24963         mkdir $DIR/$tdir
24964         mkdir $DIR/$tdir/1
24965         mkdir $DIR/$tdir/2
24966         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24967         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24968
24969         $LFS getdirstripe $DIR/$tdir/1/dir
24970
24971         #first setfattr for creating updatelog
24972         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24973
24974 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24975         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24976         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24977         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24978
24979         sleep 2
24980         fail mds2
24981         wait_recovery_complete mds2 $((2*TIMEOUT))
24982
24983         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24984         echo $log | grep "get update log failed" &&
24985                 error "update log corruption is detected" || true
24986 }
24987 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24988
24989 test_428() {
24990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24991         local cache_limit=$CACHE_MAX
24992
24993         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
24994         $LCTL set_param -n llite.*.max_cached_mb=64
24995
24996         mkdir $DIR/$tdir
24997         $LFS setstripe -c 1 $DIR/$tdir
24998         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
24999         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25000         #test write
25001         for f in $(seq 4); do
25002                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25003         done
25004         wait
25005
25006         cancel_lru_locks osc
25007         # Test read
25008         for f in $(seq 4); do
25009                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25010         done
25011         wait
25012 }
25013 run_test 428 "large block size IO should not hang"
25014
25015 test_429() { # LU-7915 / LU-10948
25016         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25017         local testfile=$DIR/$tfile
25018         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25019         local new_flag=1
25020         local first_rpc
25021         local second_rpc
25022         local third_rpc
25023
25024         $LCTL get_param $ll_opencache_threshold_count ||
25025                 skip "client does not have opencache parameter"
25026
25027         set_opencache $new_flag
25028         stack_trap "restore_opencache"
25029         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25030                 error "enable opencache failed"
25031         touch $testfile
25032         # drop MDC DLM locks
25033         cancel_lru_locks mdc
25034         # clear MDC RPC stats counters
25035         $LCTL set_param $mdc_rpcstats=clear
25036
25037         # According to the current implementation, we need to run 3 times
25038         # open & close file to verify if opencache is enabled correctly.
25039         # 1st, RPCs are sent for lookup/open and open handle is released on
25040         #      close finally.
25041         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25042         #      so open handle won't be released thereafter.
25043         # 3rd, No RPC is sent out.
25044         $MULTIOP $testfile oc || error "multiop failed"
25045         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25046         echo "1st: $first_rpc RPCs in flight"
25047
25048         $MULTIOP $testfile oc || error "multiop failed"
25049         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25050         echo "2nd: $second_rpc RPCs in flight"
25051
25052         $MULTIOP $testfile oc || error "multiop failed"
25053         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25054         echo "3rd: $third_rpc RPCs in flight"
25055
25056         #verify no MDC RPC is sent
25057         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25058 }
25059 run_test 429 "verify if opencache flag on client side does work"
25060
25061 lseek_test_430() {
25062         local offset
25063         local file=$1
25064
25065         # data at [200K, 400K)
25066         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25067                 error "256K->512K dd fails"
25068         # data at [2M, 3M)
25069         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25070                 error "2M->3M dd fails"
25071         # data at [4M, 5M)
25072         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25073                 error "4M->5M dd fails"
25074         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25075         # start at first component hole #1
25076         printf "Seeking hole from 1000 ... "
25077         offset=$(lseek_test -l 1000 $file)
25078         echo $offset
25079         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25080         printf "Seeking data from 1000 ... "
25081         offset=$(lseek_test -d 1000 $file)
25082         echo $offset
25083         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25084
25085         # start at first component data block
25086         printf "Seeking hole from 300000 ... "
25087         offset=$(lseek_test -l 300000 $file)
25088         echo $offset
25089         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25090         printf "Seeking data from 300000 ... "
25091         offset=$(lseek_test -d 300000 $file)
25092         echo $offset
25093         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25094
25095         # start at the first component but beyond end of object size
25096         printf "Seeking hole from 1000000 ... "
25097         offset=$(lseek_test -l 1000000 $file)
25098         echo $offset
25099         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25100         printf "Seeking data from 1000000 ... "
25101         offset=$(lseek_test -d 1000000 $file)
25102         echo $offset
25103         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25104
25105         # start at second component stripe 2 (empty file)
25106         printf "Seeking hole from 1500000 ... "
25107         offset=$(lseek_test -l 1500000 $file)
25108         echo $offset
25109         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25110         printf "Seeking data from 1500000 ... "
25111         offset=$(lseek_test -d 1500000 $file)
25112         echo $offset
25113         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25114
25115         # start at second component stripe 1 (all data)
25116         printf "Seeking hole from 3000000 ... "
25117         offset=$(lseek_test -l 3000000 $file)
25118         echo $offset
25119         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25120         printf "Seeking data from 3000000 ... "
25121         offset=$(lseek_test -d 3000000 $file)
25122         echo $offset
25123         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25124
25125         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25126                 error "2nd dd fails"
25127         echo "Add data block at 640K...1280K"
25128
25129         # start at before new data block, in hole
25130         printf "Seeking hole from 600000 ... "
25131         offset=$(lseek_test -l 600000 $file)
25132         echo $offset
25133         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25134         printf "Seeking data from 600000 ... "
25135         offset=$(lseek_test -d 600000 $file)
25136         echo $offset
25137         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25138
25139         # start at the first component new data block
25140         printf "Seeking hole from 1000000 ... "
25141         offset=$(lseek_test -l 1000000 $file)
25142         echo $offset
25143         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25144         printf "Seeking data from 1000000 ... "
25145         offset=$(lseek_test -d 1000000 $file)
25146         echo $offset
25147         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25148
25149         # start at second component stripe 2, new data
25150         printf "Seeking hole from 1200000 ... "
25151         offset=$(lseek_test -l 1200000 $file)
25152         echo $offset
25153         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25154         printf "Seeking data from 1200000 ... "
25155         offset=$(lseek_test -d 1200000 $file)
25156         echo $offset
25157         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25158
25159         # start beyond file end
25160         printf "Using offset > filesize ... "
25161         lseek_test -l 4000000 $file && error "lseek should fail"
25162         printf "Using offset > filesize ... "
25163         lseek_test -d 4000000 $file && error "lseek should fail"
25164
25165         printf "Done\n\n"
25166 }
25167
25168 test_430a() {
25169         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25170                 skip "MDT does not support SEEK_HOLE"
25171
25172         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25173                 skip "OST does not support SEEK_HOLE"
25174
25175         local file=$DIR/$tdir/$tfile
25176
25177         mkdir -p $DIR/$tdir
25178
25179         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25180         # OST stripe #1 will have continuous data at [1M, 3M)
25181         # OST stripe #2 is empty
25182         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25183         lseek_test_430 $file
25184         rm $file
25185         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25186         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25187         lseek_test_430 $file
25188         rm $file
25189         $LFS setstripe -c2 -S 512K $file
25190         echo "Two stripes, stripe size 512K"
25191         lseek_test_430 $file
25192         rm $file
25193         # FLR with stale mirror
25194         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25195                        -N -c2 -S 1M $file
25196         echo "Mirrored file:"
25197         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25198         echo "Plain 2 stripes 1M"
25199         lseek_test_430 $file
25200         rm $file
25201 }
25202 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25203
25204 test_430b() {
25205         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25206                 skip "OST does not support SEEK_HOLE"
25207
25208         local offset
25209         local file=$DIR/$tdir/$tfile
25210
25211         mkdir -p $DIR/$tdir
25212         # Empty layout lseek should fail
25213         $MCREATE $file
25214         # seek from 0
25215         printf "Seeking hole from 0 ... "
25216         lseek_test -l 0 $file && error "lseek should fail"
25217         printf "Seeking data from 0 ... "
25218         lseek_test -d 0 $file && error "lseek should fail"
25219         rm $file
25220
25221         # 1M-hole file
25222         $LFS setstripe -E 1M -c2 -E eof $file
25223         $TRUNCATE $file 1048576
25224         printf "Seeking hole from 1000000 ... "
25225         offset=$(lseek_test -l 1000000 $file)
25226         echo $offset
25227         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25228         printf "Seeking data from 1000000 ... "
25229         lseek_test -d 1000000 $file && error "lseek should fail"
25230         rm $file
25231
25232         # full component followed by non-inited one
25233         $LFS setstripe -E 1M -c2 -E eof $file
25234         dd if=/dev/urandom of=$file bs=1M count=1
25235         printf "Seeking hole from 1000000 ... "
25236         offset=$(lseek_test -l 1000000 $file)
25237         echo $offset
25238         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25239         printf "Seeking hole from 1048576 ... "
25240         lseek_test -l 1048576 $file && error "lseek should fail"
25241         # init second component and truncate back
25242         echo "123" >> $file
25243         $TRUNCATE $file 1048576
25244         printf "Seeking hole from 1000000 ... "
25245         offset=$(lseek_test -l 1000000 $file)
25246         echo $offset
25247         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25248         printf "Seeking hole from 1048576 ... "
25249         lseek_test -l 1048576 $file && error "lseek should fail"
25250         # boundary checks for big values
25251         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25252         offset=$(lseek_test -d 0 $file.10g)
25253         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25254         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25255         offset=$(lseek_test -d 0 $file.100g)
25256         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25257         return 0
25258 }
25259 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25260
25261 test_430c() {
25262         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25263                 skip "OST does not support SEEK_HOLE"
25264
25265         local file=$DIR/$tdir/$tfile
25266         local start
25267
25268         mkdir -p $DIR/$tdir
25269         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25270
25271         # cp version 8.33+ prefers lseek over fiemap
25272         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25273                 start=$SECONDS
25274                 time cp $file /dev/null
25275                 (( SECONDS - start < 5 )) ||
25276                         error "cp: too long runtime $((SECONDS - start))"
25277
25278         fi
25279         # tar version 1.29+ supports SEEK_HOLE/DATA
25280         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25281                 start=$SECONDS
25282                 time tar cS $file - | cat > /dev/null
25283                 (( SECONDS - start < 5 )) ||
25284                         error "tar: too long runtime $((SECONDS - start))"
25285         fi
25286 }
25287 run_test 430c "lseek: external tools check"
25288
25289 test_431() { # LU-14187
25290         local file=$DIR/$tdir/$tfile
25291
25292         mkdir -p $DIR/$tdir
25293         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25294         dd if=/dev/urandom of=$file bs=4k count=1
25295         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25296         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25297         #define OBD_FAIL_OST_RESTART_IO 0x251
25298         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25299         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25300         cp $file $file.0
25301         cancel_lru_locks
25302         sync_all_data
25303         echo 3 > /proc/sys/vm/drop_caches
25304         diff  $file $file.0 || error "data diff"
25305 }
25306 run_test 431 "Restart transaction for IO"
25307
25308 prep_801() {
25309         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25310         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25311                 skip "Need server version at least 2.9.55"
25312
25313         start_full_debug_logging
25314 }
25315
25316 post_801() {
25317         stop_full_debug_logging
25318 }
25319
25320 barrier_stat() {
25321         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25322                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25323                            awk '/The barrier for/ { print $7 }')
25324                 echo $st
25325         else
25326                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25327                 echo \'$st\'
25328         fi
25329 }
25330
25331 barrier_expired() {
25332         local expired
25333
25334         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25335                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25336                           awk '/will be expired/ { print $7 }')
25337         else
25338                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25339         fi
25340
25341         echo $expired
25342 }
25343
25344 test_801a() {
25345         prep_801
25346
25347         echo "Start barrier_freeze at: $(date)"
25348         #define OBD_FAIL_BARRIER_DELAY          0x2202
25349         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25350         # Do not reduce barrier time - See LU-11873
25351         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25352
25353         sleep 2
25354         local b_status=$(barrier_stat)
25355         echo "Got barrier status at: $(date)"
25356         [ "$b_status" = "'freezing_p1'" ] ||
25357                 error "(1) unexpected barrier status $b_status"
25358
25359         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25360         wait
25361         b_status=$(barrier_stat)
25362         [ "$b_status" = "'frozen'" ] ||
25363                 error "(2) unexpected barrier status $b_status"
25364
25365         local expired=$(barrier_expired)
25366         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25367         sleep $((expired + 3))
25368
25369         b_status=$(barrier_stat)
25370         [ "$b_status" = "'expired'" ] ||
25371                 error "(3) unexpected barrier status $b_status"
25372
25373         # Do not reduce barrier time - See LU-11873
25374         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25375                 error "(4) fail to freeze barrier"
25376
25377         b_status=$(barrier_stat)
25378         [ "$b_status" = "'frozen'" ] ||
25379                 error "(5) unexpected barrier status $b_status"
25380
25381         echo "Start barrier_thaw at: $(date)"
25382         #define OBD_FAIL_BARRIER_DELAY          0x2202
25383         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25384         do_facet mgs $LCTL barrier_thaw $FSNAME &
25385
25386         sleep 2
25387         b_status=$(barrier_stat)
25388         echo "Got barrier status at: $(date)"
25389         [ "$b_status" = "'thawing'" ] ||
25390                 error "(6) unexpected barrier status $b_status"
25391
25392         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25393         wait
25394         b_status=$(barrier_stat)
25395         [ "$b_status" = "'thawed'" ] ||
25396                 error "(7) unexpected barrier status $b_status"
25397
25398         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25399         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25400         do_facet mgs $LCTL barrier_freeze $FSNAME
25401
25402         b_status=$(barrier_stat)
25403         [ "$b_status" = "'failed'" ] ||
25404                 error "(8) unexpected barrier status $b_status"
25405
25406         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25407         do_facet mgs $LCTL barrier_thaw $FSNAME
25408
25409         post_801
25410 }
25411 run_test 801a "write barrier user interfaces and stat machine"
25412
25413 test_801b() {
25414         prep_801
25415
25416         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25417         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25418         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25419         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25420         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25421
25422         cancel_lru_locks mdc
25423
25424         # 180 seconds should be long enough
25425         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25426
25427         local b_status=$(barrier_stat)
25428         [ "$b_status" = "'frozen'" ] ||
25429                 error "(6) unexpected barrier status $b_status"
25430
25431         mkdir $DIR/$tdir/d0/d10 &
25432         mkdir_pid=$!
25433
25434         touch $DIR/$tdir/d1/f13 &
25435         touch_pid=$!
25436
25437         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25438         ln_pid=$!
25439
25440         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
25441         mv_pid=$!
25442
25443         rm -f $DIR/$tdir/d4/f12 &
25444         rm_pid=$!
25445
25446         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
25447
25448         # To guarantee taht the 'stat' is not blocked
25449         b_status=$(barrier_stat)
25450         [ "$b_status" = "'frozen'" ] ||
25451                 error "(8) unexpected barrier status $b_status"
25452
25453         # let above commands to run at background
25454         sleep 5
25455
25456         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
25457         ps -p $touch_pid || error "(10) touch should be blocked"
25458         ps -p $ln_pid || error "(11) link should be blocked"
25459         ps -p $mv_pid || error "(12) rename should be blocked"
25460         ps -p $rm_pid || error "(13) unlink should be blocked"
25461
25462         b_status=$(barrier_stat)
25463         [ "$b_status" = "'frozen'" ] ||
25464                 error "(14) unexpected barrier status $b_status"
25465
25466         do_facet mgs $LCTL barrier_thaw $FSNAME
25467         b_status=$(barrier_stat)
25468         [ "$b_status" = "'thawed'" ] ||
25469                 error "(15) unexpected barrier status $b_status"
25470
25471         wait $mkdir_pid || error "(16) mkdir should succeed"
25472         wait $touch_pid || error "(17) touch should succeed"
25473         wait $ln_pid || error "(18) link should succeed"
25474         wait $mv_pid || error "(19) rename should succeed"
25475         wait $rm_pid || error "(20) unlink should succeed"
25476
25477         post_801
25478 }
25479 run_test 801b "modification will be blocked by write barrier"
25480
25481 test_801c() {
25482         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25483
25484         prep_801
25485
25486         stop mds2 || error "(1) Fail to stop mds2"
25487
25488         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25489
25490         local b_status=$(barrier_stat)
25491         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25492                 do_facet mgs $LCTL barrier_thaw $FSNAME
25493                 error "(2) unexpected barrier status $b_status"
25494         }
25495
25496         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25497                 error "(3) Fail to rescan barrier bitmap"
25498
25499         # Do not reduce barrier time - See LU-11873
25500         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25501
25502         b_status=$(barrier_stat)
25503         [ "$b_status" = "'frozen'" ] ||
25504                 error "(4) unexpected barrier status $b_status"
25505
25506         do_facet mgs $LCTL barrier_thaw $FSNAME
25507         b_status=$(barrier_stat)
25508         [ "$b_status" = "'thawed'" ] ||
25509                 error "(5) unexpected barrier status $b_status"
25510
25511         local devname=$(mdsdevname 2)
25512
25513         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25514
25515         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25516                 error "(7) Fail to rescan barrier bitmap"
25517
25518         post_801
25519 }
25520 run_test 801c "rescan barrier bitmap"
25521
25522 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25523 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25524 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25525 saved_MOUNT_OPTS=$MOUNT_OPTS
25526
25527 cleanup_802a() {
25528         trap 0
25529
25530         stopall
25531         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25532         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25533         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25534         MOUNT_OPTS=$saved_MOUNT_OPTS
25535         setupall
25536 }
25537
25538 test_802a() {
25539         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25540         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25541         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25542                 skip "Need server version at least 2.9.55"
25543
25544         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25545
25546         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25547
25548         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25549                 error "(2) Fail to copy"
25550
25551         trap cleanup_802a EXIT
25552
25553         # sync by force before remount as readonly
25554         sync; sync_all_data; sleep 3; sync_all_data
25555
25556         stopall
25557
25558         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25559         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25560         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25561
25562         echo "Mount the server as read only"
25563         setupall server_only || error "(3) Fail to start servers"
25564
25565         echo "Mount client without ro should fail"
25566         mount_client $MOUNT &&
25567                 error "(4) Mount client without 'ro' should fail"
25568
25569         echo "Mount client with ro should succeed"
25570         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25571         mount_client $MOUNT ||
25572                 error "(5) Mount client with 'ro' should succeed"
25573
25574         echo "Modify should be refused"
25575         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25576
25577         echo "Read should be allowed"
25578         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25579                 error "(7) Read should succeed under ro mode"
25580
25581         cleanup_802a
25582 }
25583 run_test 802a "simulate readonly device"
25584
25585 test_802b() {
25586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25587         remote_mds_nodsh && skip "remote MDS with nodsh"
25588
25589         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25590                 skip "readonly option not available"
25591
25592         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25593
25594         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25595                 error "(2) Fail to copy"
25596
25597         # write back all cached data before setting MDT to readonly
25598         cancel_lru_locks
25599         sync_all_data
25600
25601         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25602         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25603
25604         echo "Modify should be refused"
25605         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25606
25607         echo "Read should be allowed"
25608         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25609                 error "(7) Read should succeed under ro mode"
25610
25611         # disable readonly
25612         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25613 }
25614 run_test 802b "be able to set MDTs to readonly"
25615
25616 test_803a() {
25617         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25618         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25619                 skip "MDS needs to be newer than 2.10.54"
25620
25621         mkdir -p $DIR/$tdir
25622         # Create some objects on all MDTs to trigger related logs objects
25623         for idx in $(seq $MDSCOUNT); do
25624                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
25625                         $DIR/$tdir/dir${idx} ||
25626                         error "Fail to create $DIR/$tdir/dir${idx}"
25627         done
25628
25629         sync; sleep 3
25630         wait_delete_completed # ensure old test cleanups are finished
25631         echo "before create:"
25632         $LFS df -i $MOUNT
25633         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25634
25635         for i in {1..10}; do
25636                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
25637                         error "Fail to create $DIR/$tdir/foo$i"
25638         done
25639
25640         sync; sleep 3
25641         echo "after create:"
25642         $LFS df -i $MOUNT
25643         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25644
25645         # allow for an llog to be cleaned up during the test
25646         [ $after_used -ge $((before_used + 10 - 1)) ] ||
25647                 error "before ($before_used) + 10 > after ($after_used)"
25648
25649         for i in {1..10}; do
25650                 rm -rf $DIR/$tdir/foo$i ||
25651                         error "Fail to remove $DIR/$tdir/foo$i"
25652         done
25653
25654         sleep 3 # avoid MDT return cached statfs
25655         wait_delete_completed
25656         echo "after unlink:"
25657         $LFS df -i $MOUNT
25658         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25659
25660         # allow for an llog to be created during the test
25661         [ $after_used -le $((before_used + 1)) ] ||
25662                 error "after ($after_used) > before ($before_used) + 1"
25663 }
25664 run_test 803a "verify agent object for remote object"
25665
25666 test_803b() {
25667         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25668         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
25669                 skip "MDS needs to be newer than 2.13.56"
25670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25671
25672         for i in $(seq 0 $((MDSCOUNT - 1))); do
25673                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
25674         done
25675
25676         local before=0
25677         local after=0
25678
25679         local tmp
25680
25681         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25682         for i in $(seq 0 $((MDSCOUNT - 1))); do
25683                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25684                         awk '/getattr/ { print $2 }')
25685                 before=$((before + tmp))
25686         done
25687         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25688         for i in $(seq 0 $((MDSCOUNT - 1))); do
25689                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25690                         awk '/getattr/ { print $2 }')
25691                 after=$((after + tmp))
25692         done
25693
25694         [ $before -eq $after ] || error "getattr count $before != $after"
25695 }
25696 run_test 803b "remote object can getattr from cache"
25697
25698 test_804() {
25699         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25700         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25701                 skip "MDS needs to be newer than 2.10.54"
25702         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
25703
25704         mkdir -p $DIR/$tdir
25705         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
25706                 error "Fail to create $DIR/$tdir/dir0"
25707
25708         local fid=$($LFS path2fid $DIR/$tdir/dir0)
25709         local dev=$(mdsdevname 2)
25710
25711         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25712                 grep ${fid} || error "NOT found agent entry for dir0"
25713
25714         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
25715                 error "Fail to create $DIR/$tdir/dir1"
25716
25717         touch $DIR/$tdir/dir1/foo0 ||
25718                 error "Fail to create $DIR/$tdir/dir1/foo0"
25719         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
25720         local rc=0
25721
25722         for idx in $(seq $MDSCOUNT); do
25723                 dev=$(mdsdevname $idx)
25724                 do_facet mds${idx} \
25725                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25726                         grep ${fid} && rc=$idx
25727         done
25728
25729         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
25730                 error "Fail to rename foo0 to foo1"
25731         if [ $rc -eq 0 ]; then
25732                 for idx in $(seq $MDSCOUNT); do
25733                         dev=$(mdsdevname $idx)
25734                         do_facet mds${idx} \
25735                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25736                         grep ${fid} && rc=$idx
25737                 done
25738         fi
25739
25740         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
25741                 error "Fail to rename foo1 to foo2"
25742         if [ $rc -eq 0 ]; then
25743                 for idx in $(seq $MDSCOUNT); do
25744                         dev=$(mdsdevname $idx)
25745                         do_facet mds${idx} \
25746                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25747                         grep ${fid} && rc=$idx
25748                 done
25749         fi
25750
25751         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
25752
25753         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
25754                 error "Fail to link to $DIR/$tdir/dir1/foo2"
25755         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
25756                 error "Fail to rename foo2 to foo0"
25757         unlink $DIR/$tdir/dir1/foo0 ||
25758                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
25759         rm -rf $DIR/$tdir/dir0 ||
25760                 error "Fail to rm $DIR/$tdir/dir0"
25761
25762         for idx in $(seq $MDSCOUNT); do
25763                 dev=$(mdsdevname $idx)
25764                 rc=0
25765
25766                 stop mds${idx}
25767                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25768                         rc=$?
25769                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25770                         error "mount mds$idx failed"
25771                 df $MOUNT > /dev/null 2>&1
25772
25773                 # e2fsck should not return error
25774                 [ $rc -eq 0 ] ||
25775                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25776         done
25777 }
25778 run_test 804 "verify agent entry for remote entry"
25779
25780 cleanup_805() {
25781         do_facet $SINGLEMDS zfs set quota=$old $fsset
25782         unlinkmany $DIR/$tdir/f- 1000000
25783         trap 0
25784 }
25785
25786 test_805() {
25787         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25788         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25789         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25790                 skip "netfree not implemented before 0.7"
25791         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25792                 skip "Need MDS version at least 2.10.57"
25793
25794         local fsset
25795         local freekb
25796         local usedkb
25797         local old
25798         local quota
25799         local pref="osd-zfs.$FSNAME-MDT0000."
25800
25801         # limit available space on MDS dataset to meet nospace issue
25802         # quickly. then ZFS 0.7.2 can use reserved space if asked
25803         # properly (using netfree flag in osd_declare_destroy()
25804         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25805         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25806                 gawk '{print $3}')
25807         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25808         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25809         let "usedkb=usedkb-freekb"
25810         let "freekb=freekb/2"
25811         if let "freekb > 5000"; then
25812                 let "freekb=5000"
25813         fi
25814         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25815         trap cleanup_805 EXIT
25816         mkdir $DIR/$tdir
25817         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25818                 error "Can't set PFL layout"
25819         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25820         rm -rf $DIR/$tdir || error "not able to remove"
25821         do_facet $SINGLEMDS zfs set quota=$old $fsset
25822         trap 0
25823 }
25824 run_test 805 "ZFS can remove from full fs"
25825
25826 # Size-on-MDS test
25827 check_lsom_data()
25828 {
25829         local file=$1
25830         local expect=$(stat -c %s $file)
25831
25832         check_lsom_size $1 $expect
25833
25834         local blocks=$($LFS getsom -b $file)
25835         expect=$(stat -c %b $file)
25836         [[ $blocks == $expect ]] ||
25837                 error "$file expected blocks: $expect, got: $blocks"
25838 }
25839
25840 check_lsom_size()
25841 {
25842         local size
25843         local expect=$2
25844
25845         cancel_lru_locks mdc
25846
25847         size=$($LFS getsom -s $1)
25848         [[ $size == $expect ]] ||
25849                 error "$file expected size: $expect, got: $size"
25850 }
25851
25852 test_806() {
25853         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25854                 skip "Need MDS version at least 2.11.52"
25855
25856         local bs=1048576
25857
25858         touch $DIR/$tfile || error "touch $tfile failed"
25859
25860         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25861         save_lustre_params client "llite.*.xattr_cache" > $save
25862         lctl set_param llite.*.xattr_cache=0
25863         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25864
25865         # single-threaded write
25866         echo "Test SOM for single-threaded write"
25867         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25868                 error "write $tfile failed"
25869         check_lsom_size $DIR/$tfile $bs
25870
25871         local num=32
25872         local size=$(($num * $bs))
25873         local offset=0
25874         local i
25875
25876         echo "Test SOM for single client multi-threaded($num) write"
25877         $TRUNCATE $DIR/$tfile 0
25878         for ((i = 0; i < $num; i++)); do
25879                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25880                 local pids[$i]=$!
25881                 offset=$((offset + $bs))
25882         done
25883         for (( i=0; i < $num; i++ )); do
25884                 wait ${pids[$i]}
25885         done
25886         check_lsom_size $DIR/$tfile $size
25887
25888         $TRUNCATE $DIR/$tfile 0
25889         for ((i = 0; i < $num; i++)); do
25890                 offset=$((offset - $bs))
25891                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25892                 local pids[$i]=$!
25893         done
25894         for (( i=0; i < $num; i++ )); do
25895                 wait ${pids[$i]}
25896         done
25897         check_lsom_size $DIR/$tfile $size
25898
25899         # multi-client writes
25900         num=$(get_node_count ${CLIENTS//,/ })
25901         size=$(($num * $bs))
25902         offset=0
25903         i=0
25904
25905         echo "Test SOM for multi-client ($num) writes"
25906         $TRUNCATE $DIR/$tfile 0
25907         for client in ${CLIENTS//,/ }; do
25908                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25909                 local pids[$i]=$!
25910                 i=$((i + 1))
25911                 offset=$((offset + $bs))
25912         done
25913         for (( i=0; i < $num; i++ )); do
25914                 wait ${pids[$i]}
25915         done
25916         check_lsom_size $DIR/$tfile $offset
25917
25918         i=0
25919         $TRUNCATE $DIR/$tfile 0
25920         for client in ${CLIENTS//,/ }; do
25921                 offset=$((offset - $bs))
25922                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25923                 local pids[$i]=$!
25924                 i=$((i + 1))
25925         done
25926         for (( i=0; i < $num; i++ )); do
25927                 wait ${pids[$i]}
25928         done
25929         check_lsom_size $DIR/$tfile $size
25930
25931         # verify truncate
25932         echo "Test SOM for truncate"
25933         $TRUNCATE $DIR/$tfile 1048576
25934         check_lsom_size $DIR/$tfile 1048576
25935         $TRUNCATE $DIR/$tfile 1234
25936         check_lsom_size $DIR/$tfile 1234
25937
25938         # verify SOM blocks count
25939         echo "Verify SOM block count"
25940         $TRUNCATE $DIR/$tfile 0
25941         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25942                 error "failed to write file $tfile"
25943         check_lsom_data $DIR/$tfile
25944 }
25945 run_test 806 "Verify Lazy Size on MDS"
25946
25947 test_807() {
25948         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25949         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25950                 skip "Need MDS version at least 2.11.52"
25951
25952         # Registration step
25953         changelog_register || error "changelog_register failed"
25954         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25955         changelog_users $SINGLEMDS | grep -q $cl_user ||
25956                 error "User $cl_user not found in changelog_users"
25957
25958         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25959         save_lustre_params client "llite.*.xattr_cache" > $save
25960         lctl set_param llite.*.xattr_cache=0
25961         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25962
25963         rm -rf $DIR/$tdir || error "rm $tdir failed"
25964         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25965         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25966         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25967         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25968                 error "truncate $tdir/trunc failed"
25969
25970         local bs=1048576
25971         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25972                 error "write $tfile failed"
25973
25974         # multi-client wirtes
25975         local num=$(get_node_count ${CLIENTS//,/ })
25976         local offset=0
25977         local i=0
25978
25979         echo "Test SOM for multi-client ($num) writes"
25980         touch $DIR/$tfile || error "touch $tfile failed"
25981         $TRUNCATE $DIR/$tfile 0
25982         for client in ${CLIENTS//,/ }; do
25983                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25984                 local pids[$i]=$!
25985                 i=$((i + 1))
25986                 offset=$((offset + $bs))
25987         done
25988         for (( i=0; i < $num; i++ )); do
25989                 wait ${pids[$i]}
25990         done
25991
25992         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25993         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25994         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25995         check_lsom_data $DIR/$tdir/trunc
25996         check_lsom_data $DIR/$tdir/single_dd
25997         check_lsom_data $DIR/$tfile
25998
25999         rm -rf $DIR/$tdir
26000         # Deregistration step
26001         changelog_deregister || error "changelog_deregister failed"
26002 }
26003 run_test 807 "verify LSOM syncing tool"
26004
26005 check_som_nologged()
26006 {
26007         local lines=$($LFS changelog $FSNAME-MDT0000 |
26008                 grep 'x=trusted.som' | wc -l)
26009         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26010 }
26011
26012 test_808() {
26013         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26014                 skip "Need MDS version at least 2.11.55"
26015
26016         # Registration step
26017         changelog_register || error "changelog_register failed"
26018
26019         touch $DIR/$tfile || error "touch $tfile failed"
26020         check_som_nologged
26021
26022         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26023                 error "write $tfile failed"
26024         check_som_nologged
26025
26026         $TRUNCATE $DIR/$tfile 1234
26027         check_som_nologged
26028
26029         $TRUNCATE $DIR/$tfile 1048576
26030         check_som_nologged
26031
26032         # Deregistration step
26033         changelog_deregister || error "changelog_deregister failed"
26034 }
26035 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26036
26037 check_som_nodata()
26038 {
26039         $LFS getsom $1
26040         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26041 }
26042
26043 test_809() {
26044         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26045                 skip "Need MDS version at least 2.11.56"
26046
26047         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26048                 error "failed to create DoM-only file $DIR/$tfile"
26049         touch $DIR/$tfile || error "touch $tfile failed"
26050         check_som_nodata $DIR/$tfile
26051
26052         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26053                 error "write $tfile failed"
26054         check_som_nodata $DIR/$tfile
26055
26056         $TRUNCATE $DIR/$tfile 1234
26057         check_som_nodata $DIR/$tfile
26058
26059         $TRUNCATE $DIR/$tfile 4097
26060         check_som_nodata $DIR/$file
26061 }
26062 run_test 809 "Verify no SOM xattr store for DoM-only files"
26063
26064 test_810() {
26065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26066         $GSS && skip_env "could not run with gss"
26067         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26068                 skip "OST < 2.12.58 doesn't align checksum"
26069
26070         set_checksums 1
26071         stack_trap "set_checksums $ORIG_CSUM" EXIT
26072         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26073
26074         local csum
26075         local before
26076         local after
26077         for csum in $CKSUM_TYPES; do
26078                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26079                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26080                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26081                         eval set -- $i
26082                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26083                         before=$(md5sum $DIR/$tfile)
26084                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26085                         after=$(md5sum $DIR/$tfile)
26086                         [ "$before" == "$after" ] ||
26087                                 error "$csum: $before != $after bs=$1 seek=$2"
26088                 done
26089         done
26090 }
26091 run_test 810 "partial page writes on ZFS (LU-11663)"
26092
26093 test_812a() {
26094         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26095                 skip "OST < 2.12.51 doesn't support this fail_loc"
26096
26097         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26098         # ensure ost1 is connected
26099         stat $DIR/$tfile >/dev/null || error "can't stat"
26100         wait_osc_import_state client ost1 FULL
26101         # no locks, no reqs to let the connection idle
26102         cancel_lru_locks osc
26103
26104         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26105 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26106         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26107         wait_osc_import_state client ost1 CONNECTING
26108         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26109
26110         stat $DIR/$tfile >/dev/null || error "can't stat file"
26111 }
26112 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26113
26114 test_812b() { # LU-12378
26115         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26116                 skip "OST < 2.12.51 doesn't support this fail_loc"
26117
26118         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26119         # ensure ost1 is connected
26120         stat $DIR/$tfile >/dev/null || error "can't stat"
26121         wait_osc_import_state client ost1 FULL
26122         # no locks, no reqs to let the connection idle
26123         cancel_lru_locks osc
26124
26125         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26126 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26127         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26128         wait_osc_import_state client ost1 CONNECTING
26129         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26130
26131         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26132         wait_osc_import_state client ost1 IDLE
26133 }
26134 run_test 812b "do not drop no resend request for idle connect"
26135
26136 test_812c() {
26137         local old
26138
26139         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26140
26141         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26142         $LFS getstripe $DIR/$tfile
26143         $LCTL set_param osc.*.idle_timeout=10
26144         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26145         # ensure ost1 is connected
26146         stat $DIR/$tfile >/dev/null || error "can't stat"
26147         wait_osc_import_state client ost1 FULL
26148         # no locks, no reqs to let the connection idle
26149         cancel_lru_locks osc
26150
26151 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26152         $LCTL set_param fail_loc=0x80000533
26153         sleep 15
26154         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26155 }
26156 run_test 812c "idle import vs lock enqueue race"
26157
26158 test_813() {
26159         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26160         [ -z "$file_heat_sav" ] && skip "no file heat support"
26161
26162         local readsample
26163         local writesample
26164         local readbyte
26165         local writebyte
26166         local readsample1
26167         local writesample1
26168         local readbyte1
26169         local writebyte1
26170
26171         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26172         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26173
26174         $LCTL set_param -n llite.*.file_heat=1
26175         echo "Turn on file heat"
26176         echo "Period second: $period_second, Decay percentage: $decay_pct"
26177
26178         echo "QQQQ" > $DIR/$tfile
26179         echo "QQQQ" > $DIR/$tfile
26180         echo "QQQQ" > $DIR/$tfile
26181         cat $DIR/$tfile > /dev/null
26182         cat $DIR/$tfile > /dev/null
26183         cat $DIR/$tfile > /dev/null
26184         cat $DIR/$tfile > /dev/null
26185
26186         local out=$($LFS heat_get $DIR/$tfile)
26187
26188         $LFS heat_get $DIR/$tfile
26189         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26190         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26191         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26192         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26193
26194         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26195         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26196         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26197         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26198
26199         sleep $((period_second + 3))
26200         echo "Sleep $((period_second + 3)) seconds..."
26201         # The recursion formula to calculate the heat of the file f is as
26202         # follow:
26203         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26204         # Where Hi is the heat value in the period between time points i*I and
26205         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26206         # to the weight of Ci.
26207         out=$($LFS heat_get $DIR/$tfile)
26208         $LFS heat_get $DIR/$tfile
26209         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26210         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26211         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26212         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26213
26214         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26215                 error "read sample ($readsample) is wrong"
26216         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26217                 error "write sample ($writesample) is wrong"
26218         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26219                 error "read bytes ($readbyte) is wrong"
26220         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26221                 error "write bytes ($writebyte) is wrong"
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         sleep $((period_second + 3))
26232         echo "Sleep $((period_second + 3)) seconds..."
26233
26234         out=$($LFS heat_get $DIR/$tfile)
26235         $LFS heat_get $DIR/$tfile
26236         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26237         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26238         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26239         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26240
26241         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26242                 4 * $decay_pct) / 100") -eq 1 ] ||
26243                 error "read sample ($readsample1) is wrong"
26244         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26245                 3 * $decay_pct) / 100") -eq 1 ] ||
26246                 error "write sample ($writesample1) is wrong"
26247         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26248                 20 * $decay_pct) / 100") -eq 1 ] ||
26249                 error "read bytes ($readbyte1) is wrong"
26250         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26251                 15 * $decay_pct) / 100") -eq 1 ] ||
26252                 error "write bytes ($writebyte1) is wrong"
26253
26254         echo "Turn off file heat for the file $DIR/$tfile"
26255         $LFS heat_set -o $DIR/$tfile
26256
26257         echo "QQQQ" > $DIR/$tfile
26258         echo "QQQQ" > $DIR/$tfile
26259         echo "QQQQ" > $DIR/$tfile
26260         cat $DIR/$tfile > /dev/null
26261         cat $DIR/$tfile > /dev/null
26262         cat $DIR/$tfile > /dev/null
26263         cat $DIR/$tfile > /dev/null
26264
26265         out=$($LFS heat_get $DIR/$tfile)
26266         $LFS heat_get $DIR/$tfile
26267         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26268         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26269         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26270         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26271
26272         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26273         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26274         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26275         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26276
26277         echo "Trun on file heat for the file $DIR/$tfile"
26278         $LFS heat_set -O $DIR/$tfile
26279
26280         echo "QQQQ" > $DIR/$tfile
26281         echo "QQQQ" > $DIR/$tfile
26282         echo "QQQQ" > $DIR/$tfile
26283         cat $DIR/$tfile > /dev/null
26284         cat $DIR/$tfile > /dev/null
26285         cat $DIR/$tfile > /dev/null
26286         cat $DIR/$tfile > /dev/null
26287
26288         out=$($LFS heat_get $DIR/$tfile)
26289         $LFS heat_get $DIR/$tfile
26290         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26291         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26292         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26293         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26294
26295         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26296         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26297         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26298         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26299
26300         $LFS heat_set -c $DIR/$tfile
26301         $LCTL set_param -n llite.*.file_heat=0
26302         echo "Turn off file heat support for the Lustre filesystem"
26303
26304         echo "QQQQ" > $DIR/$tfile
26305         echo "QQQQ" > $DIR/$tfile
26306         echo "QQQQ" > $DIR/$tfile
26307         cat $DIR/$tfile > /dev/null
26308         cat $DIR/$tfile > /dev/null
26309         cat $DIR/$tfile > /dev/null
26310         cat $DIR/$tfile > /dev/null
26311
26312         out=$($LFS heat_get $DIR/$tfile)
26313         $LFS heat_get $DIR/$tfile
26314         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26315         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26316         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26317         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26318
26319         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26320         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26321         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26322         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26323
26324         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26325         rm -f $DIR/$tfile
26326 }
26327 run_test 813 "File heat verfication"
26328
26329 test_814()
26330 {
26331         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26332         echo -n y >> $DIR/$tfile
26333         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26334         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26335 }
26336 run_test 814 "sparse cp works as expected (LU-12361)"
26337
26338 test_815()
26339 {
26340         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26341         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26342 }
26343 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26344
26345 test_816() {
26346         local ost1_imp=$(get_osc_import_name client ost1)
26347         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26348                          cut -d'.' -f2)
26349
26350         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26351         # ensure ost1 is connected
26352
26353         stat $DIR/$tfile >/dev/null || error "can't stat"
26354         wait_osc_import_state client ost1 FULL
26355         # no locks, no reqs to let the connection idle
26356         cancel_lru_locks osc
26357         lru_resize_disable osc
26358         local before
26359         local now
26360         before=$($LCTL get_param -n \
26361                  ldlm.namespaces.$imp_name.lru_size)
26362
26363         wait_osc_import_state client ost1 IDLE
26364         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26365         now=$($LCTL get_param -n \
26366               ldlm.namespaces.$imp_name.lru_size)
26367         [ $before == $now ] || error "lru_size changed $before != $now"
26368 }
26369 run_test 816 "do not reset lru_resize on idle reconnect"
26370
26371 cleanup_817() {
26372         umount $tmpdir
26373         exportfs -u localhost:$DIR/nfsexp
26374         rm -rf $DIR/nfsexp
26375 }
26376
26377 test_817() {
26378         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26379
26380         mkdir -p $DIR/nfsexp
26381         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26382                 error "failed to export nfs"
26383
26384         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26385         stack_trap cleanup_817 EXIT
26386
26387         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26388                 error "failed to mount nfs to $tmpdir"
26389
26390         cp /bin/true $tmpdir
26391         $DIR/nfsexp/true || error "failed to execute 'true' command"
26392 }
26393 run_test 817 "nfsd won't cache write lock for exec file"
26394
26395 test_818() {
26396         mkdir $DIR/$tdir
26397         $LFS setstripe -c1 -i0 $DIR/$tfile
26398         $LFS setstripe -c1 -i1 $DIR/$tfile
26399         stop $SINGLEMDS
26400         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26401         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26402         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26403                 error "start $SINGLEMDS failed"
26404         rm -rf $DIR/$tdir
26405 }
26406 run_test 818 "unlink with failed llog"
26407
26408 test_819a() {
26409         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26410         cancel_lru_locks osc
26411         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26412         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26413         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26414         rm -f $TDIR/$tfile
26415 }
26416 run_test 819a "too big niobuf in read"
26417
26418 test_819b() {
26419         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26420         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26421         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26422         cancel_lru_locks osc
26423         sleep 1
26424         rm -f $TDIR/$tfile
26425 }
26426 run_test 819b "too big niobuf in write"
26427
26428
26429 function test_820_start_ost() {
26430         sleep 5
26431
26432         for num in $(seq $OSTCOUNT); do
26433                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26434         done
26435 }
26436
26437 test_820() {
26438         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26439
26440         mkdir $DIR/$tdir
26441         umount_client $MOUNT || error "umount failed"
26442         for num in $(seq $OSTCOUNT); do
26443                 stop ost$num
26444         done
26445
26446         # mount client with no active OSTs
26447         # so that the client can't initialize max LOV EA size
26448         # from OSC notifications
26449         mount_client $MOUNT || error "mount failed"
26450         # delay OST starting to keep this 0 max EA size for a while
26451         test_820_start_ost &
26452
26453         # create a directory on MDS2
26454         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
26455                 error "Failed to create directory"
26456         # open intent should update default EA size
26457         # see mdc_update_max_ea_from_body()
26458         # notice this is the very first RPC to MDS2
26459         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
26460         ret=$?
26461         echo $out
26462         # With SSK, this situation can lead to -EPERM being returned.
26463         # In that case, simply retry.
26464         if [ $ret -ne 0 ] && $SHARED_KEY; then
26465                 if echo "$out" | grep -q "not permitted"; then
26466                         cp /etc/services $DIR/$tdir/mds2
26467                         ret=$?
26468                 fi
26469         fi
26470         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
26471 }
26472 run_test 820 "update max EA from open intent"
26473
26474 test_822() {
26475         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
26476
26477         save_lustre_params mds1 \
26478                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
26479         do_facet $SINGLEMDS "$LCTL set_param -n \
26480                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
26481         do_facet $SINGLEMDS "$LCTL set_param -n \
26482                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
26483
26484         # wait for statfs update to clear OS_STATFS_NOPRECREATE
26485         local maxage=$(do_facet mds1 $LCTL get_param -n \
26486                        osp.$FSNAME-OST0000*MDT0000.maxage)
26487         sleep $((maxage + 1))
26488
26489         #define OBD_FAIL_NET_ERROR_RPC          0x532
26490         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26491
26492         stack_trap "restore_lustre_params < $p; rm $p"
26493
26494         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26495                       osp.$FSNAME-OST0000*MDT0000.create_count")
26496         for i in $(seq 1 $count); do
26497                 touch $DIR/$tfile.${i} || error "touch failed"
26498         done
26499 }
26500 run_test 822 "test precreate failure"
26501
26502 #
26503 # tests that do cleanup/setup should be run at the end
26504 #
26505
26506 test_900() {
26507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26508         local ls
26509
26510         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26511         $LCTL set_param fail_loc=0x903
26512
26513         cancel_lru_locks MGC
26514
26515         FAIL_ON_ERROR=true cleanup
26516         FAIL_ON_ERROR=true setup
26517 }
26518 run_test 900 "umount should not race with any mgc requeue thread"
26519
26520 # LUS-6253/LU-11185
26521 test_901() {
26522         local oldc
26523         local newc
26524         local olds
26525         local news
26526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26527
26528         # some get_param have a bug to handle dot in param name
26529         cancel_lru_locks MGC
26530         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26531         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26532         umount_client $MOUNT || error "umount failed"
26533         mount_client $MOUNT || error "mount failed"
26534         cancel_lru_locks MGC
26535         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26536         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26537
26538         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26539         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26540
26541         return 0
26542 }
26543 run_test 901 "don't leak a mgc lock on client umount"
26544
26545 # LU-13377
26546 test_902() {
26547         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26548                 skip "client does not have LU-13377 fix"
26549         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26550         $LCTL set_param fail_loc=0x1415
26551         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26552         cancel_lru_locks osc
26553         rm -f $DIR/$tfile
26554 }
26555 run_test 902 "test short write doesn't hang lustre"
26556
26557 complete $SECONDS
26558 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26559 check_and_cleanup_lustre
26560 if [ "$I_MOUNTED" != "yes" ]; then
26561         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26562 fi
26563 exit_status