Whamcloud - gitweb
b9e61b32e295f634465e0802a059e8268ed5ef8e
[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 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 -ge 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 test_27p() {
1912         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1914         remote_mds_nodsh && skip "remote MDS with nodsh"
1915         remote_ost_nodsh && skip "remote OST with nodsh"
1916
1917         reset_enospc
1918         rm -f $DIR/$tdir/$tfile
1919         test_mkdir $DIR/$tdir
1920
1921         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1922         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1923         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1924
1925         exhaust_precreations 0 0x80000215
1926         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1927         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1928         $LFS getstripe $DIR/$tdir/$tfile
1929
1930         reset_enospc
1931 }
1932 run_test 27p "append to a truncated file with some full OSTs"
1933
1934 test_27q() {
1935         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1937         remote_mds_nodsh && skip "remote MDS with nodsh"
1938         remote_ost_nodsh && skip "remote OST with nodsh"
1939
1940         reset_enospc
1941         rm -f $DIR/$tdir/$tfile
1942
1943         test_mkdir $DIR/$tdir
1944         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1945         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1946                 error "truncate $DIR/$tdir/$tfile failed"
1947         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1948
1949         exhaust_all_precreations 0x215
1950
1951         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1952         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1953
1954         reset_enospc
1955 }
1956 run_test 27q "append to truncated file with all OSTs full (should error)"
1957
1958 test_27r() {
1959         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1961         remote_mds_nodsh && skip "remote MDS with nodsh"
1962         remote_ost_nodsh && skip "remote OST with nodsh"
1963
1964         reset_enospc
1965         rm -f $DIR/$tdir/$tfile
1966         exhaust_precreations 0 0x80000215
1967
1968         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1969
1970         reset_enospc
1971 }
1972 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1973
1974 test_27s() { # bug 10725
1975         test_mkdir $DIR/$tdir
1976         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1977         local stripe_count=0
1978         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1979         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1980                 error "stripe width >= 2^32 succeeded" || true
1981
1982 }
1983 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1984
1985 test_27t() { # bug 10864
1986         WDIR=$(pwd)
1987         WLFS=$(which lfs)
1988         cd $DIR
1989         touch $tfile
1990         $WLFS getstripe $tfile
1991         cd $WDIR
1992 }
1993 run_test 27t "check that utils parse path correctly"
1994
1995 test_27u() { # bug 4900
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         remote_mds_nodsh && skip "remote MDS with nodsh"
1998
1999         local index
2000         local list=$(comma_list $(mdts_nodes))
2001
2002 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2003         do_nodes $list $LCTL set_param fail_loc=0x139
2004         test_mkdir -p $DIR/$tdir
2005         trap simple_cleanup_common EXIT
2006         createmany -o $DIR/$tdir/t- 1000
2007         do_nodes $list $LCTL set_param fail_loc=0
2008
2009         TLOG=$TMP/$tfile.getstripe
2010         $LFS getstripe $DIR/$tdir > $TLOG
2011         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2012         unlinkmany $DIR/$tdir/t- 1000
2013         trap 0
2014         [[ $OBJS -gt 0 ]] &&
2015                 error "$OBJS objects created on OST-0. See $TLOG" ||
2016                 rm -f $TLOG
2017 }
2018 run_test 27u "skip object creation on OSC w/o objects"
2019
2020 test_27v() { # bug 4900
2021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2023         remote_mds_nodsh && skip "remote MDS with nodsh"
2024         remote_ost_nodsh && skip "remote OST with nodsh"
2025
2026         exhaust_all_precreations 0x215
2027         reset_enospc
2028
2029         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2030
2031         touch $DIR/$tdir/$tfile
2032         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2033         # all except ost1
2034         for (( i=1; i < OSTCOUNT; i++ )); do
2035                 do_facet ost$i lctl set_param fail_loc=0x705
2036         done
2037         local START=`date +%s`
2038         createmany -o $DIR/$tdir/$tfile 32
2039
2040         local FINISH=`date +%s`
2041         local TIMEOUT=`lctl get_param -n timeout`
2042         local PROCESS=$((FINISH - START))
2043         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2044                error "$FINISH - $START >= $TIMEOUT / 2"
2045         sleep $((TIMEOUT / 2 - PROCESS))
2046         reset_enospc
2047 }
2048 run_test 27v "skip object creation on slow OST"
2049
2050 test_27w() { # bug 10997
2051         test_mkdir $DIR/$tdir
2052         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2053         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2054                 error "stripe size $size != 65536" || true
2055         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2056                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2057 }
2058 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2059
2060 test_27wa() {
2061         [[ $OSTCOUNT -lt 2 ]] &&
2062                 skip_env "skipping multiple stripe count/offset test"
2063
2064         test_mkdir $DIR/$tdir
2065         for i in $(seq 1 $OSTCOUNT); do
2066                 offset=$((i - 1))
2067                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2068                         error "setstripe -c $i -i $offset failed"
2069                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2070                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2071                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2072                 [ $index -ne $offset ] &&
2073                         error "stripe offset $index != $offset" || true
2074         done
2075 }
2076 run_test 27wa "check $LFS setstripe -c -i options"
2077
2078 test_27x() {
2079         remote_ost_nodsh && skip "remote OST with nodsh"
2080         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2082
2083         OFFSET=$(($OSTCOUNT - 1))
2084         OSTIDX=0
2085         local OST=$(ostname_from_index $OSTIDX)
2086
2087         test_mkdir $DIR/$tdir
2088         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2089         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2090         sleep_maxage
2091         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2092         for i in $(seq 0 $OFFSET); do
2093                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2094                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2095                 error "OST0 was degraded but new created file still use it"
2096         done
2097         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2098 }
2099 run_test 27x "create files while OST0 is degraded"
2100
2101 test_27y() {
2102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2103         remote_mds_nodsh && skip "remote MDS with nodsh"
2104         remote_ost_nodsh && skip "remote OST with nodsh"
2105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2106
2107         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2108         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2109                 osp.$mdtosc.prealloc_last_id)
2110         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2111                 osp.$mdtosc.prealloc_next_id)
2112         local fcount=$((last_id - next_id))
2113         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2114         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2115
2116         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2117                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2118         local OST_DEACTIVE_IDX=-1
2119         local OSC
2120         local OSTIDX
2121         local OST
2122
2123         for OSC in $MDS_OSCS; do
2124                 OST=$(osc_to_ost $OSC)
2125                 OSTIDX=$(index_from_ostuuid $OST)
2126                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2127                         OST_DEACTIVE_IDX=$OSTIDX
2128                 fi
2129                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2130                         echo $OSC "is Deactivated:"
2131                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2132                 fi
2133         done
2134
2135         OSTIDX=$(index_from_ostuuid $OST)
2136         test_mkdir $DIR/$tdir
2137         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2138
2139         for OSC in $MDS_OSCS; do
2140                 OST=$(osc_to_ost $OSC)
2141                 OSTIDX=$(index_from_ostuuid $OST)
2142                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2143                         echo $OST "is degraded:"
2144                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2145                                                 obdfilter.$OST.degraded=1
2146                 fi
2147         done
2148
2149         sleep_maxage
2150         createmany -o $DIR/$tdir/$tfile $fcount
2151
2152         for OSC in $MDS_OSCS; do
2153                 OST=$(osc_to_ost $OSC)
2154                 OSTIDX=$(index_from_ostuuid $OST)
2155                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2156                         echo $OST "is recovered from degraded:"
2157                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2158                                                 obdfilter.$OST.degraded=0
2159                 else
2160                         do_facet $SINGLEMDS lctl --device %$OSC activate
2161                 fi
2162         done
2163
2164         # all osp devices get activated, hence -1 stripe count restored
2165         local stripe_count=0
2166
2167         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2168         # devices get activated.
2169         sleep_maxage
2170         $LFS setstripe -c -1 $DIR/$tfile
2171         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2172         rm -f $DIR/$tfile
2173         [ $stripe_count -ne $OSTCOUNT ] &&
2174                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2175         return 0
2176 }
2177 run_test 27y "create files while OST0 is degraded and the rest inactive"
2178
2179 check_seq_oid()
2180 {
2181         log "check file $1"
2182
2183         lmm_count=$($LFS getstripe -c $1)
2184         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2185         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2186
2187         local old_ifs="$IFS"
2188         IFS=$'[:]'
2189         fid=($($LFS path2fid $1))
2190         IFS="$old_ifs"
2191
2192         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2193         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2194
2195         # compare lmm_seq and lu_fid->f_seq
2196         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2197         # compare lmm_object_id and lu_fid->oid
2198         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2199
2200         # check the trusted.fid attribute of the OST objects of the file
2201         local have_obdidx=false
2202         local stripe_nr=0
2203         $LFS getstripe $1 | while read obdidx oid hex seq; do
2204                 # skip lines up to and including "obdidx"
2205                 [ -z "$obdidx" ] && break
2206                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2207                 $have_obdidx || continue
2208
2209                 local ost=$((obdidx + 1))
2210                 local dev=$(ostdevname $ost)
2211                 local oid_hex
2212
2213                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2214
2215                 seq=$(echo $seq | sed -e "s/^0x//g")
2216                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2217                         oid_hex=$(echo $oid)
2218                 else
2219                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2220                 fi
2221                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2222
2223                 local ff=""
2224                 #
2225                 # Don't unmount/remount the OSTs if we don't need to do that.
2226                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2227                 # update too, until that use mount/ll_decode_filter_fid/mount.
2228                 # Re-enable when debugfs will understand new filter_fid.
2229                 #
2230                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2231                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2232                                 $dev 2>/dev/null" | grep "parent=")
2233                 fi
2234                 if [ -z "$ff" ]; then
2235                         stop ost$ost
2236                         mount_fstype ost$ost
2237                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2238                                 $(facet_mntpt ost$ost)/$obj_file)
2239                         unmount_fstype ost$ost
2240                         start ost$ost $dev $OST_MOUNT_OPTS
2241                         clients_up
2242                 fi
2243
2244                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2245
2246                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2247
2248                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2249                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2250                 #
2251                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2252                 #       stripe_size=1048576 component_id=1 component_start=0 \
2253                 #       component_end=33554432
2254                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2255                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2256                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2257                 local ff_pstripe
2258                 if grep -q 'stripe=' <<<$ff; then
2259                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2260                 else
2261                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2262                         # into f_ver in this case.  See comment on ff_parent.
2263                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2264                 fi
2265
2266                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2267                 [ $ff_pseq = $lmm_seq ] ||
2268                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2269                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2270                 [ $ff_poid = $lmm_oid ] ||
2271                         error "FF parent OID $ff_poid != $lmm_oid"
2272                 (($ff_pstripe == $stripe_nr)) ||
2273                         error "FF stripe $ff_pstripe != $stripe_nr"
2274
2275                 stripe_nr=$((stripe_nr + 1))
2276                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2277                         continue
2278                 if grep -q 'stripe_count=' <<<$ff; then
2279                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2280                                             -e 's/ .*//' <<<$ff)
2281                         [ $lmm_count = $ff_scnt ] ||
2282                                 error "FF stripe count $lmm_count != $ff_scnt"
2283                 fi
2284         done
2285 }
2286
2287 test_27z() {
2288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2289         remote_ost_nodsh && skip "remote OST with nodsh"
2290
2291         test_mkdir $DIR/$tdir
2292         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2293                 { error "setstripe -c -1 failed"; return 1; }
2294         # We need to send a write to every object to get parent FID info set.
2295         # This _should_ also work for setattr, but does not currently.
2296         # touch $DIR/$tdir/$tfile-1 ||
2297         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2298                 { error "dd $tfile-1 failed"; return 2; }
2299         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2300                 { error "setstripe -c -1 failed"; return 3; }
2301         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2302                 { error "dd $tfile-2 failed"; return 4; }
2303
2304         # make sure write RPCs have been sent to OSTs
2305         sync; sleep 5; sync
2306
2307         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2308         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2309 }
2310 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2311
2312 test_27A() { # b=19102
2313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2314
2315         save_layout_restore_at_exit $MOUNT
2316         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2317         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2318                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2319         local default_size=$($LFS getstripe -S $MOUNT)
2320         local default_offset=$($LFS getstripe -i $MOUNT)
2321         local dsize=$(do_facet $SINGLEMDS \
2322                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2323         [ $default_size -eq $dsize ] ||
2324                 error "stripe size $default_size != $dsize"
2325         [ $default_offset -eq -1 ] ||
2326                 error "stripe offset $default_offset != -1"
2327 }
2328 run_test 27A "check filesystem-wide default LOV EA values"
2329
2330 test_27B() { # LU-2523
2331         test_mkdir $DIR/$tdir
2332         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2333         touch $DIR/$tdir/f0
2334         # open f1 with O_LOV_DELAY_CREATE
2335         # rename f0 onto f1
2336         # call setstripe ioctl on open file descriptor for f1
2337         # close
2338         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2339                 $DIR/$tdir/f0
2340
2341         rm -f $DIR/$tdir/f1
2342         # open f1 with O_LOV_DELAY_CREATE
2343         # unlink f1
2344         # call setstripe ioctl on open file descriptor for f1
2345         # close
2346         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2347
2348         # Allow multiop to fail in imitation of NFS's busted semantics.
2349         true
2350 }
2351 run_test 27B "call setstripe on open unlinked file/rename victim"
2352
2353 # 27C family tests full striping and overstriping
2354 test_27Ca() { #LU-2871
2355         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2356
2357         declare -a ost_idx
2358         local index
2359         local found
2360         local i
2361         local j
2362
2363         test_mkdir $DIR/$tdir
2364         cd $DIR/$tdir
2365         for i in $(seq 0 $((OSTCOUNT - 1))); do
2366                 # set stripe across all OSTs starting from OST$i
2367                 $LFS setstripe -i $i -c -1 $tfile$i
2368                 # get striping information
2369                 ost_idx=($($LFS getstripe $tfile$i |
2370                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2371                 echo ${ost_idx[@]}
2372
2373                 # check the layout
2374                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2375                         error "${#ost_idx[@]} != $OSTCOUNT"
2376
2377                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2378                         found=0
2379                         for j in $(echo ${ost_idx[@]}); do
2380                                 if [ $index -eq $j ]; then
2381                                         found=1
2382                                         break
2383                                 fi
2384                         done
2385                         [ $found = 1 ] ||
2386                                 error "Can not find $index in ${ost_idx[@]}"
2387                 done
2388         done
2389 }
2390 run_test 27Ca "check full striping across all OSTs"
2391
2392 test_27Cb() {
2393         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2394                 skip "server does not support overstriping"
2395         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2396                 skip_env "too many osts, skipping"
2397
2398         test_mkdir -p $DIR/$tdir
2399         local setcount=$(($OSTCOUNT * 2))
2400         [ $setcount -ge 160 ] || large_xattr_enabled ||
2401                 skip_env "ea_inode feature disabled"
2402
2403         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2404                 error "setstripe failed"
2405
2406         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2407         [ $count -eq $setcount ] ||
2408                 error "stripe count $count, should be $setcount"
2409
2410         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2411                 error "overstriped should be set in pattern"
2412
2413         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2414                 error "dd failed"
2415 }
2416 run_test 27Cb "more stripes than OSTs with -C"
2417
2418 test_27Cc() {
2419         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2420                 skip "server does not support overstriping"
2421         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2422
2423         test_mkdir -p $DIR/$tdir
2424         local setcount=$(($OSTCOUNT - 1))
2425
2426         [ $setcount -ge 160 ] || large_xattr_enabled ||
2427                 skip_env "ea_inode feature disabled"
2428
2429         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2430                 error "setstripe failed"
2431
2432         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2433         [ $count -eq $setcount ] ||
2434                 error "stripe count $count, should be $setcount"
2435
2436         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2437                 error "overstriped should not be set in pattern"
2438
2439         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2440                 error "dd failed"
2441 }
2442 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2443
2444 test_27Cd() {
2445         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2446                 skip "server does not support overstriping"
2447         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2448         large_xattr_enabled || skip_env "ea_inode feature disabled"
2449
2450         test_mkdir -p $DIR/$tdir
2451         local setcount=$LOV_MAX_STRIPE_COUNT
2452
2453         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2454                 error "setstripe failed"
2455
2456         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2457         [ $count -eq $setcount ] ||
2458                 error "stripe count $count, should be $setcount"
2459
2460         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2461                 error "overstriped should be set in pattern"
2462
2463         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2464                 error "dd failed"
2465
2466         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2467 }
2468 run_test 27Cd "test maximum stripe count"
2469
2470 test_27Ce() {
2471         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2472                 skip "server does not support overstriping"
2473         test_mkdir -p $DIR/$tdir
2474
2475         pool_add $TESTNAME || error "Pool creation failed"
2476         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2477
2478         local setcount=8
2479
2480         $LFS setstripe  -C $setcount -p "$TESTNAME" $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 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         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2494 }
2495 run_test 27Ce "test pool with overstriping"
2496
2497 test_27Cf() {
2498         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2499                 skip "server does not support overstriping"
2500         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2501                 skip_env "too many osts, skipping"
2502
2503         test_mkdir -p $DIR/$tdir
2504
2505         local setcount=$(($OSTCOUNT * 2))
2506         [ $setcount -ge 160 ] || large_xattr_enabled ||
2507                 skip_env "ea_inode feature disabled"
2508
2509         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2510                 error "setstripe failed"
2511
2512         echo 1 > $DIR/$tdir/$tfile
2513
2514         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2515         [ $count -eq $setcount ] ||
2516                 error "stripe count $count, should be $setcount"
2517
2518         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2519                 error "overstriped should be set in pattern"
2520
2521         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2522                 error "dd failed"
2523
2524         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2525 }
2526 run_test 27Cf "test default inheritance with overstriping"
2527
2528 test_27D() {
2529         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2530         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2531         remote_mds_nodsh && skip "remote MDS with nodsh"
2532
2533         local POOL=${POOL:-testpool}
2534         local first_ost=0
2535         local last_ost=$(($OSTCOUNT - 1))
2536         local ost_step=1
2537         local ost_list=$(seq $first_ost $ost_step $last_ost)
2538         local ost_range="$first_ost $last_ost $ost_step"
2539
2540         test_mkdir $DIR/$tdir
2541         pool_add $POOL || error "pool_add failed"
2542         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2543
2544         local skip27D
2545         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2546                 skip27D+="-s 29"
2547         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2548                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2549                         skip27D+=" -s 30,31"
2550         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2551           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2552                 skip27D+=" -s 32,33"
2553         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2554                 skip27D+=" -s 34"
2555         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2556                 error "llapi_layout_test failed"
2557
2558         destroy_test_pools || error "destroy test pools failed"
2559 }
2560 run_test 27D "validate llapi_layout API"
2561
2562 # Verify that default_easize is increased from its initial value after
2563 # accessing a widely striped file.
2564 test_27E() {
2565         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2566         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2567                 skip "client does not have LU-3338 fix"
2568
2569         # 72 bytes is the minimum space required to store striping
2570         # information for a file striped across one OST:
2571         # (sizeof(struct lov_user_md_v3) +
2572         #  sizeof(struct lov_user_ost_data_v1))
2573         local min_easize=72
2574         $LCTL set_param -n llite.*.default_easize $min_easize ||
2575                 error "lctl set_param failed"
2576         local easize=$($LCTL get_param -n llite.*.default_easize)
2577
2578         [ $easize -eq $min_easize ] ||
2579                 error "failed to set default_easize"
2580
2581         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2582                 error "setstripe failed"
2583         # In order to ensure stat() call actually talks to MDS we need to
2584         # do something drastic to this file to shake off all lock, e.g.
2585         # rename it (kills lookup lock forcing cache cleaning)
2586         mv $DIR/$tfile $DIR/${tfile}-1
2587         ls -l $DIR/${tfile}-1
2588         rm $DIR/${tfile}-1
2589
2590         easize=$($LCTL get_param -n llite.*.default_easize)
2591
2592         [ $easize -gt $min_easize ] ||
2593                 error "default_easize not updated"
2594 }
2595 run_test 27E "check that default extended attribute size properly increases"
2596
2597 test_27F() { # LU-5346/LU-7975
2598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2599         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2600         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2601                 skip "Need MDS version at least 2.8.51"
2602         remote_ost_nodsh && skip "remote OST with nodsh"
2603
2604         test_mkdir $DIR/$tdir
2605         rm -f $DIR/$tdir/f0
2606         $LFS setstripe -c 2 $DIR/$tdir
2607
2608         # stop all OSTs to reproduce situation for LU-7975 ticket
2609         for num in $(seq $OSTCOUNT); do
2610                 stop ost$num
2611         done
2612
2613         # open/create f0 with O_LOV_DELAY_CREATE
2614         # truncate f0 to a non-0 size
2615         # close
2616         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2617
2618         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2619         # open/write it again to force delayed layout creation
2620         cat /etc/hosts > $DIR/$tdir/f0 &
2621         catpid=$!
2622
2623         # restart OSTs
2624         for num in $(seq $OSTCOUNT); do
2625                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2626                         error "ost$num failed to start"
2627         done
2628
2629         wait $catpid || error "cat failed"
2630
2631         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2632         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2633                 error "wrong stripecount"
2634
2635 }
2636 run_test 27F "Client resend delayed layout creation with non-zero size"
2637
2638 test_27G() { #LU-10629
2639         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2640                 skip "Need MDS version at least 2.11.51"
2641         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2642         remote_mds_nodsh && skip "remote MDS with nodsh"
2643         local POOL=${POOL:-testpool}
2644         local ostrange="0 0 1"
2645
2646         test_mkdir $DIR/$tdir
2647         touch $DIR/$tdir/$tfile.nopool
2648         pool_add $POOL || error "pool_add failed"
2649         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2650         $LFS setstripe -p $POOL $DIR/$tdir
2651
2652         local pool=$($LFS getstripe -p $DIR/$tdir)
2653
2654         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2655         touch $DIR/$tdir/$tfile.default
2656         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2657         $LFS find $DIR/$tdir -type f --pool $POOL
2658         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2659         [[ "$found" == "2" ]] ||
2660                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2661
2662         $LFS setstripe -d $DIR/$tdir
2663
2664         pool=$($LFS getstripe -p -d $DIR/$tdir)
2665
2666         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2667 }
2668 run_test 27G "Clear OST pool from stripe"
2669
2670 test_27H() {
2671         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2672                 skip "Need MDS version newer than 2.11.54"
2673         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2674         test_mkdir $DIR/$tdir
2675         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2676         touch $DIR/$tdir/$tfile
2677         $LFS getstripe -c $DIR/$tdir/$tfile
2678         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2679                 error "two-stripe file doesn't have two stripes"
2680
2681         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2682         $LFS getstripe -y $DIR/$tdir/$tfile
2683         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2684              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2685                 error "expected l_ost_idx: [02]$ not matched"
2686
2687         # make sure ost list has been cleared
2688         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2689         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2690                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2691         touch $DIR/$tdir/f3
2692         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2693 }
2694 run_test 27H "Set specific OSTs stripe"
2695
2696 test_27I() {
2697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2698         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2699         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2700                 skip "Need MDS version newer than 2.12.52"
2701         local pool=$TESTNAME
2702         local ostrange="1 1 1"
2703
2704         save_layout_restore_at_exit $MOUNT
2705         $LFS setstripe -c 2 -i 0 $MOUNT
2706         pool_add $pool || error "pool_add failed"
2707         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2708         test_mkdir $DIR/$tdir
2709         $LFS setstripe -p $pool $DIR/$tdir
2710         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2711         $LFS getstripe $DIR/$tdir/$tfile
2712 }
2713 run_test 27I "check that root dir striping does not break parent dir one"
2714
2715 test_27J() {
2716         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2717                 skip "Need MDS version newer than 2.12.51"
2718
2719         test_mkdir $DIR/$tdir
2720         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2721         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2722
2723         # create foreign file (raw way)
2724         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2725                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2726
2727         # verify foreign file (raw way)
2728         parse_foreign_file -f $DIR/$tdir/$tfile |
2729                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2730                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2731         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2732                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2733         parse_foreign_file -f $DIR/$tdir/$tfile |
2734                 grep "lov_foreign_size: 73" ||
2735                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2736         parse_foreign_file -f $DIR/$tdir/$tfile |
2737                 grep "lov_foreign_type: 1" ||
2738                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2739         parse_foreign_file -f $DIR/$tdir/$tfile |
2740                 grep "lov_foreign_flags: 0x0000DA08" ||
2741                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2742         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2743                 grep "lov_foreign_value: 0x" |
2744                 sed -e 's/lov_foreign_value: 0x//')
2745         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2746         [[ $lov = ${lov2// /} ]] ||
2747                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2748
2749         # create foreign file (lfs + API)
2750         $LFS setstripe --foreign=daos --flags 0xda08 \
2751                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2752                 error "$DIR/$tdir/${tfile}2: create failed"
2753
2754         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2755                 grep "lfm_magic:.*0x0BD70BD0" ||
2756                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2757         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2758         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2759                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2760         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2761                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2762         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2763                 grep "lfm_flags:.*0x0000DA08" ||
2764                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2765         $LFS getstripe $DIR/$tdir/${tfile}2 |
2766                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2767                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2768
2769         # modify striping should fail
2770         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2771                 error "$DIR/$tdir/$tfile: setstripe should fail"
2772         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2773                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2774
2775         # R/W should fail
2776         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2777         cat $DIR/$tdir/${tfile}2 &&
2778                 error "$DIR/$tdir/${tfile}2: read should fail"
2779         cat /etc/passwd > $DIR/$tdir/$tfile &&
2780                 error "$DIR/$tdir/$tfile: write should fail"
2781         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2782                 error "$DIR/$tdir/${tfile}2: write should fail"
2783
2784         # chmod should work
2785         chmod 222 $DIR/$tdir/$tfile ||
2786                 error "$DIR/$tdir/$tfile: chmod failed"
2787         chmod 222 $DIR/$tdir/${tfile}2 ||
2788                 error "$DIR/$tdir/${tfile}2: chmod failed"
2789
2790         # chown should work
2791         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2792                 error "$DIR/$tdir/$tfile: chown failed"
2793         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2794                 error "$DIR/$tdir/${tfile}2: chown failed"
2795
2796         # rename should work
2797         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2798                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2799         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2800                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2801
2802         #remove foreign file
2803         rm $DIR/$tdir/${tfile}.new ||
2804                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2805         rm $DIR/$tdir/${tfile}2.new ||
2806                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2807 }
2808 run_test 27J "basic ops on file with foreign LOV"
2809
2810 test_27K() {
2811         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2812                 skip "Need MDS version newer than 2.12.49"
2813
2814         test_mkdir $DIR/$tdir
2815         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2816         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2817
2818         # create foreign dir (raw way)
2819         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2820                 error "create_foreign_dir FAILED"
2821
2822         # verify foreign dir (raw way)
2823         parse_foreign_dir -d $DIR/$tdir/$tdir |
2824                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2825                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2826         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2827                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2828         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2829                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2830         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2831                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2832         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2833                 grep "lmv_foreign_value: 0x" |
2834                 sed 's/lmv_foreign_value: 0x//')
2835         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2836                 sed 's/ //g')
2837         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2838
2839         # create foreign dir (lfs + API)
2840         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2841                 $DIR/$tdir/${tdir}2 ||
2842                 error "$DIR/$tdir/${tdir}2: create failed"
2843
2844         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2845                 grep "lfm_magic:.*0x0CD50CD0" ||
2846                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2847         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2848         # - sizeof(lfm_type) - sizeof(lfm_flags)
2849         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2850                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2851         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2852                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2853         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2854                 grep "lfm_flags:.*0x0000DA05" ||
2855                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2856         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2857                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2858                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2859
2860         # file create in dir should fail
2861         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2862         touch $DIR/$tdir/${tdir}2/$tfile &&
2863                 "$DIR/${tdir}2: file create should fail"
2864
2865         # chmod should work
2866         chmod 777 $DIR/$tdir/$tdir ||
2867                 error "$DIR/$tdir: chmod failed"
2868         chmod 777 $DIR/$tdir/${tdir}2 ||
2869                 error "$DIR/${tdir}2: chmod failed"
2870
2871         # chown should work
2872         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2873                 error "$DIR/$tdir: chown failed"
2874         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2875                 error "$DIR/${tdir}2: chown failed"
2876
2877         # rename should work
2878         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2879                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2880         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2881                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2882
2883         #remove foreign dir
2884         rmdir $DIR/$tdir/${tdir}.new ||
2885                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2886         rmdir $DIR/$tdir/${tdir}2.new ||
2887                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2888 }
2889 run_test 27K "basic ops on dir with foreign LMV"
2890
2891 test_27L() {
2892         remote_mds_nodsh && skip "remote MDS with nodsh"
2893
2894         local POOL=${POOL:-$TESTNAME}
2895
2896         pool_add $POOL || error "pool_add failed"
2897
2898         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2899                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2900                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2901 }
2902 run_test 27L "lfs pool_list gives correct pool name"
2903
2904 test_27M() {
2905         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2906                 skip "Need MDS version >= than 2.12.57"
2907         remote_mds_nodsh && skip "remote MDS with nodsh"
2908         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2909
2910         test_mkdir $DIR/$tdir
2911
2912         # Set default striping on directory
2913         $LFS setstripe -C 4 $DIR/$tdir
2914
2915         echo 1 > $DIR/$tdir/${tfile}.1
2916         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2917         local setcount=4
2918         [ $count -eq $setcount ] ||
2919                 error "(1) stripe count $count, should be $setcount"
2920
2921         # Capture existing append_stripe_count setting for restore
2922         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2923         local mdts=$(comma_list $(mdts_nodes))
2924         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2925
2926         local appendcount=$orig_count
2927         echo 1 >> $DIR/$tdir/${tfile}.2_append
2928         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2929         [ $count -eq $appendcount ] ||
2930                 error "(2)stripe count $count, should be $appendcount for append"
2931
2932         # Disable O_APPEND striping, verify it works
2933         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2934
2935         # Should now get the default striping, which is 4
2936         setcount=4
2937         echo 1 >> $DIR/$tdir/${tfile}.3_append
2938         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2939         [ $count -eq $setcount ] ||
2940                 error "(3) stripe count $count, should be $setcount"
2941
2942         # Try changing the stripe count for append files
2943         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2944
2945         # Append striping is now 2 (directory default is still 4)
2946         appendcount=2
2947         echo 1 >> $DIR/$tdir/${tfile}.4_append
2948         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2949         [ $count -eq $appendcount ] ||
2950                 error "(4) stripe count $count, should be $appendcount for append"
2951
2952         # Test append stripe count of -1
2953         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2954         appendcount=$OSTCOUNT
2955         echo 1 >> $DIR/$tdir/${tfile}.5
2956         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2957         [ $count -eq $appendcount ] ||
2958                 error "(5) stripe count $count, should be $appendcount for append"
2959
2960         # Set append striping back to default of 1
2961         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2962
2963         # Try a new default striping, PFL + DOM
2964         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2965
2966         # Create normal DOM file, DOM returns stripe count == 0
2967         setcount=0
2968         touch $DIR/$tdir/${tfile}.6
2969         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2970         [ $count -eq $setcount ] ||
2971                 error "(6) stripe count $count, should be $setcount"
2972
2973         # Show
2974         appendcount=1
2975         echo 1 >> $DIR/$tdir/${tfile}.7_append
2976         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2977         [ $count -eq $appendcount ] ||
2978                 error "(7) stripe count $count, should be $appendcount for append"
2979
2980         # Clean up DOM layout
2981         $LFS setstripe -d $DIR/$tdir
2982
2983         # Now test that append striping works when layout is from root
2984         $LFS setstripe -c 2 $MOUNT
2985         # Make a special directory for this
2986         mkdir $DIR/${tdir}/${tdir}.2
2987         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2988
2989         # Verify for normal file
2990         setcount=2
2991         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2992         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2993         [ $count -eq $setcount ] ||
2994                 error "(8) stripe count $count, should be $setcount"
2995
2996         appendcount=1
2997         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2998         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2999         [ $count -eq $appendcount ] ||
3000                 error "(9) stripe count $count, should be $appendcount for append"
3001
3002         # Now test O_APPEND striping with pools
3003         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3004         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3005
3006         # Create the pool
3007         pool_add $TESTNAME || error "pool creation failed"
3008         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3009
3010         echo 1 >> $DIR/$tdir/${tfile}.10_append
3011
3012         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3013         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3014
3015         # Check that count is still correct
3016         appendcount=1
3017         echo 1 >> $DIR/$tdir/${tfile}.11_append
3018         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3019         [ $count -eq $appendcount ] ||
3020                 error "(11) stripe count $count, should be $appendcount for append"
3021
3022         # Disable O_APPEND stripe count, verify pool works separately
3023         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3024
3025         echo 1 >> $DIR/$tdir/${tfile}.12_append
3026
3027         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3028         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3029
3030         # Remove pool setting, verify it's not applied
3031         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3032
3033         echo 1 >> $DIR/$tdir/${tfile}.13_append
3034
3035         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3036         [ "$pool" = "" ] || error "(13) pool found: $pool"
3037 }
3038 run_test 27M "test O_APPEND striping"
3039
3040 test_27N() {
3041         combined_mgs_mds && skip "needs separate MGS/MDT"
3042
3043         pool_add $TESTNAME || error "pool_add failed"
3044         do_facet mgs "$LCTL pool_list $FSNAME" |
3045                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3046                 error "lctl pool_list on MGS failed"
3047 }
3048 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3049
3050 # createtest also checks that device nodes are created and
3051 # then visible correctly (#2091)
3052 test_28() { # bug 2091
3053         test_mkdir $DIR/d28
3054         $CREATETEST $DIR/d28/ct || error "createtest failed"
3055 }
3056 run_test 28 "create/mknod/mkdir with bad file types ============"
3057
3058 test_29() {
3059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3060
3061         sync; sleep 1; sync # flush out any dirty pages from previous tests
3062         cancel_lru_locks
3063         test_mkdir $DIR/d29
3064         touch $DIR/d29/foo
3065         log 'first d29'
3066         ls -l $DIR/d29
3067
3068         declare -i LOCKCOUNTORIG=0
3069         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3070                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3071         done
3072         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3073
3074         declare -i LOCKUNUSEDCOUNTORIG=0
3075         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3076                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3077         done
3078
3079         log 'second d29'
3080         ls -l $DIR/d29
3081         log 'done'
3082
3083         declare -i LOCKCOUNTCURRENT=0
3084         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3085                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3086         done
3087
3088         declare -i LOCKUNUSEDCOUNTCURRENT=0
3089         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3090                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3091         done
3092
3093         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3094                 $LCTL set_param -n ldlm.dump_namespaces ""
3095                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3096                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3097                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3098                 return 2
3099         fi
3100         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3101                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3102                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3103                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3104                 return 3
3105         fi
3106 }
3107 run_test 29 "IT_GETATTR regression  ============================"
3108
3109 test_30a() { # was test_30
3110         cp $(which ls) $DIR || cp /bin/ls $DIR
3111         $DIR/ls / || error "Can't execute binary from lustre"
3112         rm $DIR/ls
3113 }
3114 run_test 30a "execute binary from Lustre (execve) =============="
3115
3116 test_30b() {
3117         cp `which ls` $DIR || cp /bin/ls $DIR
3118         chmod go+rx $DIR/ls
3119         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3120         rm $DIR/ls
3121 }
3122 run_test 30b "execute binary from Lustre as non-root ==========="
3123
3124 test_30c() { # b=22376
3125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3126
3127         cp $(which ls) $DIR || cp /bin/ls $DIR
3128         chmod a-rw $DIR/ls
3129         cancel_lru_locks mdc
3130         cancel_lru_locks osc
3131         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3132         rm -f $DIR/ls
3133 }
3134 run_test 30c "execute binary from Lustre without read perms ===="
3135
3136 test_30d() {
3137         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3138
3139         for i in {1..10}; do
3140                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3141                 local PID=$!
3142                 sleep 1
3143                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3144                 wait $PID || error "executing dd from Lustre failed"
3145                 rm -f $DIR/$tfile
3146         done
3147
3148         rm -f $DIR/dd
3149 }
3150 run_test 30d "execute binary from Lustre while clear locks"
3151
3152 test_31a() {
3153         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3154         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3155 }
3156 run_test 31a "open-unlink file =================================="
3157
3158 test_31b() {
3159         touch $DIR/f31 || error "touch $DIR/f31 failed"
3160         ln $DIR/f31 $DIR/f31b || error "ln failed"
3161         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3162         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3163 }
3164 run_test 31b "unlink file with multiple links while open ======="
3165
3166 test_31c() {
3167         touch $DIR/f31 || error "touch $DIR/f31 failed"
3168         ln $DIR/f31 $DIR/f31c || error "ln failed"
3169         multiop_bg_pause $DIR/f31 O_uc ||
3170                 error "multiop_bg_pause for $DIR/f31 failed"
3171         MULTIPID=$!
3172         $MULTIOP $DIR/f31c Ouc
3173         kill -USR1 $MULTIPID
3174         wait $MULTIPID
3175 }
3176 run_test 31c "open-unlink file with multiple links ============="
3177
3178 test_31d() {
3179         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3180         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3181 }
3182 run_test 31d "remove of open directory ========================="
3183
3184 test_31e() { # bug 2904
3185         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3186 }
3187 run_test 31e "remove of open non-empty directory ==============="
3188
3189 test_31f() { # bug 4554
3190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3191
3192         set -vx
3193         test_mkdir $DIR/d31f
3194         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3195         cp /etc/hosts $DIR/d31f
3196         ls -l $DIR/d31f
3197         $LFS getstripe $DIR/d31f/hosts
3198         multiop_bg_pause $DIR/d31f D_c || return 1
3199         MULTIPID=$!
3200
3201         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3202         test_mkdir $DIR/d31f
3203         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3204         cp /etc/hosts $DIR/d31f
3205         ls -l $DIR/d31f
3206         $LFS getstripe $DIR/d31f/hosts
3207         multiop_bg_pause $DIR/d31f D_c || return 1
3208         MULTIPID2=$!
3209
3210         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3211         wait $MULTIPID || error "first opendir $MULTIPID failed"
3212
3213         sleep 6
3214
3215         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3216         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3217         set +vx
3218 }
3219 run_test 31f "remove of open directory with open-unlink file ==="
3220
3221 test_31g() {
3222         echo "-- cross directory link --"
3223         test_mkdir -c1 $DIR/${tdir}ga
3224         test_mkdir -c1 $DIR/${tdir}gb
3225         touch $DIR/${tdir}ga/f
3226         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3227         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3228         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3229         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3230         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3231 }
3232 run_test 31g "cross directory link==============="
3233
3234 test_31h() {
3235         echo "-- cross directory link --"
3236         test_mkdir -c1 $DIR/${tdir}
3237         test_mkdir -c1 $DIR/${tdir}/dir
3238         touch $DIR/${tdir}/f
3239         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3240         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3241         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3242         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3243         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3244 }
3245 run_test 31h "cross directory link under child==============="
3246
3247 test_31i() {
3248         echo "-- cross directory link --"
3249         test_mkdir -c1 $DIR/$tdir
3250         test_mkdir -c1 $DIR/$tdir/dir
3251         touch $DIR/$tdir/dir/f
3252         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3253         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3254         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3255         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3256         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3257 }
3258 run_test 31i "cross directory link under parent==============="
3259
3260 test_31j() {
3261         test_mkdir -c1 -p $DIR/$tdir
3262         test_mkdir -c1 -p $DIR/$tdir/dir1
3263         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3264         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3265         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3266         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3267         return 0
3268 }
3269 run_test 31j "link for directory==============="
3270
3271 test_31k() {
3272         test_mkdir -c1 -p $DIR/$tdir
3273         touch $DIR/$tdir/s
3274         touch $DIR/$tdir/exist
3275         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3276         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3277         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3278         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3279         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3280         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3281         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3282         return 0
3283 }
3284 run_test 31k "link to file: the same, non-existing, dir==============="
3285
3286 test_31m() {
3287         mkdir $DIR/d31m
3288         touch $DIR/d31m/s
3289         mkdir $DIR/d31m2
3290         touch $DIR/d31m2/exist
3291         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3292         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3293         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3294         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3295         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3296         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3297         return 0
3298 }
3299 run_test 31m "link to file: the same, non-existing, dir==============="
3300
3301 test_31n() {
3302         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3303         nlink=$(stat --format=%h $DIR/$tfile)
3304         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3305         local fd=$(free_fd)
3306         local cmd="exec $fd<$DIR/$tfile"
3307         eval $cmd
3308         cmd="exec $fd<&-"
3309         trap "eval $cmd" EXIT
3310         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3311         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3312         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3313         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3314         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3315         eval $cmd
3316 }
3317 run_test 31n "check link count of unlinked file"
3318
3319 link_one() {
3320         local tempfile=$(mktemp $1_XXXXXX)
3321         mlink $tempfile $1 2> /dev/null &&
3322                 echo "$BASHPID: link $tempfile to $1 succeeded"
3323         munlink $tempfile
3324 }
3325
3326 test_31o() { # LU-2901
3327         test_mkdir $DIR/$tdir
3328         for LOOP in $(seq 100); do
3329                 rm -f $DIR/$tdir/$tfile*
3330                 for THREAD in $(seq 8); do
3331                         link_one $DIR/$tdir/$tfile.$LOOP &
3332                 done
3333                 wait
3334                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3335                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3336                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3337                         break || true
3338         done
3339 }
3340 run_test 31o "duplicate hard links with same filename"
3341
3342 test_31p() {
3343         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3344
3345         test_mkdir $DIR/$tdir
3346         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3347         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3348
3349         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3350                 error "open unlink test1 failed"
3351         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3352                 error "open unlink test2 failed"
3353
3354         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3355                 error "test1 still exists"
3356         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3357                 error "test2 still exists"
3358 }
3359 run_test 31p "remove of open striped directory"
3360
3361 test_31q() {
3362         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3363
3364         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3365         index=$($LFS getdirstripe -i $DIR/$tdir)
3366         [ $index -eq 3 ] || error "first stripe index $index != 3"
3367         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3368         [ $index -eq 1 ] || error "second stripe index $index != 1"
3369
3370         # when "-c <stripe_count>" is set, the number of MDTs specified after
3371         # "-i" should equal to the stripe count
3372         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3373 }
3374 run_test 31q "create striped directory on specific MDTs"
3375
3376 cleanup_test32_mount() {
3377         local rc=0
3378         trap 0
3379         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3380         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3381         losetup -d $loopdev || true
3382         rm -rf $DIR/$tdir
3383         return $rc
3384 }
3385
3386 test_32a() {
3387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3388
3389         echo "== more mountpoints and symlinks ================="
3390         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3391         trap cleanup_test32_mount EXIT
3392         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3393         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3394                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3395         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3396                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3397         cleanup_test32_mount
3398 }
3399 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3400
3401 test_32b() {
3402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3403
3404         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3405         trap cleanup_test32_mount EXIT
3406         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3407         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3408                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3409         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3410                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3411         cleanup_test32_mount
3412 }
3413 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3414
3415 test_32c() {
3416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3417
3418         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3419         trap cleanup_test32_mount EXIT
3420         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3421         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3422                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3423         test_mkdir -p $DIR/$tdir/d2/test_dir
3424         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3425                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3426         cleanup_test32_mount
3427 }
3428 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3429
3430 test_32d() {
3431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3432
3433         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3434         trap cleanup_test32_mount EXIT
3435         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3436         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3437                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3438         test_mkdir -p $DIR/$tdir/d2/test_dir
3439         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3440                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3441         cleanup_test32_mount
3442 }
3443 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3444
3445 test_32e() {
3446         rm -fr $DIR/$tdir
3447         test_mkdir -p $DIR/$tdir/tmp
3448         local tmp_dir=$DIR/$tdir/tmp
3449         ln -s $DIR/$tdir $tmp_dir/symlink11
3450         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3451         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3452         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3453 }
3454 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3455
3456 test_32f() {
3457         rm -fr $DIR/$tdir
3458         test_mkdir -p $DIR/$tdir/tmp
3459         local tmp_dir=$DIR/$tdir/tmp
3460         ln -s $DIR/$tdir $tmp_dir/symlink11
3461         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3462         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3463         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3464 }
3465 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3466
3467 test_32g() {
3468         local tmp_dir=$DIR/$tdir/tmp
3469         test_mkdir -p $tmp_dir
3470         test_mkdir $DIR/${tdir}2
3471         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3472         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3473         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3474         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3475         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3476         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3477 }
3478 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3479
3480 test_32h() {
3481         rm -fr $DIR/$tdir $DIR/${tdir}2
3482         tmp_dir=$DIR/$tdir/tmp
3483         test_mkdir -p $tmp_dir
3484         test_mkdir $DIR/${tdir}2
3485         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3486         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3487         ls $tmp_dir/symlink12 || error "listing symlink12"
3488         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3489 }
3490 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3491
3492 test_32i() {
3493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3494
3495         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3496         trap cleanup_test32_mount EXIT
3497         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3498         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3499                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3500         touch $DIR/$tdir/test_file
3501         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3502                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3503         cleanup_test32_mount
3504 }
3505 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3506
3507 test_32j() {
3508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3509
3510         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3511         trap cleanup_test32_mount EXIT
3512         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3513         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3514                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3515         touch $DIR/$tdir/test_file
3516         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3517                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3518         cleanup_test32_mount
3519 }
3520 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3521
3522 test_32k() {
3523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3524
3525         rm -fr $DIR/$tdir
3526         trap cleanup_test32_mount EXIT
3527         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3528         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3529                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3530         test_mkdir -p $DIR/$tdir/d2
3531         touch $DIR/$tdir/d2/test_file || error "touch failed"
3532         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3533                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3534         cleanup_test32_mount
3535 }
3536 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3537
3538 test_32l() {
3539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3540
3541         rm -fr $DIR/$tdir
3542         trap cleanup_test32_mount EXIT
3543         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3544         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3545                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3546         test_mkdir -p $DIR/$tdir/d2
3547         touch $DIR/$tdir/d2/test_file || error "touch failed"
3548         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3549                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3550         cleanup_test32_mount
3551 }
3552 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3553
3554 test_32m() {
3555         rm -fr $DIR/d32m
3556         test_mkdir -p $DIR/d32m/tmp
3557         TMP_DIR=$DIR/d32m/tmp
3558         ln -s $DIR $TMP_DIR/symlink11
3559         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3560         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3561                 error "symlink11 not a link"
3562         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3563                 error "symlink01 not a link"
3564 }
3565 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3566
3567 test_32n() {
3568         rm -fr $DIR/d32n
3569         test_mkdir -p $DIR/d32n/tmp
3570         TMP_DIR=$DIR/d32n/tmp
3571         ln -s $DIR $TMP_DIR/symlink11
3572         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3573         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3574         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3575 }
3576 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3577
3578 test_32o() {
3579         touch $DIR/$tfile
3580         test_mkdir -p $DIR/d32o/tmp
3581         TMP_DIR=$DIR/d32o/tmp
3582         ln -s $DIR/$tfile $TMP_DIR/symlink12
3583         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3584         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3585                 error "symlink12 not a link"
3586         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3587         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3588                 error "$DIR/d32o/tmp/symlink12 not file type"
3589         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3590                 error "$DIR/d32o/symlink02 not file type"
3591 }
3592 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3593
3594 test_32p() {
3595         log 32p_1
3596         rm -fr $DIR/d32p
3597         log 32p_2
3598         rm -f $DIR/$tfile
3599         log 32p_3
3600         touch $DIR/$tfile
3601         log 32p_4
3602         test_mkdir -p $DIR/d32p/tmp
3603         log 32p_5
3604         TMP_DIR=$DIR/d32p/tmp
3605         log 32p_6
3606         ln -s $DIR/$tfile $TMP_DIR/symlink12
3607         log 32p_7
3608         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3609         log 32p_8
3610         cat $DIR/d32p/tmp/symlink12 ||
3611                 error "Can't open $DIR/d32p/tmp/symlink12"
3612         log 32p_9
3613         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3614         log 32p_10
3615 }
3616 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3617
3618 test_32q() {
3619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3620
3621         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3622         trap cleanup_test32_mount EXIT
3623         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3624         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3625         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3626                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3627         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3628         cleanup_test32_mount
3629 }
3630 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3631
3632 test_32r() {
3633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3634
3635         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3636         trap cleanup_test32_mount EXIT
3637         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3638         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3639         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3640                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3641         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3642         cleanup_test32_mount
3643 }
3644 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3645
3646 test_33aa() {
3647         rm -f $DIR/$tfile
3648         touch $DIR/$tfile
3649         chmod 444 $DIR/$tfile
3650         chown $RUNAS_ID $DIR/$tfile
3651         log 33_1
3652         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3653         log 33_2
3654 }
3655 run_test 33aa "write file with mode 444 (should return error)"
3656
3657 test_33a() {
3658         rm -fr $DIR/$tdir
3659         test_mkdir $DIR/$tdir
3660         chown $RUNAS_ID $DIR/$tdir
3661         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3662                 error "$RUNAS create $tdir/$tfile failed"
3663         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3664                 error "open RDWR" || true
3665 }
3666 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3667
3668 test_33b() {
3669         rm -fr $DIR/$tdir
3670         test_mkdir $DIR/$tdir
3671         chown $RUNAS_ID $DIR/$tdir
3672         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3673 }
3674 run_test 33b "test open file with malformed flags (No panic)"
3675
3676 test_33c() {
3677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3678         remote_ost_nodsh && skip "remote OST with nodsh"
3679
3680         local ostnum
3681         local ostname
3682         local write_bytes
3683         local all_zeros
3684
3685         all_zeros=:
3686         rm -fr $DIR/$tdir
3687         test_mkdir $DIR/$tdir
3688         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3689
3690         sync
3691         for ostnum in $(seq $OSTCOUNT); do
3692                 # test-framework's OST numbering is one-based, while Lustre's
3693                 # is zero-based
3694                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3695                 # Parsing llobdstat's output sucks; we could grep the /proc
3696                 # path, but that's likely to not be as portable as using the
3697                 # llobdstat utility.  So we parse lctl output instead.
3698                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3699                         obdfilter/$ostname/stats |
3700                         awk '/^write_bytes/ {print $7}' )
3701                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3702                 if (( ${write_bytes:-0} > 0 ))
3703                 then
3704                         all_zeros=false
3705                         break;
3706                 fi
3707         done
3708
3709         $all_zeros || return 0
3710
3711         # Write four bytes
3712         echo foo > $DIR/$tdir/bar
3713         # Really write them
3714         sync
3715
3716         # Total up write_bytes after writing.  We'd better find non-zeros.
3717         for ostnum in $(seq $OSTCOUNT); do
3718                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3719                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3720                         obdfilter/$ostname/stats |
3721                         awk '/^write_bytes/ {print $7}' )
3722                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3723                 if (( ${write_bytes:-0} > 0 ))
3724                 then
3725                         all_zeros=false
3726                         break;
3727                 fi
3728         done
3729
3730         if $all_zeros
3731         then
3732                 for ostnum in $(seq $OSTCOUNT); do
3733                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3734                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3735                         do_facet ost$ostnum lctl get_param -n \
3736                                 obdfilter/$ostname/stats
3737                 done
3738                 error "OST not keeping write_bytes stats (b22312)"
3739         fi
3740 }
3741 run_test 33c "test llobdstat and write_bytes"
3742
3743 test_33d() {
3744         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3746
3747         local MDTIDX=1
3748         local remote_dir=$DIR/$tdir/remote_dir
3749
3750         test_mkdir $DIR/$tdir
3751         $LFS mkdir -i $MDTIDX $remote_dir ||
3752                 error "create remote directory failed"
3753
3754         touch $remote_dir/$tfile
3755         chmod 444 $remote_dir/$tfile
3756         chown $RUNAS_ID $remote_dir/$tfile
3757
3758         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3759
3760         chown $RUNAS_ID $remote_dir
3761         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3762                                         error "create" || true
3763         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3764                                     error "open RDWR" || true
3765         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3766 }
3767 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3768
3769 test_33e() {
3770         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3771
3772         mkdir $DIR/$tdir
3773
3774         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3775         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3776         mkdir $DIR/$tdir/local_dir
3777
3778         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3779         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3780         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3781
3782         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3783                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3784
3785         rmdir $DIR/$tdir/* || error "rmdir failed"
3786
3787         umask 777
3788         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3789         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3790         mkdir $DIR/$tdir/local_dir
3791
3792         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3793         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3794         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3795
3796         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3797                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3798
3799         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3800
3801         umask 000
3802         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3803         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3804         mkdir $DIR/$tdir/local_dir
3805
3806         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3807         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3808         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3809
3810         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3811                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3812 }
3813 run_test 33e "mkdir and striped directory should have same mode"
3814
3815 cleanup_33f() {
3816         trap 0
3817         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3818 }
3819
3820 test_33f() {
3821         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3822         remote_mds_nodsh && skip "remote MDS with nodsh"
3823
3824         mkdir $DIR/$tdir
3825         chmod go+rwx $DIR/$tdir
3826         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3827         trap cleanup_33f EXIT
3828
3829         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3830                 error "cannot create striped directory"
3831
3832         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3833                 error "cannot create files in striped directory"
3834
3835         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3836                 error "cannot remove files in striped directory"
3837
3838         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3839                 error "cannot remove striped directory"
3840
3841         cleanup_33f
3842 }
3843 run_test 33f "nonroot user can create, access, and remove a striped directory"
3844
3845 test_33g() {
3846         mkdir -p $DIR/$tdir/dir2
3847
3848         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3849         echo $err
3850         [[ $err =~ "exists" ]] || error "Not exists error"
3851 }
3852 run_test 33g "nonroot user create already existing root created file"
3853
3854 test_33h() {
3855         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3856         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3857                 skip "Need MDS version at least 2.13.50"
3858
3859         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3860                 error "mkdir $tdir failed"
3861         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3862
3863         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3864         local index2
3865
3866         for fname in $DIR/$tdir/$tfile.bak \
3867                      $DIR/$tdir/$tfile.SAV \
3868                      $DIR/$tdir/$tfile.orig \
3869                      $DIR/$tdir/$tfile~; do
3870                 touch $fname  || error "touch $fname failed"
3871                 index2=$($LFS getstripe -m $fname)
3872                 [ $index -eq $index2 ] ||
3873                         error "$fname MDT index mismatch $index != $index2"
3874         done
3875
3876         local failed=0
3877         for i in {1..250}; do
3878                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3879                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3880                         touch $fname  || error "touch $fname failed"
3881                         index2=$($LFS getstripe -m $fname)
3882                         if [[ $index != $index2 ]]; then
3883                                 failed=$((failed + 1))
3884                                 echo "$fname MDT index mismatch $index != $index2"
3885                         fi
3886                 done
3887         done
3888         echo "$failed MDT index mismatches"
3889         (( failed < 20 )) || error "MDT index mismatch $failed times"
3890
3891 }
3892 run_test 33h "temp file is located on the same MDT as target"
3893
3894 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3895 test_34a() {
3896         rm -f $DIR/f34
3897         $MCREATE $DIR/f34 || error "mcreate failed"
3898         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3899                 error "getstripe failed"
3900         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3901         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3902                 error "getstripe failed"
3903         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3904                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3905 }
3906 run_test 34a "truncate file that has not been opened ==========="
3907
3908 test_34b() {
3909         [ ! -f $DIR/f34 ] && test_34a
3910         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3911                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3912         $OPENFILE -f O_RDONLY $DIR/f34
3913         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3914                 error "getstripe failed"
3915         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3916                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3917 }
3918 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3919
3920 test_34c() {
3921         [ ! -f $DIR/f34 ] && test_34a
3922         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3923                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3924         $OPENFILE -f O_RDWR $DIR/f34
3925         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3926                 error "$LFS getstripe failed"
3927         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3928                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3929 }
3930 run_test 34c "O_RDWR opening file-with-size works =============="
3931
3932 test_34d() {
3933         [ ! -f $DIR/f34 ] && test_34a
3934         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3935                 error "dd failed"
3936         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3937                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3938         rm $DIR/f34
3939 }
3940 run_test 34d "write to sparse file ============================="
3941
3942 test_34e() {
3943         rm -f $DIR/f34e
3944         $MCREATE $DIR/f34e || error "mcreate failed"
3945         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3946         $CHECKSTAT -s 1000 $DIR/f34e ||
3947                 error "Size of $DIR/f34e not equal to 1000 bytes"
3948         $OPENFILE -f O_RDWR $DIR/f34e
3949         $CHECKSTAT -s 1000 $DIR/f34e ||
3950                 error "Size of $DIR/f34e not equal to 1000 bytes"
3951 }
3952 run_test 34e "create objects, some with size and some without =="
3953
3954 test_34f() { # bug 6242, 6243
3955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3956
3957         SIZE34F=48000
3958         rm -f $DIR/f34f
3959         $MCREATE $DIR/f34f || error "mcreate failed"
3960         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3961         dd if=$DIR/f34f of=$TMP/f34f
3962         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3963         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3964         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3965         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3966         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3967 }
3968 run_test 34f "read from a file with no objects until EOF ======="
3969
3970 test_34g() {
3971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3972
3973         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3974                 error "dd failed"
3975         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3976         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3977                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3978         cancel_lru_locks osc
3979         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3980                 error "wrong size after lock cancel"
3981
3982         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3983         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3984                 error "expanding truncate failed"
3985         cancel_lru_locks osc
3986         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3987                 error "wrong expanded size after lock cancel"
3988 }
3989 run_test 34g "truncate long file ==============================="
3990
3991 test_34h() {
3992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3993
3994         local gid=10
3995         local sz=1000
3996
3997         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3998         sync # Flush the cache so that multiop below does not block on cache
3999              # flush when getting the group lock
4000         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4001         MULTIPID=$!
4002
4003         # Since just timed wait is not good enough, let's do a sync write
4004         # that way we are sure enough time for a roundtrip + processing
4005         # passed + 2 seconds of extra margin.
4006         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4007         rm $DIR/${tfile}-1
4008         sleep 2
4009
4010         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4011                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4012                 kill -9 $MULTIPID
4013         fi
4014         wait $MULTIPID
4015         local nsz=`stat -c %s $DIR/$tfile`
4016         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4017 }
4018 run_test 34h "ftruncate file under grouplock should not block"
4019
4020 test_35a() {
4021         cp /bin/sh $DIR/f35a
4022         chmod 444 $DIR/f35a
4023         chown $RUNAS_ID $DIR/f35a
4024         $RUNAS $DIR/f35a && error || true
4025         rm $DIR/f35a
4026 }
4027 run_test 35a "exec file with mode 444 (should return and not leak)"
4028
4029 test_36a() {
4030         rm -f $DIR/f36
4031         utime $DIR/f36 || error "utime failed for MDS"
4032 }
4033 run_test 36a "MDS utime check (mknod, utime)"
4034
4035 test_36b() {
4036         echo "" > $DIR/f36
4037         utime $DIR/f36 || error "utime failed for OST"
4038 }
4039 run_test 36b "OST utime check (open, utime)"
4040
4041 test_36c() {
4042         rm -f $DIR/d36/f36
4043         test_mkdir $DIR/d36
4044         chown $RUNAS_ID $DIR/d36
4045         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4046 }
4047 run_test 36c "non-root MDS utime check (mknod, utime)"
4048
4049 test_36d() {
4050         [ ! -d $DIR/d36 ] && test_36c
4051         echo "" > $DIR/d36/f36
4052         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4053 }
4054 run_test 36d "non-root OST utime check (open, utime)"
4055
4056 test_36e() {
4057         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4058
4059         test_mkdir $DIR/$tdir
4060         touch $DIR/$tdir/$tfile
4061         $RUNAS utime $DIR/$tdir/$tfile &&
4062                 error "utime worked, expected failure" || true
4063 }
4064 run_test 36e "utime on non-owned file (should return error)"
4065
4066 subr_36fh() {
4067         local fl="$1"
4068         local LANG_SAVE=$LANG
4069         local LC_LANG_SAVE=$LC_LANG
4070         export LANG=C LC_LANG=C # for date language
4071
4072         DATESTR="Dec 20  2000"
4073         test_mkdir $DIR/$tdir
4074         lctl set_param fail_loc=$fl
4075         date; date +%s
4076         cp /etc/hosts $DIR/$tdir/$tfile
4077         sync & # write RPC generated with "current" inode timestamp, but delayed
4078         sleep 1
4079         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4080         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4081         cancel_lru_locks $OSC
4082         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4083         date; date +%s
4084         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4085                 echo "BEFORE: $LS_BEFORE" && \
4086                 echo "AFTER : $LS_AFTER" && \
4087                 echo "WANT  : $DATESTR" && \
4088                 error "$DIR/$tdir/$tfile timestamps changed" || true
4089
4090         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4091 }
4092
4093 test_36f() {
4094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4095
4096         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4097         subr_36fh "0x80000214"
4098 }
4099 run_test 36f "utime on file racing with OST BRW write =========="
4100
4101 test_36g() {
4102         remote_ost_nodsh && skip "remote OST with nodsh"
4103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4104         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4105                 skip "Need MDS version at least 2.12.51"
4106
4107         local fmd_max_age
4108         local fmd
4109         local facet="ost1"
4110         local tgt="obdfilter"
4111
4112         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4113
4114         test_mkdir $DIR/$tdir
4115         fmd_max_age=$(do_facet $facet \
4116                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4117                 head -n 1")
4118
4119         echo "FMD max age: ${fmd_max_age}s"
4120         touch $DIR/$tdir/$tfile
4121         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4122                 gawk '{cnt=cnt+$1}  END{print cnt}')
4123         echo "FMD before: $fmd"
4124         [[ $fmd == 0 ]] &&
4125                 error "FMD wasn't create by touch"
4126         sleep $((fmd_max_age + 12))
4127         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4128                 gawk '{cnt=cnt+$1}  END{print cnt}')
4129         echo "FMD after: $fmd"
4130         [[ $fmd == 0 ]] ||
4131                 error "FMD wasn't expired by ping"
4132 }
4133 run_test 36g "FMD cache expiry ====================="
4134
4135 test_36h() {
4136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4137
4138         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4139         subr_36fh "0x80000227"
4140 }
4141 run_test 36h "utime on file racing with OST BRW write =========="
4142
4143 test_36i() {
4144         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4145
4146         test_mkdir $DIR/$tdir
4147         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4148
4149         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4150         local new_mtime=$((mtime + 200))
4151
4152         #change Modify time of striped dir
4153         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4154                         error "change mtime failed"
4155
4156         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4157
4158         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4159 }
4160 run_test 36i "change mtime on striped directory"
4161
4162 # test_37 - duplicate with tests 32q 32r
4163
4164 test_38() {
4165         local file=$DIR/$tfile
4166         touch $file
4167         openfile -f O_DIRECTORY $file
4168         local RC=$?
4169         local ENOTDIR=20
4170         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4171         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4172 }
4173 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4174
4175 test_39a() { # was test_39
4176         touch $DIR/$tfile
4177         touch $DIR/${tfile}2
4178 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4179 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4180 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4181         sleep 2
4182         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4183         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4184                 echo "mtime"
4185                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4186                 echo "atime"
4187                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4188                 echo "ctime"
4189                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4190                 error "O_TRUNC didn't change timestamps"
4191         fi
4192 }
4193 run_test 39a "mtime changed on create"
4194
4195 test_39b() {
4196         test_mkdir -c1 $DIR/$tdir
4197         cp -p /etc/passwd $DIR/$tdir/fopen
4198         cp -p /etc/passwd $DIR/$tdir/flink
4199         cp -p /etc/passwd $DIR/$tdir/funlink
4200         cp -p /etc/passwd $DIR/$tdir/frename
4201         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4202
4203         sleep 1
4204         echo "aaaaaa" >> $DIR/$tdir/fopen
4205         echo "aaaaaa" >> $DIR/$tdir/flink
4206         echo "aaaaaa" >> $DIR/$tdir/funlink
4207         echo "aaaaaa" >> $DIR/$tdir/frename
4208
4209         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4210         local link_new=`stat -c %Y $DIR/$tdir/flink`
4211         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4212         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4213
4214         cat $DIR/$tdir/fopen > /dev/null
4215         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4216         rm -f $DIR/$tdir/funlink2
4217         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4218
4219         for (( i=0; i < 2; i++ )) ; do
4220                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4221                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4222                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4223                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4224
4225                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4226                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4227                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4228                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4229
4230                 cancel_lru_locks $OSC
4231                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4232         done
4233 }
4234 run_test 39b "mtime change on open, link, unlink, rename  ======"
4235
4236 # this should be set to past
4237 TEST_39_MTIME=`date -d "1 year ago" +%s`
4238
4239 # bug 11063
4240 test_39c() {
4241         touch $DIR1/$tfile
4242         sleep 2
4243         local mtime0=`stat -c %Y $DIR1/$tfile`
4244
4245         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4246         local mtime1=`stat -c %Y $DIR1/$tfile`
4247         [ "$mtime1" = $TEST_39_MTIME ] || \
4248                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4249
4250         local d1=`date +%s`
4251         echo hello >> $DIR1/$tfile
4252         local d2=`date +%s`
4253         local mtime2=`stat -c %Y $DIR1/$tfile`
4254         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4255                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4256
4257         mv $DIR1/$tfile $DIR1/$tfile-1
4258
4259         for (( i=0; i < 2; i++ )) ; do
4260                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4261                 [ "$mtime2" = "$mtime3" ] || \
4262                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4263
4264                 cancel_lru_locks $OSC
4265                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4266         done
4267 }
4268 run_test 39c "mtime change on rename ==========================="
4269
4270 # bug 21114
4271 test_39d() {
4272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4273
4274         touch $DIR1/$tfile
4275         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4276
4277         for (( i=0; i < 2; i++ )) ; do
4278                 local mtime=`stat -c %Y $DIR1/$tfile`
4279                 [ $mtime = $TEST_39_MTIME ] || \
4280                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4281
4282                 cancel_lru_locks $OSC
4283                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4284         done
4285 }
4286 run_test 39d "create, utime, stat =============================="
4287
4288 # bug 21114
4289 test_39e() {
4290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4291
4292         touch $DIR1/$tfile
4293         local mtime1=`stat -c %Y $DIR1/$tfile`
4294
4295         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4296
4297         for (( i=0; i < 2; i++ )) ; do
4298                 local mtime2=`stat -c %Y $DIR1/$tfile`
4299                 [ $mtime2 = $TEST_39_MTIME ] || \
4300                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4301
4302                 cancel_lru_locks $OSC
4303                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4304         done
4305 }
4306 run_test 39e "create, stat, utime, stat ========================"
4307
4308 # bug 21114
4309 test_39f() {
4310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4311
4312         touch $DIR1/$tfile
4313         mtime1=`stat -c %Y $DIR1/$tfile`
4314
4315         sleep 2
4316         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4317
4318         for (( i=0; i < 2; i++ )) ; do
4319                 local mtime2=`stat -c %Y $DIR1/$tfile`
4320                 [ $mtime2 = $TEST_39_MTIME ] || \
4321                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4322
4323                 cancel_lru_locks $OSC
4324                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4325         done
4326 }
4327 run_test 39f "create, stat, sleep, utime, stat ================="
4328
4329 # bug 11063
4330 test_39g() {
4331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4332
4333         echo hello >> $DIR1/$tfile
4334         local mtime1=`stat -c %Y $DIR1/$tfile`
4335
4336         sleep 2
4337         chmod o+r $DIR1/$tfile
4338
4339         for (( i=0; i < 2; i++ )) ; do
4340                 local mtime2=`stat -c %Y $DIR1/$tfile`
4341                 [ "$mtime1" = "$mtime2" ] || \
4342                         error "lost mtime: $mtime2, should be $mtime1"
4343
4344                 cancel_lru_locks $OSC
4345                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4346         done
4347 }
4348 run_test 39g "write, chmod, stat ==============================="
4349
4350 # bug 11063
4351 test_39h() {
4352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4353
4354         touch $DIR1/$tfile
4355         sleep 1
4356
4357         local d1=`date`
4358         echo hello >> $DIR1/$tfile
4359         local mtime1=`stat -c %Y $DIR1/$tfile`
4360
4361         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4362         local d2=`date`
4363         if [ "$d1" != "$d2" ]; then
4364                 echo "write and touch not within one second"
4365         else
4366                 for (( i=0; i < 2; i++ )) ; do
4367                         local mtime2=`stat -c %Y $DIR1/$tfile`
4368                         [ "$mtime2" = $TEST_39_MTIME ] || \
4369                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4370
4371                         cancel_lru_locks $OSC
4372                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4373                 done
4374         fi
4375 }
4376 run_test 39h "write, utime within one second, stat ============="
4377
4378 test_39i() {
4379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4380
4381         touch $DIR1/$tfile
4382         sleep 1
4383
4384         echo hello >> $DIR1/$tfile
4385         local mtime1=`stat -c %Y $DIR1/$tfile`
4386
4387         mv $DIR1/$tfile $DIR1/$tfile-1
4388
4389         for (( i=0; i < 2; i++ )) ; do
4390                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4391
4392                 [ "$mtime1" = "$mtime2" ] || \
4393                         error "lost mtime: $mtime2, should be $mtime1"
4394
4395                 cancel_lru_locks $OSC
4396                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4397         done
4398 }
4399 run_test 39i "write, rename, stat =============================="
4400
4401 test_39j() {
4402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4403
4404         start_full_debug_logging
4405         touch $DIR1/$tfile
4406         sleep 1
4407
4408         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4409         lctl set_param fail_loc=0x80000412
4410         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4411                 error "multiop failed"
4412         local multipid=$!
4413         local mtime1=`stat -c %Y $DIR1/$tfile`
4414
4415         mv $DIR1/$tfile $DIR1/$tfile-1
4416
4417         kill -USR1 $multipid
4418         wait $multipid || error "multiop close failed"
4419
4420         for (( i=0; i < 2; i++ )) ; do
4421                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4422                 [ "$mtime1" = "$mtime2" ] ||
4423                         error "mtime is lost on close: $mtime2, " \
4424                               "should be $mtime1"
4425
4426                 cancel_lru_locks
4427                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4428         done
4429         lctl set_param fail_loc=0
4430         stop_full_debug_logging
4431 }
4432 run_test 39j "write, rename, close, stat ======================="
4433
4434 test_39k() {
4435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4436
4437         touch $DIR1/$tfile
4438         sleep 1
4439
4440         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4441         local multipid=$!
4442         local mtime1=`stat -c %Y $DIR1/$tfile`
4443
4444         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4445
4446         kill -USR1 $multipid
4447         wait $multipid || error "multiop close failed"
4448
4449         for (( i=0; i < 2; i++ )) ; do
4450                 local mtime2=`stat -c %Y $DIR1/$tfile`
4451
4452                 [ "$mtime2" = $TEST_39_MTIME ] || \
4453                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4454
4455                 cancel_lru_locks
4456                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4457         done
4458 }
4459 run_test 39k "write, utime, close, stat ========================"
4460
4461 # this should be set to future
4462 TEST_39_ATIME=`date -d "1 year" +%s`
4463
4464 test_39l() {
4465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4466         remote_mds_nodsh && skip "remote MDS with nodsh"
4467
4468         local atime_diff=$(do_facet $SINGLEMDS \
4469                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4470         rm -rf $DIR/$tdir
4471         mkdir -p $DIR/$tdir
4472
4473         # test setting directory atime to future
4474         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4475         local atime=$(stat -c %X $DIR/$tdir)
4476         [ "$atime" = $TEST_39_ATIME ] ||
4477                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4478
4479         # test setting directory atime from future to now
4480         local now=$(date +%s)
4481         touch -a -d @$now $DIR/$tdir
4482
4483         atime=$(stat -c %X $DIR/$tdir)
4484         [ "$atime" -eq "$now"  ] ||
4485                 error "atime is not updated from future: $atime, $now"
4486
4487         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4488         sleep 3
4489
4490         # test setting directory atime when now > dir atime + atime_diff
4491         local d1=$(date +%s)
4492         ls $DIR/$tdir
4493         local d2=$(date +%s)
4494         cancel_lru_locks mdc
4495         atime=$(stat -c %X $DIR/$tdir)
4496         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4497                 error "atime is not updated  : $atime, should be $d2"
4498
4499         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4500         sleep 3
4501
4502         # test not setting directory atime when now < dir atime + atime_diff
4503         ls $DIR/$tdir
4504         cancel_lru_locks mdc
4505         atime=$(stat -c %X $DIR/$tdir)
4506         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4507                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4508
4509         do_facet $SINGLEMDS \
4510                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4511 }
4512 run_test 39l "directory atime update ==========================="
4513
4514 test_39m() {
4515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4516
4517         touch $DIR1/$tfile
4518         sleep 2
4519         local far_past_mtime=$(date -d "May 29 1953" +%s)
4520         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4521
4522         touch -m -d @$far_past_mtime $DIR1/$tfile
4523         touch -a -d @$far_past_atime $DIR1/$tfile
4524
4525         for (( i=0; i < 2; i++ )) ; do
4526                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4527                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4528                         error "atime or mtime set incorrectly"
4529
4530                 cancel_lru_locks $OSC
4531                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4532         done
4533 }
4534 run_test 39m "test atime and mtime before 1970"
4535
4536 test_39n() { # LU-3832
4537         remote_mds_nodsh && skip "remote MDS with nodsh"
4538
4539         local atime_diff=$(do_facet $SINGLEMDS \
4540                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4541         local atime0
4542         local atime1
4543         local atime2
4544
4545         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4546
4547         rm -rf $DIR/$tfile
4548         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4549         atime0=$(stat -c %X $DIR/$tfile)
4550
4551         sleep 5
4552         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4553         atime1=$(stat -c %X $DIR/$tfile)
4554
4555         sleep 5
4556         cancel_lru_locks mdc
4557         cancel_lru_locks osc
4558         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4559         atime2=$(stat -c %X $DIR/$tfile)
4560
4561         do_facet $SINGLEMDS \
4562                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4563
4564         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4565         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4566 }
4567 run_test 39n "check that O_NOATIME is honored"
4568
4569 test_39o() {
4570         TESTDIR=$DIR/$tdir/$tfile
4571         [ -e $TESTDIR ] && rm -rf $TESTDIR
4572         mkdir -p $TESTDIR
4573         cd $TESTDIR
4574         links1=2
4575         ls
4576         mkdir a b
4577         ls
4578         links2=$(stat -c %h .)
4579         [ $(($links1 + 2)) != $links2 ] &&
4580                 error "wrong links count $(($links1 + 2)) != $links2"
4581         rmdir b
4582         links3=$(stat -c %h .)
4583         [ $(($links1 + 1)) != $links3 ] &&
4584                 error "wrong links count $links1 != $links3"
4585         return 0
4586 }
4587 run_test 39o "directory cached attributes updated after create"
4588
4589 test_39p() {
4590         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4591
4592         local MDTIDX=1
4593         TESTDIR=$DIR/$tdir/$tdir
4594         [ -e $TESTDIR ] && rm -rf $TESTDIR
4595         test_mkdir -p $TESTDIR
4596         cd $TESTDIR
4597         links1=2
4598         ls
4599         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4600         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4601         ls
4602         links2=$(stat -c %h .)
4603         [ $(($links1 + 2)) != $links2 ] &&
4604                 error "wrong links count $(($links1 + 2)) != $links2"
4605         rmdir remote_dir2
4606         links3=$(stat -c %h .)
4607         [ $(($links1 + 1)) != $links3 ] &&
4608                 error "wrong links count $links1 != $links3"
4609         return 0
4610 }
4611 run_test 39p "remote directory cached attributes updated after create ========"
4612
4613 test_39r() {
4614         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4615                 skip "no atime update on old OST"
4616         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4617                 skip_env "ldiskfs only test"
4618         fi
4619
4620         local saved_adiff
4621         saved_adiff=$(do_facet ost1 \
4622                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4623         stack_trap "do_facet ost1 \
4624                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4625
4626         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4627
4628         $LFS setstripe -i 0 $DIR/$tfile
4629         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4630                 error "can't write initial file"
4631         cancel_lru_locks osc
4632
4633         # exceed atime_diff and access file
4634         sleep 6
4635         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4636                 error "can't udpate atime"
4637
4638         local atime_cli=$(stat -c %X $DIR/$tfile)
4639         echo "client atime: $atime_cli"
4640         # allow atime update to be written to device
4641         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4642         sleep 5
4643
4644         local ostdev=$(ostdevname 1)
4645         local fid=($(lfs getstripe -y $DIR/$tfile |
4646                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4647         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4648         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4649
4650         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4651         local atime_ost=$(do_facet ost1 "$cmd" |&
4652                           awk -F'[: ]' '/atime:/ { print $4 }')
4653         (( atime_cli == atime_ost )) ||
4654                 error "atime on client $atime_cli != ost $atime_ost"
4655 }
4656 run_test 39r "lazy atime update on OST"
4657
4658 test_39q() { # LU-8041
4659         local testdir=$DIR/$tdir
4660         mkdir -p $testdir
4661         multiop_bg_pause $testdir D_c || error "multiop failed"
4662         local multipid=$!
4663         cancel_lru_locks mdc
4664         kill -USR1 $multipid
4665         local atime=$(stat -c %X $testdir)
4666         [ "$atime" -ne 0 ] || error "atime is zero"
4667 }
4668 run_test 39q "close won't zero out atime"
4669
4670 test_40() {
4671         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4672         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4673                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4674         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4675                 error "$tfile is not 4096 bytes in size"
4676 }
4677 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4678
4679 test_41() {
4680         # bug 1553
4681         small_write $DIR/f41 18
4682 }
4683 run_test 41 "test small file write + fstat ====================="
4684
4685 count_ost_writes() {
4686         lctl get_param -n ${OSC}.*.stats |
4687                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4688                         END { printf("%0.0f", writes) }'
4689 }
4690
4691 # decent default
4692 WRITEBACK_SAVE=500
4693 DIRTY_RATIO_SAVE=40
4694 MAX_DIRTY_RATIO=50
4695 BG_DIRTY_RATIO_SAVE=10
4696 MAX_BG_DIRTY_RATIO=25
4697
4698 start_writeback() {
4699         trap 0
4700         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4701         # dirty_ratio, dirty_background_ratio
4702         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4703                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4704                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4705                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4706         else
4707                 # if file not here, we are a 2.4 kernel
4708                 kill -CONT `pidof kupdated`
4709         fi
4710 }
4711
4712 stop_writeback() {
4713         # setup the trap first, so someone cannot exit the test at the
4714         # exact wrong time and mess up a machine
4715         trap start_writeback EXIT
4716         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4717         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4718                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4719                 sysctl -w vm.dirty_writeback_centisecs=0
4720                 sysctl -w vm.dirty_writeback_centisecs=0
4721                 # save and increase /proc/sys/vm/dirty_ratio
4722                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4723                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4724                 # save and increase /proc/sys/vm/dirty_background_ratio
4725                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4726                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4727         else
4728                 # if file not here, we are a 2.4 kernel
4729                 kill -STOP `pidof kupdated`
4730         fi
4731 }
4732
4733 # ensure that all stripes have some grant before we test client-side cache
4734 setup_test42() {
4735         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4736                 dd if=/dev/zero of=$i bs=4k count=1
4737                 rm $i
4738         done
4739 }
4740
4741 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4742 # file truncation, and file removal.
4743 test_42a() {
4744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4745
4746         setup_test42
4747         cancel_lru_locks $OSC
4748         stop_writeback
4749         sync; sleep 1; sync # just to be safe
4750         BEFOREWRITES=`count_ost_writes`
4751         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4752         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4753         AFTERWRITES=`count_ost_writes`
4754         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4755                 error "$BEFOREWRITES < $AFTERWRITES"
4756         start_writeback
4757 }
4758 run_test 42a "ensure that we don't flush on close"
4759
4760 test_42b() {
4761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4762
4763         setup_test42
4764         cancel_lru_locks $OSC
4765         stop_writeback
4766         sync
4767         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4768         BEFOREWRITES=$(count_ost_writes)
4769         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4770         AFTERWRITES=$(count_ost_writes)
4771         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4772                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4773         fi
4774         BEFOREWRITES=$(count_ost_writes)
4775         sync || error "sync: $?"
4776         AFTERWRITES=$(count_ost_writes)
4777         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4778                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4779         fi
4780         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4781         start_writeback
4782         return 0
4783 }
4784 run_test 42b "test destroy of file with cached dirty data ======"
4785
4786 # if these tests just want to test the effect of truncation,
4787 # they have to be very careful.  consider:
4788 # - the first open gets a {0,EOF}PR lock
4789 # - the first write conflicts and gets a {0, count-1}PW
4790 # - the rest of the writes are under {count,EOF}PW
4791 # - the open for truncate tries to match a {0,EOF}PR
4792 #   for the filesize and cancels the PWs.
4793 # any number of fixes (don't get {0,EOF} on open, match
4794 # composite locks, do smarter file size management) fix
4795 # this, but for now we want these tests to verify that
4796 # the cancellation with truncate intent works, so we
4797 # start the file with a full-file pw lock to match against
4798 # until the truncate.
4799 trunc_test() {
4800         test=$1
4801         file=$DIR/$test
4802         offset=$2
4803         cancel_lru_locks $OSC
4804         stop_writeback
4805         # prime the file with 0,EOF PW to match
4806         touch $file
4807         $TRUNCATE $file 0
4808         sync; sync
4809         # now the real test..
4810         dd if=/dev/zero of=$file bs=1024 count=100
4811         BEFOREWRITES=`count_ost_writes`
4812         $TRUNCATE $file $offset
4813         cancel_lru_locks $OSC
4814         AFTERWRITES=`count_ost_writes`
4815         start_writeback
4816 }
4817
4818 test_42c() {
4819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4820
4821         trunc_test 42c 1024
4822         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4823                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4824         rm $file
4825 }
4826 run_test 42c "test partial truncate of file with cached dirty data"
4827
4828 test_42d() {
4829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4830
4831         trunc_test 42d 0
4832         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4833                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4834         rm $file
4835 }
4836 run_test 42d "test complete truncate of file with cached dirty data"
4837
4838 test_42e() { # bug22074
4839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4840
4841         local TDIR=$DIR/${tdir}e
4842         local pages=16 # hardcoded 16 pages, don't change it.
4843         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4844         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4845         local max_dirty_mb
4846         local warmup_files
4847
4848         test_mkdir $DIR/${tdir}e
4849         $LFS setstripe -c 1 $TDIR
4850         createmany -o $TDIR/f $files
4851
4852         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4853
4854         # we assume that with $OSTCOUNT files, at least one of them will
4855         # be allocated on OST0.
4856         warmup_files=$((OSTCOUNT * max_dirty_mb))
4857         createmany -o $TDIR/w $warmup_files
4858
4859         # write a large amount of data into one file and sync, to get good
4860         # avail_grant number from OST.
4861         for ((i=0; i<$warmup_files; i++)); do
4862                 idx=$($LFS getstripe -i $TDIR/w$i)
4863                 [ $idx -ne 0 ] && continue
4864                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4865                 break
4866         done
4867         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4868         sync
4869         $LCTL get_param $proc_osc0/cur_dirty_bytes
4870         $LCTL get_param $proc_osc0/cur_grant_bytes
4871
4872         # create as much dirty pages as we can while not to trigger the actual
4873         # RPCs directly. but depends on the env, VFS may trigger flush during this
4874         # period, hopefully we are good.
4875         for ((i=0; i<$warmup_files; i++)); do
4876                 idx=$($LFS getstripe -i $TDIR/w$i)
4877                 [ $idx -ne 0 ] && continue
4878                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4879         done
4880         $LCTL get_param $proc_osc0/cur_dirty_bytes
4881         $LCTL get_param $proc_osc0/cur_grant_bytes
4882
4883         # perform the real test
4884         $LCTL set_param $proc_osc0/rpc_stats 0
4885         for ((;i<$files; i++)); do
4886                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4887                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4888         done
4889         sync
4890         $LCTL get_param $proc_osc0/rpc_stats
4891
4892         local percent=0
4893         local have_ppr=false
4894         $LCTL get_param $proc_osc0/rpc_stats |
4895                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4896                         # skip lines until we are at the RPC histogram data
4897                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4898                         $have_ppr || continue
4899
4900                         # we only want the percent stat for < 16 pages
4901                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4902
4903                         percent=$((percent + WPCT))
4904                         if [[ $percent -gt 15 ]]; then
4905                                 error "less than 16-pages write RPCs" \
4906                                       "$percent% > 15%"
4907                                 break
4908                         fi
4909                 done
4910         rm -rf $TDIR
4911 }
4912 run_test 42e "verify sub-RPC writes are not done synchronously"
4913
4914 test_43A() { # was test_43
4915         test_mkdir $DIR/$tdir
4916         cp -p /bin/ls $DIR/$tdir/$tfile
4917         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4918         pid=$!
4919         # give multiop a chance to open
4920         sleep 1
4921
4922         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4923         kill -USR1 $pid
4924         # Wait for multiop to exit
4925         wait $pid
4926 }
4927 run_test 43A "execution of file opened for write should return -ETXTBSY"
4928
4929 test_43a() {
4930         test_mkdir $DIR/$tdir
4931         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4932         $DIR/$tdir/sleep 60 &
4933         SLEEP_PID=$!
4934         # Make sure exec of $tdir/sleep wins race with truncate
4935         sleep 1
4936         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4937         kill $SLEEP_PID
4938 }
4939 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4940
4941 test_43b() {
4942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4943
4944         test_mkdir $DIR/$tdir
4945         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4946         $DIR/$tdir/sleep 60 &
4947         SLEEP_PID=$!
4948         # Make sure exec of $tdir/sleep wins race with truncate
4949         sleep 1
4950         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4951         kill $SLEEP_PID
4952 }
4953 run_test 43b "truncate of file being executed should return -ETXTBSY"
4954
4955 test_43c() {
4956         local testdir="$DIR/$tdir"
4957         test_mkdir $testdir
4958         cp $SHELL $testdir/
4959         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4960                 ( cd $testdir && md5sum -c )
4961 }
4962 run_test 43c "md5sum of copy into lustre"
4963
4964 test_44A() { # was test_44
4965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4966
4967         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4968         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4969 }
4970 run_test 44A "zero length read from a sparse stripe"
4971
4972 test_44a() {
4973         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4974                 awk '{ print $2 }')
4975         [ -z "$nstripe" ] && skip "can't get stripe info"
4976         [[ $nstripe -gt $OSTCOUNT ]] &&
4977                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4978
4979         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4980                 awk '{ print $2 }')
4981         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4982                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4983                         awk '{ print $2 }')
4984         fi
4985
4986         OFFSETS="0 $((stride/2)) $((stride-1))"
4987         for offset in $OFFSETS; do
4988                 for i in $(seq 0 $((nstripe-1))); do
4989                         local GLOBALOFFSETS=""
4990                         # size in Bytes
4991                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4992                         local myfn=$DIR/d44a-$size
4993                         echo "--------writing $myfn at $size"
4994                         ll_sparseness_write $myfn $size ||
4995                                 error "ll_sparseness_write"
4996                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4997                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4998                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4999
5000                         for j in $(seq 0 $((nstripe-1))); do
5001                                 # size in Bytes
5002                                 size=$((((j + $nstripe )*$stride + $offset)))
5003                                 ll_sparseness_write $myfn $size ||
5004                                         error "ll_sparseness_write"
5005                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5006                         done
5007                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5008                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5009                         rm -f $myfn
5010                 done
5011         done
5012 }
5013 run_test 44a "test sparse pwrite ==============================="
5014
5015 dirty_osc_total() {
5016         tot=0
5017         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5018                 tot=$(($tot + $d))
5019         done
5020         echo $tot
5021 }
5022 do_dirty_record() {
5023         before=`dirty_osc_total`
5024         echo executing "\"$*\""
5025         eval $*
5026         after=`dirty_osc_total`
5027         echo before $before, after $after
5028 }
5029 test_45() {
5030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5031
5032         f="$DIR/f45"
5033         # Obtain grants from OST if it supports it
5034         echo blah > ${f}_grant
5035         stop_writeback
5036         sync
5037         do_dirty_record "echo blah > $f"
5038         [[ $before -eq $after ]] && error "write wasn't cached"
5039         do_dirty_record "> $f"
5040         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5041         do_dirty_record "echo blah > $f"
5042         [[ $before -eq $after ]] && error "write wasn't cached"
5043         do_dirty_record "sync"
5044         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5045         do_dirty_record "echo blah > $f"
5046         [[ $before -eq $after ]] && error "write wasn't cached"
5047         do_dirty_record "cancel_lru_locks osc"
5048         [[ $before -gt $after ]] ||
5049                 error "lock cancellation didn't lower dirty count"
5050         start_writeback
5051 }
5052 run_test 45 "osc io page accounting ============================"
5053
5054 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5055 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5056 # objects offset and an assert hit when an rpc was built with 1023's mapped
5057 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5058 test_46() {
5059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5060
5061         f="$DIR/f46"
5062         stop_writeback
5063         sync
5064         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5065         sync
5066         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5067         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5068         sync
5069         start_writeback
5070 }
5071 run_test 46 "dirtying a previously written page ================"
5072
5073 # test_47 is removed "Device nodes check" is moved to test_28
5074
5075 test_48a() { # bug 2399
5076         [ "$mds1_FSTYPE" = "zfs" ] &&
5077         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5078                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5079
5080         test_mkdir $DIR/$tdir
5081         cd $DIR/$tdir
5082         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5083         test_mkdir $DIR/$tdir
5084         touch foo || error "'touch foo' failed after recreating cwd"
5085         test_mkdir bar
5086         touch .foo || error "'touch .foo' failed after recreating cwd"
5087         test_mkdir .bar
5088         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5089         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5090         cd . || error "'cd .' failed after recreating cwd"
5091         mkdir . && error "'mkdir .' worked after recreating cwd"
5092         rmdir . && error "'rmdir .' worked after recreating cwd"
5093         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5094         cd .. || error "'cd ..' failed after recreating cwd"
5095 }
5096 run_test 48a "Access renamed working dir (should return errors)="
5097
5098 test_48b() { # bug 2399
5099         rm -rf $DIR/$tdir
5100         test_mkdir $DIR/$tdir
5101         cd $DIR/$tdir
5102         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5103         touch foo && error "'touch foo' worked after removing cwd"
5104         mkdir foo && error "'mkdir foo' worked after removing cwd"
5105         touch .foo && error "'touch .foo' worked after removing cwd"
5106         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5107         ls . > /dev/null && error "'ls .' worked after removing cwd"
5108         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5109         mkdir . && error "'mkdir .' worked after removing cwd"
5110         rmdir . && error "'rmdir .' worked after removing cwd"
5111         ln -s . foo && error "'ln -s .' worked after removing cwd"
5112         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5113 }
5114 run_test 48b "Access removed working dir (should return errors)="
5115
5116 test_48c() { # bug 2350
5117         #lctl set_param debug=-1
5118         #set -vx
5119         rm -rf $DIR/$tdir
5120         test_mkdir -p $DIR/$tdir/dir
5121         cd $DIR/$tdir/dir
5122         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5123         $TRACE touch foo && error "touch foo worked after removing cwd"
5124         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5125         touch .foo && error "touch .foo worked after removing cwd"
5126         mkdir .foo && error "mkdir .foo worked after removing cwd"
5127         $TRACE ls . && error "'ls .' worked after removing cwd"
5128         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5129         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5130         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5131         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5132         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5133 }
5134 run_test 48c "Access removed working subdir (should return errors)"
5135
5136 test_48d() { # bug 2350
5137         #lctl set_param debug=-1
5138         #set -vx
5139         rm -rf $DIR/$tdir
5140         test_mkdir -p $DIR/$tdir/dir
5141         cd $DIR/$tdir/dir
5142         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5143         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5144         $TRACE touch foo && error "'touch foo' worked after removing parent"
5145         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5146         touch .foo && error "'touch .foo' worked after removing parent"
5147         mkdir .foo && error "mkdir .foo worked after removing parent"
5148         $TRACE ls . && error "'ls .' worked after removing parent"
5149         $TRACE ls .. && error "'ls ..' worked after removing parent"
5150         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5151         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5152         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5153         true
5154 }
5155 run_test 48d "Access removed parent subdir (should return errors)"
5156
5157 test_48e() { # bug 4134
5158         #lctl set_param debug=-1
5159         #set -vx
5160         rm -rf $DIR/$tdir
5161         test_mkdir -p $DIR/$tdir/dir
5162         cd $DIR/$tdir/dir
5163         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5164         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5165         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5166         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5167         # On a buggy kernel addition of "touch foo" after cd .. will
5168         # produce kernel oops in lookup_hash_it
5169         touch ../foo && error "'cd ..' worked after recreate parent"
5170         cd $DIR
5171         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5172 }
5173 run_test 48e "Access to recreated parent subdir (should return errors)"
5174
5175 test_48f() {
5176         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5177                 skip "need MDS >= 2.13.55"
5178         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5179         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5180                 skip "needs different host for mdt1 mdt2"
5181         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5182
5183         $LFS mkdir -i0 $DIR/$tdir
5184         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5185
5186         for d in sub1 sub2 sub3; do
5187                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5188                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5189                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5190         done
5191
5192         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5193 }
5194 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5195
5196 test_49() { # LU-1030
5197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5198         remote_ost_nodsh && skip "remote OST with nodsh"
5199
5200         # get ost1 size - $FSNAME-OST0000
5201         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5202                 awk '{ print $4 }')
5203         # write 800M at maximum
5204         [[ $ost1_size -lt 2 ]] && ost1_size=2
5205         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5206
5207         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5208         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5209         local dd_pid=$!
5210
5211         # change max_pages_per_rpc while writing the file
5212         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5213         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5214         # loop until dd process exits
5215         while ps ax -opid | grep -wq $dd_pid; do
5216                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5217                 sleep $((RANDOM % 5 + 1))
5218         done
5219         # restore original max_pages_per_rpc
5220         $LCTL set_param $osc1_mppc=$orig_mppc
5221         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5222 }
5223 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5224
5225 test_50() {
5226         # bug 1485
5227         test_mkdir $DIR/$tdir
5228         cd $DIR/$tdir
5229         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5230 }
5231 run_test 50 "special situations: /proc symlinks  ==============="
5232
5233 test_51a() {    # was test_51
5234         # bug 1516 - create an empty entry right after ".." then split dir
5235         test_mkdir -c1 $DIR/$tdir
5236         touch $DIR/$tdir/foo
5237         $MCREATE $DIR/$tdir/bar
5238         rm $DIR/$tdir/foo
5239         createmany -m $DIR/$tdir/longfile 201
5240         FNUM=202
5241         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5242                 $MCREATE $DIR/$tdir/longfile$FNUM
5243                 FNUM=$(($FNUM + 1))
5244                 echo -n "+"
5245         done
5246         echo
5247         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5248 }
5249 run_test 51a "special situations: split htree with empty entry =="
5250
5251 cleanup_print_lfs_df () {
5252         trap 0
5253         $LFS df
5254         $LFS df -i
5255 }
5256
5257 test_51b() {
5258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5259
5260         local dir=$DIR/$tdir
5261         local nrdirs=$((65536 + 100))
5262
5263         # cleanup the directory
5264         rm -fr $dir
5265
5266         test_mkdir -c1 $dir
5267
5268         $LFS df
5269         $LFS df -i
5270         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5271         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5272         [[ $numfree -lt $nrdirs ]] &&
5273                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5274
5275         # need to check free space for the directories as well
5276         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5277         numfree=$(( blkfree / $(fs_inode_ksize) ))
5278         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5279
5280         trap cleanup_print_lfs_df EXIT
5281
5282         # create files
5283         createmany -d $dir/d $nrdirs || {
5284                 unlinkmany $dir/d $nrdirs
5285                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5286         }
5287
5288         # really created :
5289         nrdirs=$(ls -U $dir | wc -l)
5290
5291         # unlink all but 100 subdirectories, then check it still works
5292         local left=100
5293         local delete=$((nrdirs - left))
5294
5295         $LFS df
5296         $LFS df -i
5297
5298         # for ldiskfs the nlink count should be 1, but this is OSD specific
5299         # and so this is listed for informational purposes only
5300         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5301         unlinkmany -d $dir/d $delete ||
5302                 error "unlink of first $delete subdirs failed"
5303
5304         echo "nlink between: $(stat -c %h $dir)"
5305         local found=$(ls -U $dir | wc -l)
5306         [ $found -ne $left ] &&
5307                 error "can't find subdirs: found only $found, expected $left"
5308
5309         unlinkmany -d $dir/d $delete $left ||
5310                 error "unlink of second $left subdirs failed"
5311         # regardless of whether the backing filesystem tracks nlink accurately
5312         # or not, the nlink count shouldn't be more than "." and ".." here
5313         local after=$(stat -c %h $dir)
5314         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5315                 echo "nlink after: $after"
5316
5317         cleanup_print_lfs_df
5318 }
5319 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5320
5321 test_51d() {
5322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5323         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5324
5325         test_mkdir $DIR/$tdir
5326         createmany -o $DIR/$tdir/t- 1000
5327         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5328         for N in $(seq 0 $((OSTCOUNT - 1))); do
5329                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5330                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5331                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5332                         '($1 == '$N') { objs += 1 } \
5333                         END { printf("%0.0f", objs) }')
5334                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5335         done
5336         unlinkmany $DIR/$tdir/t- 1000
5337
5338         NLAST=0
5339         for N in $(seq 1 $((OSTCOUNT - 1))); do
5340                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5341                         error "OST $N has less objects vs OST $NLAST" \
5342                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5343                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5344                         error "OST $N has less objects vs OST $NLAST" \
5345                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5346
5347                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5348                         error "OST $N has less #0 objects vs OST $NLAST" \
5349                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5350                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5351                         error "OST $N has less #0 objects vs OST $NLAST" \
5352                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5353                 NLAST=$N
5354         done
5355         rm -f $TMP/$tfile
5356 }
5357 run_test 51d "check object distribution"
5358
5359 test_51e() {
5360         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5361                 skip_env "ldiskfs only test"
5362         fi
5363
5364         test_mkdir -c1 $DIR/$tdir
5365         test_mkdir -c1 $DIR/$tdir/d0
5366
5367         touch $DIR/$tdir/d0/foo
5368         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5369                 error "file exceed 65000 nlink limit!"
5370         unlinkmany $DIR/$tdir/d0/f- 65001
5371         return 0
5372 }
5373 run_test 51e "check file nlink limit"
5374
5375 test_51f() {
5376         test_mkdir $DIR/$tdir
5377
5378         local max=100000
5379         local ulimit_old=$(ulimit -n)
5380         local spare=20 # number of spare fd's for scripts/libraries, etc.
5381         local mdt=$($LFS getstripe -m $DIR/$tdir)
5382         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5383
5384         echo "MDT$mdt numfree=$numfree, max=$max"
5385         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5386         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5387                 while ! ulimit -n $((numfree + spare)); do
5388                         numfree=$((numfree * 3 / 4))
5389                 done
5390                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5391         else
5392                 echo "left ulimit at $ulimit_old"
5393         fi
5394
5395         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5396                 unlinkmany $DIR/$tdir/f $numfree
5397                 error "create+open $numfree files in $DIR/$tdir failed"
5398         }
5399         ulimit -n $ulimit_old
5400
5401         # if createmany exits at 120s there will be fewer than $numfree files
5402         unlinkmany $DIR/$tdir/f $numfree || true
5403 }
5404 run_test 51f "check many open files limit"
5405
5406 test_52a() {
5407         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5408         test_mkdir $DIR/$tdir
5409         touch $DIR/$tdir/foo
5410         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5411         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5412         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5413         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5414         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5415                                         error "link worked"
5416         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5417         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5418         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5419                                                      error "lsattr"
5420         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5421         cp -r $DIR/$tdir $TMP/
5422         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5423 }
5424 run_test 52a "append-only flag test (should return errors)"
5425
5426 test_52b() {
5427         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5428         test_mkdir $DIR/$tdir
5429         touch $DIR/$tdir/foo
5430         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5431         cat test > $DIR/$tdir/foo && error "cat test worked"
5432         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5433         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5434         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5435                                         error "link worked"
5436         echo foo >> $DIR/$tdir/foo && error "echo worked"
5437         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5438         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5439         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5440         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5441                                                         error "lsattr"
5442         chattr -i $DIR/$tdir/foo || error "chattr failed"
5443
5444         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5445 }
5446 run_test 52b "immutable flag test (should return errors) ======="
5447
5448 test_53() {
5449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5450         remote_mds_nodsh && skip "remote MDS with nodsh"
5451         remote_ost_nodsh && skip "remote OST with nodsh"
5452
5453         local param
5454         local param_seq
5455         local ostname
5456         local mds_last
5457         local mds_last_seq
5458         local ost_last
5459         local ost_last_seq
5460         local ost_last_id
5461         local ostnum
5462         local node
5463         local found=false
5464         local support_last_seq=true
5465
5466         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5467                 support_last_seq=false
5468
5469         # only test MDT0000
5470         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5471         local value
5472         for value in $(do_facet $SINGLEMDS \
5473                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5474                 param=$(echo ${value[0]} | cut -d "=" -f1)
5475                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5476
5477                 if $support_last_seq; then
5478                         param_seq=$(echo $param |
5479                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5480                         mds_last_seq=$(do_facet $SINGLEMDS \
5481                                        $LCTL get_param -n $param_seq)
5482                 fi
5483                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5484
5485                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5486                 node=$(facet_active_host ost$((ostnum+1)))
5487                 param="obdfilter.$ostname.last_id"
5488                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5489                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5490                         ost_last_id=$ost_last
5491
5492                         if $support_last_seq; then
5493                                 ost_last_id=$(echo $ost_last |
5494                                               awk -F':' '{print $2}' |
5495                                               sed -e "s/^0x//g")
5496                                 ost_last_seq=$(echo $ost_last |
5497                                                awk -F':' '{print $1}')
5498                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5499                         fi
5500
5501                         if [[ $ost_last_id != $mds_last ]]; then
5502                                 error "$ost_last_id != $mds_last"
5503                         else
5504                                 found=true
5505                                 break
5506                         fi
5507                 done
5508         done
5509         $found || error "can not match last_seq/last_id for $mdtosc"
5510         return 0
5511 }
5512 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5513
5514 test_54a() {
5515         perl -MSocket -e ';' || skip "no Socket perl module installed"
5516
5517         $SOCKETSERVER $DIR/socket ||
5518                 error "$SOCKETSERVER $DIR/socket failed: $?"
5519         $SOCKETCLIENT $DIR/socket ||
5520                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5521         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5522 }
5523 run_test 54a "unix domain socket test =========================="
5524
5525 test_54b() {
5526         f="$DIR/f54b"
5527         mknod $f c 1 3
5528         chmod 0666 $f
5529         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5530 }
5531 run_test 54b "char device works in lustre ======================"
5532
5533 find_loop_dev() {
5534         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5535         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5536         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5537
5538         for i in $(seq 3 7); do
5539                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5540                 LOOPDEV=$LOOPBASE$i
5541                 LOOPNUM=$i
5542                 break
5543         done
5544 }
5545
5546 cleanup_54c() {
5547         local rc=0
5548         loopdev="$DIR/loop54c"
5549
5550         trap 0
5551         $UMOUNT $DIR/$tdir || rc=$?
5552         losetup -d $loopdev || true
5553         losetup -d $LOOPDEV || true
5554         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5555         return $rc
5556 }
5557
5558 test_54c() {
5559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5560
5561         loopdev="$DIR/loop54c"
5562
5563         find_loop_dev
5564         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5565         trap cleanup_54c EXIT
5566         mknod $loopdev b 7 $LOOPNUM
5567         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5568         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5569         losetup $loopdev $DIR/$tfile ||
5570                 error "can't set up $loopdev for $DIR/$tfile"
5571         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5572         test_mkdir $DIR/$tdir
5573         mount -t ext2 $loopdev $DIR/$tdir ||
5574                 error "error mounting $loopdev on $DIR/$tdir"
5575         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5576                 error "dd write"
5577         df $DIR/$tdir
5578         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5579                 error "dd read"
5580         cleanup_54c
5581 }
5582 run_test 54c "block device works in lustre ====================="
5583
5584 test_54d() {
5585         f="$DIR/f54d"
5586         string="aaaaaa"
5587         mknod $f p
5588         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5589 }
5590 run_test 54d "fifo device works in lustre ======================"
5591
5592 test_54e() {
5593         f="$DIR/f54e"
5594         string="aaaaaa"
5595         cp -aL /dev/console $f
5596         echo $string > $f || error "echo $string to $f failed"
5597 }
5598 run_test 54e "console/tty device works in lustre ======================"
5599
5600 test_56a() {
5601         local numfiles=3
5602         local dir=$DIR/$tdir
5603
5604         rm -rf $dir
5605         test_mkdir -p $dir/dir
5606         for i in $(seq $numfiles); do
5607                 touch $dir/file$i
5608                 touch $dir/dir/file$i
5609         done
5610
5611         local numcomp=$($LFS getstripe --component-count $dir)
5612
5613         [[ $numcomp == 0 ]] && numcomp=1
5614
5615         # test lfs getstripe with --recursive
5616         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5617
5618         [[ $filenum -eq $((numfiles * 2)) ]] ||
5619                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5620         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5621         [[ $filenum -eq $numfiles ]] ||
5622                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5623         echo "$LFS getstripe showed obdidx or l_ost_idx"
5624
5625         # test lfs getstripe with file instead of dir
5626         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5627         [[ $filenum -eq 1 ]] ||
5628                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5629         echo "$LFS getstripe file1 passed"
5630
5631         #test lfs getstripe with --verbose
5632         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5633         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5634                 error "$LFS getstripe --verbose $dir: "\
5635                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5636         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5637                 error "$LFS getstripe $dir: showed lmm_magic"
5638
5639         #test lfs getstripe with -v prints lmm_fid
5640         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5641         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5642                 error "$LFS getstripe -v $dir: "\
5643                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5644         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5645                 error "$LFS getstripe $dir: showed lmm_fid by default"
5646         echo "$LFS getstripe --verbose passed"
5647
5648         #check for FID information
5649         local fid1=$($LFS getstripe --fid $dir/file1)
5650         local fid2=$($LFS getstripe --verbose $dir/file1 |
5651                      awk '/lmm_fid: / { print $2; exit; }')
5652         local fid3=$($LFS path2fid $dir/file1)
5653
5654         [ "$fid1" != "$fid2" ] &&
5655                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5656         [ "$fid1" != "$fid3" ] &&
5657                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5658         echo "$LFS getstripe --fid passed"
5659
5660         #test lfs getstripe with --obd
5661         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5662                 error "$LFS getstripe --obd wrong_uuid: should return error"
5663
5664         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5665
5666         local ostidx=1
5667         local obduuid=$(ostuuid_from_index $ostidx)
5668         local found=$($LFS getstripe -r --obd $obduuid $dir |
5669                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5670
5671         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5672         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5673                 ((filenum--))
5674         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5675                 ((filenum--))
5676
5677         [[ $found -eq $filenum ]] ||
5678                 error "$LFS getstripe --obd: found $found expect $filenum"
5679         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5680                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5681                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5682                 error "$LFS getstripe --obd: should not show file on other obd"
5683         echo "$LFS getstripe --obd passed"
5684 }
5685 run_test 56a "check $LFS getstripe"
5686
5687 test_56b() {
5688         local dir=$DIR/$tdir
5689         local numdirs=3
5690
5691         test_mkdir $dir
5692         for i in $(seq $numdirs); do
5693                 test_mkdir $dir/dir$i
5694         done
5695
5696         # test lfs getdirstripe default mode is non-recursion, which is
5697         # different from lfs getstripe
5698         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5699
5700         [[ $dircnt -eq 1 ]] ||
5701                 error "$LFS getdirstripe: found $dircnt, not 1"
5702         dircnt=$($LFS getdirstripe --recursive $dir |
5703                 grep -c lmv_stripe_count)
5704         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5705                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5706 }
5707 run_test 56b "check $LFS getdirstripe"
5708
5709 test_56c() {
5710         remote_ost_nodsh && skip "remote OST with nodsh"
5711
5712         local ost_idx=0
5713         local ost_name=$(ostname_from_index $ost_idx)
5714         local old_status=$(ost_dev_status $ost_idx)
5715         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5716
5717         [[ -z "$old_status" ]] ||
5718                 skip_env "OST $ost_name is in $old_status status"
5719
5720         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5721         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5722                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5723         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5724                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5725                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5726         fi
5727
5728         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5729                 error "$LFS df -v showing inactive devices"
5730         sleep_maxage
5731
5732         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5733
5734         [[ "$new_status" =~ "D" ]] ||
5735                 error "$ost_name status is '$new_status', missing 'D'"
5736         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5737                 [[ "$new_status" =~ "N" ]] ||
5738                         error "$ost_name status is '$new_status', missing 'N'"
5739         fi
5740         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5741                 [[ "$new_status" =~ "f" ]] ||
5742                         error "$ost_name status is '$new_status', missing 'f'"
5743         fi
5744
5745         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5746         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5747                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5748         [[ -z "$p" ]] && restore_lustre_params < $p || true
5749         sleep_maxage
5750
5751         new_status=$(ost_dev_status $ost_idx)
5752         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5753                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5754         # can't check 'f' as devices may actually be on flash
5755 }
5756 run_test 56c "check 'lfs df' showing device status"
5757
5758 test_56d() {
5759         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5760         local osts=$($LFS df -v $MOUNT | grep -c OST)
5761
5762         $LFS df $MOUNT
5763
5764         (( mdts == MDSCOUNT )) ||
5765                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5766         (( osts == OSTCOUNT )) ||
5767                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5768 }
5769 run_test 56d "'lfs df -v' prints only configured devices"
5770
5771 NUMFILES=3
5772 NUMDIRS=3
5773 setup_56() {
5774         local local_tdir="$1"
5775         local local_numfiles="$2"
5776         local local_numdirs="$3"
5777         local dir_params="$4"
5778         local dir_stripe_params="$5"
5779
5780         if [ ! -d "$local_tdir" ] ; then
5781                 test_mkdir -p $dir_stripe_params $local_tdir
5782                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5783                 for i in $(seq $local_numfiles) ; do
5784                         touch $local_tdir/file$i
5785                 done
5786                 for i in $(seq $local_numdirs) ; do
5787                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5788                         for j in $(seq $local_numfiles) ; do
5789                                 touch $local_tdir/dir$i/file$j
5790                         done
5791                 done
5792         fi
5793 }
5794
5795 setup_56_special() {
5796         local local_tdir=$1
5797         local local_numfiles=$2
5798         local local_numdirs=$3
5799
5800         setup_56 $local_tdir $local_numfiles $local_numdirs
5801
5802         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5803                 for i in $(seq $local_numfiles) ; do
5804                         mknod $local_tdir/loop${i}b b 7 $i
5805                         mknod $local_tdir/null${i}c c 1 3
5806                         ln -s $local_tdir/file1 $local_tdir/link${i}
5807                 done
5808                 for i in $(seq $local_numdirs) ; do
5809                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5810                         mknod $local_tdir/dir$i/null${i}c c 1 3
5811                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5812                 done
5813         fi
5814 }
5815
5816 test_56g() {
5817         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5818         local expected=$(($NUMDIRS + 2))
5819
5820         setup_56 $dir $NUMFILES $NUMDIRS
5821
5822         # test lfs find with -name
5823         for i in $(seq $NUMFILES) ; do
5824                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5825
5826                 [ $nums -eq $expected ] ||
5827                         error "lfs find -name '*$i' $dir wrong: "\
5828                               "found $nums, expected $expected"
5829         done
5830 }
5831 run_test 56g "check lfs find -name"
5832
5833 test_56h() {
5834         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5835         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5836
5837         setup_56 $dir $NUMFILES $NUMDIRS
5838
5839         # test lfs find with ! -name
5840         for i in $(seq $NUMFILES) ; do
5841                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5842
5843                 [ $nums -eq $expected ] ||
5844                         error "lfs find ! -name '*$i' $dir wrong: "\
5845                               "found $nums, expected $expected"
5846         done
5847 }
5848 run_test 56h "check lfs find ! -name"
5849
5850 test_56i() {
5851         local dir=$DIR/$tdir
5852
5853         test_mkdir $dir
5854
5855         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5856         local out=$($cmd)
5857
5858         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5859 }
5860 run_test 56i "check 'lfs find -ost UUID' skips directories"
5861
5862 test_56j() {
5863         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5864
5865         setup_56_special $dir $NUMFILES $NUMDIRS
5866
5867         local expected=$((NUMDIRS + 1))
5868         local cmd="$LFS find -type d $dir"
5869         local nums=$($cmd | wc -l)
5870
5871         [ $nums -eq $expected ] ||
5872                 error "'$cmd' wrong: found $nums, expected $expected"
5873 }
5874 run_test 56j "check lfs find -type d"
5875
5876 test_56k() {
5877         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5878
5879         setup_56_special $dir $NUMFILES $NUMDIRS
5880
5881         local expected=$(((NUMDIRS + 1) * NUMFILES))
5882         local cmd="$LFS find -type f $dir"
5883         local nums=$($cmd | wc -l)
5884
5885         [ $nums -eq $expected ] ||
5886                 error "'$cmd' wrong: found $nums, expected $expected"
5887 }
5888 run_test 56k "check lfs find -type f"
5889
5890 test_56l() {
5891         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5892
5893         setup_56_special $dir $NUMFILES $NUMDIRS
5894
5895         local expected=$((NUMDIRS + NUMFILES))
5896         local cmd="$LFS find -type b $dir"
5897         local nums=$($cmd | wc -l)
5898
5899         [ $nums -eq $expected ] ||
5900                 error "'$cmd' wrong: found $nums, expected $expected"
5901 }
5902 run_test 56l "check lfs find -type b"
5903
5904 test_56m() {
5905         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5906
5907         setup_56_special $dir $NUMFILES $NUMDIRS
5908
5909         local expected=$((NUMDIRS + NUMFILES))
5910         local cmd="$LFS find -type c $dir"
5911         local nums=$($cmd | wc -l)
5912         [ $nums -eq $expected ] ||
5913                 error "'$cmd' wrong: found $nums, expected $expected"
5914 }
5915 run_test 56m "check lfs find -type c"
5916
5917 test_56n() {
5918         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5919         setup_56_special $dir $NUMFILES $NUMDIRS
5920
5921         local expected=$((NUMDIRS + NUMFILES))
5922         local cmd="$LFS find -type l $dir"
5923         local nums=$($cmd | wc -l)
5924
5925         [ $nums -eq $expected ] ||
5926                 error "'$cmd' wrong: found $nums, expected $expected"
5927 }
5928 run_test 56n "check lfs find -type l"
5929
5930 test_56o() {
5931         local dir=$DIR/$tdir
5932
5933         setup_56 $dir $NUMFILES $NUMDIRS
5934         utime $dir/file1 > /dev/null || error "utime (1)"
5935         utime $dir/file2 > /dev/null || error "utime (2)"
5936         utime $dir/dir1 > /dev/null || error "utime (3)"
5937         utime $dir/dir2 > /dev/null || error "utime (4)"
5938         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5939         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5940
5941         local expected=4
5942         local nums=$($LFS find -mtime +0 $dir | wc -l)
5943
5944         [ $nums -eq $expected ] ||
5945                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5946
5947         expected=12
5948         cmd="$LFS find -mtime 0 $dir"
5949         nums=$($cmd | wc -l)
5950         [ $nums -eq $expected ] ||
5951                 error "'$cmd' wrong: found $nums, expected $expected"
5952 }
5953 run_test 56o "check lfs find -mtime for old files"
5954
5955 test_56ob() {
5956         local dir=$DIR/$tdir
5957         local expected=1
5958         local count=0
5959
5960         # just to make sure there is something that won't be found
5961         test_mkdir $dir
5962         touch $dir/$tfile.now
5963
5964         for age in year week day hour min; do
5965                 count=$((count + 1))
5966
5967                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5968                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5969                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5970
5971                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5972                 local nums=$($cmd | wc -l)
5973                 [ $nums -eq $expected ] ||
5974                         error "'$cmd' wrong: found $nums, expected $expected"
5975
5976                 cmd="$LFS find $dir -atime $count${age:0:1}"
5977                 nums=$($cmd | wc -l)
5978                 [ $nums -eq $expected ] ||
5979                         error "'$cmd' wrong: found $nums, expected $expected"
5980         done
5981
5982         sleep 2
5983         cmd="$LFS find $dir -ctime +1s -type f"
5984         nums=$($cmd | wc -l)
5985         (( $nums == $count * 2 + 1)) ||
5986                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5987 }
5988 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5989
5990 test_newerXY_base() {
5991         local x=$1
5992         local y=$2
5993         local dir=$DIR/$tdir
5994         local ref
5995         local negref
5996
5997         if [ $y == "t" ]; then
5998                 if [ $x == "b" ]; then
5999                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6000                 else
6001                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6002                 fi
6003         else
6004                 ref=$DIR/$tfile.newer.$x$y
6005                 touch $ref || error "touch $ref failed"
6006         fi
6007
6008         echo "before = $ref"
6009         sleep 2
6010         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6011         sleep 2
6012         if [ $y == "t" ]; then
6013                 if [ $x == "b" ]; then
6014                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6015                 else
6016                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6017                 fi
6018         else
6019                 negref=$DIR/$tfile.negnewer.$x$y
6020                 touch $negref || error "touch $negref failed"
6021         fi
6022
6023         echo "after = $negref"
6024         local cmd="$LFS find $dir -newer$x$y $ref"
6025         local nums=$(eval $cmd | wc -l)
6026         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6027
6028         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6029                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6030
6031         cmd="$LFS find $dir ! -newer$x$y $negref"
6032         nums=$(eval $cmd | wc -l)
6033         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6034                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6035
6036         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6037         nums=$(eval $cmd | wc -l)
6038         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6039                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6040
6041         rm -rf $DIR/*
6042 }
6043
6044 test_56oc() {
6045         test_newerXY_base "a" "a"
6046         test_newerXY_base "a" "m"
6047         test_newerXY_base "a" "c"
6048         test_newerXY_base "m" "a"
6049         test_newerXY_base "m" "m"
6050         test_newerXY_base "m" "c"
6051         test_newerXY_base "c" "a"
6052         test_newerXY_base "c" "m"
6053         test_newerXY_base "c" "c"
6054
6055         [[ -n "$sles_version" ]] &&
6056                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6057
6058         test_newerXY_base "a" "t"
6059         test_newerXY_base "m" "t"
6060         test_newerXY_base "c" "t"
6061
6062         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6063            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6064                 ! btime_supported && echo "btime unsupported" && return 0
6065
6066         test_newerXY_base "b" "b"
6067         test_newerXY_base "b" "t"
6068 }
6069 run_test 56oc "check lfs find -newerXY work"
6070
6071 btime_supported() {
6072         local dir=$DIR/$tdir
6073         local rc
6074
6075         mkdir -p $dir
6076         touch $dir/$tfile
6077         $LFS find $dir -btime -1d -type f
6078         rc=$?
6079         rm -rf $dir
6080         return $rc
6081 }
6082
6083 test_56od() {
6084         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6085                 ! btime_supported && skip "btime unsupported on MDS"
6086
6087         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6088                 ! btime_supported && skip "btime unsupported on clients"
6089
6090         local dir=$DIR/$tdir
6091         local ref=$DIR/$tfile.ref
6092         local negref=$DIR/$tfile.negref
6093
6094         mkdir $dir || error "mkdir $dir failed"
6095         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6096         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6097         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6098         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6099         touch $ref || error "touch $ref failed"
6100         # sleep 3 seconds at least
6101         sleep 3
6102
6103         local before=$(do_facet mds1 date +%s)
6104         local skew=$(($(date +%s) - before + 1))
6105
6106         if (( skew < 0 && skew > -5 )); then
6107                 sleep $((0 - skew + 1))
6108                 skew=0
6109         fi
6110
6111         # Set the dir stripe params to limit files all on MDT0,
6112         # otherwise we need to calc the max clock skew between
6113         # the client and MDTs.
6114         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6115         sleep 2
6116         touch $negref || error "touch $negref failed"
6117
6118         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6119         local nums=$($cmd | wc -l)
6120         local expected=$(((NUMFILES + 1) * NUMDIRS))
6121
6122         [ $nums -eq $expected ] ||
6123                 error "'$cmd' wrong: found $nums, expected $expected"
6124
6125         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6126         nums=$($cmd | wc -l)
6127         expected=$((NUMFILES + 1))
6128         [ $nums -eq $expected ] ||
6129                 error "'$cmd' wrong: found $nums, expected $expected"
6130
6131         [ $skew -lt 0 ] && return
6132
6133         local after=$(do_facet mds1 date +%s)
6134         local age=$((after - before + 1 + skew))
6135
6136         cmd="$LFS find $dir -btime -${age}s -type f"
6137         nums=$($cmd | wc -l)
6138         expected=$(((NUMFILES + 1) * NUMDIRS))
6139
6140         echo "Clock skew between client and server: $skew, age:$age"
6141         [ $nums -eq $expected ] ||
6142                 error "'$cmd' wrong: found $nums, expected $expected"
6143
6144         expected=$(($NUMDIRS + 1))
6145         cmd="$LFS find $dir -btime -${age}s -type d"
6146         nums=$($cmd | wc -l)
6147         [ $nums -eq $expected ] ||
6148                 error "'$cmd' wrong: found $nums, expected $expected"
6149         rm -f $ref $negref || error "Failed to remove $ref $negref"
6150 }
6151 run_test 56od "check lfs find -btime with units"
6152
6153 test_56p() {
6154         [ $RUNAS_ID -eq $UID ] &&
6155                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6156
6157         local dir=$DIR/$tdir
6158
6159         setup_56 $dir $NUMFILES $NUMDIRS
6160         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6161
6162         local expected=$NUMFILES
6163         local cmd="$LFS find -uid $RUNAS_ID $dir"
6164         local nums=$($cmd | wc -l)
6165
6166         [ $nums -eq $expected ] ||
6167                 error "'$cmd' wrong: found $nums, expected $expected"
6168
6169         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6170         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6171         nums=$($cmd | wc -l)
6172         [ $nums -eq $expected ] ||
6173                 error "'$cmd' wrong: found $nums, expected $expected"
6174 }
6175 run_test 56p "check lfs find -uid and ! -uid"
6176
6177 test_56q() {
6178         [ $RUNAS_ID -eq $UID ] &&
6179                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6180
6181         local dir=$DIR/$tdir
6182
6183         setup_56 $dir $NUMFILES $NUMDIRS
6184         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6185
6186         local expected=$NUMFILES
6187         local cmd="$LFS find -gid $RUNAS_GID $dir"
6188         local nums=$($cmd | wc -l)
6189
6190         [ $nums -eq $expected ] ||
6191                 error "'$cmd' wrong: found $nums, expected $expected"
6192
6193         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6194         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6195         nums=$($cmd | wc -l)
6196         [ $nums -eq $expected ] ||
6197                 error "'$cmd' wrong: found $nums, expected $expected"
6198 }
6199 run_test 56q "check lfs find -gid and ! -gid"
6200
6201 test_56r() {
6202         local dir=$DIR/$tdir
6203
6204         setup_56 $dir $NUMFILES $NUMDIRS
6205
6206         local expected=12
6207         local cmd="$LFS find -size 0 -type f -lazy $dir"
6208         local nums=$($cmd | wc -l)
6209
6210         [ $nums -eq $expected ] ||
6211                 error "'$cmd' wrong: found $nums, expected $expected"
6212         cmd="$LFS find -size 0 -type f $dir"
6213         nums=$($cmd | wc -l)
6214         [ $nums -eq $expected ] ||
6215                 error "'$cmd' wrong: found $nums, expected $expected"
6216
6217         expected=0
6218         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6219         nums=$($cmd | wc -l)
6220         [ $nums -eq $expected ] ||
6221                 error "'$cmd' wrong: found $nums, expected $expected"
6222         cmd="$LFS find ! -size 0 -type f $dir"
6223         nums=$($cmd | wc -l)
6224         [ $nums -eq $expected ] ||
6225                 error "'$cmd' wrong: found $nums, expected $expected"
6226
6227         echo "test" > $dir/$tfile
6228         echo "test2" > $dir/$tfile.2 && sync
6229         expected=1
6230         cmd="$LFS find -size 5 -type f -lazy $dir"
6231         nums=$($cmd | wc -l)
6232         [ $nums -eq $expected ] ||
6233                 error "'$cmd' wrong: found $nums, expected $expected"
6234         cmd="$LFS find -size 5 -type f $dir"
6235         nums=$($cmd | wc -l)
6236         [ $nums -eq $expected ] ||
6237                 error "'$cmd' wrong: found $nums, expected $expected"
6238
6239         expected=1
6240         cmd="$LFS find -size +5 -type f -lazy $dir"
6241         nums=$($cmd | wc -l)
6242         [ $nums -eq $expected ] ||
6243                 error "'$cmd' wrong: found $nums, expected $expected"
6244         cmd="$LFS find -size +5 -type f $dir"
6245         nums=$($cmd | wc -l)
6246         [ $nums -eq $expected ] ||
6247                 error "'$cmd' wrong: found $nums, expected $expected"
6248
6249         expected=2
6250         cmd="$LFS find -size +0 -type f -lazy $dir"
6251         nums=$($cmd | wc -l)
6252         [ $nums -eq $expected ] ||
6253                 error "'$cmd' wrong: found $nums, expected $expected"
6254         cmd="$LFS find -size +0 -type f $dir"
6255         nums=$($cmd | wc -l)
6256         [ $nums -eq $expected ] ||
6257                 error "'$cmd' wrong: found $nums, expected $expected"
6258
6259         expected=2
6260         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6261         nums=$($cmd | wc -l)
6262         [ $nums -eq $expected ] ||
6263                 error "'$cmd' wrong: found $nums, expected $expected"
6264         cmd="$LFS find ! -size -5 -type f $dir"
6265         nums=$($cmd | wc -l)
6266         [ $nums -eq $expected ] ||
6267                 error "'$cmd' wrong: found $nums, expected $expected"
6268
6269         expected=12
6270         cmd="$LFS find -size -5 -type f -lazy $dir"
6271         nums=$($cmd | wc -l)
6272         [ $nums -eq $expected ] ||
6273                 error "'$cmd' wrong: found $nums, expected $expected"
6274         cmd="$LFS find -size -5 -type f $dir"
6275         nums=$($cmd | wc -l)
6276         [ $nums -eq $expected ] ||
6277                 error "'$cmd' wrong: found $nums, expected $expected"
6278 }
6279 run_test 56r "check lfs find -size works"
6280
6281 test_56ra_sub() {
6282         local expected=$1
6283         local glimpses=$2
6284         local cmd="$3"
6285
6286         cancel_lru_locks $OSC
6287
6288         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6289         local nums=$($cmd | wc -l)
6290
6291         [ $nums -eq $expected ] ||
6292                 error "'$cmd' wrong: found $nums, expected $expected"
6293
6294         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6295
6296         if (( rpcs_before + glimpses != rpcs_after )); then
6297                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6298                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6299
6300                 if [[ $glimpses == 0 ]]; then
6301                         error "'$cmd' should not send glimpse RPCs to OST"
6302                 else
6303                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6304                 fi
6305         fi
6306 }
6307
6308 test_56ra() {
6309         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6310                 skip "MDS < 2.12.58 doesn't return LSOM data"
6311         local dir=$DIR/$tdir
6312         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6313
6314         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6315
6316         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6317         $LCTL set_param -n llite.*.statahead_agl=0
6318         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6319
6320         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6321         # open and close all files to ensure LSOM is updated
6322         cancel_lru_locks $OSC
6323         find $dir -type f | xargs cat > /dev/null
6324
6325         #   expect_found  glimpse_rpcs  command_to_run
6326         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6327         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6328         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6329         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6330
6331         echo "test" > $dir/$tfile
6332         echo "test2" > $dir/$tfile.2 && sync
6333         cancel_lru_locks $OSC
6334         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6335
6336         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6337         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6338         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6339         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6340
6341         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6342         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6343         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6344         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6345         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6346         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6347 }
6348 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6349
6350 test_56rb() {
6351         local dir=$DIR/$tdir
6352         local tmp=$TMP/$tfile.log
6353         local mdt_idx;
6354
6355         test_mkdir -p $dir || error "failed to mkdir $dir"
6356         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6357                 error "failed to setstripe $dir/$tfile"
6358         mdt_idx=$($LFS getdirstripe -i $dir)
6359         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6360
6361         stack_trap "rm -f $tmp" EXIT
6362         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6363         ! grep -q obd_uuid $tmp ||
6364                 error "failed to find --size +100K --ost 0 $dir"
6365         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6366         ! grep -q obd_uuid $tmp ||
6367                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6368 }
6369 run_test 56rb "check lfs find --size --ost/--mdt works"
6370
6371 test_56s() { # LU-611 #LU-9369
6372         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6373
6374         local dir=$DIR/$tdir
6375         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6376
6377         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6378         for i in $(seq $NUMDIRS); do
6379                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6380         done
6381
6382         local expected=$NUMDIRS
6383         local cmd="$LFS find -c $OSTCOUNT $dir"
6384         local nums=$($cmd | wc -l)
6385
6386         [ $nums -eq $expected ] || {
6387                 $LFS getstripe -R $dir
6388                 error "'$cmd' wrong: found $nums, expected $expected"
6389         }
6390
6391         expected=$((NUMDIRS + onestripe))
6392         cmd="$LFS find -stripe-count +0 -type f $dir"
6393         nums=$($cmd | wc -l)
6394         [ $nums -eq $expected ] || {
6395                 $LFS getstripe -R $dir
6396                 error "'$cmd' wrong: found $nums, expected $expected"
6397         }
6398
6399         expected=$onestripe
6400         cmd="$LFS find -stripe-count 1 -type f $dir"
6401         nums=$($cmd | wc -l)
6402         [ $nums -eq $expected ] || {
6403                 $LFS getstripe -R $dir
6404                 error "'$cmd' wrong: found $nums, expected $expected"
6405         }
6406
6407         cmd="$LFS find -stripe-count -2 -type f $dir"
6408         nums=$($cmd | wc -l)
6409         [ $nums -eq $expected ] || {
6410                 $LFS getstripe -R $dir
6411                 error "'$cmd' wrong: found $nums, expected $expected"
6412         }
6413
6414         expected=0
6415         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6416         nums=$($cmd | wc -l)
6417         [ $nums -eq $expected ] || {
6418                 $LFS getstripe -R $dir
6419                 error "'$cmd' wrong: found $nums, expected $expected"
6420         }
6421 }
6422 run_test 56s "check lfs find -stripe-count works"
6423
6424 test_56t() { # LU-611 #LU-9369
6425         local dir=$DIR/$tdir
6426
6427         setup_56 $dir 0 $NUMDIRS
6428         for i in $(seq $NUMDIRS); do
6429                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6430         done
6431
6432         local expected=$NUMDIRS
6433         local cmd="$LFS find -S 8M $dir"
6434         local nums=$($cmd | wc -l)
6435
6436         [ $nums -eq $expected ] || {
6437                 $LFS getstripe -R $dir
6438                 error "'$cmd' wrong: found $nums, expected $expected"
6439         }
6440         rm -rf $dir
6441
6442         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6443
6444         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6445
6446         expected=$(((NUMDIRS + 1) * NUMFILES))
6447         cmd="$LFS find -stripe-size 512k -type f $dir"
6448         nums=$($cmd | wc -l)
6449         [ $nums -eq $expected ] ||
6450                 error "'$cmd' wrong: found $nums, expected $expected"
6451
6452         cmd="$LFS find -stripe-size +320k -type f $dir"
6453         nums=$($cmd | wc -l)
6454         [ $nums -eq $expected ] ||
6455                 error "'$cmd' wrong: found $nums, expected $expected"
6456
6457         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6458         cmd="$LFS find -stripe-size +200k -type f $dir"
6459         nums=$($cmd | wc -l)
6460         [ $nums -eq $expected ] ||
6461                 error "'$cmd' wrong: found $nums, expected $expected"
6462
6463         cmd="$LFS find -stripe-size -640k -type f $dir"
6464         nums=$($cmd | wc -l)
6465         [ $nums -eq $expected ] ||
6466                 error "'$cmd' wrong: found $nums, expected $expected"
6467
6468         expected=4
6469         cmd="$LFS find -stripe-size 256k -type f $dir"
6470         nums=$($cmd | wc -l)
6471         [ $nums -eq $expected ] ||
6472                 error "'$cmd' wrong: found $nums, expected $expected"
6473
6474         cmd="$LFS find -stripe-size -320k -type f $dir"
6475         nums=$($cmd | wc -l)
6476         [ $nums -eq $expected ] ||
6477                 error "'$cmd' wrong: found $nums, expected $expected"
6478
6479         expected=0
6480         cmd="$LFS find -stripe-size 1024k -type f $dir"
6481         nums=$($cmd | wc -l)
6482         [ $nums -eq $expected ] ||
6483                 error "'$cmd' wrong: found $nums, expected $expected"
6484 }
6485 run_test 56t "check lfs find -stripe-size works"
6486
6487 test_56u() { # LU-611
6488         local dir=$DIR/$tdir
6489
6490         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6491
6492         if [[ $OSTCOUNT -gt 1 ]]; then
6493                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6494                 onestripe=4
6495         else
6496                 onestripe=0
6497         fi
6498
6499         local expected=$(((NUMDIRS + 1) * NUMFILES))
6500         local cmd="$LFS find -stripe-index 0 -type f $dir"
6501         local nums=$($cmd | wc -l)
6502
6503         [ $nums -eq $expected ] ||
6504                 error "'$cmd' wrong: found $nums, expected $expected"
6505
6506         expected=$onestripe
6507         cmd="$LFS find -stripe-index 1 -type f $dir"
6508         nums=$($cmd | wc -l)
6509         [ $nums -eq $expected ] ||
6510                 error "'$cmd' wrong: found $nums, expected $expected"
6511
6512         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6513         nums=$($cmd | wc -l)
6514         [ $nums -eq $expected ] ||
6515                 error "'$cmd' wrong: found $nums, expected $expected"
6516
6517         expected=0
6518         # This should produce an error and not return any files
6519         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6520         nums=$($cmd 2>/dev/null | wc -l)
6521         [ $nums -eq $expected ] ||
6522                 error "'$cmd' wrong: found $nums, expected $expected"
6523
6524         if [[ $OSTCOUNT -gt 1 ]]; then
6525                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6526                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6527                 nums=$($cmd | wc -l)
6528                 [ $nums -eq $expected ] ||
6529                         error "'$cmd' wrong: found $nums, expected $expected"
6530         fi
6531 }
6532 run_test 56u "check lfs find -stripe-index works"
6533
6534 test_56v() {
6535         local mdt_idx=0
6536         local dir=$DIR/$tdir
6537
6538         setup_56 $dir $NUMFILES $NUMDIRS
6539
6540         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6541         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6542
6543         for file in $($LFS find -m $UUID $dir); do
6544                 file_midx=$($LFS getstripe -m $file)
6545                 [ $file_midx -eq $mdt_idx ] ||
6546                         error "lfs find -m $UUID != getstripe -m $file_midx"
6547         done
6548 }
6549 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6550
6551 test_56w() {
6552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6554
6555         local dir=$DIR/$tdir
6556
6557         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6558
6559         local stripe_size=$($LFS getstripe -S -d $dir) ||
6560                 error "$LFS getstripe -S -d $dir failed"
6561         stripe_size=${stripe_size%% *}
6562
6563         local file_size=$((stripe_size * OSTCOUNT))
6564         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6565         local required_space=$((file_num * file_size))
6566         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6567                            head -n1)
6568         [[ $free_space -le $((required_space / 1024)) ]] &&
6569                 skip_env "need $required_space, have $free_space kbytes"
6570
6571         local dd_bs=65536
6572         local dd_count=$((file_size / dd_bs))
6573
6574         # write data into the files
6575         local i
6576         local j
6577         local file
6578
6579         for i in $(seq $NUMFILES); do
6580                 file=$dir/file$i
6581                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6582                         error "write data into $file failed"
6583         done
6584         for i in $(seq $NUMDIRS); do
6585                 for j in $(seq $NUMFILES); do
6586                         file=$dir/dir$i/file$j
6587                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6588                                 error "write data into $file failed"
6589                 done
6590         done
6591
6592         # $LFS_MIGRATE will fail if hard link migration is unsupported
6593         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6594                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6595                         error "creating links to $dir/dir1/file1 failed"
6596         fi
6597
6598         local expected=-1
6599
6600         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6601
6602         # lfs_migrate file
6603         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6604
6605         echo "$cmd"
6606         eval $cmd || error "$cmd failed"
6607
6608         check_stripe_count $dir/file1 $expected
6609
6610         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6611         then
6612                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6613                 # OST 1 if it is on OST 0. This file is small enough to
6614                 # be on only one stripe.
6615                 file=$dir/migr_1_ost
6616                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6617                         error "write data into $file failed"
6618                 local obdidx=$($LFS getstripe -i $file)
6619                 local oldmd5=$(md5sum $file)
6620                 local newobdidx=0
6621
6622                 [[ $obdidx -eq 0 ]] && newobdidx=1
6623                 cmd="$LFS migrate -i $newobdidx $file"
6624                 echo $cmd
6625                 eval $cmd || error "$cmd failed"
6626
6627                 local realobdix=$($LFS getstripe -i $file)
6628                 local newmd5=$(md5sum $file)
6629
6630                 [[ $newobdidx -ne $realobdix ]] &&
6631                         error "new OST is different (was=$obdidx, "\
6632                               "wanted=$newobdidx, got=$realobdix)"
6633                 [[ "$oldmd5" != "$newmd5" ]] &&
6634                         error "md5sum differ: $oldmd5, $newmd5"
6635         fi
6636
6637         # lfs_migrate dir
6638         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6639         echo "$cmd"
6640         eval $cmd || error "$cmd failed"
6641
6642         for j in $(seq $NUMFILES); do
6643                 check_stripe_count $dir/dir1/file$j $expected
6644         done
6645
6646         # lfs_migrate works with lfs find
6647         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6648              $LFS_MIGRATE -y -c $expected"
6649         echo "$cmd"
6650         eval $cmd || error "$cmd failed"
6651
6652         for i in $(seq 2 $NUMFILES); do
6653                 check_stripe_count $dir/file$i $expected
6654         done
6655         for i in $(seq 2 $NUMDIRS); do
6656                 for j in $(seq $NUMFILES); do
6657                 check_stripe_count $dir/dir$i/file$j $expected
6658                 done
6659         done
6660 }
6661 run_test 56w "check lfs_migrate -c stripe_count works"
6662
6663 test_56wb() {
6664         local file1=$DIR/$tdir/file1
6665         local create_pool=false
6666         local initial_pool=$($LFS getstripe -p $DIR)
6667         local pool_list=()
6668         local pool=""
6669
6670         echo -n "Creating test dir..."
6671         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6672         echo "done."
6673
6674         echo -n "Creating test file..."
6675         touch $file1 || error "cannot create file"
6676         echo "done."
6677
6678         echo -n "Detecting existing pools..."
6679         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6680
6681         if [ ${#pool_list[@]} -gt 0 ]; then
6682                 echo "${pool_list[@]}"
6683                 for thispool in "${pool_list[@]}"; do
6684                         if [[ -z "$initial_pool" ||
6685                               "$initial_pool" != "$thispool" ]]; then
6686                                 pool="$thispool"
6687                                 echo "Using existing pool '$pool'"
6688                                 break
6689                         fi
6690                 done
6691         else
6692                 echo "none detected."
6693         fi
6694         if [ -z "$pool" ]; then
6695                 pool=${POOL:-testpool}
6696                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6697                 echo -n "Creating pool '$pool'..."
6698                 create_pool=true
6699                 pool_add $pool &> /dev/null ||
6700                         error "pool_add failed"
6701                 echo "done."
6702
6703                 echo -n "Adding target to pool..."
6704                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6705                         error "pool_add_targets failed"
6706                 echo "done."
6707         fi
6708
6709         echo -n "Setting pool using -p option..."
6710         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6711                 error "migrate failed rc = $?"
6712         echo "done."
6713
6714         echo -n "Verifying test file is in pool after migrating..."
6715         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6716                 error "file was not migrated to pool $pool"
6717         echo "done."
6718
6719         echo -n "Removing test file from pool '$pool'..."
6720         # "lfs migrate $file" won't remove the file from the pool
6721         # until some striping information is changed.
6722         $LFS migrate -c 1 $file1 &> /dev/null ||
6723                 error "cannot remove from pool"
6724         [ "$($LFS getstripe -p $file1)" ] &&
6725                 error "pool still set"
6726         echo "done."
6727
6728         echo -n "Setting pool using --pool option..."
6729         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6730                 error "migrate failed rc = $?"
6731         echo "done."
6732
6733         # Clean up
6734         rm -f $file1
6735         if $create_pool; then
6736                 destroy_test_pools 2> /dev/null ||
6737                         error "destroy test pools failed"
6738         fi
6739 }
6740 run_test 56wb "check lfs_migrate pool support"
6741
6742 test_56wc() {
6743         local file1="$DIR/$tdir/file1"
6744         local parent_ssize
6745         local parent_scount
6746         local cur_ssize
6747         local cur_scount
6748         local orig_ssize
6749
6750         echo -n "Creating test dir..."
6751         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6752         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6753                 error "cannot set stripe by '-S 1M -c 1'"
6754         echo "done"
6755
6756         echo -n "Setting initial stripe for test file..."
6757         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6758                 error "cannot set stripe"
6759         cur_ssize=$($LFS getstripe -S "$file1")
6760         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6761         echo "done."
6762
6763         # File currently set to -S 512K -c 1
6764
6765         # Ensure -c and -S options are rejected when -R is set
6766         echo -n "Verifying incompatible options are detected..."
6767         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6768                 error "incompatible -c and -R options not detected"
6769         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6770                 error "incompatible -S and -R options not detected"
6771         echo "done."
6772
6773         # Ensure unrecognized options are passed through to 'lfs migrate'
6774         echo -n "Verifying -S option is passed through to lfs migrate..."
6775         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6776                 error "migration failed"
6777         cur_ssize=$($LFS getstripe -S "$file1")
6778         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6779         echo "done."
6780
6781         # File currently set to -S 1M -c 1
6782
6783         # Ensure long options are supported
6784         echo -n "Verifying long options supported..."
6785         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6786                 error "long option without argument not supported"
6787         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6788                 error "long option with argument not supported"
6789         cur_ssize=$($LFS getstripe -S "$file1")
6790         [ $cur_ssize -eq 524288 ] ||
6791                 error "migrate --stripe-size $cur_ssize != 524288"
6792         echo "done."
6793
6794         # File currently set to -S 512K -c 1
6795
6796         if [ "$OSTCOUNT" -gt 1 ]; then
6797                 echo -n "Verifying explicit stripe count can be set..."
6798                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6799                         error "migrate failed"
6800                 cur_scount=$($LFS getstripe -c "$file1")
6801                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6802                 echo "done."
6803         fi
6804
6805         # File currently set to -S 512K -c 1 or -S 512K -c 2
6806
6807         # Ensure parent striping is used if -R is set, and no stripe
6808         # count or size is specified
6809         echo -n "Setting stripe for parent directory..."
6810         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6811                 error "cannot set stripe '-S 2M -c 1'"
6812         echo "done."
6813
6814         echo -n "Verifying restripe option uses parent stripe settings..."
6815         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6816         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6817         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6818                 error "migrate failed"
6819         cur_ssize=$($LFS getstripe -S "$file1")
6820         [ $cur_ssize -eq $parent_ssize ] ||
6821                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6822         cur_scount=$($LFS getstripe -c "$file1")
6823         [ $cur_scount -eq $parent_scount ] ||
6824                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6825         echo "done."
6826
6827         # File currently set to -S 1M -c 1
6828
6829         # Ensure striping is preserved if -R is not set, and no stripe
6830         # count or size is specified
6831         echo -n "Verifying striping size preserved when not specified..."
6832         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6833         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6834                 error "cannot set stripe on parent directory"
6835         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6836                 error "migrate failed"
6837         cur_ssize=$($LFS getstripe -S "$file1")
6838         [ $cur_ssize -eq $orig_ssize ] ||
6839                 error "migrate by default $cur_ssize != $orig_ssize"
6840         echo "done."
6841
6842         # Ensure file name properly detected when final option has no argument
6843         echo -n "Verifying file name properly detected..."
6844         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6845                 error "file name interpreted as option argument"
6846         echo "done."
6847
6848         # Clean up
6849         rm -f "$file1"
6850 }
6851 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6852
6853 test_56wd() {
6854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6855
6856         local file1=$DIR/$tdir/file1
6857
6858         echo -n "Creating test dir..."
6859         test_mkdir $DIR/$tdir || error "cannot create dir"
6860         echo "done."
6861
6862         echo -n "Creating test file..."
6863         touch $file1
6864         echo "done."
6865
6866         # Ensure 'lfs migrate' will fail by using a non-existent option,
6867         # and make sure rsync is not called to recover
6868         echo -n "Make sure --no-rsync option works..."
6869         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6870                 grep -q 'refusing to fall back to rsync' ||
6871                 error "rsync was called with --no-rsync set"
6872         echo "done."
6873
6874         # Ensure rsync is called without trying 'lfs migrate' first
6875         echo -n "Make sure --rsync option works..."
6876         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6877                 grep -q 'falling back to rsync' &&
6878                 error "lfs migrate was called with --rsync set"
6879         echo "done."
6880
6881         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6882         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6883                 grep -q 'at the same time' ||
6884                 error "--rsync and --no-rsync accepted concurrently"
6885         echo "done."
6886
6887         # Clean up
6888         rm -f $file1
6889 }
6890 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6891
6892 test_56we() {
6893         local td=$DIR/$tdir
6894         local tf=$td/$tfile
6895
6896         test_mkdir $td || error "cannot create $td"
6897         touch $tf || error "cannot touch $tf"
6898
6899         echo -n "Make sure --non-direct|-D works..."
6900         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6901                 grep -q "lfs migrate --non-direct" ||
6902                 error "--non-direct option cannot work correctly"
6903         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6904                 grep -q "lfs migrate -D" ||
6905                 error "-D option cannot work correctly"
6906         echo "done."
6907 }
6908 run_test 56we "check lfs_migrate --non-direct|-D support"
6909
6910 test_56x() {
6911         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6912         check_swap_layouts_support
6913
6914         local dir=$DIR/$tdir
6915         local ref1=/etc/passwd
6916         local file1=$dir/file1
6917
6918         test_mkdir $dir || error "creating dir $dir"
6919         $LFS setstripe -c 2 $file1
6920         cp $ref1 $file1
6921         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6922         stripe=$($LFS getstripe -c $file1)
6923         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6924         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6925
6926         # clean up
6927         rm -f $file1
6928 }
6929 run_test 56x "lfs migration support"
6930
6931 test_56xa() {
6932         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6933         check_swap_layouts_support
6934
6935         local dir=$DIR/$tdir/$testnum
6936
6937         test_mkdir -p $dir
6938
6939         local ref1=/etc/passwd
6940         local file1=$dir/file1
6941
6942         $LFS setstripe -c 2 $file1
6943         cp $ref1 $file1
6944         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6945
6946         local stripe=$($LFS getstripe -c $file1)
6947
6948         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6949         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6950
6951         # clean up
6952         rm -f $file1
6953 }
6954 run_test 56xa "lfs migration --block support"
6955
6956 check_migrate_links() {
6957         local dir="$1"
6958         local file1="$dir/file1"
6959         local begin="$2"
6960         local count="$3"
6961         local runas="$4"
6962         local total_count=$(($begin + $count - 1))
6963         local symlink_count=10
6964         local uniq_count=10
6965
6966         if [ ! -f "$file1" ]; then
6967                 echo -n "creating initial file..."
6968                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6969                         error "cannot setstripe initial file"
6970                 echo "done"
6971
6972                 echo -n "creating symlinks..."
6973                 for s in $(seq 1 $symlink_count); do
6974                         ln -s "$file1" "$dir/slink$s" ||
6975                                 error "cannot create symlinks"
6976                 done
6977                 echo "done"
6978
6979                 echo -n "creating nonlinked files..."
6980                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6981                         error "cannot create nonlinked files"
6982                 echo "done"
6983         fi
6984
6985         # create hard links
6986         if [ ! -f "$dir/file$total_count" ]; then
6987                 echo -n "creating hard links $begin:$total_count..."
6988                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6989                         /dev/null || error "cannot create hard links"
6990                 echo "done"
6991         fi
6992
6993         echo -n "checking number of hard links listed in xattrs..."
6994         local fid=$($LFS getstripe -F "$file1")
6995         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6996
6997         echo "${#paths[*]}"
6998         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6999                         skip "hard link list has unexpected size, skipping test"
7000         fi
7001         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7002                         error "link names should exceed xattrs size"
7003         fi
7004
7005         echo -n "migrating files..."
7006         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7007         local rc=$?
7008         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7009         echo "done"
7010
7011         # make sure all links have been properly migrated
7012         echo -n "verifying files..."
7013         fid=$($LFS getstripe -F "$file1") ||
7014                 error "cannot get fid for file $file1"
7015         for i in $(seq 2 $total_count); do
7016                 local fid2=$($LFS getstripe -F $dir/file$i)
7017
7018                 [ "$fid2" == "$fid" ] ||
7019                         error "migrated hard link has mismatched FID"
7020         done
7021
7022         # make sure hard links were properly detected, and migration was
7023         # performed only once for the entire link set; nonlinked files should
7024         # also be migrated
7025         local actual=$(grep -c 'done' <<< "$migrate_out")
7026         local expected=$(($uniq_count + 1))
7027
7028         [ "$actual" -eq  "$expected" ] ||
7029                 error "hard links individually migrated ($actual != $expected)"
7030
7031         # make sure the correct number of hard links are present
7032         local hardlinks=$(stat -c '%h' "$file1")
7033
7034         [ $hardlinks -eq $total_count ] ||
7035                 error "num hard links $hardlinks != $total_count"
7036         echo "done"
7037
7038         return 0
7039 }
7040
7041 test_56xb() {
7042         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7043                 skip "Need MDS version at least 2.10.55"
7044
7045         local dir="$DIR/$tdir"
7046
7047         test_mkdir "$dir" || error "cannot create dir $dir"
7048
7049         echo "testing lfs migrate mode when all links fit within xattrs"
7050         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7051
7052         echo "testing rsync mode when all links fit within xattrs"
7053         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7054
7055         echo "testing lfs migrate mode when all links do not fit within xattrs"
7056         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7057
7058         echo "testing rsync mode when all links do not fit within xattrs"
7059         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7060
7061         chown -R $RUNAS_ID $dir
7062         echo "testing non-root lfs migrate mode when not all links are in xattr"
7063         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7064
7065         # clean up
7066         rm -rf $dir
7067 }
7068 run_test 56xb "lfs migration hard link support"
7069
7070 test_56xc() {
7071         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7072
7073         local dir="$DIR/$tdir"
7074
7075         test_mkdir "$dir" || error "cannot create dir $dir"
7076
7077         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7078         echo -n "Setting initial stripe for 20MB test file..."
7079         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7080                 error "cannot setstripe 20MB file"
7081         echo "done"
7082         echo -n "Sizing 20MB test file..."
7083         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7084         echo "done"
7085         echo -n "Verifying small file autostripe count is 1..."
7086         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7087                 error "cannot migrate 20MB file"
7088         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7089                 error "cannot get stripe for $dir/20mb"
7090         [ $stripe_count -eq 1 ] ||
7091                 error "unexpected stripe count $stripe_count for 20MB file"
7092         rm -f "$dir/20mb"
7093         echo "done"
7094
7095         # Test 2: File is small enough to fit within the available space on
7096         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7097         # have at least an additional 1KB for each desired stripe for test 3
7098         echo -n "Setting stripe for 1GB test file..."
7099         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7100         echo "done"
7101         echo -n "Sizing 1GB test file..."
7102         # File size is 1GB + 3KB
7103         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7104         echo "done"
7105
7106         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7107         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7108         if (( avail > 524288 * OSTCOUNT )); then
7109                 echo -n "Migrating 1GB file..."
7110                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7111                         error "cannot migrate 1GB file"
7112                 echo "done"
7113                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7114                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7115                         error "cannot getstripe for 1GB file"
7116                 [ $stripe_count -eq 2 ] ||
7117                         error "unexpected stripe count $stripe_count != 2"
7118                 echo "done"
7119         fi
7120
7121         # Test 3: File is too large to fit within the available space on
7122         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7123         if [ $OSTCOUNT -ge 3 ]; then
7124                 # The required available space is calculated as
7125                 # file size (1GB + 3KB) / OST count (3).
7126                 local kb_per_ost=349526
7127
7128                 echo -n "Migrating 1GB file with limit..."
7129                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7130                         error "cannot migrate 1GB file with limit"
7131                 echo "done"
7132
7133                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7134                 echo -n "Verifying 1GB autostripe count with limited space..."
7135                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7136                         error "unexpected stripe count $stripe_count (min 3)"
7137                 echo "done"
7138         fi
7139
7140         # clean up
7141         rm -rf $dir
7142 }
7143 run_test 56xc "lfs migration autostripe"
7144
7145 test_56xd() {
7146         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7147
7148         local dir=$DIR/$tdir
7149         local f_mgrt=$dir/$tfile.mgrt
7150         local f_yaml=$dir/$tfile.yaml
7151         local f_copy=$dir/$tfile.copy
7152         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7153         local layout_copy="-c 2 -S 2M -i 1"
7154         local yamlfile=$dir/yamlfile
7155         local layout_before;
7156         local layout_after;
7157
7158         test_mkdir "$dir" || error "cannot create dir $dir"
7159         $LFS setstripe $layout_yaml $f_yaml ||
7160                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7161         $LFS getstripe --yaml $f_yaml > $yamlfile
7162         $LFS setstripe $layout_copy $f_copy ||
7163                 error "cannot setstripe $f_copy with layout $layout_copy"
7164         touch $f_mgrt
7165         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7166
7167         # 1. test option --yaml
7168         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7169                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7170         layout_before=$(get_layout_param $f_yaml)
7171         layout_after=$(get_layout_param $f_mgrt)
7172         [ "$layout_after" == "$layout_before" ] ||
7173                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7174
7175         # 2. test option --copy
7176         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7177                 error "cannot migrate $f_mgrt with --copy $f_copy"
7178         layout_before=$(get_layout_param $f_copy)
7179         layout_after=$(get_layout_param $f_mgrt)
7180         [ "$layout_after" == "$layout_before" ] ||
7181                 error "lfs_migrate --copy: $layout_after != $layout_before"
7182 }
7183 run_test 56xd "check lfs_migrate --yaml and --copy support"
7184
7185 test_56xe() {
7186         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7187
7188         local dir=$DIR/$tdir
7189         local f_comp=$dir/$tfile
7190         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7191         local layout_before=""
7192         local layout_after=""
7193
7194         test_mkdir "$dir" || error "cannot create dir $dir"
7195         $LFS setstripe $layout $f_comp ||
7196                 error "cannot setstripe $f_comp with layout $layout"
7197         layout_before=$(get_layout_param $f_comp)
7198         dd if=/dev/zero of=$f_comp bs=1M count=4
7199
7200         # 1. migrate a comp layout file by lfs_migrate
7201         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7202         layout_after=$(get_layout_param $f_comp)
7203         [ "$layout_before" == "$layout_after" ] ||
7204                 error "lfs_migrate: $layout_before != $layout_after"
7205
7206         # 2. migrate a comp layout file by lfs migrate
7207         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7208         layout_after=$(get_layout_param $f_comp)
7209         [ "$layout_before" == "$layout_after" ] ||
7210                 error "lfs migrate: $layout_before != $layout_after"
7211 }
7212 run_test 56xe "migrate a composite layout file"
7213
7214 test_56xf() {
7215         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7216
7217         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7218                 skip "Need server version at least 2.13.53"
7219
7220         local dir=$DIR/$tdir
7221         local f_comp=$dir/$tfile
7222         local layout="-E 1M -c1 -E -1 -c2"
7223         local fid_before=""
7224         local fid_after=""
7225
7226         test_mkdir "$dir" || error "cannot create dir $dir"
7227         $LFS setstripe $layout $f_comp ||
7228                 error "cannot setstripe $f_comp with layout $layout"
7229         fid_before=$($LFS getstripe --fid $f_comp)
7230         dd if=/dev/zero of=$f_comp bs=1M count=4
7231
7232         # 1. migrate a comp layout file to a comp layout
7233         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7234         fid_after=$($LFS getstripe --fid $f_comp)
7235         [ "$fid_before" == "$fid_after" ] ||
7236                 error "comp-to-comp migrate: $fid_before != $fid_after"
7237
7238         # 2. migrate a comp layout file to a plain layout
7239         $LFS migrate -c2 $f_comp ||
7240                 error "cannot migrate $f_comp by lfs migrate"
7241         fid_after=$($LFS getstripe --fid $f_comp)
7242         [ "$fid_before" == "$fid_after" ] ||
7243                 error "comp-to-plain migrate: $fid_before != $fid_after"
7244
7245         # 3. migrate a plain layout file to a comp layout
7246         $LFS migrate $layout $f_comp ||
7247                 error "cannot migrate $f_comp by lfs migrate"
7248         fid_after=$($LFS getstripe --fid $f_comp)
7249         [ "$fid_before" == "$fid_after" ] ||
7250                 error "plain-to-comp migrate: $fid_before != $fid_after"
7251 }
7252 run_test 56xf "FID is not lost during migration of a composite layout file"
7253
7254 test_56y() {
7255         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7256                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7257
7258         local res=""
7259         local dir=$DIR/$tdir
7260         local f1=$dir/file1
7261         local f2=$dir/file2
7262
7263         test_mkdir -p $dir || error "creating dir $dir"
7264         touch $f1 || error "creating std file $f1"
7265         $MULTIOP $f2 H2c || error "creating released file $f2"
7266
7267         # a directory can be raid0, so ask only for files
7268         res=$($LFS find $dir -L raid0 -type f | wc -l)
7269         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7270
7271         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7272         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7273
7274         # only files can be released, so no need to force file search
7275         res=$($LFS find $dir -L released)
7276         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7277
7278         res=$($LFS find $dir -type f \! -L released)
7279         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7280 }
7281 run_test 56y "lfs find -L raid0|released"
7282
7283 test_56z() { # LU-4824
7284         # This checks to make sure 'lfs find' continues after errors
7285         # There are two classes of errors that should be caught:
7286         # - If multiple paths are provided, all should be searched even if one
7287         #   errors out
7288         # - If errors are encountered during the search, it should not terminate
7289         #   early
7290         local dir=$DIR/$tdir
7291         local i
7292
7293         test_mkdir $dir
7294         for i in d{0..9}; do
7295                 test_mkdir $dir/$i
7296                 touch $dir/$i/$tfile
7297         done
7298         $LFS find $DIR/non_existent_dir $dir &&
7299                 error "$LFS find did not return an error"
7300         # Make a directory unsearchable. This should NOT be the last entry in
7301         # directory order.  Arbitrarily pick the 6th entry
7302         chmod 700 $($LFS find $dir -type d | sed '6!d')
7303
7304         $RUNAS $LFS find $DIR/non_existent $dir
7305         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7306
7307         # The user should be able to see 10 directories and 9 files
7308         (( count == 19 )) ||
7309                 error "$LFS find found $count != 19 entries after error"
7310 }
7311 run_test 56z "lfs find should continue after an error"
7312
7313 test_56aa() { # LU-5937
7314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7315
7316         local dir=$DIR/$tdir
7317
7318         mkdir $dir
7319         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7320
7321         createmany -o $dir/striped_dir/${tfile}- 1024
7322         local dirs=$($LFS find --size +8k $dir/)
7323
7324         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7325 }
7326 run_test 56aa "lfs find --size under striped dir"
7327
7328 test_56ab() { # LU-10705
7329         test_mkdir $DIR/$tdir
7330         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7331         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7332         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7333         # Flush writes to ensure valid blocks.  Need to be more thorough for
7334         # ZFS, since blocks are not allocated/returned to client immediately.
7335         sync_all_data
7336         wait_zfs_commit ost1 2
7337         cancel_lru_locks osc
7338         ls -ls $DIR/$tdir
7339
7340         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7341
7342         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7343
7344         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7345         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7346
7347         rm -f $DIR/$tdir/$tfile.[123]
7348 }
7349 run_test 56ab "lfs find --blocks"
7350
7351 test_56ba() {
7352         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7353                 skip "Need MDS version at least 2.10.50"
7354
7355         # Create composite files with one component
7356         local dir=$DIR/$tdir
7357
7358         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7359         # Create composite files with three components
7360         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7361         # Create non-composite files
7362         createmany -o $dir/${tfile}- 10
7363
7364         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7365
7366         [[ $nfiles == 10 ]] ||
7367                 error "lfs find -E 1M found $nfiles != 10 files"
7368
7369         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7370         [[ $nfiles == 25 ]] ||
7371                 error "lfs find ! -E 1M found $nfiles != 25 files"
7372
7373         # All files have a component that starts at 0
7374         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7375         [[ $nfiles == 35 ]] ||
7376                 error "lfs find --component-start 0 - $nfiles != 35 files"
7377
7378         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7379         [[ $nfiles == 15 ]] ||
7380                 error "lfs find --component-start 2M - $nfiles != 15 files"
7381
7382         # All files created here have a componenet that does not starts at 2M
7383         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7384         [[ $nfiles == 35 ]] ||
7385                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7386
7387         # Find files with a specified number of components
7388         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7389         [[ $nfiles == 15 ]] ||
7390                 error "lfs find --component-count 3 - $nfiles != 15 files"
7391
7392         # Remember non-composite files have a component count of zero
7393         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7394         [[ $nfiles == 10 ]] ||
7395                 error "lfs find --component-count 0 - $nfiles != 10 files"
7396
7397         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7398         [[ $nfiles == 20 ]] ||
7399                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7400
7401         # All files have a flag called "init"
7402         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7403         [[ $nfiles == 35 ]] ||
7404                 error "lfs find --component-flags init - $nfiles != 35 files"
7405
7406         # Multi-component files will have a component not initialized
7407         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7408         [[ $nfiles == 15 ]] ||
7409                 error "lfs find !--component-flags init - $nfiles != 15 files"
7410
7411         rm -rf $dir
7412
7413 }
7414 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7415
7416 test_56ca() {
7417         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7418                 skip "Need MDS version at least 2.10.57"
7419
7420         local td=$DIR/$tdir
7421         local tf=$td/$tfile
7422         local dir
7423         local nfiles
7424         local cmd
7425         local i
7426         local j
7427
7428         # create mirrored directories and mirrored files
7429         mkdir $td || error "mkdir $td failed"
7430         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7431         createmany -o $tf- 10 || error "create $tf- failed"
7432
7433         for i in $(seq 2); do
7434                 dir=$td/dir$i
7435                 mkdir $dir || error "mkdir $dir failed"
7436                 $LFS mirror create -N$((3 + i)) $dir ||
7437                         error "create mirrored dir $dir failed"
7438                 createmany -o $dir/$tfile- 10 ||
7439                         error "create $dir/$tfile- failed"
7440         done
7441
7442         # change the states of some mirrored files
7443         echo foo > $tf-6
7444         for i in $(seq 2); do
7445                 dir=$td/dir$i
7446                 for j in $(seq 4 9); do
7447                         echo foo > $dir/$tfile-$j
7448                 done
7449         done
7450
7451         # find mirrored files with specific mirror count
7452         cmd="$LFS find --mirror-count 3 --type f $td"
7453         nfiles=$($cmd | wc -l)
7454         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7455
7456         cmd="$LFS find ! --mirror-count 3 --type f $td"
7457         nfiles=$($cmd | wc -l)
7458         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7459
7460         cmd="$LFS find --mirror-count +2 --type f $td"
7461         nfiles=$($cmd | wc -l)
7462         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7463
7464         cmd="$LFS find --mirror-count -6 --type f $td"
7465         nfiles=$($cmd | wc -l)
7466         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7467
7468         # find mirrored files with specific file state
7469         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7470         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7471
7472         cmd="$LFS find --mirror-state=ro --type f $td"
7473         nfiles=$($cmd | wc -l)
7474         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7475
7476         cmd="$LFS find ! --mirror-state=ro --type f $td"
7477         nfiles=$($cmd | wc -l)
7478         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7479
7480         cmd="$LFS find --mirror-state=wp --type f $td"
7481         nfiles=$($cmd | wc -l)
7482         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7483
7484         cmd="$LFS find ! --mirror-state=sp --type f $td"
7485         nfiles=$($cmd | wc -l)
7486         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7487 }
7488 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7489
7490 test_57a() {
7491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7492         # note test will not do anything if MDS is not local
7493         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7494                 skip_env "ldiskfs only test"
7495         fi
7496         remote_mds_nodsh && skip "remote MDS with nodsh"
7497
7498         local MNTDEV="osd*.*MDT*.mntdev"
7499         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7500         [ -z "$DEV" ] && error "can't access $MNTDEV"
7501         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7502                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7503                         error "can't access $DEV"
7504                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7505                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7506                 rm $TMP/t57a.dump
7507         done
7508 }
7509 run_test 57a "verify MDS filesystem created with large inodes =="
7510
7511 test_57b() {
7512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7513         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7514                 skip_env "ldiskfs only test"
7515         fi
7516         remote_mds_nodsh && skip "remote MDS with nodsh"
7517
7518         local dir=$DIR/$tdir
7519         local filecount=100
7520         local file1=$dir/f1
7521         local fileN=$dir/f$filecount
7522
7523         rm -rf $dir || error "removing $dir"
7524         test_mkdir -c1 $dir
7525         local mdtidx=$($LFS getstripe -m $dir)
7526         local mdtname=MDT$(printf %04x $mdtidx)
7527         local facet=mds$((mdtidx + 1))
7528
7529         echo "mcreating $filecount files"
7530         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7531
7532         # verify that files do not have EAs yet
7533         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7534                 error "$file1 has an EA"
7535         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7536                 error "$fileN has an EA"
7537
7538         sync
7539         sleep 1
7540         df $dir  #make sure we get new statfs data
7541         local mdsfree=$(do_facet $facet \
7542                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7543         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7544         local file
7545
7546         echo "opening files to create objects/EAs"
7547         for file in $(seq -f $dir/f%g 1 $filecount); do
7548                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7549                         error "opening $file"
7550         done
7551
7552         # verify that files have EAs now
7553         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7554         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7555
7556         sleep 1  #make sure we get new statfs data
7557         df $dir
7558         local mdsfree2=$(do_facet $facet \
7559                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7560         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7561
7562         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7563                 if [ "$mdsfree" != "$mdsfree2" ]; then
7564                         error "MDC before $mdcfree != after $mdcfree2"
7565                 else
7566                         echo "MDC before $mdcfree != after $mdcfree2"
7567                         echo "unable to confirm if MDS has large inodes"
7568                 fi
7569         fi
7570         rm -rf $dir
7571 }
7572 run_test 57b "default LOV EAs are stored inside large inodes ==="
7573
7574 test_58() {
7575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7576         [ -z "$(which wiretest 2>/dev/null)" ] &&
7577                         skip_env "could not find wiretest"
7578
7579         wiretest
7580 }
7581 run_test 58 "verify cross-platform wire constants =============="
7582
7583 test_59() {
7584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7585
7586         echo "touch 130 files"
7587         createmany -o $DIR/f59- 130
7588         echo "rm 130 files"
7589         unlinkmany $DIR/f59- 130
7590         sync
7591         # wait for commitment of removal
7592         wait_delete_completed
7593 }
7594 run_test 59 "verify cancellation of llog records async ========="
7595
7596 TEST60_HEAD="test_60 run $RANDOM"
7597 test_60a() {
7598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7599         remote_mgs_nodsh && skip "remote MGS with nodsh"
7600         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7601                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7602                         skip_env "missing subtest run-llog.sh"
7603
7604         log "$TEST60_HEAD - from kernel mode"
7605         do_facet mgs "$LCTL dk > /dev/null"
7606         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7607         do_facet mgs $LCTL dk > $TMP/$tfile
7608
7609         # LU-6388: test llog_reader
7610         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7611         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7612         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7613                         skip_env "missing llog_reader"
7614         local fstype=$(facet_fstype mgs)
7615         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7616                 skip_env "Only for ldiskfs or zfs type mgs"
7617
7618         local mntpt=$(facet_mntpt mgs)
7619         local mgsdev=$(mgsdevname 1)
7620         local fid_list
7621         local fid
7622         local rec_list
7623         local rec
7624         local rec_type
7625         local obj_file
7626         local path
7627         local seq
7628         local oid
7629         local pass=true
7630
7631         #get fid and record list
7632         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7633                 tail -n 4))
7634         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7635                 tail -n 4))
7636         #remount mgs as ldiskfs or zfs type
7637         stop mgs || error "stop mgs failed"
7638         mount_fstype mgs || error "remount mgs failed"
7639         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7640                 fid=${fid_list[i]}
7641                 rec=${rec_list[i]}
7642                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7643                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7644                 oid=$((16#$oid))
7645
7646                 case $fstype in
7647                         ldiskfs )
7648                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7649                         zfs )
7650                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7651                 esac
7652                 echo "obj_file is $obj_file"
7653                 do_facet mgs $llog_reader $obj_file
7654
7655                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7656                         awk '{ print $3 }' | sed -e "s/^type=//g")
7657                 if [ $rec_type != $rec ]; then
7658                         echo "FAILED test_60a wrong record type $rec_type," \
7659                               "should be $rec"
7660                         pass=false
7661                         break
7662                 fi
7663
7664                 #check obj path if record type is LLOG_LOGID_MAGIC
7665                 if [ "$rec" == "1064553b" ]; then
7666                         path=$(do_facet mgs $llog_reader $obj_file |
7667                                 grep "path=" | awk '{ print $NF }' |
7668                                 sed -e "s/^path=//g")
7669                         if [ $obj_file != $mntpt/$path ]; then
7670                                 echo "FAILED test_60a wrong obj path" \
7671                                       "$montpt/$path, should be $obj_file"
7672                                 pass=false
7673                                 break
7674                         fi
7675                 fi
7676         done
7677         rm -f $TMP/$tfile
7678         #restart mgs before "error", otherwise it will block the next test
7679         stop mgs || error "stop mgs failed"
7680         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7681         $pass || error "test failed, see FAILED test_60a messages for specifics"
7682 }
7683 run_test 60a "llog_test run from kernel module and test llog_reader"
7684
7685 test_60b() { # bug 6411
7686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7687
7688         dmesg > $DIR/$tfile
7689         LLOG_COUNT=$(do_facet mgs dmesg |
7690                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7691                           /llog_[a-z]*.c:[0-9]/ {
7692                                 if (marker)
7693                                         from_marker++
7694                                 from_begin++
7695                           }
7696                           END {
7697                                 if (marker)
7698                                         print from_marker
7699                                 else
7700                                         print from_begin
7701                           }")
7702
7703         [[ $LLOG_COUNT -gt 120 ]] &&
7704                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7705 }
7706 run_test 60b "limit repeated messages from CERROR/CWARN"
7707
7708 test_60c() {
7709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7710
7711         echo "create 5000 files"
7712         createmany -o $DIR/f60c- 5000
7713 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7714         lctl set_param fail_loc=0x80000137
7715         unlinkmany $DIR/f60c- 5000
7716         lctl set_param fail_loc=0
7717 }
7718 run_test 60c "unlink file when mds full"
7719
7720 test_60d() {
7721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7722
7723         SAVEPRINTK=$(lctl get_param -n printk)
7724         # verify "lctl mark" is even working"
7725         MESSAGE="test message ID $RANDOM $$"
7726         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7727         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7728
7729         lctl set_param printk=0 || error "set lnet.printk failed"
7730         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7731         MESSAGE="new test message ID $RANDOM $$"
7732         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7733         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7734         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7735
7736         lctl set_param -n printk="$SAVEPRINTK"
7737 }
7738 run_test 60d "test printk console message masking"
7739
7740 test_60e() {
7741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7742         remote_mds_nodsh && skip "remote MDS with nodsh"
7743
7744         touch $DIR/$tfile
7745 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7746         do_facet mds1 lctl set_param fail_loc=0x15b
7747         rm $DIR/$tfile
7748 }
7749 run_test 60e "no space while new llog is being created"
7750
7751 test_60g() {
7752         local pid
7753         local i
7754
7755         test_mkdir -c $MDSCOUNT $DIR/$tdir
7756
7757         (
7758                 local index=0
7759                 while true; do
7760                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7761                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7762                                 2>/dev/null
7763                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7764                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7765                         index=$((index + 1))
7766                 done
7767         ) &
7768
7769         pid=$!
7770
7771         for i in {0..100}; do
7772                 # define OBD_FAIL_OSD_TXN_START    0x19a
7773                 local index=$((i % MDSCOUNT + 1))
7774
7775                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7776                         > /dev/null
7777                 sleep 0.01
7778         done
7779
7780         kill -9 $pid
7781
7782         for i in $(seq $MDSCOUNT); do
7783                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7784         done
7785
7786         mkdir $DIR/$tdir/new || error "mkdir failed"
7787         rmdir $DIR/$tdir/new || error "rmdir failed"
7788
7789         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7790                 -t namespace
7791         for i in $(seq $MDSCOUNT); do
7792                 wait_update_facet mds$i "$LCTL get_param -n \
7793                         mdd.$(facet_svc mds$i).lfsck_namespace |
7794                         awk '/^status/ { print \\\$2 }'" "completed"
7795         done
7796
7797         ls -R $DIR/$tdir || error "ls failed"
7798         rm -rf $DIR/$tdir || error "rmdir failed"
7799 }
7800 run_test 60g "transaction abort won't cause MDT hung"
7801
7802 test_60h() {
7803         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7804                 skip "Need MDS version at least 2.12.52"
7805         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7806
7807         local f
7808
7809         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7810         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7811         for fail_loc in 0x80000188 0x80000189; do
7812                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7813                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7814                         error "mkdir $dir-$fail_loc failed"
7815                 for i in {0..10}; do
7816                         # create may fail on missing stripe
7817                         echo $i > $DIR/$tdir-$fail_loc/$i
7818                 done
7819                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7820                         error "getdirstripe $tdir-$fail_loc failed"
7821                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7822                         error "migrate $tdir-$fail_loc failed"
7823                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7824                         error "getdirstripe $tdir-$fail_loc failed"
7825                 pushd $DIR/$tdir-$fail_loc
7826                 for f in *; do
7827                         echo $f | cmp $f - || error "$f data mismatch"
7828                 done
7829                 popd
7830                 rm -rf $DIR/$tdir-$fail_loc
7831         done
7832 }
7833 run_test 60h "striped directory with missing stripes can be accessed"
7834
7835 test_61a() {
7836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7837
7838         f="$DIR/f61"
7839         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7840         cancel_lru_locks osc
7841         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7842         sync
7843 }
7844 run_test 61a "mmap() writes don't make sync hang ================"
7845
7846 test_61b() {
7847         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7848 }
7849 run_test 61b "mmap() of unstriped file is successful"
7850
7851 # bug 2330 - insufficient obd_match error checking causes LBUG
7852 test_62() {
7853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7854
7855         f="$DIR/f62"
7856         echo foo > $f
7857         cancel_lru_locks osc
7858         lctl set_param fail_loc=0x405
7859         cat $f && error "cat succeeded, expect -EIO"
7860         lctl set_param fail_loc=0
7861 }
7862 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7863 # match every page all of the time.
7864 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7865
7866 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7867 # Though this test is irrelevant anymore, it helped to reveal some
7868 # other grant bugs (LU-4482), let's keep it.
7869 test_63a() {   # was test_63
7870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7871
7872         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7873
7874         for i in `seq 10` ; do
7875                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7876                 sleep 5
7877                 kill $!
7878                 sleep 1
7879         done
7880
7881         rm -f $DIR/f63 || true
7882 }
7883 run_test 63a "Verify oig_wait interruption does not crash ======="
7884
7885 # bug 2248 - async write errors didn't return to application on sync
7886 # bug 3677 - async write errors left page locked
7887 test_63b() {
7888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7889
7890         debugsave
7891         lctl set_param debug=-1
7892
7893         # ensure we have a grant to do async writes
7894         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7895         rm $DIR/$tfile
7896
7897         sync    # sync lest earlier test intercept the fail_loc
7898
7899         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7900         lctl set_param fail_loc=0x80000406
7901         $MULTIOP $DIR/$tfile Owy && \
7902                 error "sync didn't return ENOMEM"
7903         sync; sleep 2; sync     # do a real sync this time to flush page
7904         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7905                 error "locked page left in cache after async error" || true
7906         debugrestore
7907 }
7908 run_test 63b "async write errors should be returned to fsync ==="
7909
7910 test_64a () {
7911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7912
7913         lfs df $DIR
7914         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7915 }
7916 run_test 64a "verify filter grant calculations (in kernel) ====="
7917
7918 test_64b () {
7919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7920
7921         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7922 }
7923 run_test 64b "check out-of-space detection on client"
7924
7925 test_64c() {
7926         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7927 }
7928 run_test 64c "verify grant shrink"
7929
7930 import_param() {
7931         local tgt=$1
7932         local param=$2
7933
7934         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7935 }
7936
7937 # this does exactly what osc_request.c:osc_announce_cached() does in
7938 # order to calculate max amount of grants to ask from server
7939 want_grant() {
7940         local tgt=$1
7941
7942         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7943         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7944
7945         ((rpc_in_flight++));
7946         nrpages=$((nrpages * rpc_in_flight))
7947
7948         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7949
7950         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7951
7952         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7953         local undirty=$((nrpages * PAGE_SIZE))
7954
7955         local max_extent_pages
7956         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7957         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7958         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7959         local grant_extent_tax
7960         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7961
7962         undirty=$((undirty + nrextents * grant_extent_tax))
7963
7964         echo $undirty
7965 }
7966
7967 # this is size of unit for grant allocation. It should be equal to
7968 # what tgt_grant.c:tgt_grant_chunk() calculates
7969 grant_chunk() {
7970         local tgt=$1
7971         local max_brw_size
7972         local grant_extent_tax
7973
7974         max_brw_size=$(import_param $tgt max_brw_size)
7975
7976         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7977
7978         echo $(((max_brw_size + grant_extent_tax) * 2))
7979 }
7980
7981 test_64d() {
7982         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7983                 skip "OST < 2.10.55 doesn't limit grants enough"
7984
7985         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7986
7987         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7988                 skip "no grant_param connect flag"
7989
7990         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7991
7992         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7993         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7994
7995
7996         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7997         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7998
7999         $LFS setstripe $DIR/$tfile -i 0 -c 1
8000         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8001         ddpid=$!
8002
8003         while kill -0 $ddpid; do
8004                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8005
8006                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8007                         kill $ddpid
8008                         error "cur_grant $cur_grant > $max_cur_granted"
8009                 fi
8010
8011                 sleep 1
8012         done
8013 }
8014 run_test 64d "check grant limit exceed"
8015
8016 check_grants() {
8017         local tgt=$1
8018         local expected=$2
8019         local msg=$3
8020         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8021
8022         ((cur_grants == expected)) ||
8023                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8024 }
8025
8026 round_up_p2() {
8027         echo $((($1 + $2 - 1) & ~($2 - 1)))
8028 }
8029
8030 test_64e() {
8031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8032         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8033                 skip "Need OSS version at least 2.11.56"
8034
8035         # Remount client to reset grant
8036         remount_client $MOUNT || error "failed to remount client"
8037         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8038
8039         local init_grants=$(import_param $osc_tgt initial_grant)
8040
8041         check_grants $osc_tgt $init_grants "init grants"
8042
8043         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8044         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8045         local gbs=$(import_param $osc_tgt grant_block_size)
8046
8047         # write random number of bytes from max_brw_size / 4 to max_brw_size
8048         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8049         # align for direct io
8050         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8051         # round to grant consumption unit
8052         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8053
8054         local grants=$((wb_round_up + extent_tax))
8055
8056         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8057
8058         # define OBD_FAIL_TGT_NO_GRANT 0x725
8059         # make the server not grant more back
8060         do_facet ost1 $LCTL set_param fail_loc=0x725
8061         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8062
8063         do_facet ost1 $LCTL set_param fail_loc=0
8064
8065         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8066
8067         rm -f $DIR/$tfile || error "rm failed"
8068
8069         # Remount client to reset grant
8070         remount_client $MOUNT || error "failed to remount client"
8071         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8072
8073         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8074
8075         # define OBD_FAIL_TGT_NO_GRANT 0x725
8076         # make the server not grant more back
8077         do_facet ost1 $LCTL set_param fail_loc=0x725
8078         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8079         do_facet ost1 $LCTL set_param fail_loc=0
8080
8081         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8082 }
8083 run_test 64e "check grant consumption (no grant allocation)"
8084
8085 test_64f() {
8086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8087
8088         # Remount client to reset grant
8089         remount_client $MOUNT || error "failed to remount client"
8090         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8091
8092         local init_grants=$(import_param $osc_tgt initial_grant)
8093         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8094         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8095         local gbs=$(import_param $osc_tgt grant_block_size)
8096         local chunk=$(grant_chunk $osc_tgt)
8097
8098         # write random number of bytes from max_brw_size / 4 to max_brw_size
8099         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8100         # align for direct io
8101         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8102         # round to grant consumption unit
8103         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8104
8105         local grants=$((wb_round_up + extent_tax))
8106
8107         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8108         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8109                 error "error writing to $DIR/$tfile"
8110
8111         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8112                 "direct io with grant allocation"
8113
8114         rm -f $DIR/$tfile || error "rm failed"
8115
8116         # Remount client to reset grant
8117         remount_client $MOUNT || error "failed to remount client"
8118         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8119
8120         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8121
8122         local cmd="oO_WRONLY:w${write_bytes}_yc"
8123
8124         $MULTIOP $DIR/$tfile $cmd &
8125         MULTIPID=$!
8126         sleep 1
8127
8128         check_grants $osc_tgt $((init_grants - grants)) \
8129                 "buffered io, not write rpc"
8130
8131         kill -USR1 $MULTIPID
8132         wait
8133
8134         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8135                 "buffered io, one RPC"
8136 }
8137 run_test 64f "check grant consumption (with grant allocation)"
8138
8139 # bug 1414 - set/get directories' stripe info
8140 test_65a() {
8141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8142
8143         test_mkdir $DIR/$tdir
8144         touch $DIR/$tdir/f1
8145         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8146 }
8147 run_test 65a "directory with no stripe info"
8148
8149 test_65b() {
8150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8151
8152         test_mkdir $DIR/$tdir
8153         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8154
8155         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8156                                                 error "setstripe"
8157         touch $DIR/$tdir/f2
8158         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8159 }
8160 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8161
8162 test_65c() {
8163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8164         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8165
8166         test_mkdir $DIR/$tdir
8167         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8168
8169         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8170                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8171         touch $DIR/$tdir/f3
8172         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8173 }
8174 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8175
8176 test_65d() {
8177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8178
8179         test_mkdir $DIR/$tdir
8180         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8181         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8182
8183         if [[ $STRIPECOUNT -le 0 ]]; then
8184                 sc=1
8185         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8186                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8187                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8188         else
8189                 sc=$(($STRIPECOUNT - 1))
8190         fi
8191         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8192         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8193         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8194                 error "lverify failed"
8195 }
8196 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8197
8198 test_65e() {
8199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8200
8201         test_mkdir $DIR/$tdir
8202
8203         $LFS setstripe $DIR/$tdir || error "setstripe"
8204         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8205                                         error "no stripe info failed"
8206         touch $DIR/$tdir/f6
8207         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8208 }
8209 run_test 65e "directory setstripe defaults"
8210
8211 test_65f() {
8212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8213
8214         test_mkdir $DIR/${tdir}f
8215         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8216                 error "setstripe succeeded" || true
8217 }
8218 run_test 65f "dir setstripe permission (should return error) ==="
8219
8220 test_65g() {
8221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8222
8223         test_mkdir $DIR/$tdir
8224         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8225
8226         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8227                 error "setstripe -S failed"
8228         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8229         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8230                 error "delete default stripe failed"
8231 }
8232 run_test 65g "directory setstripe -d"
8233
8234 test_65h() {
8235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8236
8237         test_mkdir $DIR/$tdir
8238         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8239
8240         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8241                 error "setstripe -S failed"
8242         test_mkdir $DIR/$tdir/dd1
8243         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8244                 error "stripe info inherit failed"
8245 }
8246 run_test 65h "directory stripe info inherit ===================="
8247
8248 test_65i() {
8249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8250
8251         save_layout_restore_at_exit $MOUNT
8252
8253         # bug6367: set non-default striping on root directory
8254         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8255
8256         # bug12836: getstripe on -1 default directory striping
8257         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8258
8259         # bug12836: getstripe -v on -1 default directory striping
8260         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8261
8262         # bug12836: new find on -1 default directory striping
8263         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8264 }
8265 run_test 65i "various tests to set root directory striping"
8266
8267 test_65j() { # bug6367
8268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8269
8270         sync; sleep 1
8271
8272         # if we aren't already remounting for each test, do so for this test
8273         if [ "$I_MOUNTED" = "yes" ]; then
8274                 cleanup || error "failed to unmount"
8275                 setup
8276         fi
8277
8278         save_layout_restore_at_exit $MOUNT
8279
8280         $LFS setstripe -d $MOUNT || error "setstripe failed"
8281 }
8282 run_test 65j "set default striping on root directory (bug 6367)="
8283
8284 cleanup_65k() {
8285         rm -rf $DIR/$tdir
8286         wait_delete_completed
8287         do_facet $SINGLEMDS "lctl set_param -n \
8288                 osp.$ost*MDT0000.max_create_count=$max_count"
8289         do_facet $SINGLEMDS "lctl set_param -n \
8290                 osp.$ost*MDT0000.create_count=$count"
8291         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8292         echo $INACTIVE_OSC "is Activate"
8293
8294         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8295 }
8296
8297 test_65k() { # bug11679
8298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8299         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8300         remote_mds_nodsh && skip "remote MDS with nodsh"
8301
8302         local disable_precreate=true
8303         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8304                 disable_precreate=false
8305
8306         echo "Check OST status: "
8307         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8308                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8309
8310         for OSC in $MDS_OSCS; do
8311                 echo $OSC "is active"
8312                 do_facet $SINGLEMDS lctl --device %$OSC activate
8313         done
8314
8315         for INACTIVE_OSC in $MDS_OSCS; do
8316                 local ost=$(osc_to_ost $INACTIVE_OSC)
8317                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8318                                lov.*md*.target_obd |
8319                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8320
8321                 mkdir -p $DIR/$tdir
8322                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8323                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8324
8325                 echo "Deactivate: " $INACTIVE_OSC
8326                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8327
8328                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8329                               osp.$ost*MDT0000.create_count")
8330                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8331                                   osp.$ost*MDT0000.max_create_count")
8332                 $disable_precreate &&
8333                         do_facet $SINGLEMDS "lctl set_param -n \
8334                                 osp.$ost*MDT0000.max_create_count=0"
8335
8336                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8337                         [ -f $DIR/$tdir/$idx ] && continue
8338                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8339                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8340                                 { cleanup_65k;
8341                                   error "setstripe $idx should succeed"; }
8342                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8343                 done
8344                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8345                 rmdir $DIR/$tdir
8346
8347                 do_facet $SINGLEMDS "lctl set_param -n \
8348                         osp.$ost*MDT0000.max_create_count=$max_count"
8349                 do_facet $SINGLEMDS "lctl set_param -n \
8350                         osp.$ost*MDT0000.create_count=$count"
8351                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8352                 echo $INACTIVE_OSC "is Activate"
8353
8354                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8355         done
8356 }
8357 run_test 65k "validate manual striping works properly with deactivated OSCs"
8358
8359 test_65l() { # bug 12836
8360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8361
8362         test_mkdir -p $DIR/$tdir/test_dir
8363         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8364         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8365 }
8366 run_test 65l "lfs find on -1 stripe dir ========================"
8367
8368 test_65m() {
8369         local layout=$(save_layout $MOUNT)
8370         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8371                 restore_layout $MOUNT $layout
8372                 error "setstripe should fail by non-root users"
8373         }
8374         true
8375 }
8376 run_test 65m "normal user can't set filesystem default stripe"
8377
8378 test_65n() {
8379         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8380         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8381                 skip "Need MDS version at least 2.12.50"
8382         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8383
8384         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8385         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8386         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8387
8388         local root_layout=$(save_layout $MOUNT)
8389         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8390
8391         # new subdirectory under root directory should not inherit
8392         # the default layout from root
8393         local dir1=$MOUNT/$tdir-1
8394         mkdir $dir1 || error "mkdir $dir1 failed"
8395         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8396                 error "$dir1 shouldn't have LOV EA"
8397
8398         # delete the default layout on root directory
8399         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8400
8401         local dir2=$MOUNT/$tdir-2
8402         mkdir $dir2 || error "mkdir $dir2 failed"
8403         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8404                 error "$dir2 shouldn't have LOV EA"
8405
8406         # set a new striping pattern on root directory
8407         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8408         local new_def_stripe_size=$((def_stripe_size * 2))
8409         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8410                 error "set stripe size on $MOUNT failed"
8411
8412         # new file created in $dir2 should inherit the new stripe size from
8413         # the filesystem default
8414         local file2=$dir2/$tfile-2
8415         touch $file2 || error "touch $file2 failed"
8416
8417         local file2_stripe_size=$($LFS getstripe -S $file2)
8418         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8419         {
8420                 echo "file2_stripe_size: '$file2_stripe_size'"
8421                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8422                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8423         }
8424
8425         local dir3=$MOUNT/$tdir-3
8426         mkdir $dir3 || error "mkdir $dir3 failed"
8427         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8428         # the root layout, which is the actual default layout that will be used
8429         # when new files are created in $dir3.
8430         local dir3_layout=$(get_layout_param $dir3)
8431         local root_dir_layout=$(get_layout_param $MOUNT)
8432         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8433         {
8434                 echo "dir3_layout: '$dir3_layout'"
8435                 echo "root_dir_layout: '$root_dir_layout'"
8436                 error "$dir3 should show the default layout from $MOUNT"
8437         }
8438
8439         # set OST pool on root directory
8440         local pool=$TESTNAME
8441         pool_add $pool || error "add $pool failed"
8442         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8443                 error "add targets to $pool failed"
8444
8445         $LFS setstripe -p $pool $MOUNT ||
8446                 error "set OST pool on $MOUNT failed"
8447
8448         # new file created in $dir3 should inherit the pool from
8449         # the filesystem default
8450         local file3=$dir3/$tfile-3
8451         touch $file3 || error "touch $file3 failed"
8452
8453         local file3_pool=$($LFS getstripe -p $file3)
8454         [[ "$file3_pool" = "$pool" ]] ||
8455                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8456
8457         local dir4=$MOUNT/$tdir-4
8458         mkdir $dir4 || error "mkdir $dir4 failed"
8459         local dir4_layout=$(get_layout_param $dir4)
8460         root_dir_layout=$(get_layout_param $MOUNT)
8461         echo "$LFS getstripe -d $dir4"
8462         $LFS getstripe -d $dir4
8463         echo "$LFS getstripe -d $MOUNT"
8464         $LFS getstripe -d $MOUNT
8465         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8466         {
8467                 echo "dir4_layout: '$dir4_layout'"
8468                 echo "root_dir_layout: '$root_dir_layout'"
8469                 error "$dir4 should show the default layout from $MOUNT"
8470         }
8471
8472         # new file created in $dir4 should inherit the pool from
8473         # the filesystem default
8474         local file4=$dir4/$tfile-4
8475         touch $file4 || error "touch $file4 failed"
8476
8477         local file4_pool=$($LFS getstripe -p $file4)
8478         [[ "$file4_pool" = "$pool" ]] ||
8479                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8480
8481         # new subdirectory under non-root directory should inherit
8482         # the default layout from its parent directory
8483         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8484                 error "set directory layout on $dir4 failed"
8485
8486         local dir5=$dir4/$tdir-5
8487         mkdir $dir5 || error "mkdir $dir5 failed"
8488
8489         dir4_layout=$(get_layout_param $dir4)
8490         local dir5_layout=$(get_layout_param $dir5)
8491         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8492         {
8493                 echo "dir4_layout: '$dir4_layout'"
8494                 echo "dir5_layout: '$dir5_layout'"
8495                 error "$dir5 should inherit the default layout from $dir4"
8496         }
8497
8498         # though subdir under ROOT doesn't inherit default layout, but
8499         # its sub dir/file should be created with default layout.
8500         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8501         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8502                 skip "Need MDS version at least 2.12.59"
8503
8504         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8505         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8506         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8507
8508         if [ $default_lmv_hash == "none" ]; then
8509                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8510         else
8511                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8512                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8513         fi
8514
8515         $LFS setdirstripe -D -c 2 $MOUNT ||
8516                 error "setdirstripe -D -c 2 failed"
8517         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8518         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8519         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8520 }
8521 run_test 65n "don't inherit default layout from root for new subdirectories"
8522
8523 # bug 2543 - update blocks count on client
8524 test_66() {
8525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8526
8527         COUNT=${COUNT:-8}
8528         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8529         sync; sync_all_data; sync; sync_all_data
8530         cancel_lru_locks osc
8531         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8532         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8533 }
8534 run_test 66 "update inode blocks count on client ==============="
8535
8536 meminfo() {
8537         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8538 }
8539
8540 swap_used() {
8541         swapon -s | awk '($1 == "'$1'") { print $4 }'
8542 }
8543
8544 # bug5265, obdfilter oa2dentry return -ENOENT
8545 # #define OBD_FAIL_SRV_ENOENT 0x217
8546 test_69() {
8547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8548         remote_ost_nodsh && skip "remote OST with nodsh"
8549
8550         f="$DIR/$tfile"
8551         $LFS setstripe -c 1 -i 0 $f
8552
8553         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8554
8555         do_facet ost1 lctl set_param fail_loc=0x217
8556         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8557         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8558
8559         do_facet ost1 lctl set_param fail_loc=0
8560         $DIRECTIO write $f 0 2 || error "write error"
8561
8562         cancel_lru_locks osc
8563         $DIRECTIO read $f 0 1 || error "read error"
8564
8565         do_facet ost1 lctl set_param fail_loc=0x217
8566         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8567
8568         do_facet ost1 lctl set_param fail_loc=0
8569         rm -f $f
8570 }
8571 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8572
8573 test_71() {
8574         test_mkdir $DIR/$tdir
8575         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8576         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8577 }
8578 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8579
8580 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8582         [ "$RUNAS_ID" = "$UID" ] &&
8583                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8584         # Check that testing environment is properly set up. Skip if not
8585         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8586                 skip_env "User $RUNAS_ID does not exist - skipping"
8587
8588         touch $DIR/$tfile
8589         chmod 777 $DIR/$tfile
8590         chmod ug+s $DIR/$tfile
8591         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8592                 error "$RUNAS dd $DIR/$tfile failed"
8593         # See if we are still setuid/sgid
8594         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8595                 error "S/gid is not dropped on write"
8596         # Now test that MDS is updated too
8597         cancel_lru_locks mdc
8598         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8599                 error "S/gid is not dropped on MDS"
8600         rm -f $DIR/$tfile
8601 }
8602 run_test 72a "Test that remove suid works properly (bug5695) ===="
8603
8604 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8605         local perm
8606
8607         [ "$RUNAS_ID" = "$UID" ] &&
8608                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8609         [ "$RUNAS_ID" -eq 0 ] &&
8610                 skip_env "RUNAS_ID = 0 -- skipping"
8611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8612         # Check that testing environment is properly set up. Skip if not
8613         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8614                 skip_env "User $RUNAS_ID does not exist - skipping"
8615
8616         touch $DIR/${tfile}-f{g,u}
8617         test_mkdir $DIR/${tfile}-dg
8618         test_mkdir $DIR/${tfile}-du
8619         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8620         chmod g+s $DIR/${tfile}-{f,d}g
8621         chmod u+s $DIR/${tfile}-{f,d}u
8622         for perm in 777 2777 4777; do
8623                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8624                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8625                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8626                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8627         done
8628         true
8629 }
8630 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8631
8632 # bug 3462 - multiple simultaneous MDC requests
8633 test_73() {
8634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8635
8636         test_mkdir $DIR/d73-1
8637         test_mkdir $DIR/d73-2
8638         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8639         pid1=$!
8640
8641         lctl set_param fail_loc=0x80000129
8642         $MULTIOP $DIR/d73-1/f73-2 Oc &
8643         sleep 1
8644         lctl set_param fail_loc=0
8645
8646         $MULTIOP $DIR/d73-2/f73-3 Oc &
8647         pid3=$!
8648
8649         kill -USR1 $pid1
8650         wait $pid1 || return 1
8651
8652         sleep 25
8653
8654         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8655         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8656         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8657
8658         rm -rf $DIR/d73-*
8659 }
8660 run_test 73 "multiple MDC requests (should not deadlock)"
8661
8662 test_74a() { # bug 6149, 6184
8663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8664
8665         touch $DIR/f74a
8666         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8667         #
8668         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8669         # will spin in a tight reconnection loop
8670         $LCTL set_param fail_loc=0x8000030e
8671         # get any lock that won't be difficult - lookup works.
8672         ls $DIR/f74a
8673         $LCTL set_param fail_loc=0
8674         rm -f $DIR/f74a
8675         true
8676 }
8677 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8678
8679 test_74b() { # bug 13310
8680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8681
8682         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8683         #
8684         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8685         # will spin in a tight reconnection loop
8686         $LCTL set_param fail_loc=0x8000030e
8687         # get a "difficult" lock
8688         touch $DIR/f74b
8689         $LCTL set_param fail_loc=0
8690         rm -f $DIR/f74b
8691         true
8692 }
8693 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8694
8695 test_74c() {
8696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8697
8698         #define OBD_FAIL_LDLM_NEW_LOCK
8699         $LCTL set_param fail_loc=0x319
8700         touch $DIR/$tfile && error "touch successful"
8701         $LCTL set_param fail_loc=0
8702         true
8703 }
8704 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8705
8706 slab_lic=/sys/kernel/slab/lustre_inode_cache
8707 num_objects() {
8708         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8709         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8710                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8711 }
8712
8713 test_76a() { # Now for b=20433, added originally in b=1443
8714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8715
8716         cancel_lru_locks osc
8717         # there may be some slab objects cached per core
8718         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8719         local before=$(num_objects)
8720         local count=$((512 * cpus))
8721         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8722         local margin=$((count / 10))
8723         if [[ -f $slab_lic/aliases ]]; then
8724                 local aliases=$(cat $slab_lic/aliases)
8725                 (( aliases > 0 )) && margin=$((margin * aliases))
8726         fi
8727
8728         echo "before slab objects: $before"
8729         for i in $(seq $count); do
8730                 touch $DIR/$tfile
8731                 rm -f $DIR/$tfile
8732         done
8733         cancel_lru_locks osc
8734         local after=$(num_objects)
8735         echo "created: $count, after slab objects: $after"
8736         # shared slab counts are not very accurate, allow significant margin
8737         # the main goal is that the cache growth is not permanently > $count
8738         while (( after > before + margin )); do
8739                 sleep 1
8740                 after=$(num_objects)
8741                 wait=$((wait + 1))
8742                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8743                 if (( wait > 60 )); then
8744                         error "inode slab grew from $before+$margin to $after"
8745                 fi
8746         done
8747 }
8748 run_test 76a "confirm clients recycle inodes properly ===="
8749
8750 test_76b() {
8751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8752         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8753
8754         local count=512
8755         local before=$(num_objects)
8756
8757         for i in $(seq $count); do
8758                 mkdir $DIR/$tdir
8759                 rmdir $DIR/$tdir
8760         done
8761
8762         local after=$(num_objects)
8763         local wait=0
8764
8765         while (( after > before )); do
8766                 sleep 1
8767                 after=$(num_objects)
8768                 wait=$((wait + 1))
8769                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8770                 if (( wait > 60 )); then
8771                         error "inode slab grew from $before to $after"
8772                 fi
8773         done
8774
8775         echo "slab objects before: $before, after: $after"
8776 }
8777 run_test 76b "confirm clients recycle directory inodes properly ===="
8778
8779 export ORIG_CSUM=""
8780 set_checksums()
8781 {
8782         # Note: in sptlrpc modes which enable its own bulk checksum, the
8783         # original crc32_le bulk checksum will be automatically disabled,
8784         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8785         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8786         # In this case set_checksums() will not be no-op, because sptlrpc
8787         # bulk checksum will be enabled all through the test.
8788
8789         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8790         lctl set_param -n osc.*.checksums $1
8791         return 0
8792 }
8793
8794 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8795                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8796 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8797                              tr -d [] | head -n1)}
8798 set_checksum_type()
8799 {
8800         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8801         rc=$?
8802         log "set checksum type to $1, rc = $rc"
8803         return $rc
8804 }
8805
8806 get_osc_checksum_type()
8807 {
8808         # arugment 1: OST name, like OST0000
8809         ost=$1
8810         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8811                         sed 's/.*\[\(.*\)\].*/\1/g')
8812         rc=$?
8813         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8814         echo $checksum_type
8815 }
8816
8817 F77_TMP=$TMP/f77-temp
8818 F77SZ=8
8819 setup_f77() {
8820         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8821                 error "error writing to $F77_TMP"
8822 }
8823
8824 test_77a() { # bug 10889
8825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8826         $GSS && skip_env "could not run with gss"
8827
8828         [ ! -f $F77_TMP ] && setup_f77
8829         set_checksums 1
8830         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8831         set_checksums 0
8832         rm -f $DIR/$tfile
8833 }
8834 run_test 77a "normal checksum read/write operation"
8835
8836 test_77b() { # bug 10889
8837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8838         $GSS && skip_env "could not run with gss"
8839
8840         [ ! -f $F77_TMP ] && setup_f77
8841         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8842         $LCTL set_param fail_loc=0x80000409
8843         set_checksums 1
8844
8845         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8846                 error "dd error: $?"
8847         $LCTL set_param fail_loc=0
8848
8849         for algo in $CKSUM_TYPES; do
8850                 cancel_lru_locks osc
8851                 set_checksum_type $algo
8852                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8853                 $LCTL set_param fail_loc=0x80000408
8854                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8855                 $LCTL set_param fail_loc=0
8856         done
8857         set_checksums 0
8858         set_checksum_type $ORIG_CSUM_TYPE
8859         rm -f $DIR/$tfile
8860 }
8861 run_test 77b "checksum error on client write, read"
8862
8863 cleanup_77c() {
8864         trap 0
8865         set_checksums 0
8866         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8867         $check_ost &&
8868                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8869         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8870         $check_ost && [ -n "$ost_file_prefix" ] &&
8871                 do_facet ost1 rm -f ${ost_file_prefix}\*
8872 }
8873
8874 test_77c() {
8875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8876         $GSS && skip_env "could not run with gss"
8877         remote_ost_nodsh && skip "remote OST with nodsh"
8878
8879         local bad1
8880         local osc_file_prefix
8881         local osc_file
8882         local check_ost=false
8883         local ost_file_prefix
8884         local ost_file
8885         local orig_cksum
8886         local dump_cksum
8887         local fid
8888
8889         # ensure corruption will occur on first OSS/OST
8890         $LFS setstripe -i 0 $DIR/$tfile
8891
8892         [ ! -f $F77_TMP ] && setup_f77
8893         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8894                 error "dd write error: $?"
8895         fid=$($LFS path2fid $DIR/$tfile)
8896
8897         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8898         then
8899                 check_ost=true
8900                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8901                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8902         else
8903                 echo "OSS do not support bulk pages dump upon error"
8904         fi
8905
8906         osc_file_prefix=$($LCTL get_param -n debug_path)
8907         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8908
8909         trap cleanup_77c EXIT
8910
8911         set_checksums 1
8912         # enable bulk pages dump upon error on Client
8913         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8914         # enable bulk pages dump upon error on OSS
8915         $check_ost &&
8916                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8917
8918         # flush Client cache to allow next read to reach OSS
8919         cancel_lru_locks osc
8920
8921         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8922         $LCTL set_param fail_loc=0x80000408
8923         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8924         $LCTL set_param fail_loc=0
8925
8926         rm -f $DIR/$tfile
8927
8928         # check cksum dump on Client
8929         osc_file=$(ls ${osc_file_prefix}*)
8930         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8931         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8932         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8933         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8934         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8935                      cksum)
8936         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8937         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8938                 error "dump content does not match on Client"
8939
8940         $check_ost || skip "No need to check cksum dump on OSS"
8941
8942         # check cksum dump on OSS
8943         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8944         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8945         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8946         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8947         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8948                 error "dump content does not match on OSS"
8949
8950         cleanup_77c
8951 }
8952 run_test 77c "checksum error on client read with debug"
8953
8954 test_77d() { # bug 10889
8955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8956         $GSS && skip_env "could not run with gss"
8957
8958         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8959         $LCTL set_param fail_loc=0x80000409
8960         set_checksums 1
8961         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8962                 error "direct write: rc=$?"
8963         $LCTL set_param fail_loc=0
8964         set_checksums 0
8965
8966         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8967         $LCTL set_param fail_loc=0x80000408
8968         set_checksums 1
8969         cancel_lru_locks osc
8970         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8971                 error "direct read: rc=$?"
8972         $LCTL set_param fail_loc=0
8973         set_checksums 0
8974 }
8975 run_test 77d "checksum error on OST direct write, read"
8976
8977 test_77f() { # bug 10889
8978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8979         $GSS && skip_env "could not run with gss"
8980
8981         set_checksums 1
8982         for algo in $CKSUM_TYPES; do
8983                 cancel_lru_locks osc
8984                 set_checksum_type $algo
8985                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8986                 $LCTL set_param fail_loc=0x409
8987                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8988                         error "direct write succeeded"
8989                 $LCTL set_param fail_loc=0
8990         done
8991         set_checksum_type $ORIG_CSUM_TYPE
8992         set_checksums 0
8993 }
8994 run_test 77f "repeat checksum error on write (expect error)"
8995
8996 test_77g() { # bug 10889
8997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8998         $GSS && skip_env "could not run with gss"
8999         remote_ost_nodsh && skip "remote OST with nodsh"
9000
9001         [ ! -f $F77_TMP ] && setup_f77
9002
9003         local file=$DIR/$tfile
9004         stack_trap "rm -f $file" EXIT
9005
9006         $LFS setstripe -c 1 -i 0 $file
9007         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9008         do_facet ost1 lctl set_param fail_loc=0x8000021a
9009         set_checksums 1
9010         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9011                 error "write error: rc=$?"
9012         do_facet ost1 lctl set_param fail_loc=0
9013         set_checksums 0
9014
9015         cancel_lru_locks osc
9016         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9017         do_facet ost1 lctl set_param fail_loc=0x8000021b
9018         set_checksums 1
9019         cmp $F77_TMP $file || error "file compare failed"
9020         do_facet ost1 lctl set_param fail_loc=0
9021         set_checksums 0
9022 }
9023 run_test 77g "checksum error on OST write, read"
9024
9025 test_77k() { # LU-10906
9026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9027         $GSS && skip_env "could not run with gss"
9028
9029         local cksum_param="osc.$FSNAME*.checksums"
9030         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9031         local checksum
9032         local i
9033
9034         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9035         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9036         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9037
9038         for i in 0 1; do
9039                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9040                         error "failed to set checksum=$i on MGS"
9041                 wait_update $HOSTNAME "$get_checksum" $i
9042                 #remount
9043                 echo "remount client, checksum should be $i"
9044                 remount_client $MOUNT || error "failed to remount client"
9045                 checksum=$(eval $get_checksum)
9046                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9047         done
9048         # remove persistent param to avoid races with checksum mountopt below
9049         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9050                 error "failed to delete checksum on MGS"
9051
9052         for opt in "checksum" "nochecksum"; do
9053                 #remount with mount option
9054                 echo "remount client with option $opt, checksum should be $i"
9055                 umount_client $MOUNT || error "failed to umount client"
9056                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9057                         error "failed to mount client with option '$opt'"
9058                 checksum=$(eval $get_checksum)
9059                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9060                 i=$((i - 1))
9061         done
9062
9063         remount_client $MOUNT || error "failed to remount client"
9064 }
9065 run_test 77k "enable/disable checksum correctly"
9066
9067 test_77l() {
9068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9069         $GSS && skip_env "could not run with gss"
9070
9071         set_checksums 1
9072         stack_trap "set_checksums $ORIG_CSUM" EXIT
9073         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9074
9075         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9076
9077         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9078         for algo in $CKSUM_TYPES; do
9079                 set_checksum_type $algo || error "fail to set checksum type $algo"
9080                 osc_algo=$(get_osc_checksum_type OST0000)
9081                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9082
9083                 # no locks, no reqs to let the connection idle
9084                 cancel_lru_locks osc
9085                 lru_resize_disable osc
9086                 wait_osc_import_state client ost1 IDLE
9087
9088                 # ensure ost1 is connected
9089                 stat $DIR/$tfile >/dev/null || error "can't stat"
9090                 wait_osc_import_state client ost1 FULL
9091
9092                 osc_algo=$(get_osc_checksum_type OST0000)
9093                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9094         done
9095         return 0
9096 }
9097 run_test 77l "preferred checksum type is remembered after reconnected"
9098
9099 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9100 rm -f $F77_TMP
9101 unset F77_TMP
9102
9103 cleanup_test_78() {
9104         trap 0
9105         rm -f $DIR/$tfile
9106 }
9107
9108 test_78() { # bug 10901
9109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9110         remote_ost || skip_env "local OST"
9111
9112         NSEQ=5
9113         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9114         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9115         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9116         echo "MemTotal: $MEMTOTAL"
9117
9118         # reserve 256MB of memory for the kernel and other running processes,
9119         # and then take 1/2 of the remaining memory for the read/write buffers.
9120         if [ $MEMTOTAL -gt 512 ] ;then
9121                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9122         else
9123                 # for those poor memory-starved high-end clusters...
9124                 MEMTOTAL=$((MEMTOTAL / 2))
9125         fi
9126         echo "Mem to use for directio: $MEMTOTAL"
9127
9128         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9129         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9130         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9131         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9132                 head -n1)
9133         echo "Smallest OST: $SMALLESTOST"
9134         [[ $SMALLESTOST -lt 10240 ]] &&
9135                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9136
9137         trap cleanup_test_78 EXIT
9138
9139         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9140                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9141
9142         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9143         echo "File size: $F78SIZE"
9144         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9145         for i in $(seq 1 $NSEQ); do
9146                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9147                 echo directIO rdwr round $i of $NSEQ
9148                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9149         done
9150
9151         cleanup_test_78
9152 }
9153 run_test 78 "handle large O_DIRECT writes correctly ============"
9154
9155 test_79() { # bug 12743
9156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9157
9158         wait_delete_completed
9159
9160         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9161         BKFREE=$(calc_osc_kbytes kbytesfree)
9162         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9163
9164         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9165         DFTOTAL=`echo $STRING | cut -d, -f1`
9166         DFUSED=`echo $STRING  | cut -d, -f2`
9167         DFAVAIL=`echo $STRING | cut -d, -f3`
9168         DFFREE=$(($DFTOTAL - $DFUSED))
9169
9170         ALLOWANCE=$((64 * $OSTCOUNT))
9171
9172         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9173            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9174                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9175         fi
9176         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9177            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9178                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9179         fi
9180         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9181            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9182                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9183         fi
9184 }
9185 run_test 79 "df report consistency check ======================="
9186
9187 test_80() { # bug 10718
9188         remote_ost_nodsh && skip "remote OST with nodsh"
9189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9190
9191         # relax strong synchronous semantics for slow backends like ZFS
9192         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9193                 local soc="obdfilter.*.sync_lock_cancel"
9194                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9195
9196                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9197                 if [ -z "$save" ]; then
9198                         soc="obdfilter.*.sync_on_lock_cancel"
9199                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9200                 fi
9201
9202                 if [ "$save" != "never" ]; then
9203                         local hosts=$(comma_list $(osts_nodes))
9204
9205                         do_nodes $hosts $LCTL set_param $soc=never
9206                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9207                 fi
9208         fi
9209
9210         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9211         sync; sleep 1; sync
9212         local before=$(date +%s)
9213         cancel_lru_locks osc
9214         local after=$(date +%s)
9215         local diff=$((after - before))
9216         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9217
9218         rm -f $DIR/$tfile
9219 }
9220 run_test 80 "Page eviction is equally fast at high offsets too"
9221
9222 test_81a() { # LU-456
9223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9224         remote_ost_nodsh && skip "remote OST with nodsh"
9225
9226         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9227         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9228         do_facet ost1 lctl set_param fail_loc=0x80000228
9229
9230         # write should trigger a retry and success
9231         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9232         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9233         RC=$?
9234         if [ $RC -ne 0 ] ; then
9235                 error "write should success, but failed for $RC"
9236         fi
9237 }
9238 run_test 81a "OST should retry write when get -ENOSPC ==============="
9239
9240 test_81b() { # LU-456
9241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9242         remote_ost_nodsh && skip "remote OST with nodsh"
9243
9244         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9245         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9246         do_facet ost1 lctl set_param fail_loc=0x228
9247
9248         # write should retry several times and return -ENOSPC finally
9249         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9250         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9251         RC=$?
9252         ENOSPC=28
9253         if [ $RC -ne $ENOSPC ] ; then
9254                 error "dd should fail for -ENOSPC, but succeed."
9255         fi
9256 }
9257 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9258
9259 test_99() {
9260         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9261
9262         test_mkdir $DIR/$tdir.cvsroot
9263         chown $RUNAS_ID $DIR/$tdir.cvsroot
9264
9265         cd $TMP
9266         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9267
9268         cd /etc/init.d
9269         # some versions of cvs import exit(1) when asked to import links or
9270         # files they can't read.  ignore those files.
9271         local toignore=$(find . -type l -printf '-I %f\n' -o \
9272                          ! -perm /4 -printf '-I %f\n')
9273         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9274                 $tdir.reposname vtag rtag
9275
9276         cd $DIR
9277         test_mkdir $DIR/$tdir.reposname
9278         chown $RUNAS_ID $DIR/$tdir.reposname
9279         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9280
9281         cd $DIR/$tdir.reposname
9282         $RUNAS touch foo99
9283         $RUNAS cvs add -m 'addmsg' foo99
9284         $RUNAS cvs update
9285         $RUNAS cvs commit -m 'nomsg' foo99
9286         rm -fr $DIR/$tdir.cvsroot
9287 }
9288 run_test 99 "cvs strange file/directory operations"
9289
9290 test_100() {
9291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9292         [[ "$NETTYPE" =~ tcp ]] ||
9293                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9294         remote_ost_nodsh && skip "remote OST with nodsh"
9295         remote_mds_nodsh && skip "remote MDS with nodsh"
9296         remote_servers ||
9297                 skip "useless for local single node setup"
9298
9299         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9300                 [ "$PROT" != "tcp" ] && continue
9301                 RPORT=$(echo $REMOTE | cut -d: -f2)
9302                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9303
9304                 rc=0
9305                 LPORT=`echo $LOCAL | cut -d: -f2`
9306                 if [ $LPORT -ge 1024 ]; then
9307                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9308                         netstat -tna
9309                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9310                 fi
9311         done
9312         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9313 }
9314 run_test 100 "check local port using privileged port ==========="
9315
9316 function get_named_value()
9317 {
9318     local tag
9319
9320     tag=$1
9321     while read ;do
9322         line=$REPLY
9323         case $line in
9324         $tag*)
9325             echo $line | sed "s/^$tag[ ]*//"
9326             break
9327             ;;
9328         esac
9329     done
9330 }
9331
9332 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9333                    awk '/^max_cached_mb/ { print $2 }')
9334
9335 cleanup_101a() {
9336         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9337         trap 0
9338 }
9339
9340 test_101a() {
9341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9342
9343         local s
9344         local discard
9345         local nreads=10000
9346         local cache_limit=32
9347
9348         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9349         trap cleanup_101a EXIT
9350         $LCTL set_param -n llite.*.read_ahead_stats 0
9351         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9352
9353         #
9354         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9355         #
9356         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9357         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9358
9359         discard=0
9360         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9361                 get_named_value 'read but discarded' | cut -d" " -f1); do
9362                         discard=$(($discard + $s))
9363         done
9364         cleanup_101a
9365
9366         $LCTL get_param osc.*-osc*.rpc_stats
9367         $LCTL get_param llite.*.read_ahead_stats
9368
9369         # Discard is generally zero, but sometimes a few random reads line up
9370         # and trigger larger readahead, which is wasted & leads to discards.
9371         if [[ $(($discard)) -gt $nreads ]]; then
9372                 error "too many ($discard) discarded pages"
9373         fi
9374         rm -f $DIR/$tfile || true
9375 }
9376 run_test 101a "check read-ahead for random reads"
9377
9378 setup_test101bc() {
9379         test_mkdir $DIR/$tdir
9380         local ssize=$1
9381         local FILE_LENGTH=$2
9382         STRIPE_OFFSET=0
9383
9384         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9385
9386         local list=$(comma_list $(osts_nodes))
9387         set_osd_param $list '' read_cache_enable 0
9388         set_osd_param $list '' writethrough_cache_enable 0
9389
9390         trap cleanup_test101bc EXIT
9391         # prepare the read-ahead file
9392         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9393
9394         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9395                                 count=$FILE_SIZE_MB 2> /dev/null
9396
9397 }
9398
9399 cleanup_test101bc() {
9400         trap 0
9401         rm -rf $DIR/$tdir
9402         rm -f $DIR/$tfile
9403
9404         local list=$(comma_list $(osts_nodes))
9405         set_osd_param $list '' read_cache_enable 1
9406         set_osd_param $list '' writethrough_cache_enable 1
9407 }
9408
9409 calc_total() {
9410         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9411 }
9412
9413 ra_check_101() {
9414         local READ_SIZE=$1
9415         local STRIPE_SIZE=$2
9416         local FILE_LENGTH=$3
9417         local RA_INC=1048576
9418         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9419         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9420                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9421         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9422                         get_named_value 'read but discarded' |
9423                         cut -d" " -f1 | calc_total)
9424         if [[ $DISCARD -gt $discard_limit ]]; then
9425                 $LCTL get_param llite.*.read_ahead_stats
9426                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9427         else
9428                 echo "Read-ahead success for size ${READ_SIZE}"
9429         fi
9430 }
9431
9432 test_101b() {
9433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9434         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9435
9436         local STRIPE_SIZE=1048576
9437         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9438
9439         if [ $SLOW == "yes" ]; then
9440                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9441         else
9442                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9443         fi
9444
9445         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9446
9447         # prepare the read-ahead file
9448         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9449         cancel_lru_locks osc
9450         for BIDX in 2 4 8 16 32 64 128 256
9451         do
9452                 local BSIZE=$((BIDX*4096))
9453                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9454                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9455                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9456                 $LCTL set_param -n llite.*.read_ahead_stats 0
9457                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9458                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9459                 cancel_lru_locks osc
9460                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9461         done
9462         cleanup_test101bc
9463         true
9464 }
9465 run_test 101b "check stride-io mode read-ahead ================="
9466
9467 test_101c() {
9468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9469
9470         local STRIPE_SIZE=1048576
9471         local FILE_LENGTH=$((STRIPE_SIZE*100))
9472         local nreads=10000
9473         local rsize=65536
9474         local osc_rpc_stats
9475
9476         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9477
9478         cancel_lru_locks osc
9479         $LCTL set_param osc.*.rpc_stats 0
9480         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9481         $LCTL get_param osc.*.rpc_stats
9482         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9483                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9484                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9485                 local size
9486
9487                 if [ $lines -le 20 ]; then
9488                         echo "continue debug"
9489                         continue
9490                 fi
9491                 for size in 1 2 4 8; do
9492                         local rpc=$(echo "$stats" |
9493                                     awk '($1 == "'$size':") {print $2; exit; }')
9494                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9495                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9496                 done
9497                 echo "$osc_rpc_stats check passed!"
9498         done
9499         cleanup_test101bc
9500         true
9501 }
9502 run_test 101c "check stripe_size aligned read-ahead ================="
9503
9504 test_101d() {
9505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9506
9507         local file=$DIR/$tfile
9508         local sz_MB=${FILESIZE_101d:-80}
9509         local ra_MB=${READAHEAD_MB:-40}
9510
9511         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9512         [ $free_MB -lt $sz_MB ] &&
9513                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9514
9515         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9516         $LFS setstripe -c -1 $file || error "setstripe failed"
9517
9518         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9519         echo Cancel LRU locks on lustre client to flush the client cache
9520         cancel_lru_locks osc
9521
9522         echo Disable read-ahead
9523         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9524         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9525         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9526         $LCTL get_param -n llite.*.max_read_ahead_mb
9527
9528         echo "Reading the test file $file with read-ahead disabled"
9529         local sz_KB=$((sz_MB * 1024 / 4))
9530         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9531         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9532         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9533                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9534
9535         echo "Cancel LRU locks on lustre client to flush the client cache"
9536         cancel_lru_locks osc
9537         echo Enable read-ahead with ${ra_MB}MB
9538         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9539
9540         echo "Reading the test file $file with read-ahead enabled"
9541         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9542                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9543
9544         echo "read-ahead disabled time read $raOFF"
9545         echo "read-ahead enabled time read $raON"
9546
9547         rm -f $file
9548         wait_delete_completed
9549
9550         # use awk for this check instead of bash because it handles decimals
9551         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9552                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9553 }
9554 run_test 101d "file read with and without read-ahead enabled"
9555
9556 test_101e() {
9557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9558
9559         local file=$DIR/$tfile
9560         local size_KB=500  #KB
9561         local count=100
9562         local bsize=1024
9563
9564         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9565         local need_KB=$((count * size_KB))
9566         [[ $free_KB -le $need_KB ]] &&
9567                 skip_env "Need free space $need_KB, have $free_KB"
9568
9569         echo "Creating $count ${size_KB}K test files"
9570         for ((i = 0; i < $count; i++)); do
9571                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9572         done
9573
9574         echo "Cancel LRU locks on lustre client to flush the client cache"
9575         cancel_lru_locks $OSC
9576
9577         echo "Reset readahead stats"
9578         $LCTL set_param -n llite.*.read_ahead_stats 0
9579
9580         for ((i = 0; i < $count; i++)); do
9581                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9582         done
9583
9584         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9585                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9586
9587         for ((i = 0; i < $count; i++)); do
9588                 rm -rf $file.$i 2>/dev/null
9589         done
9590
9591         #10000 means 20% reads are missing in readahead
9592         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9593 }
9594 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9595
9596 test_101f() {
9597         which iozone || skip_env "no iozone installed"
9598
9599         local old_debug=$($LCTL get_param debug)
9600         old_debug=${old_debug#*=}
9601         $LCTL set_param debug="reada mmap"
9602
9603         # create a test file
9604         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9605
9606         echo Cancel LRU locks on lustre client to flush the client cache
9607         cancel_lru_locks osc
9608
9609         echo Reset readahead stats
9610         $LCTL set_param -n llite.*.read_ahead_stats 0
9611
9612         echo mmap read the file with small block size
9613         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9614                 > /dev/null 2>&1
9615
9616         echo checking missing pages
9617         $LCTL get_param llite.*.read_ahead_stats
9618         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9619                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9620
9621         $LCTL set_param debug="$old_debug"
9622         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9623         rm -f $DIR/$tfile
9624 }
9625 run_test 101f "check mmap read performance"
9626
9627 test_101g_brw_size_test() {
9628         local mb=$1
9629         local pages=$((mb * 1048576 / PAGE_SIZE))
9630         local file=$DIR/$tfile
9631
9632         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9633                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9634         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9635                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9636                         return 2
9637         done
9638
9639         stack_trap "rm -f $file" EXIT
9640         $LCTL set_param -n osc.*.rpc_stats=0
9641
9642         # 10 RPCs should be enough for the test
9643         local count=10
9644         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9645                 { error "dd write ${mb} MB blocks failed"; return 3; }
9646         cancel_lru_locks osc
9647         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9648                 { error "dd write ${mb} MB blocks failed"; return 4; }
9649
9650         # calculate number of full-sized read and write RPCs
9651         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9652                 sed -n '/pages per rpc/,/^$/p' |
9653                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9654                 END { print reads,writes }'))
9655         # allow one extra full-sized read RPC for async readahead
9656         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9657                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9658         [[ ${rpcs[1]} == $count ]] ||
9659                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9660 }
9661
9662 test_101g() {
9663         remote_ost_nodsh && skip "remote OST with nodsh"
9664
9665         local rpcs
9666         local osts=$(get_facets OST)
9667         local list=$(comma_list $(osts_nodes))
9668         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9669         local brw_size="obdfilter.*.brw_size"
9670
9671         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9672
9673         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9674
9675         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9676                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9677                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9678            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9679                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9680                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9681
9682                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9683                         suffix="M"
9684
9685                 if [[ $orig_mb -lt 16 ]]; then
9686                         save_lustre_params $osts "$brw_size" > $p
9687                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9688                                 error "set 16MB RPC size failed"
9689
9690                         echo "remount client to enable new RPC size"
9691                         remount_client $MOUNT || error "remount_client failed"
9692                 fi
9693
9694                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9695                 # should be able to set brw_size=12, but no rpc_stats for that
9696                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9697         fi
9698
9699         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9700
9701         if [[ $orig_mb -lt 16 ]]; then
9702                 restore_lustre_params < $p
9703                 remount_client $MOUNT || error "remount_client restore failed"
9704         fi
9705
9706         rm -f $p $DIR/$tfile
9707 }
9708 run_test 101g "Big bulk(4/16 MiB) readahead"
9709
9710 test_101h() {
9711         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9712
9713         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9714                 error "dd 70M file failed"
9715         echo Cancel LRU locks on lustre client to flush the client cache
9716         cancel_lru_locks osc
9717
9718         echo "Reset readahead stats"
9719         $LCTL set_param -n llite.*.read_ahead_stats 0
9720
9721         echo "Read 10M of data but cross 64M bundary"
9722         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9723         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9724                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9725         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9726         rm -f $p $DIR/$tfile
9727 }
9728 run_test 101h "Readahead should cover current read window"
9729
9730 test_101i() {
9731         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9732                 error "dd 10M file failed"
9733
9734         local max_per_file_mb=$($LCTL get_param -n \
9735                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9736         cancel_lru_locks osc
9737         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9738         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9739                 error "set max_read_ahead_per_file_mb to 1 failed"
9740
9741         echo "Reset readahead stats"
9742         $LCTL set_param llite.*.read_ahead_stats=0
9743
9744         dd if=$DIR/$tfile of=/dev/null bs=2M
9745
9746         $LCTL get_param llite.*.read_ahead_stats
9747         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9748                      awk '/misses/ { print $2 }')
9749         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9750         rm -f $DIR/$tfile
9751 }
9752 run_test 101i "allow current readahead to exceed reservation"
9753
9754 test_101j() {
9755         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9756                 error "setstripe $DIR/$tfile failed"
9757         local file_size=$((1048576 * 16))
9758         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9759         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9760
9761         echo Disable read-ahead
9762         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9763
9764         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9765         for blk in $PAGE_SIZE 1048576 $file_size; do
9766                 cancel_lru_locks osc
9767                 echo "Reset readahead stats"
9768                 $LCTL set_param -n llite.*.read_ahead_stats=0
9769                 local count=$(($file_size / $blk))
9770                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9771                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9772                              get_named_value 'failed to fast read' |
9773                              cut -d" " -f1 | calc_total)
9774                 $LCTL get_param -n llite.*.read_ahead_stats
9775                 [ $miss -eq $count ] || error "expected $count got $miss"
9776         done
9777
9778         rm -f $p $DIR/$tfile
9779 }
9780 run_test 101j "A complete read block should be submitted when no RA"
9781
9782 setup_test102() {
9783         test_mkdir $DIR/$tdir
9784         chown $RUNAS_ID $DIR/$tdir
9785         STRIPE_SIZE=65536
9786         STRIPE_OFFSET=1
9787         STRIPE_COUNT=$OSTCOUNT
9788         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9789
9790         trap cleanup_test102 EXIT
9791         cd $DIR
9792         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9793         cd $DIR/$tdir
9794         for num in 1 2 3 4; do
9795                 for count in $(seq 1 $STRIPE_COUNT); do
9796                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9797                                 local size=`expr $STRIPE_SIZE \* $num`
9798                                 local file=file"$num-$idx-$count"
9799                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9800                         done
9801                 done
9802         done
9803
9804         cd $DIR
9805         $1 tar cf $TMP/f102.tar $tdir --xattrs
9806 }
9807
9808 cleanup_test102() {
9809         trap 0
9810         rm -f $TMP/f102.tar
9811         rm -rf $DIR/d0.sanity/d102
9812 }
9813
9814 test_102a() {
9815         [ "$UID" != 0 ] && skip "must run as root"
9816         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9817                 skip_env "must have user_xattr"
9818
9819         [ -z "$(which setfattr 2>/dev/null)" ] &&
9820                 skip_env "could not find setfattr"
9821
9822         local testfile=$DIR/$tfile
9823
9824         touch $testfile
9825         echo "set/get xattr..."
9826         setfattr -n trusted.name1 -v value1 $testfile ||
9827                 error "setfattr -n trusted.name1=value1 $testfile failed"
9828         getfattr -n trusted.name1 $testfile 2> /dev/null |
9829           grep "trusted.name1=.value1" ||
9830                 error "$testfile missing trusted.name1=value1"
9831
9832         setfattr -n user.author1 -v author1 $testfile ||
9833                 error "setfattr -n user.author1=author1 $testfile failed"
9834         getfattr -n user.author1 $testfile 2> /dev/null |
9835           grep "user.author1=.author1" ||
9836                 error "$testfile missing trusted.author1=author1"
9837
9838         echo "listxattr..."
9839         setfattr -n trusted.name2 -v value2 $testfile ||
9840                 error "$testfile unable to set trusted.name2"
9841         setfattr -n trusted.name3 -v value3 $testfile ||
9842                 error "$testfile unable to set trusted.name3"
9843         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9844             grep "trusted.name" | wc -l) -eq 3 ] ||
9845                 error "$testfile missing 3 trusted.name xattrs"
9846
9847         setfattr -n user.author2 -v author2 $testfile ||
9848                 error "$testfile unable to set user.author2"
9849         setfattr -n user.author3 -v author3 $testfile ||
9850                 error "$testfile unable to set user.author3"
9851         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9852             grep "user.author" | wc -l) -eq 3 ] ||
9853                 error "$testfile missing 3 user.author xattrs"
9854
9855         echo "remove xattr..."
9856         setfattr -x trusted.name1 $testfile ||
9857                 error "$testfile error deleting trusted.name1"
9858         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9859                 error "$testfile did not delete trusted.name1 xattr"
9860
9861         setfattr -x user.author1 $testfile ||
9862                 error "$testfile error deleting user.author1"
9863         echo "set lustre special xattr ..."
9864         $LFS setstripe -c1 $testfile
9865         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9866                 awk -F "=" '/trusted.lov/ { print $2 }' )
9867         setfattr -n "trusted.lov" -v $lovea $testfile ||
9868                 error "$testfile doesn't ignore setting trusted.lov again"
9869         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9870                 error "$testfile allow setting invalid trusted.lov"
9871         rm -f $testfile
9872 }
9873 run_test 102a "user xattr test =================================="
9874
9875 check_102b_layout() {
9876         local layout="$*"
9877         local testfile=$DIR/$tfile
9878
9879         echo "test layout '$layout'"
9880         $LFS setstripe $layout $testfile || error "setstripe failed"
9881         $LFS getstripe -y $testfile
9882
9883         echo "get/set/list trusted.lov xattr ..." # b=10930
9884         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9885         [[ "$value" =~ "trusted.lov" ]] ||
9886                 error "can't get trusted.lov from $testfile"
9887         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9888                 error "getstripe failed"
9889
9890         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9891
9892         value=$(cut -d= -f2 <<<$value)
9893         # LU-13168: truncated xattr should fail if short lov_user_md header
9894         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9895                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9896         for len in $lens; do
9897                 echo "setfattr $len $testfile.2"
9898                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9899                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9900         done
9901         local stripe_size=$($LFS getstripe -S $testfile.2)
9902         local stripe_count=$($LFS getstripe -c $testfile.2)
9903         [[ $stripe_size -eq 65536 ]] ||
9904                 error "stripe size $stripe_size != 65536"
9905         [[ $stripe_count -eq $stripe_count_orig ]] ||
9906                 error "stripe count $stripe_count != $stripe_count_orig"
9907         rm $testfile $testfile.2
9908 }
9909
9910 test_102b() {
9911         [ -z "$(which setfattr 2>/dev/null)" ] &&
9912                 skip_env "could not find setfattr"
9913         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9914
9915         # check plain layout
9916         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9917
9918         # and also check composite layout
9919         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9920
9921 }
9922 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9923
9924 test_102c() {
9925         [ -z "$(which setfattr 2>/dev/null)" ] &&
9926                 skip_env "could not find setfattr"
9927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9928
9929         # b10930: get/set/list lustre.lov xattr
9930         echo "get/set/list lustre.lov xattr ..."
9931         test_mkdir $DIR/$tdir
9932         chown $RUNAS_ID $DIR/$tdir
9933         local testfile=$DIR/$tdir/$tfile
9934         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9935                 error "setstripe failed"
9936         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9937                 error "getstripe failed"
9938         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9939         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9940
9941         local testfile2=${testfile}2
9942         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9943                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9944
9945         $RUNAS $MCREATE $testfile2
9946         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9947         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9948         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9949         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9950         [ $stripe_count -eq $STRIPECOUNT ] ||
9951                 error "stripe count $stripe_count != $STRIPECOUNT"
9952 }
9953 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9954
9955 compare_stripe_info1() {
9956         local stripe_index_all_zero=true
9957
9958         for num in 1 2 3 4; do
9959                 for count in $(seq 1 $STRIPE_COUNT); do
9960                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9961                                 local size=$((STRIPE_SIZE * num))
9962                                 local file=file"$num-$offset-$count"
9963                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9964                                 [[ $stripe_size -ne $size ]] &&
9965                                     error "$file: size $stripe_size != $size"
9966                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9967                                 # allow fewer stripes to be created, ORI-601
9968                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9969                                     error "$file: count $stripe_count != $count"
9970                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9971                                 [[ $stripe_index -ne 0 ]] &&
9972                                         stripe_index_all_zero=false
9973                         done
9974                 done
9975         done
9976         $stripe_index_all_zero &&
9977                 error "all files are being extracted starting from OST index 0"
9978         return 0
9979 }
9980
9981 have_xattrs_include() {
9982         tar --help | grep -q xattrs-include &&
9983                 echo --xattrs-include="lustre.*"
9984 }
9985
9986 test_102d() {
9987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9988         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9989
9990         XINC=$(have_xattrs_include)
9991         setup_test102
9992         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9993         cd $DIR/$tdir/$tdir
9994         compare_stripe_info1
9995 }
9996 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9997
9998 test_102f() {
9999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10000         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10001
10002         XINC=$(have_xattrs_include)
10003         setup_test102
10004         test_mkdir $DIR/$tdir.restore
10005         cd $DIR
10006         tar cf - --xattrs $tdir | tar xf - \
10007                 -C $DIR/$tdir.restore --xattrs $XINC
10008         cd $DIR/$tdir.restore/$tdir
10009         compare_stripe_info1
10010 }
10011 run_test 102f "tar copy files, not keep osts"
10012
10013 grow_xattr() {
10014         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10015                 skip "must have user_xattr"
10016         [ -z "$(which setfattr 2>/dev/null)" ] &&
10017                 skip_env "could not find setfattr"
10018         [ -z "$(which getfattr 2>/dev/null)" ] &&
10019                 skip_env "could not find getfattr"
10020
10021         local xsize=${1:-1024}  # in bytes
10022         local file=$DIR/$tfile
10023         local value="$(generate_string $xsize)"
10024         local xbig=trusted.big
10025         local toobig=$2
10026
10027         touch $file
10028         log "save $xbig on $file"
10029         if [ -z "$toobig" ]
10030         then
10031                 setfattr -n $xbig -v $value $file ||
10032                         error "saving $xbig on $file failed"
10033         else
10034                 setfattr -n $xbig -v $value $file &&
10035                         error "saving $xbig on $file succeeded"
10036                 return 0
10037         fi
10038
10039         local orig=$(get_xattr_value $xbig $file)
10040         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10041
10042         local xsml=trusted.sml
10043         log "save $xsml on $file"
10044         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10045
10046         local new=$(get_xattr_value $xbig $file)
10047         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10048
10049         log "grow $xsml on $file"
10050         setfattr -n $xsml -v "$value" $file ||
10051                 error "growing $xsml on $file failed"
10052
10053         new=$(get_xattr_value $xbig $file)
10054         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10055         log "$xbig still valid after growing $xsml"
10056
10057         rm -f $file
10058 }
10059
10060 test_102h() { # bug 15777
10061         grow_xattr 1024
10062 }
10063 run_test 102h "grow xattr from inside inode to external block"
10064
10065 test_102ha() {
10066         large_xattr_enabled || skip_env "ea_inode feature disabled"
10067
10068         echo "setting xattr of max xattr size: $(max_xattr_size)"
10069         grow_xattr $(max_xattr_size)
10070
10071         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10072         echo "This should fail:"
10073         grow_xattr $(($(max_xattr_size) + 10)) 1
10074 }
10075 run_test 102ha "grow xattr from inside inode to external inode"
10076
10077 test_102i() { # bug 17038
10078         [ -z "$(which getfattr 2>/dev/null)" ] &&
10079                 skip "could not find getfattr"
10080
10081         touch $DIR/$tfile
10082         ln -s $DIR/$tfile $DIR/${tfile}link
10083         getfattr -n trusted.lov $DIR/$tfile ||
10084                 error "lgetxattr on $DIR/$tfile failed"
10085         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10086                 grep -i "no such attr" ||
10087                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10088         rm -f $DIR/$tfile $DIR/${tfile}link
10089 }
10090 run_test 102i "lgetxattr test on symbolic link ============"
10091
10092 test_102j() {
10093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10094         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10095
10096         XINC=$(have_xattrs_include)
10097         setup_test102 "$RUNAS"
10098         chown $RUNAS_ID $DIR/$tdir
10099         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10100         cd $DIR/$tdir/$tdir
10101         compare_stripe_info1 "$RUNAS"
10102 }
10103 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10104
10105 test_102k() {
10106         [ -z "$(which setfattr 2>/dev/null)" ] &&
10107                 skip "could not find setfattr"
10108
10109         touch $DIR/$tfile
10110         # b22187 just check that does not crash for regular file.
10111         setfattr -n trusted.lov $DIR/$tfile
10112         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10113         local test_kdir=$DIR/$tdir
10114         test_mkdir $test_kdir
10115         local default_size=$($LFS getstripe -S $test_kdir)
10116         local default_count=$($LFS getstripe -c $test_kdir)
10117         local default_offset=$($LFS getstripe -i $test_kdir)
10118         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10119                 error 'dir setstripe failed'
10120         setfattr -n trusted.lov $test_kdir
10121         local stripe_size=$($LFS getstripe -S $test_kdir)
10122         local stripe_count=$($LFS getstripe -c $test_kdir)
10123         local stripe_offset=$($LFS getstripe -i $test_kdir)
10124         [ $stripe_size -eq $default_size ] ||
10125                 error "stripe size $stripe_size != $default_size"
10126         [ $stripe_count -eq $default_count ] ||
10127                 error "stripe count $stripe_count != $default_count"
10128         [ $stripe_offset -eq $default_offset ] ||
10129                 error "stripe offset $stripe_offset != $default_offset"
10130         rm -rf $DIR/$tfile $test_kdir
10131 }
10132 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10133
10134 test_102l() {
10135         [ -z "$(which getfattr 2>/dev/null)" ] &&
10136                 skip "could not find getfattr"
10137
10138         # LU-532 trusted. xattr is invisible to non-root
10139         local testfile=$DIR/$tfile
10140
10141         touch $testfile
10142
10143         echo "listxattr as user..."
10144         chown $RUNAS_ID $testfile
10145         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10146             grep -q "trusted" &&
10147                 error "$testfile trusted xattrs are user visible"
10148
10149         return 0;
10150 }
10151 run_test 102l "listxattr size test =================================="
10152
10153 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10154         local path=$DIR/$tfile
10155         touch $path
10156
10157         listxattr_size_check $path || error "listattr_size_check $path failed"
10158 }
10159 run_test 102m "Ensure listxattr fails on small bufffer ========"
10160
10161 cleanup_test102
10162
10163 getxattr() { # getxattr path name
10164         # Return the base64 encoding of the value of xattr name on path.
10165         local path=$1
10166         local name=$2
10167
10168         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10169         # file: $path
10170         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10171         #
10172         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10173
10174         getfattr --absolute-names --encoding=base64 --name=$name $path |
10175                 awk -F= -v name=$name '$1 == name {
10176                         print substr($0, index($0, "=") + 1);
10177         }'
10178 }
10179
10180 test_102n() { # LU-4101 mdt: protect internal xattrs
10181         [ -z "$(which setfattr 2>/dev/null)" ] &&
10182                 skip "could not find setfattr"
10183         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10184         then
10185                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10186         fi
10187
10188         local file0=$DIR/$tfile.0
10189         local file1=$DIR/$tfile.1
10190         local xattr0=$TMP/$tfile.0
10191         local xattr1=$TMP/$tfile.1
10192         local namelist="lov lma lmv link fid version som hsm"
10193         local name
10194         local value
10195
10196         rm -rf $file0 $file1 $xattr0 $xattr1
10197         touch $file0 $file1
10198
10199         # Get 'before' xattrs of $file1.
10200         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10201
10202         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10203                 namelist+=" lfsck_namespace"
10204         for name in $namelist; do
10205                 # Try to copy xattr from $file0 to $file1.
10206                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10207
10208                 setfattr --name=trusted.$name --value="$value" $file1 ||
10209                         error "setxattr 'trusted.$name' failed"
10210
10211                 # Try to set a garbage xattr.
10212                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10213
10214                 if [[ x$name == "xlov" ]]; then
10215                         setfattr --name=trusted.lov --value="$value" $file1 &&
10216                         error "setxattr invalid 'trusted.lov' success"
10217                 else
10218                         setfattr --name=trusted.$name --value="$value" $file1 ||
10219                                 error "setxattr invalid 'trusted.$name' failed"
10220                 fi
10221
10222                 # Try to remove the xattr from $file1. We don't care if this
10223                 # appears to succeed or fail, we just don't want there to be
10224                 # any changes or crashes.
10225                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10226         done
10227
10228         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10229         then
10230                 name="lfsck_ns"
10231                 # Try to copy xattr from $file0 to $file1.
10232                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10233
10234                 setfattr --name=trusted.$name --value="$value" $file1 ||
10235                         error "setxattr 'trusted.$name' failed"
10236
10237                 # Try to set a garbage xattr.
10238                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10239
10240                 setfattr --name=trusted.$name --value="$value" $file1 ||
10241                         error "setxattr 'trusted.$name' failed"
10242
10243                 # Try to remove the xattr from $file1. We don't care if this
10244                 # appears to succeed or fail, we just don't want there to be
10245                 # any changes or crashes.
10246                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10247         fi
10248
10249         # Get 'after' xattrs of file1.
10250         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10251
10252         if ! diff $xattr0 $xattr1; then
10253                 error "before and after xattrs of '$file1' differ"
10254         fi
10255
10256         rm -rf $file0 $file1 $xattr0 $xattr1
10257
10258         return 0
10259 }
10260 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10261
10262 test_102p() { # LU-4703 setxattr did not check ownership
10263         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10264                 skip "MDS needs to be at least 2.5.56"
10265
10266         local testfile=$DIR/$tfile
10267
10268         touch $testfile
10269
10270         echo "setfacl as user..."
10271         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10272         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10273
10274         echo "setfattr as user..."
10275         setfacl -m "u:$RUNAS_ID:---" $testfile
10276         $RUNAS setfattr -x system.posix_acl_access $testfile
10277         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10278 }
10279 run_test 102p "check setxattr(2) correctly fails without permission"
10280
10281 test_102q() {
10282         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10283                 skip "MDS needs to be at least 2.6.92"
10284
10285         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10286 }
10287 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10288
10289 test_102r() {
10290         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10291                 skip "MDS needs to be at least 2.6.93"
10292
10293         touch $DIR/$tfile || error "touch"
10294         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10295         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10296         rm $DIR/$tfile || error "rm"
10297
10298         #normal directory
10299         mkdir -p $DIR/$tdir || error "mkdir"
10300         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10301         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10302         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10303                 error "$testfile error deleting user.author1"
10304         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10305                 grep "user.$(basename $tdir)" &&
10306                 error "$tdir did not delete user.$(basename $tdir)"
10307         rmdir $DIR/$tdir || error "rmdir"
10308
10309         #striped directory
10310         test_mkdir $DIR/$tdir
10311         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10312         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10313         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10314                 error "$testfile error deleting user.author1"
10315         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10316                 grep "user.$(basename $tdir)" &&
10317                 error "$tdir did not delete user.$(basename $tdir)"
10318         rmdir $DIR/$tdir || error "rm striped dir"
10319 }
10320 run_test 102r "set EAs with empty values"
10321
10322 test_102s() {
10323         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10324                 skip "MDS needs to be at least 2.11.52"
10325
10326         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10327
10328         save_lustre_params client "llite.*.xattr_cache" > $save
10329
10330         for cache in 0 1; do
10331                 lctl set_param llite.*.xattr_cache=$cache
10332
10333                 rm -f $DIR/$tfile
10334                 touch $DIR/$tfile || error "touch"
10335                 for prefix in lustre security system trusted user; do
10336                         # Note getxattr() may fail with 'Operation not
10337                         # supported' or 'No such attribute' depending
10338                         # on prefix and cache.
10339                         getfattr -n $prefix.n102s $DIR/$tfile &&
10340                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10341                 done
10342         done
10343
10344         restore_lustre_params < $save
10345 }
10346 run_test 102s "getting nonexistent xattrs should fail"
10347
10348 test_102t() {
10349         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10350                 skip "MDS needs to be at least 2.11.52"
10351
10352         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10353
10354         save_lustre_params client "llite.*.xattr_cache" > $save
10355
10356         for cache in 0 1; do
10357                 lctl set_param llite.*.xattr_cache=$cache
10358
10359                 for buf_size in 0 256; do
10360                         rm -f $DIR/$tfile
10361                         touch $DIR/$tfile || error "touch"
10362                         setfattr -n user.multiop $DIR/$tfile
10363                         $MULTIOP $DIR/$tfile oa$buf_size ||
10364                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10365                 done
10366         done
10367
10368         restore_lustre_params < $save
10369 }
10370 run_test 102t "zero length xattr values handled correctly"
10371
10372 run_acl_subtest()
10373 {
10374     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10375     return $?
10376 }
10377
10378 test_103a() {
10379         [ "$UID" != 0 ] && skip "must run as root"
10380         $GSS && skip_env "could not run under gss"
10381         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10382                 skip_env "must have acl enabled"
10383         [ -z "$(which setfacl 2>/dev/null)" ] &&
10384                 skip_env "could not find setfacl"
10385         remote_mds_nodsh && skip "remote MDS with nodsh"
10386
10387         gpasswd -a daemon bin                           # LU-5641
10388         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10389
10390         declare -a identity_old
10391
10392         for num in $(seq $MDSCOUNT); do
10393                 switch_identity $num true || identity_old[$num]=$?
10394         done
10395
10396         SAVE_UMASK=$(umask)
10397         umask 0022
10398         mkdir -p $DIR/$tdir
10399         cd $DIR/$tdir
10400
10401         echo "performing cp ..."
10402         run_acl_subtest cp || error "run_acl_subtest cp failed"
10403         echo "performing getfacl-noacl..."
10404         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10405         echo "performing misc..."
10406         run_acl_subtest misc || error  "misc test failed"
10407         echo "performing permissions..."
10408         run_acl_subtest permissions || error "permissions failed"
10409         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10410         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10411                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10412                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10413         then
10414                 echo "performing permissions xattr..."
10415                 run_acl_subtest permissions_xattr ||
10416                         error "permissions_xattr failed"
10417         fi
10418         echo "performing setfacl..."
10419         run_acl_subtest setfacl || error  "setfacl test failed"
10420
10421         # inheritance test got from HP
10422         echo "performing inheritance..."
10423         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10424         chmod +x make-tree || error "chmod +x failed"
10425         run_acl_subtest inheritance || error "inheritance test failed"
10426         rm -f make-tree
10427
10428         echo "LU-974 ignore umask when acl is enabled..."
10429         run_acl_subtest 974 || error "LU-974 umask test failed"
10430         if [ $MDSCOUNT -ge 2 ]; then
10431                 run_acl_subtest 974_remote ||
10432                         error "LU-974 umask test failed under remote dir"
10433         fi
10434
10435         echo "LU-2561 newly created file is same size as directory..."
10436         if [ "$mds1_FSTYPE" != "zfs" ]; then
10437                 run_acl_subtest 2561 || error "LU-2561 test failed"
10438         else
10439                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10440         fi
10441
10442         run_acl_subtest 4924 || error "LU-4924 test failed"
10443
10444         cd $SAVE_PWD
10445         umask $SAVE_UMASK
10446
10447         for num in $(seq $MDSCOUNT); do
10448                 if [ "${identity_old[$num]}" = 1 ]; then
10449                         switch_identity $num false || identity_old[$num]=$?
10450                 fi
10451         done
10452 }
10453 run_test 103a "acl test"
10454
10455 test_103b() {
10456         declare -a pids
10457         local U
10458
10459         for U in {0..511}; do
10460                 {
10461                 local O=$(printf "%04o" $U)
10462
10463                 umask $(printf "%04o" $((511 ^ $O)))
10464                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10465                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10466
10467                 (( $S == ($O & 0666) )) ||
10468                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10469
10470                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10471                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10472                 (( $S == ($O & 0666) )) ||
10473                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10474
10475                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10476                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10477                 (( $S == ($O & 0666) )) ||
10478                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10479                 rm -f $DIR/$tfile.[smp]$0
10480                 } &
10481                 local pid=$!
10482
10483                 # limit the concurrently running threads to 64. LU-11878
10484                 local idx=$((U % 64))
10485                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10486                 pids[idx]=$pid
10487         done
10488         wait
10489 }
10490 run_test 103b "umask lfs setstripe"
10491
10492 test_103c() {
10493         mkdir -p $DIR/$tdir
10494         cp -rp $DIR/$tdir $DIR/$tdir.bak
10495
10496         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10497                 error "$DIR/$tdir shouldn't contain default ACL"
10498         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10499                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10500         true
10501 }
10502 run_test 103c "'cp -rp' won't set empty acl"
10503
10504 test_103e() {
10505         (( $MDS1_VERSION >= $(version_code 2.13.59) )) ||
10506                 skip "MDS needs to be at least 2.13.59"
10507
10508         mkdir -p $DIR/$tdir
10509         # one default ACL will be created for the file owner
10510         for U in {2..256}; do
10511                 setfacl -m default:user:$U:rwx $DIR/$tdir
10512                 numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10513                 touch $DIR/$tdir/$tfile.$U ||
10514                         error "failed to create $tfile.$U with $numacl ACLs"
10515         done
10516 }
10517 run_test 103e "inheritance of big amount of default ACLs"
10518
10519 test_104a() {
10520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10521
10522         touch $DIR/$tfile
10523         lfs df || error "lfs df failed"
10524         lfs df -ih || error "lfs df -ih failed"
10525         lfs df -h $DIR || error "lfs df -h $DIR failed"
10526         lfs df -i $DIR || error "lfs df -i $DIR failed"
10527         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10528         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10529
10530         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10531         lctl --device %$OSC deactivate
10532         lfs df || error "lfs df with deactivated OSC failed"
10533         lctl --device %$OSC activate
10534         # wait the osc back to normal
10535         wait_osc_import_ready client ost
10536
10537         lfs df || error "lfs df with reactivated OSC failed"
10538         rm -f $DIR/$tfile
10539 }
10540 run_test 104a "lfs df [-ih] [path] test ========================="
10541
10542 test_104b() {
10543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10544         [ $RUNAS_ID -eq $UID ] &&
10545                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10546
10547         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10548                         grep "Permission denied" | wc -l)))
10549         if [ $denied_cnt -ne 0 ]; then
10550                 error "lfs check servers test failed"
10551         fi
10552 }
10553 run_test 104b "$RUNAS lfs check servers test ===================="
10554
10555 test_105a() {
10556         # doesn't work on 2.4 kernels
10557         touch $DIR/$tfile
10558         if $(flock_is_enabled); then
10559                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10560         else
10561                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10562         fi
10563         rm -f $DIR/$tfile
10564 }
10565 run_test 105a "flock when mounted without -o flock test ========"
10566
10567 test_105b() {
10568         touch $DIR/$tfile
10569         if $(flock_is_enabled); then
10570                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10571         else
10572                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10573         fi
10574         rm -f $DIR/$tfile
10575 }
10576 run_test 105b "fcntl when mounted without -o flock test ========"
10577
10578 test_105c() {
10579         touch $DIR/$tfile
10580         if $(flock_is_enabled); then
10581                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10582         else
10583                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10584         fi
10585         rm -f $DIR/$tfile
10586 }
10587 run_test 105c "lockf when mounted without -o flock test"
10588
10589 test_105d() { # bug 15924
10590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10591
10592         test_mkdir $DIR/$tdir
10593         flock_is_enabled || skip_env "mount w/o flock enabled"
10594         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10595         $LCTL set_param fail_loc=0x80000315
10596         flocks_test 2 $DIR/$tdir
10597 }
10598 run_test 105d "flock race (should not freeze) ========"
10599
10600 test_105e() { # bug 22660 && 22040
10601         flock_is_enabled || skip_env "mount w/o flock enabled"
10602
10603         touch $DIR/$tfile
10604         flocks_test 3 $DIR/$tfile
10605 }
10606 run_test 105e "Two conflicting flocks from same process"
10607
10608 test_106() { #bug 10921
10609         test_mkdir $DIR/$tdir
10610         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10611         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10612 }
10613 run_test 106 "attempt exec of dir followed by chown of that dir"
10614
10615 test_107() {
10616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10617
10618         CDIR=`pwd`
10619         local file=core
10620
10621         cd $DIR
10622         rm -f $file
10623
10624         local save_pattern=$(sysctl -n kernel.core_pattern)
10625         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10626         sysctl -w kernel.core_pattern=$file
10627         sysctl -w kernel.core_uses_pid=0
10628
10629         ulimit -c unlimited
10630         sleep 60 &
10631         SLEEPPID=$!
10632
10633         sleep 1
10634
10635         kill -s 11 $SLEEPPID
10636         wait $SLEEPPID
10637         if [ -e $file ]; then
10638                 size=`stat -c%s $file`
10639                 [ $size -eq 0 ] && error "Fail to create core file $file"
10640         else
10641                 error "Fail to create core file $file"
10642         fi
10643         rm -f $file
10644         sysctl -w kernel.core_pattern=$save_pattern
10645         sysctl -w kernel.core_uses_pid=$save_uses_pid
10646         cd $CDIR
10647 }
10648 run_test 107 "Coredump on SIG"
10649
10650 test_110() {
10651         test_mkdir $DIR/$tdir
10652         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10653         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10654                 error "mkdir with 256 char should fail, but did not"
10655         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10656                 error "create with 255 char failed"
10657         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10658                 error "create with 256 char should fail, but did not"
10659
10660         ls -l $DIR/$tdir
10661         rm -rf $DIR/$tdir
10662 }
10663 run_test 110 "filename length checking"
10664
10665 #
10666 # Purpose: To verify dynamic thread (OSS) creation.
10667 #
10668 test_115() {
10669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10670         remote_ost_nodsh && skip "remote OST with nodsh"
10671
10672         # Lustre does not stop service threads once they are started.
10673         # Reset number of running threads to default.
10674         stopall
10675         setupall
10676
10677         local OSTIO_pre
10678         local save_params="$TMP/sanity-$TESTNAME.parameters"
10679
10680         # Get ll_ost_io count before I/O
10681         OSTIO_pre=$(do_facet ost1 \
10682                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10683         # Exit if lustre is not running (ll_ost_io not running).
10684         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10685
10686         echo "Starting with $OSTIO_pre threads"
10687         local thread_max=$((OSTIO_pre * 2))
10688         local rpc_in_flight=$((thread_max * 2))
10689         # Number of I/O Process proposed to be started.
10690         local nfiles
10691         local facets=$(get_facets OST)
10692
10693         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10694         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10695
10696         # Set in_flight to $rpc_in_flight
10697         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10698                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10699         nfiles=${rpc_in_flight}
10700         # Set ost thread_max to $thread_max
10701         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10702
10703         # 5 Minutes should be sufficient for max number of OSS
10704         # threads(thread_max) to be created.
10705         local timeout=300
10706
10707         # Start I/O.
10708         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10709         test_mkdir $DIR/$tdir
10710         for i in $(seq $nfiles); do
10711                 local file=$DIR/$tdir/${tfile}-$i
10712                 $LFS setstripe -c -1 -i 0 $file
10713                 ($WTL $file $timeout)&
10714         done
10715
10716         # I/O Started - Wait for thread_started to reach thread_max or report
10717         # error if thread_started is more than thread_max.
10718         echo "Waiting for thread_started to reach thread_max"
10719         local thread_started=0
10720         local end_time=$((SECONDS + timeout))
10721
10722         while [ $SECONDS -le $end_time ] ; do
10723                 echo -n "."
10724                 # Get ost i/o thread_started count.
10725                 thread_started=$(do_facet ost1 \
10726                         "$LCTL get_param \
10727                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10728                 # Break out if thread_started is equal/greater than thread_max
10729                 if [[ $thread_started -ge $thread_max ]]; then
10730                         echo ll_ost_io thread_started $thread_started, \
10731                                 equal/greater than thread_max $thread_max
10732                         break
10733                 fi
10734                 sleep 1
10735         done
10736
10737         # Cleanup - We have the numbers, Kill i/o jobs if running.
10738         jobcount=($(jobs -p))
10739         for i in $(seq 0 $((${#jobcount[@]}-1)))
10740         do
10741                 kill -9 ${jobcount[$i]}
10742                 if [ $? -ne 0 ] ; then
10743                         echo Warning: \
10744                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10745                 fi
10746         done
10747
10748         # Cleanup files left by WTL binary.
10749         for i in $(seq $nfiles); do
10750                 local file=$DIR/$tdir/${tfile}-$i
10751                 rm -rf $file
10752                 if [ $? -ne 0 ] ; then
10753                         echo "Warning: Failed to delete file $file"
10754                 fi
10755         done
10756
10757         restore_lustre_params <$save_params
10758         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10759
10760         # Error out if no new thread has started or Thread started is greater
10761         # than thread max.
10762         if [[ $thread_started -le $OSTIO_pre ||
10763                         $thread_started -gt $thread_max ]]; then
10764                 error "ll_ost_io: thread_started $thread_started" \
10765                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10766                       "No new thread started or thread started greater " \
10767                       "than thread_max."
10768         fi
10769 }
10770 run_test 115 "verify dynamic thread creation===================="
10771
10772 free_min_max () {
10773         wait_delete_completed
10774         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10775         echo "OST kbytes available: ${AVAIL[@]}"
10776         MAXV=${AVAIL[0]}
10777         MAXI=0
10778         MINV=${AVAIL[0]}
10779         MINI=0
10780         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10781                 #echo OST $i: ${AVAIL[i]}kb
10782                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10783                         MAXV=${AVAIL[i]}
10784                         MAXI=$i
10785                 fi
10786                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10787                         MINV=${AVAIL[i]}
10788                         MINI=$i
10789                 fi
10790         done
10791         echo "Min free space: OST $MINI: $MINV"
10792         echo "Max free space: OST $MAXI: $MAXV"
10793 }
10794
10795 test_116a() { # was previously test_116()
10796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10797         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10798         remote_mds_nodsh && skip "remote MDS with nodsh"
10799
10800         echo -n "Free space priority "
10801         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10802                 head -n1
10803         declare -a AVAIL
10804         free_min_max
10805
10806         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10807         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10808         trap simple_cleanup_common EXIT
10809
10810         # Check if we need to generate uneven OSTs
10811         test_mkdir -p $DIR/$tdir/OST${MINI}
10812         local FILL=$((MINV / 4))
10813         local DIFF=$((MAXV - MINV))
10814         local DIFF2=$((DIFF * 100 / MINV))
10815
10816         local threshold=$(do_facet $SINGLEMDS \
10817                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10818         threshold=${threshold%%%}
10819         echo -n "Check for uneven OSTs: "
10820         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10821
10822         if [[ $DIFF2 -gt $threshold ]]; then
10823                 echo "ok"
10824                 echo "Don't need to fill OST$MINI"
10825         else
10826                 # generate uneven OSTs. Write 2% over the QOS threshold value
10827                 echo "no"
10828                 DIFF=$((threshold - DIFF2 + 2))
10829                 DIFF2=$((MINV * DIFF / 100))
10830                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10831                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10832                         error "setstripe failed"
10833                 DIFF=$((DIFF2 / 2048))
10834                 i=0
10835                 while [ $i -lt $DIFF ]; do
10836                         i=$((i + 1))
10837                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10838                                 bs=2M count=1 2>/dev/null
10839                         echo -n .
10840                 done
10841                 echo .
10842                 sync
10843                 sleep_maxage
10844                 free_min_max
10845         fi
10846
10847         DIFF=$((MAXV - MINV))
10848         DIFF2=$((DIFF * 100 / MINV))
10849         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10850         if [ $DIFF2 -gt $threshold ]; then
10851                 echo "ok"
10852         else
10853                 echo "failed - QOS mode won't be used"
10854                 simple_cleanup_common
10855                 skip "QOS imbalance criteria not met"
10856         fi
10857
10858         MINI1=$MINI
10859         MINV1=$MINV
10860         MAXI1=$MAXI
10861         MAXV1=$MAXV
10862
10863         # now fill using QOS
10864         $LFS setstripe -c 1 $DIR/$tdir
10865         FILL=$((FILL / 200))
10866         if [ $FILL -gt 600 ]; then
10867                 FILL=600
10868         fi
10869         echo "writing $FILL files to QOS-assigned OSTs"
10870         i=0
10871         while [ $i -lt $FILL ]; do
10872                 i=$((i + 1))
10873                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10874                         count=1 2>/dev/null
10875                 echo -n .
10876         done
10877         echo "wrote $i 200k files"
10878         sync
10879         sleep_maxage
10880
10881         echo "Note: free space may not be updated, so measurements might be off"
10882         free_min_max
10883         DIFF2=$((MAXV - MINV))
10884         echo "free space delta: orig $DIFF final $DIFF2"
10885         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10886         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10887         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10888         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10889         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10890         if [[ $DIFF -gt 0 ]]; then
10891                 FILL=$((DIFF2 * 100 / DIFF - 100))
10892                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10893         fi
10894
10895         # Figure out which files were written where
10896         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10897                awk '/'$MINI1': / {print $2; exit}')
10898         echo $UUID
10899         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10900         echo "$MINC files created on smaller OST $MINI1"
10901         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10902                awk '/'$MAXI1': / {print $2; exit}')
10903         echo $UUID
10904         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10905         echo "$MAXC files created on larger OST $MAXI1"
10906         if [[ $MINC -gt 0 ]]; then
10907                 FILL=$((MAXC * 100 / MINC - 100))
10908                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10909         fi
10910         [[ $MAXC -gt $MINC ]] ||
10911                 error_ignore LU-9 "stripe QOS didn't balance free space"
10912         simple_cleanup_common
10913 }
10914 run_test 116a "stripe QOS: free space balance ==================="
10915
10916 test_116b() { # LU-2093
10917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10918         remote_mds_nodsh && skip "remote MDS with nodsh"
10919
10920 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10921         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10922                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10923         [ -z "$old_rr" ] && skip "no QOS"
10924         do_facet $SINGLEMDS lctl set_param \
10925                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10926         mkdir -p $DIR/$tdir
10927         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10928         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10929         do_facet $SINGLEMDS lctl set_param fail_loc=0
10930         rm -rf $DIR/$tdir
10931         do_facet $SINGLEMDS lctl set_param \
10932                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10933 }
10934 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10935
10936 test_117() # bug 10891
10937 {
10938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10939
10940         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10941         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10942         lctl set_param fail_loc=0x21e
10943         > $DIR/$tfile || error "truncate failed"
10944         lctl set_param fail_loc=0
10945         echo "Truncate succeeded."
10946         rm -f $DIR/$tfile
10947 }
10948 run_test 117 "verify osd extend =========="
10949
10950 NO_SLOW_RESENDCOUNT=4
10951 export OLD_RESENDCOUNT=""
10952 set_resend_count () {
10953         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10954         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10955         lctl set_param -n $PROC_RESENDCOUNT $1
10956         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10957 }
10958
10959 # for reduce test_118* time (b=14842)
10960 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10961
10962 # Reset async IO behavior after error case
10963 reset_async() {
10964         FILE=$DIR/reset_async
10965
10966         # Ensure all OSCs are cleared
10967         $LFS setstripe -c -1 $FILE
10968         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10969         sync
10970         rm $FILE
10971 }
10972
10973 test_118a() #bug 11710
10974 {
10975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10976
10977         reset_async
10978
10979         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10980         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10981         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10982
10983         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10984                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10985                 return 1;
10986         fi
10987         rm -f $DIR/$tfile
10988 }
10989 run_test 118a "verify O_SYNC works =========="
10990
10991 test_118b()
10992 {
10993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10994         remote_ost_nodsh && skip "remote OST with nodsh"
10995
10996         reset_async
10997
10998         #define OBD_FAIL_SRV_ENOENT 0x217
10999         set_nodes_failloc "$(osts_nodes)" 0x217
11000         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11001         RC=$?
11002         set_nodes_failloc "$(osts_nodes)" 0
11003         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11004         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11005                     grep -c writeback)
11006
11007         if [[ $RC -eq 0 ]]; then
11008                 error "Must return error due to dropped pages, rc=$RC"
11009                 return 1;
11010         fi
11011
11012         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11013                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11014                 return 1;
11015         fi
11016
11017         echo "Dirty pages not leaked on ENOENT"
11018
11019         # Due to the above error the OSC will issue all RPCs syncronously
11020         # until a subsequent RPC completes successfully without error.
11021         $MULTIOP $DIR/$tfile Ow4096yc
11022         rm -f $DIR/$tfile
11023
11024         return 0
11025 }
11026 run_test 118b "Reclaim dirty pages on fatal error =========="
11027
11028 test_118c()
11029 {
11030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11031
11032         # for 118c, restore the original resend count, LU-1940
11033         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11034                                 set_resend_count $OLD_RESENDCOUNT
11035         remote_ost_nodsh && skip "remote OST with nodsh"
11036
11037         reset_async
11038
11039         #define OBD_FAIL_OST_EROFS               0x216
11040         set_nodes_failloc "$(osts_nodes)" 0x216
11041
11042         # multiop should block due to fsync until pages are written
11043         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11044         MULTIPID=$!
11045         sleep 1
11046
11047         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11048                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11049         fi
11050
11051         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11052                     grep -c writeback)
11053         if [[ $WRITEBACK -eq 0 ]]; then
11054                 error "No page in writeback, writeback=$WRITEBACK"
11055         fi
11056
11057         set_nodes_failloc "$(osts_nodes)" 0
11058         wait $MULTIPID
11059         RC=$?
11060         if [[ $RC -ne 0 ]]; then
11061                 error "Multiop fsync failed, rc=$RC"
11062         fi
11063
11064         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11065         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11066                     grep -c writeback)
11067         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11068                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11069         fi
11070
11071         rm -f $DIR/$tfile
11072         echo "Dirty pages flushed via fsync on EROFS"
11073         return 0
11074 }
11075 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11076
11077 # continue to use small resend count to reduce test_118* time (b=14842)
11078 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11079
11080 test_118d()
11081 {
11082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11083         remote_ost_nodsh && skip "remote OST with nodsh"
11084
11085         reset_async
11086
11087         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11088         set_nodes_failloc "$(osts_nodes)" 0x214
11089         # multiop should block due to fsync until pages are written
11090         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11091         MULTIPID=$!
11092         sleep 1
11093
11094         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11095                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11096         fi
11097
11098         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11099                     grep -c writeback)
11100         if [[ $WRITEBACK -eq 0 ]]; then
11101                 error "No page in writeback, writeback=$WRITEBACK"
11102         fi
11103
11104         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11105         set_nodes_failloc "$(osts_nodes)" 0
11106
11107         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11108         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11109                     grep -c writeback)
11110         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11111                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11112         fi
11113
11114         rm -f $DIR/$tfile
11115         echo "Dirty pages gaurenteed flushed via fsync"
11116         return 0
11117 }
11118 run_test 118d "Fsync validation inject a delay of the bulk =========="
11119
11120 test_118f() {
11121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11122
11123         reset_async
11124
11125         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11126         lctl set_param fail_loc=0x8000040a
11127
11128         # Should simulate EINVAL error which is fatal
11129         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11130         RC=$?
11131         if [[ $RC -eq 0 ]]; then
11132                 error "Must return error due to dropped pages, rc=$RC"
11133         fi
11134
11135         lctl set_param fail_loc=0x0
11136
11137         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11138         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11139         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11140                     grep -c writeback)
11141         if [[ $LOCKED -ne 0 ]]; then
11142                 error "Locked pages remain in cache, locked=$LOCKED"
11143         fi
11144
11145         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11146                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11147         fi
11148
11149         rm -f $DIR/$tfile
11150         echo "No pages locked after fsync"
11151
11152         reset_async
11153         return 0
11154 }
11155 run_test 118f "Simulate unrecoverable OSC side error =========="
11156
11157 test_118g() {
11158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11159
11160         reset_async
11161
11162         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11163         lctl set_param fail_loc=0x406
11164
11165         # simulate local -ENOMEM
11166         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11167         RC=$?
11168
11169         lctl set_param fail_loc=0
11170         if [[ $RC -eq 0 ]]; then
11171                 error "Must return error due to dropped pages, rc=$RC"
11172         fi
11173
11174         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11175         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11176         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11177                         grep -c writeback)
11178         if [[ $LOCKED -ne 0 ]]; then
11179                 error "Locked pages remain in cache, locked=$LOCKED"
11180         fi
11181
11182         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11183                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11184         fi
11185
11186         rm -f $DIR/$tfile
11187         echo "No pages locked after fsync"
11188
11189         reset_async
11190         return 0
11191 }
11192 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11193
11194 test_118h() {
11195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11196         remote_ost_nodsh && skip "remote OST with nodsh"
11197
11198         reset_async
11199
11200         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11201         set_nodes_failloc "$(osts_nodes)" 0x20e
11202         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11203         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11204         RC=$?
11205
11206         set_nodes_failloc "$(osts_nodes)" 0
11207         if [[ $RC -eq 0 ]]; then
11208                 error "Must return error due to dropped pages, rc=$RC"
11209         fi
11210
11211         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11212         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11213         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11214                     grep -c writeback)
11215         if [[ $LOCKED -ne 0 ]]; then
11216                 error "Locked pages remain in cache, locked=$LOCKED"
11217         fi
11218
11219         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11220                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11221         fi
11222
11223         rm -f $DIR/$tfile
11224         echo "No pages locked after fsync"
11225
11226         return 0
11227 }
11228 run_test 118h "Verify timeout in handling recoverables errors  =========="
11229
11230 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11231
11232 test_118i() {
11233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11234         remote_ost_nodsh && skip "remote OST with nodsh"
11235
11236         reset_async
11237
11238         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11239         set_nodes_failloc "$(osts_nodes)" 0x20e
11240
11241         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11242         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11243         PID=$!
11244         sleep 5
11245         set_nodes_failloc "$(osts_nodes)" 0
11246
11247         wait $PID
11248         RC=$?
11249         if [[ $RC -ne 0 ]]; then
11250                 error "got error, but should be not, rc=$RC"
11251         fi
11252
11253         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11254         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11255         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11256         if [[ $LOCKED -ne 0 ]]; then
11257                 error "Locked pages remain in cache, locked=$LOCKED"
11258         fi
11259
11260         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11261                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11262         fi
11263
11264         rm -f $DIR/$tfile
11265         echo "No pages locked after fsync"
11266
11267         return 0
11268 }
11269 run_test 118i "Fix error before timeout in recoverable error  =========="
11270
11271 [ "$SLOW" = "no" ] && set_resend_count 4
11272
11273 test_118j() {
11274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11275         remote_ost_nodsh && skip "remote OST with nodsh"
11276
11277         reset_async
11278
11279         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11280         set_nodes_failloc "$(osts_nodes)" 0x220
11281
11282         # return -EIO from OST
11283         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11284         RC=$?
11285         set_nodes_failloc "$(osts_nodes)" 0x0
11286         if [[ $RC -eq 0 ]]; then
11287                 error "Must return error due to dropped pages, rc=$RC"
11288         fi
11289
11290         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11291         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11292         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11293         if [[ $LOCKED -ne 0 ]]; then
11294                 error "Locked pages remain in cache, locked=$LOCKED"
11295         fi
11296
11297         # in recoverable error on OST we want resend and stay until it finished
11298         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11299                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11300         fi
11301
11302         rm -f $DIR/$tfile
11303         echo "No pages locked after fsync"
11304
11305         return 0
11306 }
11307 run_test 118j "Simulate unrecoverable OST side error =========="
11308
11309 test_118k()
11310 {
11311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11312         remote_ost_nodsh && skip "remote OSTs with nodsh"
11313
11314         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11315         set_nodes_failloc "$(osts_nodes)" 0x20e
11316         test_mkdir $DIR/$tdir
11317
11318         for ((i=0;i<10;i++)); do
11319                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11320                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11321                 SLEEPPID=$!
11322                 sleep 0.500s
11323                 kill $SLEEPPID
11324                 wait $SLEEPPID
11325         done
11326
11327         set_nodes_failloc "$(osts_nodes)" 0
11328         rm -rf $DIR/$tdir
11329 }
11330 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11331
11332 test_118l() # LU-646
11333 {
11334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11335
11336         test_mkdir $DIR/$tdir
11337         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11338         rm -rf $DIR/$tdir
11339 }
11340 run_test 118l "fsync dir"
11341
11342 test_118m() # LU-3066
11343 {
11344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11345
11346         test_mkdir $DIR/$tdir
11347         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11348         rm -rf $DIR/$tdir
11349 }
11350 run_test 118m "fdatasync dir ========="
11351
11352 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11353
11354 test_118n()
11355 {
11356         local begin
11357         local end
11358
11359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11360         remote_ost_nodsh && skip "remote OSTs with nodsh"
11361
11362         # Sleep to avoid a cached response.
11363         #define OBD_STATFS_CACHE_SECONDS 1
11364         sleep 2
11365
11366         # Inject a 10 second delay in the OST_STATFS handler.
11367         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11368         set_nodes_failloc "$(osts_nodes)" 0x242
11369
11370         begin=$SECONDS
11371         stat --file-system $MOUNT > /dev/null
11372         end=$SECONDS
11373
11374         set_nodes_failloc "$(osts_nodes)" 0
11375
11376         if ((end - begin > 20)); then
11377             error "statfs took $((end - begin)) seconds, expected 10"
11378         fi
11379 }
11380 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11381
11382 test_119a() # bug 11737
11383 {
11384         BSIZE=$((512 * 1024))
11385         directio write $DIR/$tfile 0 1 $BSIZE
11386         # We ask to read two blocks, which is more than a file size.
11387         # directio will indicate an error when requested and actual
11388         # sizes aren't equeal (a normal situation in this case) and
11389         # print actual read amount.
11390         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11391         if [ "$NOB" != "$BSIZE" ]; then
11392                 error "read $NOB bytes instead of $BSIZE"
11393         fi
11394         rm -f $DIR/$tfile
11395 }
11396 run_test 119a "Short directIO read must return actual read amount"
11397
11398 test_119b() # bug 11737
11399 {
11400         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11401
11402         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11403         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11404         sync
11405         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11406                 error "direct read failed"
11407         rm -f $DIR/$tfile
11408 }
11409 run_test 119b "Sparse directIO read must return actual read amount"
11410
11411 test_119c() # bug 13099
11412 {
11413         BSIZE=1048576
11414         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11415         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11416         rm -f $DIR/$tfile
11417 }
11418 run_test 119c "Testing for direct read hitting hole"
11419
11420 test_119d() # bug 15950
11421 {
11422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11423
11424         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11425         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11426         BSIZE=1048576
11427         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11428         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11429         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11430         lctl set_param fail_loc=0x40d
11431         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11432         pid_dio=$!
11433         sleep 1
11434         cat $DIR/$tfile > /dev/null &
11435         lctl set_param fail_loc=0
11436         pid_reads=$!
11437         wait $pid_dio
11438         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11439         sleep 2
11440         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11441         error "the read rpcs have not completed in 2s"
11442         rm -f $DIR/$tfile
11443         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11444 }
11445 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11446
11447 test_120a() {
11448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11449         remote_mds_nodsh && skip "remote MDS with nodsh"
11450         test_mkdir -i0 -c1 $DIR/$tdir
11451         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11452                 skip_env "no early lock cancel on server"
11453
11454         lru_resize_disable mdc
11455         lru_resize_disable osc
11456         cancel_lru_locks mdc
11457         # asynchronous object destroy at MDT could cause bl ast to client
11458         cancel_lru_locks osc
11459
11460         stat $DIR/$tdir > /dev/null
11461         can1=$(do_facet mds1 \
11462                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11463                awk '/ldlm_cancel/ {print $2}')
11464         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11465                awk '/ldlm_bl_callback/ {print $2}')
11466         test_mkdir -i0 -c1 $DIR/$tdir/d1
11467         can2=$(do_facet mds1 \
11468                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11469                awk '/ldlm_cancel/ {print $2}')
11470         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11471                awk '/ldlm_bl_callback/ {print $2}')
11472         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11473         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11474         lru_resize_enable mdc
11475         lru_resize_enable osc
11476 }
11477 run_test 120a "Early Lock Cancel: mkdir test"
11478
11479 test_120b() {
11480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11481         remote_mds_nodsh && skip "remote MDS with nodsh"
11482         test_mkdir $DIR/$tdir
11483         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11484                 skip_env "no early lock cancel on server"
11485
11486         lru_resize_disable mdc
11487         lru_resize_disable osc
11488         cancel_lru_locks mdc
11489         stat $DIR/$tdir > /dev/null
11490         can1=$(do_facet $SINGLEMDS \
11491                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11492                awk '/ldlm_cancel/ {print $2}')
11493         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11494                awk '/ldlm_bl_callback/ {print $2}')
11495         touch $DIR/$tdir/f1
11496         can2=$(do_facet $SINGLEMDS \
11497                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11498                awk '/ldlm_cancel/ {print $2}')
11499         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11500                awk '/ldlm_bl_callback/ {print $2}')
11501         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11502         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11503         lru_resize_enable mdc
11504         lru_resize_enable osc
11505 }
11506 run_test 120b "Early Lock Cancel: create test"
11507
11508 test_120c() {
11509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11510         remote_mds_nodsh && skip "remote MDS with nodsh"
11511         test_mkdir -i0 -c1 $DIR/$tdir
11512         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11513                 skip "no early lock cancel on server"
11514
11515         lru_resize_disable mdc
11516         lru_resize_disable osc
11517         test_mkdir -i0 -c1 $DIR/$tdir/d1
11518         test_mkdir -i0 -c1 $DIR/$tdir/d2
11519         touch $DIR/$tdir/d1/f1
11520         cancel_lru_locks mdc
11521         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11522         can1=$(do_facet mds1 \
11523                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11524                awk '/ldlm_cancel/ {print $2}')
11525         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11526                awk '/ldlm_bl_callback/ {print $2}')
11527         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11528         can2=$(do_facet mds1 \
11529                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11530                awk '/ldlm_cancel/ {print $2}')
11531         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11532                awk '/ldlm_bl_callback/ {print $2}')
11533         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11534         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11535         lru_resize_enable mdc
11536         lru_resize_enable osc
11537 }
11538 run_test 120c "Early Lock Cancel: link test"
11539
11540 test_120d() {
11541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11542         remote_mds_nodsh && skip "remote MDS with nodsh"
11543         test_mkdir -i0 -c1 $DIR/$tdir
11544         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11545                 skip_env "no early lock cancel on server"
11546
11547         lru_resize_disable mdc
11548         lru_resize_disable osc
11549         touch $DIR/$tdir
11550         cancel_lru_locks mdc
11551         stat $DIR/$tdir > /dev/null
11552         can1=$(do_facet mds1 \
11553                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11554                awk '/ldlm_cancel/ {print $2}')
11555         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11556                awk '/ldlm_bl_callback/ {print $2}')
11557         chmod a+x $DIR/$tdir
11558         can2=$(do_facet mds1 \
11559                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11560                awk '/ldlm_cancel/ {print $2}')
11561         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11562                awk '/ldlm_bl_callback/ {print $2}')
11563         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11564         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11565         lru_resize_enable mdc
11566         lru_resize_enable osc
11567 }
11568 run_test 120d "Early Lock Cancel: setattr test"
11569
11570 test_120e() {
11571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11572         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11573                 skip_env "no early lock cancel on server"
11574         remote_mds_nodsh && skip "remote MDS with nodsh"
11575
11576         local dlmtrace_set=false
11577
11578         test_mkdir -i0 -c1 $DIR/$tdir
11579         lru_resize_disable mdc
11580         lru_resize_disable osc
11581         ! $LCTL get_param debug | grep -q dlmtrace &&
11582                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11583         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11584         cancel_lru_locks mdc
11585         cancel_lru_locks osc
11586         dd if=$DIR/$tdir/f1 of=/dev/null
11587         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11588         # XXX client can not do early lock cancel of OST lock
11589         # during unlink (LU-4206), so cancel osc lock now.
11590         sleep 2
11591         cancel_lru_locks osc
11592         can1=$(do_facet mds1 \
11593                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11594                awk '/ldlm_cancel/ {print $2}')
11595         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11596                awk '/ldlm_bl_callback/ {print $2}')
11597         unlink $DIR/$tdir/f1
11598         sleep 5
11599         can2=$(do_facet mds1 \
11600                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11601                awk '/ldlm_cancel/ {print $2}')
11602         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11603                awk '/ldlm_bl_callback/ {print $2}')
11604         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11605                 $LCTL dk $TMP/cancel.debug.txt
11606         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11607                 $LCTL dk $TMP/blocking.debug.txt
11608         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11609         lru_resize_enable mdc
11610         lru_resize_enable osc
11611 }
11612 run_test 120e "Early Lock Cancel: unlink test"
11613
11614 test_120f() {
11615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11616         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11617                 skip_env "no early lock cancel on server"
11618         remote_mds_nodsh && skip "remote MDS with nodsh"
11619
11620         test_mkdir -i0 -c1 $DIR/$tdir
11621         lru_resize_disable mdc
11622         lru_resize_disable osc
11623         test_mkdir -i0 -c1 $DIR/$tdir/d1
11624         test_mkdir -i0 -c1 $DIR/$tdir/d2
11625         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11626         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11627         cancel_lru_locks mdc
11628         cancel_lru_locks osc
11629         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11630         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11631         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11632         # XXX client can not do early lock cancel of OST lock
11633         # during rename (LU-4206), so cancel osc lock now.
11634         sleep 2
11635         cancel_lru_locks osc
11636         can1=$(do_facet mds1 \
11637                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11638                awk '/ldlm_cancel/ {print $2}')
11639         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11640                awk '/ldlm_bl_callback/ {print $2}')
11641         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11642         sleep 5
11643         can2=$(do_facet mds1 \
11644                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11645                awk '/ldlm_cancel/ {print $2}')
11646         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11647                awk '/ldlm_bl_callback/ {print $2}')
11648         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11649         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11650         lru_resize_enable mdc
11651         lru_resize_enable osc
11652 }
11653 run_test 120f "Early Lock Cancel: rename test"
11654
11655 test_120g() {
11656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11657         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11658                 skip_env "no early lock cancel on server"
11659         remote_mds_nodsh && skip "remote MDS with nodsh"
11660
11661         lru_resize_disable mdc
11662         lru_resize_disable osc
11663         count=10000
11664         echo create $count files
11665         test_mkdir $DIR/$tdir
11666         cancel_lru_locks mdc
11667         cancel_lru_locks osc
11668         t0=$(date +%s)
11669
11670         can0=$(do_facet $SINGLEMDS \
11671                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11672                awk '/ldlm_cancel/ {print $2}')
11673         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11674                awk '/ldlm_bl_callback/ {print $2}')
11675         createmany -o $DIR/$tdir/f $count
11676         sync
11677         can1=$(do_facet $SINGLEMDS \
11678                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11679                awk '/ldlm_cancel/ {print $2}')
11680         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11681                awk '/ldlm_bl_callback/ {print $2}')
11682         t1=$(date +%s)
11683         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11684         echo rm $count files
11685         rm -r $DIR/$tdir
11686         sync
11687         can2=$(do_facet $SINGLEMDS \
11688                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11689                awk '/ldlm_cancel/ {print $2}')
11690         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11691                awk '/ldlm_bl_callback/ {print $2}')
11692         t2=$(date +%s)
11693         echo total: $count removes in $((t2-t1))
11694         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11695         sleep 2
11696         # wait for commitment of removal
11697         lru_resize_enable mdc
11698         lru_resize_enable osc
11699 }
11700 run_test 120g "Early Lock Cancel: performance test"
11701
11702 test_121() { #bug #10589
11703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11704
11705         rm -rf $DIR/$tfile
11706         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11707 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11708         lctl set_param fail_loc=0x310
11709         cancel_lru_locks osc > /dev/null
11710         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11711         lctl set_param fail_loc=0
11712         [[ $reads -eq $writes ]] ||
11713                 error "read $reads blocks, must be $writes blocks"
11714 }
11715 run_test 121 "read cancel race ========="
11716
11717 test_123a_base() { # was test 123, statahead(bug 11401)
11718         local lsx="$1"
11719
11720         SLOWOK=0
11721         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11722                 log "testing UP system. Performance may be lower than expected."
11723                 SLOWOK=1
11724         fi
11725
11726         rm -rf $DIR/$tdir
11727         test_mkdir $DIR/$tdir
11728         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11729         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11730         MULT=10
11731         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11732                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11733
11734                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11735                 lctl set_param -n llite.*.statahead_max 0
11736                 lctl get_param llite.*.statahead_max
11737                 cancel_lru_locks mdc
11738                 cancel_lru_locks osc
11739                 stime=$(date +%s)
11740                 time $lsx $DIR/$tdir | wc -l
11741                 etime=$(date +%s)
11742                 delta=$((etime - stime))
11743                 log "$lsx $i files without statahead: $delta sec"
11744                 lctl set_param llite.*.statahead_max=$max
11745
11746                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11747                         grep "statahead wrong:" | awk '{print $3}')
11748                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11749                 cancel_lru_locks mdc
11750                 cancel_lru_locks osc
11751                 stime=$(date +%s)
11752                 time $lsx $DIR/$tdir | wc -l
11753                 etime=$(date +%s)
11754                 delta_sa=$((etime - stime))
11755                 log "$lsx $i files with statahead: $delta_sa sec"
11756                 lctl get_param -n llite.*.statahead_stats
11757                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11758                         grep "statahead wrong:" | awk '{print $3}')
11759
11760                 [[ $swrong -lt $ewrong ]] &&
11761                         log "statahead was stopped, maybe too many locks held!"
11762                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11763
11764                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11765                         max=$(lctl get_param -n llite.*.statahead_max |
11766                                 head -n 1)
11767                         lctl set_param -n llite.*.statahead_max 0
11768                         lctl get_param llite.*.statahead_max
11769                         cancel_lru_locks mdc
11770                         cancel_lru_locks osc
11771                         stime=$(date +%s)
11772                         time $lsx $DIR/$tdir | wc -l
11773                         etime=$(date +%s)
11774                         delta=$((etime - stime))
11775                         log "$lsx $i files again without statahead: $delta sec"
11776                         lctl set_param llite.*.statahead_max=$max
11777                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11778                                 if [  $SLOWOK -eq 0 ]; then
11779                                         error "$lsx $i files is slower with statahead!"
11780                                 else
11781                                         log "$lsx $i files is slower with statahead!"
11782                                 fi
11783                                 break
11784                         fi
11785                 fi
11786
11787                 [ $delta -gt 20 ] && break
11788                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11789                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11790         done
11791         log "$lsx done"
11792
11793         stime=$(date +%s)
11794         rm -r $DIR/$tdir
11795         sync
11796         etime=$(date +%s)
11797         delta=$((etime - stime))
11798         log "rm -r $DIR/$tdir/: $delta seconds"
11799         log "rm done"
11800         lctl get_param -n llite.*.statahead_stats
11801 }
11802
11803 test_123aa() {
11804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11805
11806         test_123a_base "ls -l"
11807 }
11808 run_test 123aa "verify statahead work"
11809
11810 test_123ab() {
11811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11812
11813         statx_supported || skip_env "Test must be statx() syscall supported"
11814
11815         test_123a_base "$STATX -l"
11816 }
11817 run_test 123ab "verify statahead work by using statx"
11818
11819 test_123ac() {
11820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11821
11822         statx_supported || skip_env "Test must be statx() syscall supported"
11823
11824         local rpcs_before
11825         local rpcs_after
11826         local agl_before
11827         local agl_after
11828
11829         cancel_lru_locks $OSC
11830         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11831         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11832                 awk '/agl.total:/ {print $3}')
11833         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11834         test_123a_base "$STATX --cached=always -D"
11835         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11836                 awk '/agl.total:/ {print $3}')
11837         [ $agl_before -eq $agl_after ] ||
11838                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11839         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11840         [ $rpcs_after -eq $rpcs_before ] ||
11841                 error "$STATX should not send glimpse RPCs to $OSC"
11842 }
11843 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11844
11845 test_123b () { # statahead(bug 15027)
11846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11847
11848         test_mkdir $DIR/$tdir
11849         createmany -o $DIR/$tdir/$tfile-%d 1000
11850
11851         cancel_lru_locks mdc
11852         cancel_lru_locks osc
11853
11854 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11855         lctl set_param fail_loc=0x80000803
11856         ls -lR $DIR/$tdir > /dev/null
11857         log "ls done"
11858         lctl set_param fail_loc=0x0
11859         lctl get_param -n llite.*.statahead_stats
11860         rm -r $DIR/$tdir
11861         sync
11862
11863 }
11864 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11865
11866 test_123c() {
11867         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11868
11869         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11870         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11871         touch $DIR/$tdir.1/{1..3}
11872         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11873
11874         remount_client $MOUNT
11875
11876         $MULTIOP $DIR/$tdir.0 Q
11877
11878         # let statahead to complete
11879         ls -l $DIR/$tdir.0 > /dev/null
11880
11881         testid=$(echo $TESTNAME | tr '_' ' ')
11882         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11883                 error "statahead warning" || true
11884 }
11885 run_test 123c "Can not initialize inode warning on DNE statahead"
11886
11887 test_124a() {
11888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11889         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11890                 skip_env "no lru resize on server"
11891
11892         local NR=2000
11893
11894         test_mkdir $DIR/$tdir
11895
11896         log "create $NR files at $DIR/$tdir"
11897         createmany -o $DIR/$tdir/f $NR ||
11898                 error "failed to create $NR files in $DIR/$tdir"
11899
11900         cancel_lru_locks mdc
11901         ls -l $DIR/$tdir > /dev/null
11902
11903         local NSDIR=""
11904         local LRU_SIZE=0
11905         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11906                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11907                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11908                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11909                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11910                         log "NSDIR=$NSDIR"
11911                         log "NS=$(basename $NSDIR)"
11912                         break
11913                 fi
11914         done
11915
11916         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11917                 skip "Not enough cached locks created!"
11918         fi
11919         log "LRU=$LRU_SIZE"
11920
11921         local SLEEP=30
11922
11923         # We know that lru resize allows one client to hold $LIMIT locks
11924         # for 10h. After that locks begin to be killed by client.
11925         local MAX_HRS=10
11926         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11927         log "LIMIT=$LIMIT"
11928         if [ $LIMIT -lt $LRU_SIZE ]; then
11929                 skip "Limit is too small $LIMIT"
11930         fi
11931
11932         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11933         # killing locks. Some time was spent for creating locks. This means
11934         # that up to the moment of sleep finish we must have killed some of
11935         # them (10-100 locks). This depends on how fast ther were created.
11936         # Many of them were touched in almost the same moment and thus will
11937         # be killed in groups.
11938         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11939
11940         # Use $LRU_SIZE_B here to take into account real number of locks
11941         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11942         local LRU_SIZE_B=$LRU_SIZE
11943         log "LVF=$LVF"
11944         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11945         log "OLD_LVF=$OLD_LVF"
11946         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11947
11948         # Let's make sure that we really have some margin. Client checks
11949         # cached locks every 10 sec.
11950         SLEEP=$((SLEEP+20))
11951         log "Sleep ${SLEEP} sec"
11952         local SEC=0
11953         while ((SEC<$SLEEP)); do
11954                 echo -n "..."
11955                 sleep 5
11956                 SEC=$((SEC+5))
11957                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11958                 echo -n "$LRU_SIZE"
11959         done
11960         echo ""
11961         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11962         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11963
11964         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11965                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11966                 unlinkmany $DIR/$tdir/f $NR
11967                 return
11968         }
11969
11970         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11971         log "unlink $NR files at $DIR/$tdir"
11972         unlinkmany $DIR/$tdir/f $NR
11973 }
11974 run_test 124a "lru resize ======================================="
11975
11976 get_max_pool_limit()
11977 {
11978         local limit=$($LCTL get_param \
11979                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11980         local max=0
11981         for l in $limit; do
11982                 if [[ $l -gt $max ]]; then
11983                         max=$l
11984                 fi
11985         done
11986         echo $max
11987 }
11988
11989 test_124b() {
11990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11991         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11992                 skip_env "no lru resize on server"
11993
11994         LIMIT=$(get_max_pool_limit)
11995
11996         NR=$(($(default_lru_size)*20))
11997         if [[ $NR -gt $LIMIT ]]; then
11998                 log "Limit lock number by $LIMIT locks"
11999                 NR=$LIMIT
12000         fi
12001
12002         IFree=$(mdsrate_inodes_available)
12003         if [ $IFree -lt $NR ]; then
12004                 log "Limit lock number by $IFree inodes"
12005                 NR=$IFree
12006         fi
12007
12008         lru_resize_disable mdc
12009         test_mkdir -p $DIR/$tdir/disable_lru_resize
12010
12011         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12012         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12013         cancel_lru_locks mdc
12014         stime=`date +%s`
12015         PID=""
12016         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12017         PID="$PID $!"
12018         sleep 2
12019         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12020         PID="$PID $!"
12021         sleep 2
12022         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12023         PID="$PID $!"
12024         wait $PID
12025         etime=`date +%s`
12026         nolruresize_delta=$((etime-stime))
12027         log "ls -la time: $nolruresize_delta seconds"
12028         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12029         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12030
12031         lru_resize_enable mdc
12032         test_mkdir -p $DIR/$tdir/enable_lru_resize
12033
12034         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12035         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12036         cancel_lru_locks mdc
12037         stime=`date +%s`
12038         PID=""
12039         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12040         PID="$PID $!"
12041         sleep 2
12042         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12043         PID="$PID $!"
12044         sleep 2
12045         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12046         PID="$PID $!"
12047         wait $PID
12048         etime=`date +%s`
12049         lruresize_delta=$((etime-stime))
12050         log "ls -la time: $lruresize_delta seconds"
12051         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12052
12053         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12054                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12055         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12056                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12057         else
12058                 log "lru resize performs the same with no lru resize"
12059         fi
12060         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12061 }
12062 run_test 124b "lru resize (performance test) ======================="
12063
12064 test_124c() {
12065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12066         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12067                 skip_env "no lru resize on server"
12068
12069         # cache ununsed locks on client
12070         local nr=100
12071         cancel_lru_locks mdc
12072         test_mkdir $DIR/$tdir
12073         createmany -o $DIR/$tdir/f $nr ||
12074                 error "failed to create $nr files in $DIR/$tdir"
12075         ls -l $DIR/$tdir > /dev/null
12076
12077         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12078         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12079         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12080         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12081         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12082
12083         # set lru_max_age to 1 sec
12084         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12085         echo "sleep $((recalc_p * 2)) seconds..."
12086         sleep $((recalc_p * 2))
12087
12088         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12089         # restore lru_max_age
12090         $LCTL set_param -n $nsdir.lru_max_age $max_age
12091         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12092         unlinkmany $DIR/$tdir/f $nr
12093 }
12094 run_test 124c "LRUR cancel very aged locks"
12095
12096 test_124d() {
12097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12098         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12099                 skip_env "no lru resize on server"
12100
12101         # cache ununsed locks on client
12102         local nr=100
12103
12104         lru_resize_disable mdc
12105         stack_trap "lru_resize_enable mdc" EXIT
12106
12107         cancel_lru_locks mdc
12108
12109         # asynchronous object destroy at MDT could cause bl ast to client
12110         test_mkdir $DIR/$tdir
12111         createmany -o $DIR/$tdir/f $nr ||
12112                 error "failed to create $nr files in $DIR/$tdir"
12113         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12114
12115         ls -l $DIR/$tdir > /dev/null
12116
12117         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12118         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12119         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12120         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12121
12122         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12123
12124         # set lru_max_age to 1 sec
12125         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12126         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12127
12128         echo "sleep $((recalc_p * 2)) seconds..."
12129         sleep $((recalc_p * 2))
12130
12131         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12132
12133         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12134 }
12135 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12136
12137 test_125() { # 13358
12138         $LCTL get_param -n llite.*.client_type | grep -q local ||
12139                 skip "must run as local client"
12140         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12141                 skip_env "must have acl enabled"
12142         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12143
12144         test_mkdir $DIR/$tdir
12145         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12146         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12147         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12148 }
12149 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12150
12151 test_126() { # bug 12829/13455
12152         $GSS && skip_env "must run as gss disabled"
12153         $LCTL get_param -n llite.*.client_type | grep -q local ||
12154                 skip "must run as local client"
12155         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12156
12157         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12158         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12159         rm -f $DIR/$tfile
12160         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12161 }
12162 run_test 126 "check that the fsgid provided by the client is taken into account"
12163
12164 test_127a() { # bug 15521
12165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12166         local name count samp unit min max sum sumsq
12167
12168         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12169         echo "stats before reset"
12170         $LCTL get_param osc.*.stats
12171         $LCTL set_param osc.*.stats=0
12172         local fsize=$((2048 * 1024))
12173
12174         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12175         cancel_lru_locks osc
12176         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12177
12178         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12179         stack_trap "rm -f $TMP/$tfile.tmp"
12180         while read name count samp unit min max sum sumsq; do
12181                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12182                 [ ! $min ] && error "Missing min value for $name proc entry"
12183                 eval $name=$count || error "Wrong proc format"
12184
12185                 case $name in
12186                 read_bytes|write_bytes)
12187                         [[ "$unit" =~ "bytes" ]] ||
12188                                 error "unit is not 'bytes': $unit"
12189                         (( $min >= 4096 )) || error "min is too small: $min"
12190                         (( $min <= $fsize )) || error "min is too big: $min"
12191                         (( $max >= 4096 )) || error "max is too small: $max"
12192                         (( $max <= $fsize )) || error "max is too big: $max"
12193                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12194                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12195                                 error "sumsquare is too small: $sumsq"
12196                         (( $sumsq <= $fsize * $fsize )) ||
12197                                 error "sumsquare is too big: $sumsq"
12198                         ;;
12199                 ost_read|ost_write)
12200                         [[ "$unit" =~ "usec" ]] ||
12201                                 error "unit is not 'usec': $unit"
12202                         ;;
12203                 *)      ;;
12204                 esac
12205         done < $DIR/$tfile.tmp
12206
12207         #check that we actually got some stats
12208         [ "$read_bytes" ] || error "Missing read_bytes stats"
12209         [ "$write_bytes" ] || error "Missing write_bytes stats"
12210         [ "$read_bytes" != 0 ] || error "no read done"
12211         [ "$write_bytes" != 0 ] || error "no write done"
12212 }
12213 run_test 127a "verify the client stats are sane"
12214
12215 test_127b() { # bug LU-333
12216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12217         local name count samp unit min max sum sumsq
12218
12219         echo "stats before reset"
12220         $LCTL get_param llite.*.stats
12221         $LCTL set_param llite.*.stats=0
12222
12223         # perform 2 reads and writes so MAX is different from SUM.
12224         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12225         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12226         cancel_lru_locks osc
12227         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12228         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12229
12230         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12231         stack_trap "rm -f $TMP/$tfile.tmp"
12232         while read name count samp unit min max sum sumsq; do
12233                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12234                 eval $name=$count || error "Wrong proc format"
12235
12236                 case $name in
12237                 read_bytes|write_bytes)
12238                         [[ "$unit" =~ "bytes" ]] ||
12239                                 error "unit is not 'bytes': $unit"
12240                         (( $count == 2 )) || error "count is not 2: $count"
12241                         (( $min == $PAGE_SIZE )) ||
12242                                 error "min is not $PAGE_SIZE: $min"
12243                         (( $max == $PAGE_SIZE )) ||
12244                                 error "max is not $PAGE_SIZE: $max"
12245                         (( $sum == $PAGE_SIZE * 2 )) ||
12246                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12247                         ;;
12248                 read|write)
12249                         [[ "$unit" =~ "usec" ]] ||
12250                                 error "unit is not 'usec': $unit"
12251                         ;;
12252                 *)      ;;
12253                 esac
12254         done < $TMP/$tfile.tmp
12255
12256         #check that we actually got some stats
12257         [ "$read_bytes" ] || error "Missing read_bytes stats"
12258         [ "$write_bytes" ] || error "Missing write_bytes stats"
12259         [ "$read_bytes" != 0 ] || error "no read done"
12260         [ "$write_bytes" != 0 ] || error "no write done"
12261 }
12262 run_test 127b "verify the llite client stats are sane"
12263
12264 test_127c() { # LU-12394
12265         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12266         local size
12267         local bsize
12268         local reads
12269         local writes
12270         local count
12271
12272         $LCTL set_param llite.*.extents_stats=1
12273         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12274
12275         # Use two stripes so there is enough space in default config
12276         $LFS setstripe -c 2 $DIR/$tfile
12277
12278         # Extent stats start at 0-4K and go in power of two buckets
12279         # LL_HIST_START = 12 --> 2^12 = 4K
12280         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12281         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12282         # small configs
12283         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12284                 do
12285                 # Write and read, 2x each, second time at a non-zero offset
12286                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12287                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12288                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12289                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12290                 rm -f $DIR/$tfile
12291         done
12292
12293         $LCTL get_param llite.*.extents_stats
12294
12295         count=2
12296         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12297                 do
12298                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12299                                 grep -m 1 $bsize)
12300                 reads=$(echo $bucket | awk '{print $5}')
12301                 writes=$(echo $bucket | awk '{print $9}')
12302                 [ "$reads" -eq $count ] ||
12303                         error "$reads reads in < $bsize bucket, expect $count"
12304                 [ "$writes" -eq $count ] ||
12305                         error "$writes writes in < $bsize bucket, expect $count"
12306         done
12307
12308         # Test mmap write and read
12309         $LCTL set_param llite.*.extents_stats=c
12310         size=512
12311         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12312         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12313         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12314
12315         $LCTL get_param llite.*.extents_stats
12316
12317         count=$(((size*1024) / PAGE_SIZE))
12318
12319         bsize=$((2 * PAGE_SIZE / 1024))K
12320
12321         bucket=$($LCTL get_param -n llite.*.extents_stats |
12322                         grep -m 1 $bsize)
12323         reads=$(echo $bucket | awk '{print $5}')
12324         writes=$(echo $bucket | awk '{print $9}')
12325         # mmap writes fault in the page first, creating an additonal read
12326         [ "$reads" -eq $((2 * count)) ] ||
12327                 error "$reads reads in < $bsize bucket, expect $count"
12328         [ "$writes" -eq $count ] ||
12329                 error "$writes writes in < $bsize bucket, expect $count"
12330 }
12331 run_test 127c "test llite extent stats with regular & mmap i/o"
12332
12333 test_128() { # bug 15212
12334         touch $DIR/$tfile
12335         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12336                 find $DIR/$tfile
12337                 find $DIR/$tfile
12338         EOF
12339
12340         result=$(grep error $TMP/$tfile.log)
12341         rm -f $DIR/$tfile $TMP/$tfile.log
12342         [ -z "$result" ] ||
12343                 error "consecutive find's under interactive lfs failed"
12344 }
12345 run_test 128 "interactive lfs for 2 consecutive find's"
12346
12347 set_dir_limits () {
12348         local mntdev
12349         local canondev
12350         local node
12351
12352         local ldproc=/proc/fs/ldiskfs
12353         local facets=$(get_facets MDS)
12354
12355         for facet in ${facets//,/ }; do
12356                 canondev=$(ldiskfs_canon \
12357                            *.$(convert_facet2label $facet).mntdev $facet)
12358                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12359                         ldproc=/sys/fs/ldiskfs
12360                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12361                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12362         done
12363 }
12364
12365 check_mds_dmesg() {
12366         local facets=$(get_facets MDS)
12367         for facet in ${facets//,/ }; do
12368                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12369         done
12370         return 1
12371 }
12372
12373 test_129() {
12374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12375         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12376                 skip "Need MDS version with at least 2.5.56"
12377         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12378                 skip_env "ldiskfs only test"
12379         fi
12380         remote_mds_nodsh && skip "remote MDS with nodsh"
12381
12382         local ENOSPC=28
12383         local has_warning=false
12384
12385         rm -rf $DIR/$tdir
12386         mkdir -p $DIR/$tdir
12387
12388         # block size of mds1
12389         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12390         set_dir_limits $maxsize $((maxsize * 6 / 8))
12391         stack_trap "set_dir_limits 0 0"
12392         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12393         local dirsize=$(stat -c%s "$DIR/$tdir")
12394         local nfiles=0
12395         while (( $dirsize <= $maxsize )); do
12396                 $MCREATE $DIR/$tdir/file_base_$nfiles
12397                 rc=$?
12398                 # check two errors:
12399                 # ENOSPC for ext4 max_dir_size, which has been used since
12400                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12401                 if (( rc == ENOSPC )); then
12402                         set_dir_limits 0 0
12403                         echo "rc=$rc returned as expected after $nfiles files"
12404
12405                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12406                                 error "create failed w/o dir size limit"
12407
12408                         # messages may be rate limited if test is run repeatedly
12409                         check_mds_dmesg '"is approaching max"' ||
12410                                 echo "warning message should be output"
12411                         check_mds_dmesg '"has reached max"' ||
12412                                 echo "reached message should be output"
12413
12414                         dirsize=$(stat -c%s "$DIR/$tdir")
12415
12416                         [[ $dirsize -ge $maxsize ]] && return 0
12417                         error "dirsize $dirsize < $maxsize after $nfiles files"
12418                 elif (( rc != 0 )); then
12419                         break
12420                 fi
12421                 nfiles=$((nfiles + 1))
12422                 dirsize=$(stat -c%s "$DIR/$tdir")
12423         done
12424
12425         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12426 }
12427 run_test 129 "test directory size limit ========================"
12428
12429 OLDIFS="$IFS"
12430 cleanup_130() {
12431         trap 0
12432         IFS="$OLDIFS"
12433 }
12434
12435 test_130a() {
12436         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12437         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12438
12439         trap cleanup_130 EXIT RETURN
12440
12441         local fm_file=$DIR/$tfile
12442         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12443         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12444                 error "dd failed for $fm_file"
12445
12446         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12447         filefrag -ves $fm_file
12448         RC=$?
12449         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12450                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12451         [ $RC != 0 ] && error "filefrag $fm_file failed"
12452
12453         filefrag_op=$(filefrag -ve -k $fm_file |
12454                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12455         lun=$($LFS getstripe -i $fm_file)
12456
12457         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12458         IFS=$'\n'
12459         tot_len=0
12460         for line in $filefrag_op
12461         do
12462                 frag_lun=`echo $line | cut -d: -f5`
12463                 ext_len=`echo $line | cut -d: -f4`
12464                 if (( $frag_lun != $lun )); then
12465                         cleanup_130
12466                         error "FIEMAP on 1-stripe file($fm_file) failed"
12467                         return
12468                 fi
12469                 (( tot_len += ext_len ))
12470         done
12471
12472         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12473                 cleanup_130
12474                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12475                 return
12476         fi
12477
12478         cleanup_130
12479
12480         echo "FIEMAP on single striped file succeeded"
12481 }
12482 run_test 130a "FIEMAP (1-stripe file)"
12483
12484 test_130b() {
12485         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12486
12487         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12488         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12489
12490         trap cleanup_130 EXIT RETURN
12491
12492         local fm_file=$DIR/$tfile
12493         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12494                         error "setstripe on $fm_file"
12495         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12496                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12497
12498         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12499                 error "dd failed on $fm_file"
12500
12501         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12502         filefrag_op=$(filefrag -ve -k $fm_file |
12503                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12504
12505         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12506                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12507
12508         IFS=$'\n'
12509         tot_len=0
12510         num_luns=1
12511         for line in $filefrag_op
12512         do
12513                 frag_lun=$(echo $line | cut -d: -f5 |
12514                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12515                 ext_len=$(echo $line | cut -d: -f4)
12516                 if (( $frag_lun != $last_lun )); then
12517                         if (( tot_len != 1024 )); then
12518                                 cleanup_130
12519                                 error "FIEMAP on $fm_file failed; returned " \
12520                                 "len $tot_len for OST $last_lun instead of 1024"
12521                                 return
12522                         else
12523                                 (( num_luns += 1 ))
12524                                 tot_len=0
12525                         fi
12526                 fi
12527                 (( tot_len += ext_len ))
12528                 last_lun=$frag_lun
12529         done
12530         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12531                 cleanup_130
12532                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12533                         "luns or wrong len for OST $last_lun"
12534                 return
12535         fi
12536
12537         cleanup_130
12538
12539         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12540 }
12541 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12542
12543 test_130c() {
12544         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12545
12546         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12547         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12548
12549         trap cleanup_130 EXIT RETURN
12550
12551         local fm_file=$DIR/$tfile
12552         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12553         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12554                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12555
12556         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12557                         error "dd failed on $fm_file"
12558
12559         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12560         filefrag_op=$(filefrag -ve -k $fm_file |
12561                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12562
12563         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12564                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12565
12566         IFS=$'\n'
12567         tot_len=0
12568         num_luns=1
12569         for line in $filefrag_op
12570         do
12571                 frag_lun=$(echo $line | cut -d: -f5 |
12572                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12573                 ext_len=$(echo $line | cut -d: -f4)
12574                 if (( $frag_lun != $last_lun )); then
12575                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12576                         if (( logical != 512 )); then
12577                                 cleanup_130
12578                                 error "FIEMAP on $fm_file failed; returned " \
12579                                 "logical start for lun $logical instead of 512"
12580                                 return
12581                         fi
12582                         if (( tot_len != 512 )); then
12583                                 cleanup_130
12584                                 error "FIEMAP on $fm_file failed; returned " \
12585                                 "len $tot_len for OST $last_lun instead of 1024"
12586                                 return
12587                         else
12588                                 (( num_luns += 1 ))
12589                                 tot_len=0
12590                         fi
12591                 fi
12592                 (( tot_len += ext_len ))
12593                 last_lun=$frag_lun
12594         done
12595         if (( num_luns != 2 || tot_len != 512 )); then
12596                 cleanup_130
12597                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12598                         "luns or wrong len for OST $last_lun"
12599                 return
12600         fi
12601
12602         cleanup_130
12603
12604         echo "FIEMAP on 2-stripe file with hole succeeded"
12605 }
12606 run_test 130c "FIEMAP (2-stripe file with hole)"
12607
12608 test_130d() {
12609         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12610
12611         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12612         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12613
12614         trap cleanup_130 EXIT RETURN
12615
12616         local fm_file=$DIR/$tfile
12617         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12618                         error "setstripe on $fm_file"
12619         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12620                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12621
12622         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12623         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12624                 error "dd failed on $fm_file"
12625
12626         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12627         filefrag_op=$(filefrag -ve -k $fm_file |
12628                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12629
12630         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12631                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12632
12633         IFS=$'\n'
12634         tot_len=0
12635         num_luns=1
12636         for line in $filefrag_op
12637         do
12638                 frag_lun=$(echo $line | cut -d: -f5 |
12639                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12640                 ext_len=$(echo $line | cut -d: -f4)
12641                 if (( $frag_lun != $last_lun )); then
12642                         if (( tot_len != 1024 )); then
12643                                 cleanup_130
12644                                 error "FIEMAP on $fm_file failed; returned " \
12645                                 "len $tot_len for OST $last_lun instead of 1024"
12646                                 return
12647                         else
12648                                 (( num_luns += 1 ))
12649                                 tot_len=0
12650                         fi
12651                 fi
12652                 (( tot_len += ext_len ))
12653                 last_lun=$frag_lun
12654         done
12655         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12656                 cleanup_130
12657                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12658                         "luns or wrong len for OST $last_lun"
12659                 return
12660         fi
12661
12662         cleanup_130
12663
12664         echo "FIEMAP on N-stripe file succeeded"
12665 }
12666 run_test 130d "FIEMAP (N-stripe file)"
12667
12668 test_130e() {
12669         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12670
12671         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12672         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12673
12674         trap cleanup_130 EXIT RETURN
12675
12676         local fm_file=$DIR/$tfile
12677         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12678
12679         NUM_BLKS=512
12680         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12681         for ((i = 0; i < $NUM_BLKS; i++)); do
12682                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
12683                         conv=notrunc > /dev/null 2>&1
12684         done
12685
12686         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12687         filefrag_op=$(filefrag -ve -k $fm_file |
12688                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12689
12690         last_lun=$(echo $filefrag_op | cut -d: -f5)
12691
12692         IFS=$'\n'
12693         tot_len=0
12694         num_luns=1
12695         for line in $filefrag_op; do
12696                 frag_lun=$(echo $line | cut -d: -f5)
12697                 ext_len=$(echo $line | cut -d: -f4)
12698                 if [[ "$frag_lun" != "$last_lun" ]]; then
12699                         if (( tot_len != $EXPECTED_LEN )); then
12700                                 cleanup_130
12701                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
12702                         else
12703                                 (( num_luns += 1 ))
12704                                 tot_len=0
12705                         fi
12706                 fi
12707                 (( tot_len += ext_len ))
12708                 last_lun=$frag_lun
12709         done
12710         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12711                 cleanup_130
12712                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
12713         fi
12714
12715         echo "FIEMAP with continuation calls succeeded"
12716 }
12717 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12718
12719 test_130f() {
12720         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12721         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12722
12723         local fm_file=$DIR/$tfile
12724         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12725                 error "multiop create with lov_delay_create on $fm_file"
12726
12727         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12728         filefrag_extents=$(filefrag -vek $fm_file |
12729                            awk '/extents? found/ { print $2 }')
12730         if [[ "$filefrag_extents" != "0" ]]; then
12731                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
12732         fi
12733
12734         rm -f $fm_file
12735 }
12736 run_test 130f "FIEMAP (unstriped file)"
12737
12738 test_130g() {
12739         local file=$DIR/$tfile
12740         local nr=$((OSTCOUNT * 100))
12741
12742         $LFS setstripe -C $nr $file ||
12743                 error "failed to setstripe -C $nr $file"
12744
12745         dd if=/dev/zero of=$file count=$nr bs=1M
12746         sync
12747         nr=$($LFS getstripe -c $file)
12748
12749         local extents=$(filefrag -v $file |
12750                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
12751
12752         echo "filefrag list $extents extents in file with stripecount $nr"
12753         if (( extents < nr )); then
12754                 $LFS getstripe $file
12755                 filefrag -v $file
12756                 error "filefrag printed $extents < $nr extents"
12757         fi
12758
12759         rm -f $file
12760 }
12761 run_test 130g "FIEMAP (overstripe file)"
12762
12763 # Test for writev/readv
12764 test_131a() {
12765         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12766                 error "writev test failed"
12767         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12768                 error "readv failed"
12769         rm -f $DIR/$tfile
12770 }
12771 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12772
12773 test_131b() {
12774         local fsize=$((524288 + 1048576 + 1572864))
12775         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12776                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12777                         error "append writev test failed"
12778
12779         ((fsize += 1572864 + 1048576))
12780         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12781                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12782                         error "append writev test failed"
12783         rm -f $DIR/$tfile
12784 }
12785 run_test 131b "test append writev"
12786
12787 test_131c() {
12788         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12789         error "NOT PASS"
12790 }
12791 run_test 131c "test read/write on file w/o objects"
12792
12793 test_131d() {
12794         rwv -f $DIR/$tfile -w -n 1 1572864
12795         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12796         if [ "$NOB" != 1572864 ]; then
12797                 error "Short read filed: read $NOB bytes instead of 1572864"
12798         fi
12799         rm -f $DIR/$tfile
12800 }
12801 run_test 131d "test short read"
12802
12803 test_131e() {
12804         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12805         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12806         error "read hitting hole failed"
12807         rm -f $DIR/$tfile
12808 }
12809 run_test 131e "test read hitting hole"
12810
12811 check_stats() {
12812         local facet=$1
12813         local op=$2
12814         local want=${3:-0}
12815         local res
12816
12817         case $facet in
12818         mds*) res=$(do_facet $facet \
12819                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12820                  ;;
12821         ost*) res=$(do_facet $facet \
12822                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12823                  ;;
12824         *) error "Wrong facet '$facet'" ;;
12825         esac
12826         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12827         # if the argument $3 is zero, it means any stat increment is ok.
12828         if [[ $want -gt 0 ]]; then
12829                 local count=$(echo $res | awk '{ print $2 }')
12830                 [[ $count -ne $want ]] &&
12831                         error "The $op counter on $facet is $count, not $want"
12832         fi
12833 }
12834
12835 test_133a() {
12836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12837         remote_ost_nodsh && skip "remote OST with nodsh"
12838         remote_mds_nodsh && skip "remote MDS with nodsh"
12839         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12840                 skip_env "MDS doesn't support rename stats"
12841
12842         local testdir=$DIR/${tdir}/stats_testdir
12843
12844         mkdir -p $DIR/${tdir}
12845
12846         # clear stats.
12847         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12848         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12849
12850         # verify mdt stats first.
12851         mkdir ${testdir} || error "mkdir failed"
12852         check_stats $SINGLEMDS "mkdir" 1
12853         touch ${testdir}/${tfile} || error "touch failed"
12854         check_stats $SINGLEMDS "open" 1
12855         check_stats $SINGLEMDS "close" 1
12856         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12857                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12858                 check_stats $SINGLEMDS "mknod" 2
12859         }
12860         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12861         check_stats $SINGLEMDS "unlink" 1
12862         rm -f ${testdir}/${tfile} || error "file remove failed"
12863         check_stats $SINGLEMDS "unlink" 2
12864
12865         # remove working dir and check mdt stats again.
12866         rmdir ${testdir} || error "rmdir failed"
12867         check_stats $SINGLEMDS "rmdir" 1
12868
12869         local testdir1=$DIR/${tdir}/stats_testdir1
12870         mkdir -p ${testdir}
12871         mkdir -p ${testdir1}
12872         touch ${testdir1}/test1
12873         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12874         check_stats $SINGLEMDS "crossdir_rename" 1
12875
12876         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12877         check_stats $SINGLEMDS "samedir_rename" 1
12878
12879         rm -rf $DIR/${tdir}
12880 }
12881 run_test 133a "Verifying MDT stats ========================================"
12882
12883 test_133b() {
12884         local res
12885
12886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12887         remote_ost_nodsh && skip "remote OST with nodsh"
12888         remote_mds_nodsh && skip "remote MDS with nodsh"
12889
12890         local testdir=$DIR/${tdir}/stats_testdir
12891
12892         mkdir -p ${testdir} || error "mkdir failed"
12893         touch ${testdir}/${tfile} || error "touch failed"
12894         cancel_lru_locks mdc
12895
12896         # clear stats.
12897         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12898         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12899
12900         # extra mdt stats verification.
12901         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12902         check_stats $SINGLEMDS "setattr" 1
12903         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12904         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12905         then            # LU-1740
12906                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12907                 check_stats $SINGLEMDS "getattr" 1
12908         fi
12909         rm -rf $DIR/${tdir}
12910
12911         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12912         # so the check below is not reliable
12913         [ $MDSCOUNT -eq 1 ] || return 0
12914
12915         # Sleep to avoid a cached response.
12916         #define OBD_STATFS_CACHE_SECONDS 1
12917         sleep 2
12918         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12919         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12920         $LFS df || error "lfs failed"
12921         check_stats $SINGLEMDS "statfs" 1
12922
12923         # check aggregated statfs (LU-10018)
12924         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12925                 return 0
12926         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12927                 return 0
12928         sleep 2
12929         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12930         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12931         df $DIR
12932         check_stats $SINGLEMDS "statfs" 1
12933
12934         # We want to check that the client didn't send OST_STATFS to
12935         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12936         # extra care is needed here.
12937         if remote_mds; then
12938                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12939                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12940
12941                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12942                 [ "$res" ] && error "OST got STATFS"
12943         fi
12944
12945         return 0
12946 }
12947 run_test 133b "Verifying extra MDT stats =================================="
12948
12949 test_133c() {
12950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12951         remote_ost_nodsh && skip "remote OST with nodsh"
12952         remote_mds_nodsh && skip "remote MDS with nodsh"
12953
12954         local testdir=$DIR/$tdir/stats_testdir
12955
12956         test_mkdir -p $testdir
12957
12958         # verify obdfilter stats.
12959         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12960         sync
12961         cancel_lru_locks osc
12962         wait_delete_completed
12963
12964         # clear stats.
12965         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12966         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12967
12968         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12969                 error "dd failed"
12970         sync
12971         cancel_lru_locks osc
12972         check_stats ost1 "write" 1
12973
12974         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12975         check_stats ost1 "read" 1
12976
12977         > $testdir/$tfile || error "truncate failed"
12978         check_stats ost1 "punch" 1
12979
12980         rm -f $testdir/$tfile || error "file remove failed"
12981         wait_delete_completed
12982         check_stats ost1 "destroy" 1
12983
12984         rm -rf $DIR/$tdir
12985 }
12986 run_test 133c "Verifying OST stats ========================================"
12987
12988 order_2() {
12989         local value=$1
12990         local orig=$value
12991         local order=1
12992
12993         while [ $value -ge 2 ]; do
12994                 order=$((order*2))
12995                 value=$((value/2))
12996         done
12997
12998         if [ $orig -gt $order ]; then
12999                 order=$((order*2))
13000         fi
13001         echo $order
13002 }
13003
13004 size_in_KMGT() {
13005     local value=$1
13006     local size=('K' 'M' 'G' 'T');
13007     local i=0
13008     local size_string=$value
13009
13010     while [ $value -ge 1024 ]; do
13011         if [ $i -gt 3 ]; then
13012             #T is the biggest unit we get here, if that is bigger,
13013             #just return XXXT
13014             size_string=${value}T
13015             break
13016         fi
13017         value=$((value >> 10))
13018         if [ $value -lt 1024 ]; then
13019             size_string=${value}${size[$i]}
13020             break
13021         fi
13022         i=$((i + 1))
13023     done
13024
13025     echo $size_string
13026 }
13027
13028 get_rename_size() {
13029         local size=$1
13030         local context=${2:-.}
13031         local sample=$(do_facet $SINGLEMDS $LCTL \
13032                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13033                 grep -A1 $context |
13034                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13035         echo $sample
13036 }
13037
13038 test_133d() {
13039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13040         remote_ost_nodsh && skip "remote OST with nodsh"
13041         remote_mds_nodsh && skip "remote MDS with nodsh"
13042         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13043                 skip_env "MDS doesn't support rename stats"
13044
13045         local testdir1=$DIR/${tdir}/stats_testdir1
13046         local testdir2=$DIR/${tdir}/stats_testdir2
13047         mkdir -p $DIR/${tdir}
13048
13049         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13050
13051         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13052         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13053
13054         createmany -o $testdir1/test 512 || error "createmany failed"
13055
13056         # check samedir rename size
13057         mv ${testdir1}/test0 ${testdir1}/test_0
13058
13059         local testdir1_size=$(ls -l $DIR/${tdir} |
13060                 awk '/stats_testdir1/ {print $5}')
13061         local testdir2_size=$(ls -l $DIR/${tdir} |
13062                 awk '/stats_testdir2/ {print $5}')
13063
13064         testdir1_size=$(order_2 $testdir1_size)
13065         testdir2_size=$(order_2 $testdir2_size)
13066
13067         testdir1_size=$(size_in_KMGT $testdir1_size)
13068         testdir2_size=$(size_in_KMGT $testdir2_size)
13069
13070         echo "source rename dir size: ${testdir1_size}"
13071         echo "target rename dir size: ${testdir2_size}"
13072
13073         local cmd="do_facet $SINGLEMDS $LCTL "
13074         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13075
13076         eval $cmd || error "$cmd failed"
13077         local samedir=$($cmd | grep 'same_dir')
13078         local same_sample=$(get_rename_size $testdir1_size)
13079         [ -z "$samedir" ] && error "samedir_rename_size count error"
13080         [[ $same_sample -eq 1 ]] ||
13081                 error "samedir_rename_size error $same_sample"
13082         echo "Check same dir rename stats success"
13083
13084         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13085
13086         # check crossdir rename size
13087         mv ${testdir1}/test_0 ${testdir2}/test_0
13088
13089         testdir1_size=$(ls -l $DIR/${tdir} |
13090                 awk '/stats_testdir1/ {print $5}')
13091         testdir2_size=$(ls -l $DIR/${tdir} |
13092                 awk '/stats_testdir2/ {print $5}')
13093
13094         testdir1_size=$(order_2 $testdir1_size)
13095         testdir2_size=$(order_2 $testdir2_size)
13096
13097         testdir1_size=$(size_in_KMGT $testdir1_size)
13098         testdir2_size=$(size_in_KMGT $testdir2_size)
13099
13100         echo "source rename dir size: ${testdir1_size}"
13101         echo "target rename dir size: ${testdir2_size}"
13102
13103         eval $cmd || error "$cmd failed"
13104         local crossdir=$($cmd | grep 'crossdir')
13105         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13106         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13107         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13108         [[ $src_sample -eq 1 ]] ||
13109                 error "crossdir_rename_size error $src_sample"
13110         [[ $tgt_sample -eq 1 ]] ||
13111                 error "crossdir_rename_size error $tgt_sample"
13112         echo "Check cross dir rename stats success"
13113         rm -rf $DIR/${tdir}
13114 }
13115 run_test 133d "Verifying rename_stats ========================================"
13116
13117 test_133e() {
13118         remote_mds_nodsh && skip "remote MDS with nodsh"
13119         remote_ost_nodsh && skip "remote OST with nodsh"
13120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13121
13122         local testdir=$DIR/${tdir}/stats_testdir
13123         local ctr f0 f1 bs=32768 count=42 sum
13124
13125         mkdir -p ${testdir} || error "mkdir failed"
13126
13127         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13128
13129         for ctr in {write,read}_bytes; do
13130                 sync
13131                 cancel_lru_locks osc
13132
13133                 do_facet ost1 $LCTL set_param -n \
13134                         "obdfilter.*.exports.clear=clear"
13135
13136                 if [ $ctr = write_bytes ]; then
13137                         f0=/dev/zero
13138                         f1=${testdir}/${tfile}
13139                 else
13140                         f0=${testdir}/${tfile}
13141                         f1=/dev/null
13142                 fi
13143
13144                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13145                         error "dd failed"
13146                 sync
13147                 cancel_lru_locks osc
13148
13149                 sum=$(do_facet ost1 $LCTL get_param \
13150                         "obdfilter.*.exports.*.stats" |
13151                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13152                                 $1 == ctr { sum += $7 }
13153                                 END { printf("%0.0f", sum) }')
13154
13155                 if ((sum != bs * count)); then
13156                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13157                 fi
13158         done
13159
13160         rm -rf $DIR/${tdir}
13161 }
13162 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13163
13164 test_133f() {
13165         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13166                 skip "too old lustre for get_param -R ($facet_ver)"
13167
13168         # verifying readability.
13169         $LCTL get_param -R '*' &> /dev/null
13170
13171         # Verifing writability with badarea_io.
13172         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13173                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13174                 error "client badarea_io failed"
13175
13176         # remount the FS in case writes/reads /proc break the FS
13177         cleanup || error "failed to unmount"
13178         setup || error "failed to setup"
13179 }
13180 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13181
13182 test_133g() {
13183         remote_mds_nodsh && skip "remote MDS with nodsh"
13184         remote_ost_nodsh && skip "remote OST with nodsh"
13185
13186         local facet
13187         for facet in mds1 ost1; do
13188                 local facet_ver=$(lustre_version_code $facet)
13189                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13190                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13191                 else
13192                         log "$facet: too old lustre for get_param -R"
13193                 fi
13194                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13195                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13196                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13197                                 xargs badarea_io" ||
13198                                         error "$facet badarea_io failed"
13199                 else
13200                         skip_noexit "$facet: too old lustre for get_param -R"
13201                 fi
13202         done
13203
13204         # remount the FS in case writes/reads /proc break the FS
13205         cleanup || error "failed to unmount"
13206         setup || error "failed to setup"
13207 }
13208 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13209
13210 test_133h() {
13211         remote_mds_nodsh && skip "remote MDS with nodsh"
13212         remote_ost_nodsh && skip "remote OST with nodsh"
13213         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13214                 skip "Need MDS version at least 2.9.54"
13215
13216         local facet
13217         for facet in client mds1 ost1; do
13218                 # Get the list of files that are missing the terminating newline
13219                 local plist=$(do_facet $facet
13220                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13221                 local ent
13222                 for ent in $plist; do
13223                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13224                                 awk -v FS='\v' -v RS='\v\v' \
13225                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13226                                         print FILENAME}'" 2>/dev/null)
13227                         [ -z $missing ] || {
13228                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13229                                 error "file does not end with newline: $facet-$ent"
13230                         }
13231                 done
13232         done
13233 }
13234 run_test 133h "Proc files should end with newlines"
13235
13236 test_134a() {
13237         remote_mds_nodsh && skip "remote MDS with nodsh"
13238         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13239                 skip "Need MDS version at least 2.7.54"
13240
13241         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13242         cancel_lru_locks mdc
13243
13244         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13245         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13246         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13247
13248         local nr=1000
13249         createmany -o $DIR/$tdir/f $nr ||
13250                 error "failed to create $nr files in $DIR/$tdir"
13251         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13252
13253         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13254         do_facet mds1 $LCTL set_param fail_loc=0x327
13255         do_facet mds1 $LCTL set_param fail_val=500
13256         touch $DIR/$tdir/m
13257
13258         echo "sleep 10 seconds ..."
13259         sleep 10
13260         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13261
13262         do_facet mds1 $LCTL set_param fail_loc=0
13263         do_facet mds1 $LCTL set_param fail_val=0
13264         [ $lck_cnt -lt $unused ] ||
13265                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13266
13267         rm $DIR/$tdir/m
13268         unlinkmany $DIR/$tdir/f $nr
13269 }
13270 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13271
13272 test_134b() {
13273         remote_mds_nodsh && skip "remote MDS with nodsh"
13274         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13275                 skip "Need MDS version at least 2.7.54"
13276
13277         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13278         cancel_lru_locks mdc
13279
13280         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13281                         ldlm.lock_reclaim_threshold_mb)
13282         # disable reclaim temporarily
13283         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13284
13285         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13286         do_facet mds1 $LCTL set_param fail_loc=0x328
13287         do_facet mds1 $LCTL set_param fail_val=500
13288
13289         $LCTL set_param debug=+trace
13290
13291         local nr=600
13292         createmany -o $DIR/$tdir/f $nr &
13293         local create_pid=$!
13294
13295         echo "Sleep $TIMEOUT seconds ..."
13296         sleep $TIMEOUT
13297         if ! ps -p $create_pid  > /dev/null 2>&1; then
13298                 do_facet mds1 $LCTL set_param fail_loc=0
13299                 do_facet mds1 $LCTL set_param fail_val=0
13300                 do_facet mds1 $LCTL set_param \
13301                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13302                 error "createmany finished incorrectly!"
13303         fi
13304         do_facet mds1 $LCTL set_param fail_loc=0
13305         do_facet mds1 $LCTL set_param fail_val=0
13306         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13307         wait $create_pid || return 1
13308
13309         unlinkmany $DIR/$tdir/f $nr
13310 }
13311 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13312
13313 test_135() {
13314         remote_mds_nodsh && skip "remote MDS with nodsh"
13315         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13316                 skip "Need MDS version at least 2.13.50"
13317         local fname
13318
13319         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13320
13321 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13322         #set only one record at plain llog
13323         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13324
13325         #fill already existed plain llog each 64767
13326         #wrapping whole catalog
13327         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13328
13329         createmany -o $DIR/$tdir/$tfile_ 64700
13330         for (( i = 0; i < 64700; i = i + 2 ))
13331         do
13332                 rm $DIR/$tdir/$tfile_$i &
13333                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13334                 local pid=$!
13335                 wait $pid
13336         done
13337
13338         #waiting osp synchronization
13339         wait_delete_completed
13340 }
13341 run_test 135 "Race catalog processing"
13342
13343 test_136() {
13344         remote_mds_nodsh && skip "remote MDS with nodsh"
13345         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13346                 skip "Need MDS version at least 2.13.50"
13347         local fname
13348
13349         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13350         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13351         #set only one record at plain llog
13352 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13353         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13354
13355         #fill already existed 2 plain llogs each 64767
13356         #wrapping whole catalog
13357         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13358         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13359         wait_delete_completed
13360
13361         createmany -o $DIR/$tdir/$tfile_ 10
13362         sleep 25
13363
13364         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13365         for (( i = 0; i < 10; i = i + 3 ))
13366         do
13367                 rm $DIR/$tdir/$tfile_$i &
13368                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13369                 local pid=$!
13370                 wait $pid
13371                 sleep 7
13372                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13373         done
13374
13375         #waiting osp synchronization
13376         wait_delete_completed
13377 }
13378 run_test 136 "Race catalog processing 2"
13379
13380 test_140() { #bug-17379
13381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13382
13383         test_mkdir $DIR/$tdir
13384         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13385         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13386
13387         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13388         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13389         local i=0
13390         while i=$((i + 1)); do
13391                 test_mkdir $i
13392                 cd $i || error "Changing to $i"
13393                 ln -s ../stat stat || error "Creating stat symlink"
13394                 # Read the symlink until ELOOP present,
13395                 # not LBUGing the system is considered success,
13396                 # we didn't overrun the stack.
13397                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13398                 if [ $ret -ne 0 ]; then
13399                         if [ $ret -eq 40 ]; then
13400                                 break  # -ELOOP
13401                         else
13402                                 error "Open stat symlink"
13403                                         return
13404                         fi
13405                 fi
13406         done
13407         i=$((i - 1))
13408         echo "The symlink depth = $i"
13409         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13410                 error "Invalid symlink depth"
13411
13412         # Test recursive symlink
13413         ln -s symlink_self symlink_self
13414         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13415         echo "open symlink_self returns $ret"
13416         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13417 }
13418 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13419
13420 test_150a() {
13421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13422
13423         local TF="$TMP/$tfile"
13424
13425         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13426         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13427         cp $TF $DIR/$tfile
13428         cancel_lru_locks $OSC
13429         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13430         remount_client $MOUNT
13431         df -P $MOUNT
13432         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13433
13434         $TRUNCATE $TF 6000
13435         $TRUNCATE $DIR/$tfile 6000
13436         cancel_lru_locks $OSC
13437         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13438
13439         echo "12345" >>$TF
13440         echo "12345" >>$DIR/$tfile
13441         cancel_lru_locks $OSC
13442         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13443
13444         echo "12345" >>$TF
13445         echo "12345" >>$DIR/$tfile
13446         cancel_lru_locks $OSC
13447         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13448 }
13449 run_test 150a "truncate/append tests"
13450
13451 test_150b() {
13452         check_set_fallocate_or_skip
13453
13454         touch $DIR/$tfile
13455         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13456         check_fallocate $DIR/$tfile || error "fallocate failed"
13457 }
13458 run_test 150b "Verify fallocate (prealloc) functionality"
13459
13460 test_150bb() {
13461         check_set_fallocate_or_skip
13462
13463         touch $DIR/$tfile
13464         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13465         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13466         > $DIR/$tfile
13467         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13468         # precomputed md5sum for 20MB of zeroes
13469         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13470         local sum=($(md5sum $DIR/$tfile))
13471
13472         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13473
13474         check_set_fallocate 1
13475
13476         > $DIR/$tfile
13477         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13478         sum=($(md5sum $DIR/$tfile))
13479
13480         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13481 }
13482 run_test 150bb "Verify fallocate modes both zero space"
13483
13484 test_150c() {
13485         check_set_fallocate_or_skip
13486
13487         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13488         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13489         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13490         sync; sync_all_data
13491         cancel_lru_locks $OSC
13492         sleep 5
13493         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13494         want=$((OSTCOUNT * 1048576))
13495
13496         # Must allocate all requested space, not more than 5% extra
13497         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13498                 error "bytes $bytes is not $want"
13499
13500         rm -f $DIR/$tfile
13501         # verify fallocate on PFL file
13502         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13503                 error "Create $DIR/$tfile failed"
13504         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13505                         error "fallocate failed"
13506         sync; sync_all_data
13507         cancel_lru_locks $OSC
13508         sleep 5
13509         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13510         local want=$((1024 * 1048576))
13511
13512         # Must allocate all requested space, not more than 5% extra
13513         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13514                 error "bytes $bytes is not $want"
13515 }
13516 run_test 150c "Verify fallocate Size and Blocks"
13517
13518 test_150d() {
13519         check_set_fallocate_or_skip
13520
13521         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13522         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13523         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13524         sync; sync_all_data
13525         cancel_lru_locks $OSC
13526         sleep 5
13527         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13528         local want=$((OSTCOUNT * 1048576))
13529
13530         # Must allocate all requested space, not more than 5% extra
13531         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13532                 error "bytes $bytes is not $want"
13533 }
13534 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13535
13536 test_150e() {
13537         check_set_fallocate_or_skip
13538
13539         echo "df before:"
13540         $LFS df
13541         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13542         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13543                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13544
13545         # Find OST with Minimum Size
13546         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13547                        sort -un | head -1)
13548
13549         # Get 100MB per OST of the available space to reduce run time
13550         # else 60% of the available space if we are running SLOW tests
13551         if [ $SLOW == "no" ]; then
13552                 local space=$((1024 * 100 * OSTCOUNT))
13553         else
13554                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
13555         fi
13556
13557         fallocate -l${space}k $DIR/$tfile ||
13558                 error "fallocate ${space}k $DIR/$tfile failed"
13559         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13560
13561         # get size immediately after fallocate. This should be correctly
13562         # updated
13563         local size=$(stat -c '%s' $DIR/$tfile)
13564         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13565
13566         # Sleep for a while for statfs to get updated. And not pull from cache.
13567         sleep 2
13568
13569         echo "df after fallocate:"
13570         $LFS df
13571
13572         (( size / 1024 == space )) || error "size $size != requested $space"
13573         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13574                 error "used $used < space $space"
13575
13576         rm $DIR/$tfile || error "rm failed"
13577         sync
13578         wait_delete_completed
13579
13580         echo "df after unlink:"
13581         $LFS df
13582 }
13583 run_test 150e "Verify 60% of available OST space consumed by fallocate"
13584
13585 #LU-2902 roc_hit was not able to read all values from lproc
13586 function roc_hit_init() {
13587         local list=$(comma_list $(osts_nodes))
13588         local dir=$DIR/$tdir-check
13589         local file=$dir/$tfile
13590         local BEFORE
13591         local AFTER
13592         local idx
13593
13594         test_mkdir $dir
13595         #use setstripe to do a write to every ost
13596         for i in $(seq 0 $((OSTCOUNT-1))); do
13597                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13598                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13599                 idx=$(printf %04x $i)
13600                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13601                         awk '$1 == "cache_access" {sum += $7}
13602                                 END { printf("%0.0f", sum) }')
13603
13604                 cancel_lru_locks osc
13605                 cat $file >/dev/null
13606
13607                 AFTER=$(get_osd_param $list *OST*$idx stats |
13608                         awk '$1 == "cache_access" {sum += $7}
13609                                 END { printf("%0.0f", sum) }')
13610
13611                 echo BEFORE:$BEFORE AFTER:$AFTER
13612                 if ! let "AFTER - BEFORE == 4"; then
13613                         rm -rf $dir
13614                         error "roc_hit is not safe to use"
13615                 fi
13616                 rm $file
13617         done
13618
13619         rm -rf $dir
13620 }
13621
13622 function roc_hit() {
13623         local list=$(comma_list $(osts_nodes))
13624         echo $(get_osd_param $list '' stats |
13625                 awk '$1 == "cache_hit" {sum += $7}
13626                         END { printf("%0.0f", sum) }')
13627 }
13628
13629 function set_cache() {
13630         local on=1
13631
13632         if [ "$2" == "off" ]; then
13633                 on=0;
13634         fi
13635         local list=$(comma_list $(osts_nodes))
13636         set_osd_param $list '' $1_cache_enable $on
13637
13638         cancel_lru_locks osc
13639 }
13640
13641 test_151() {
13642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13643         remote_ost_nodsh && skip "remote OST with nodsh"
13644
13645         local CPAGES=3
13646         local list=$(comma_list $(osts_nodes))
13647
13648         # check whether obdfilter is cache capable at all
13649         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13650                 skip "not cache-capable obdfilter"
13651         fi
13652
13653         # check cache is enabled on all obdfilters
13654         if get_osd_param $list '' read_cache_enable | grep 0; then
13655                 skip "oss cache is disabled"
13656         fi
13657
13658         set_osd_param $list '' writethrough_cache_enable 1
13659
13660         # check write cache is enabled on all obdfilters
13661         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13662                 skip "oss write cache is NOT enabled"
13663         fi
13664
13665         roc_hit_init
13666
13667         #define OBD_FAIL_OBD_NO_LRU  0x609
13668         do_nodes $list $LCTL set_param fail_loc=0x609
13669
13670         # pages should be in the case right after write
13671         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13672                 error "dd failed"
13673
13674         local BEFORE=$(roc_hit)
13675         cancel_lru_locks osc
13676         cat $DIR/$tfile >/dev/null
13677         local AFTER=$(roc_hit)
13678
13679         do_nodes $list $LCTL set_param fail_loc=0
13680
13681         if ! let "AFTER - BEFORE == CPAGES"; then
13682                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13683         fi
13684
13685         cancel_lru_locks osc
13686         # invalidates OST cache
13687         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13688         set_osd_param $list '' read_cache_enable 0
13689         cat $DIR/$tfile >/dev/null
13690
13691         # now data shouldn't be found in the cache
13692         BEFORE=$(roc_hit)
13693         cancel_lru_locks osc
13694         cat $DIR/$tfile >/dev/null
13695         AFTER=$(roc_hit)
13696         if let "AFTER - BEFORE != 0"; then
13697                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13698         fi
13699
13700         set_osd_param $list '' read_cache_enable 1
13701         rm -f $DIR/$tfile
13702 }
13703 run_test 151 "test cache on oss and controls ==============================="
13704
13705 test_152() {
13706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13707
13708         local TF="$TMP/$tfile"
13709
13710         # simulate ENOMEM during write
13711 #define OBD_FAIL_OST_NOMEM      0x226
13712         lctl set_param fail_loc=0x80000226
13713         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13714         cp $TF $DIR/$tfile
13715         sync || error "sync failed"
13716         lctl set_param fail_loc=0
13717
13718         # discard client's cache
13719         cancel_lru_locks osc
13720
13721         # simulate ENOMEM during read
13722         lctl set_param fail_loc=0x80000226
13723         cmp $TF $DIR/$tfile || error "cmp failed"
13724         lctl set_param fail_loc=0
13725
13726         rm -f $TF
13727 }
13728 run_test 152 "test read/write with enomem ============================"
13729
13730 test_153() {
13731         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13732 }
13733 run_test 153 "test if fdatasync does not crash ======================="
13734
13735 dot_lustre_fid_permission_check() {
13736         local fid=$1
13737         local ffid=$MOUNT/.lustre/fid/$fid
13738         local test_dir=$2
13739
13740         echo "stat fid $fid"
13741         stat $ffid > /dev/null || error "stat $ffid failed."
13742         echo "touch fid $fid"
13743         touch $ffid || error "touch $ffid failed."
13744         echo "write to fid $fid"
13745         cat /etc/hosts > $ffid || error "write $ffid failed."
13746         echo "read fid $fid"
13747         diff /etc/hosts $ffid || error "read $ffid failed."
13748         echo "append write to fid $fid"
13749         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13750         echo "rename fid $fid"
13751         mv $ffid $test_dir/$tfile.1 &&
13752                 error "rename $ffid to $tfile.1 should fail."
13753         touch $test_dir/$tfile.1
13754         mv $test_dir/$tfile.1 $ffid &&
13755                 error "rename $tfile.1 to $ffid should fail."
13756         rm -f $test_dir/$tfile.1
13757         echo "truncate fid $fid"
13758         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13759         echo "link fid $fid"
13760         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13761         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13762                 echo "setfacl fid $fid"
13763                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13764                 echo "getfacl fid $fid"
13765                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13766         fi
13767         echo "unlink fid $fid"
13768         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13769         echo "mknod fid $fid"
13770         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13771
13772         fid=[0xf00000400:0x1:0x0]
13773         ffid=$MOUNT/.lustre/fid/$fid
13774
13775         echo "stat non-exist fid $fid"
13776         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13777         echo "write to non-exist fid $fid"
13778         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13779         echo "link new fid $fid"
13780         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13781
13782         mkdir -p $test_dir/$tdir
13783         touch $test_dir/$tdir/$tfile
13784         fid=$($LFS path2fid $test_dir/$tdir)
13785         rc=$?
13786         [ $rc -ne 0 ] &&
13787                 error "error: could not get fid for $test_dir/$dir/$tfile."
13788
13789         ffid=$MOUNT/.lustre/fid/$fid
13790
13791         echo "ls $fid"
13792         ls $ffid > /dev/null || error "ls $ffid failed."
13793         echo "touch $fid/$tfile.1"
13794         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13795
13796         echo "touch $MOUNT/.lustre/fid/$tfile"
13797         touch $MOUNT/.lustre/fid/$tfile && \
13798                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13799
13800         echo "setxattr to $MOUNT/.lustre/fid"
13801         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13802
13803         echo "listxattr for $MOUNT/.lustre/fid"
13804         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13805
13806         echo "delxattr from $MOUNT/.lustre/fid"
13807         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13808
13809         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13810         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13811                 error "touch invalid fid should fail."
13812
13813         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13814         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13815                 error "touch non-normal fid should fail."
13816
13817         echo "rename $tdir to $MOUNT/.lustre/fid"
13818         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13819                 error "rename to $MOUNT/.lustre/fid should fail."
13820
13821         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13822         then            # LU-3547
13823                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13824                 local new_obf_mode=777
13825
13826                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13827                 chmod $new_obf_mode $DIR/.lustre/fid ||
13828                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13829
13830                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13831                 [ $obf_mode -eq $new_obf_mode ] ||
13832                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13833
13834                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13835                 chmod $old_obf_mode $DIR/.lustre/fid ||
13836                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13837         fi
13838
13839         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13840         fid=$($LFS path2fid $test_dir/$tfile-2)
13841
13842         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13843         then # LU-5424
13844                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13845                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13846                         error "create lov data thru .lustre failed"
13847         fi
13848         echo "cp /etc/passwd $test_dir/$tfile-2"
13849         cp /etc/passwd $test_dir/$tfile-2 ||
13850                 error "copy to $test_dir/$tfile-2 failed."
13851         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13852         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13853                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13854
13855         rm -rf $test_dir/tfile.lnk
13856         rm -rf $test_dir/$tfile-2
13857 }
13858
13859 test_154A() {
13860         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13861                 skip "Need MDS version at least 2.4.1"
13862
13863         local tf=$DIR/$tfile
13864         touch $tf
13865
13866         local fid=$($LFS path2fid $tf)
13867         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13868
13869         # check that we get the same pathname back
13870         local rootpath
13871         local found
13872         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13873                 echo "$rootpath $fid"
13874                 found=$($LFS fid2path $rootpath "$fid")
13875                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13876                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13877         done
13878
13879         # check wrong root path format
13880         rootpath=$MOUNT"_wrong"
13881         found=$($LFS fid2path $rootpath "$fid")
13882         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13883 }
13884 run_test 154A "lfs path2fid and fid2path basic checks"
13885
13886 test_154B() {
13887         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13888                 skip "Need MDS version at least 2.4.1"
13889
13890         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13891         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13892         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13893         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13894
13895         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13896         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13897
13898         # check that we get the same pathname
13899         echo "PFID: $PFID, name: $name"
13900         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13901         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13902         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13903                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13904
13905         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13906 }
13907 run_test 154B "verify the ll_decode_linkea tool"
13908
13909 test_154a() {
13910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13911         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13912         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13913                 skip "Need MDS version at least 2.2.51"
13914         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13915
13916         cp /etc/hosts $DIR/$tfile
13917
13918         fid=$($LFS path2fid $DIR/$tfile)
13919         rc=$?
13920         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13921
13922         dot_lustre_fid_permission_check "$fid" $DIR ||
13923                 error "dot lustre permission check $fid failed"
13924
13925         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13926
13927         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13928
13929         touch $MOUNT/.lustre/file &&
13930                 error "creation is not allowed under .lustre"
13931
13932         mkdir $MOUNT/.lustre/dir &&
13933                 error "mkdir is not allowed under .lustre"
13934
13935         rm -rf $DIR/$tfile
13936 }
13937 run_test 154a "Open-by-FID"
13938
13939 test_154b() {
13940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13941         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13942         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13943         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13944                 skip "Need MDS version at least 2.2.51"
13945
13946         local remote_dir=$DIR/$tdir/remote_dir
13947         local MDTIDX=1
13948         local rc=0
13949
13950         mkdir -p $DIR/$tdir
13951         $LFS mkdir -i $MDTIDX $remote_dir ||
13952                 error "create remote directory failed"
13953
13954         cp /etc/hosts $remote_dir/$tfile
13955
13956         fid=$($LFS path2fid $remote_dir/$tfile)
13957         rc=$?
13958         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13959
13960         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13961                 error "dot lustre permission check $fid failed"
13962         rm -rf $DIR/$tdir
13963 }
13964 run_test 154b "Open-by-FID for remote directory"
13965
13966 test_154c() {
13967         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13968                 skip "Need MDS version at least 2.4.1"
13969
13970         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13971         local FID1=$($LFS path2fid $DIR/$tfile.1)
13972         local FID2=$($LFS path2fid $DIR/$tfile.2)
13973         local FID3=$($LFS path2fid $DIR/$tfile.3)
13974
13975         local N=1
13976         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13977                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13978                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13979                 local want=FID$N
13980                 [ "$FID" = "${!want}" ] ||
13981                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13982                 N=$((N + 1))
13983         done
13984
13985         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13986         do
13987                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13988                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13989                 N=$((N + 1))
13990         done
13991 }
13992 run_test 154c "lfs path2fid and fid2path multiple arguments"
13993
13994 test_154d() {
13995         remote_mds_nodsh && skip "remote MDS with nodsh"
13996         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13997                 skip "Need MDS version at least 2.5.53"
13998
13999         if remote_mds; then
14000                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14001         else
14002                 nid="0@lo"
14003         fi
14004         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14005         local fd
14006         local cmd
14007
14008         rm -f $DIR/$tfile
14009         touch $DIR/$tfile
14010
14011         local fid=$($LFS path2fid $DIR/$tfile)
14012         # Open the file
14013         fd=$(free_fd)
14014         cmd="exec $fd<$DIR/$tfile"
14015         eval $cmd
14016         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14017         echo "$fid_list" | grep "$fid"
14018         rc=$?
14019
14020         cmd="exec $fd>/dev/null"
14021         eval $cmd
14022         if [ $rc -ne 0 ]; then
14023                 error "FID $fid not found in open files list $fid_list"
14024         fi
14025 }
14026 run_test 154d "Verify open file fid"
14027
14028 test_154e()
14029 {
14030         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14031                 skip "Need MDS version at least 2.6.50"
14032
14033         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14034                 error ".lustre returned by readdir"
14035         fi
14036 }
14037 run_test 154e ".lustre is not returned by readdir"
14038
14039 test_154f() {
14040         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14041
14042         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14043         test_mkdir -p -c1 $DIR/$tdir/d
14044         # test dirs inherit from its stripe
14045         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14046         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14047         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14048         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14049         touch $DIR/f
14050
14051         # get fid of parents
14052         local FID0=$($LFS path2fid $DIR/$tdir/d)
14053         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14054         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14055         local FID3=$($LFS path2fid $DIR)
14056
14057         # check that path2fid --parents returns expected <parent_fid>/name
14058         # 1) test for a directory (single parent)
14059         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14060         [ "$parent" == "$FID0/foo1" ] ||
14061                 error "expected parent: $FID0/foo1, got: $parent"
14062
14063         # 2) test for a file with nlink > 1 (multiple parents)
14064         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14065         echo "$parent" | grep -F "$FID1/$tfile" ||
14066                 error "$FID1/$tfile not returned in parent list"
14067         echo "$parent" | grep -F "$FID2/link" ||
14068                 error "$FID2/link not returned in parent list"
14069
14070         # 3) get parent by fid
14071         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14072         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14073         echo "$parent" | grep -F "$FID1/$tfile" ||
14074                 error "$FID1/$tfile not returned in parent list (by fid)"
14075         echo "$parent" | grep -F "$FID2/link" ||
14076                 error "$FID2/link not returned in parent list (by fid)"
14077
14078         # 4) test for entry in root directory
14079         parent=$($LFS path2fid --parents $DIR/f)
14080         echo "$parent" | grep -F "$FID3/f" ||
14081                 error "$FID3/f not returned in parent list"
14082
14083         # 5) test it on root directory
14084         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14085                 error "$MOUNT should not have parents"
14086
14087         # enable xattr caching and check that linkea is correctly updated
14088         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14089         save_lustre_params client "llite.*.xattr_cache" > $save
14090         lctl set_param llite.*.xattr_cache 1
14091
14092         # 6.1) linkea update on rename
14093         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14094
14095         # get parents by fid
14096         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14097         # foo1 should no longer be returned in parent list
14098         echo "$parent" | grep -F "$FID1" &&
14099                 error "$FID1 should no longer be in parent list"
14100         # the new path should appear
14101         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14102                 error "$FID2/$tfile.moved is not in parent list"
14103
14104         # 6.2) linkea update on unlink
14105         rm -f $DIR/$tdir/d/foo2/link
14106         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14107         # foo2/link should no longer be returned in parent list
14108         echo "$parent" | grep -F "$FID2/link" &&
14109                 error "$FID2/link should no longer be in parent list"
14110         true
14111
14112         rm -f $DIR/f
14113         restore_lustre_params < $save
14114         rm -f $save
14115 }
14116 run_test 154f "get parent fids by reading link ea"
14117
14118 test_154g()
14119 {
14120         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14121         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14122            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14123                 skip "Need MDS version at least 2.6.92"
14124
14125         mkdir -p $DIR/$tdir
14126         llapi_fid_test -d $DIR/$tdir
14127 }
14128 run_test 154g "various llapi FID tests"
14129
14130 test_155_small_load() {
14131     local temp=$TMP/$tfile
14132     local file=$DIR/$tfile
14133
14134     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14135         error "dd of=$temp bs=6096 count=1 failed"
14136     cp $temp $file
14137     cancel_lru_locks $OSC
14138     cmp $temp $file || error "$temp $file differ"
14139
14140     $TRUNCATE $temp 6000
14141     $TRUNCATE $file 6000
14142     cmp $temp $file || error "$temp $file differ (truncate1)"
14143
14144     echo "12345" >>$temp
14145     echo "12345" >>$file
14146     cmp $temp $file || error "$temp $file differ (append1)"
14147
14148     echo "12345" >>$temp
14149     echo "12345" >>$file
14150     cmp $temp $file || error "$temp $file differ (append2)"
14151
14152     rm -f $temp $file
14153     true
14154 }
14155
14156 test_155_big_load() {
14157         remote_ost_nodsh && skip "remote OST with nodsh"
14158
14159         local temp=$TMP/$tfile
14160         local file=$DIR/$tfile
14161
14162         free_min_max
14163         local cache_size=$(do_facet ost$((MAXI+1)) \
14164                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14165         local large_file_size=$((cache_size * 2))
14166
14167         echo "OSS cache size: $cache_size KB"
14168         echo "Large file size: $large_file_size KB"
14169
14170         [ $MAXV -le $large_file_size ] &&
14171                 skip_env "max available OST size needs > $large_file_size KB"
14172
14173         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14174
14175         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14176                 error "dd of=$temp bs=$large_file_size count=1k failed"
14177         cp $temp $file
14178         ls -lh $temp $file
14179         cancel_lru_locks osc
14180         cmp $temp $file || error "$temp $file differ"
14181
14182         rm -f $temp $file
14183         true
14184 }
14185
14186 save_writethrough() {
14187         local facets=$(get_facets OST)
14188
14189         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14190 }
14191
14192 test_155a() {
14193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14194
14195         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14196
14197         save_writethrough $p
14198
14199         set_cache read on
14200         set_cache writethrough on
14201         test_155_small_load
14202         restore_lustre_params < $p
14203         rm -f $p
14204 }
14205 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14206
14207 test_155b() {
14208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14209
14210         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14211
14212         save_writethrough $p
14213
14214         set_cache read on
14215         set_cache writethrough off
14216         test_155_small_load
14217         restore_lustre_params < $p
14218         rm -f $p
14219 }
14220 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14221
14222 test_155c() {
14223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14224
14225         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14226
14227         save_writethrough $p
14228
14229         set_cache read off
14230         set_cache writethrough on
14231         test_155_small_load
14232         restore_lustre_params < $p
14233         rm -f $p
14234 }
14235 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14236
14237 test_155d() {
14238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14239
14240         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14241
14242         save_writethrough $p
14243
14244         set_cache read off
14245         set_cache writethrough off
14246         test_155_small_load
14247         restore_lustre_params < $p
14248         rm -f $p
14249 }
14250 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14251
14252 test_155e() {
14253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14254
14255         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14256
14257         save_writethrough $p
14258
14259         set_cache read on
14260         set_cache writethrough on
14261         test_155_big_load
14262         restore_lustre_params < $p
14263         rm -f $p
14264 }
14265 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14266
14267 test_155f() {
14268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14269
14270         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14271
14272         save_writethrough $p
14273
14274         set_cache read on
14275         set_cache writethrough off
14276         test_155_big_load
14277         restore_lustre_params < $p
14278         rm -f $p
14279 }
14280 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14281
14282 test_155g() {
14283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14284
14285         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14286
14287         save_writethrough $p
14288
14289         set_cache read off
14290         set_cache writethrough on
14291         test_155_big_load
14292         restore_lustre_params < $p
14293         rm -f $p
14294 }
14295 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14296
14297 test_155h() {
14298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14299
14300         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14301
14302         save_writethrough $p
14303
14304         set_cache read off
14305         set_cache writethrough off
14306         test_155_big_load
14307         restore_lustre_params < $p
14308         rm -f $p
14309 }
14310 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14311
14312 test_156() {
14313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14314         remote_ost_nodsh && skip "remote OST with nodsh"
14315         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14316                 skip "stats not implemented on old servers"
14317         [ "$ost1_FSTYPE" = "zfs" ] &&
14318                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14319
14320         local CPAGES=3
14321         local BEFORE
14322         local AFTER
14323         local file="$DIR/$tfile"
14324         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14325
14326         save_writethrough $p
14327         roc_hit_init
14328
14329         log "Turn on read and write cache"
14330         set_cache read on
14331         set_cache writethrough on
14332
14333         log "Write data and read it back."
14334         log "Read should be satisfied from the cache."
14335         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14336         BEFORE=$(roc_hit)
14337         cancel_lru_locks osc
14338         cat $file >/dev/null
14339         AFTER=$(roc_hit)
14340         if ! let "AFTER - BEFORE == CPAGES"; then
14341                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14342         else
14343                 log "cache hits: before: $BEFORE, after: $AFTER"
14344         fi
14345
14346         log "Read again; it should be satisfied from the cache."
14347         BEFORE=$AFTER
14348         cancel_lru_locks osc
14349         cat $file >/dev/null
14350         AFTER=$(roc_hit)
14351         if ! let "AFTER - BEFORE == CPAGES"; then
14352                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14353         else
14354                 log "cache hits:: before: $BEFORE, after: $AFTER"
14355         fi
14356
14357         log "Turn off the read cache and turn on the write cache"
14358         set_cache read off
14359         set_cache writethrough on
14360
14361         log "Read again; it should be satisfied from the cache."
14362         BEFORE=$(roc_hit)
14363         cancel_lru_locks osc
14364         cat $file >/dev/null
14365         AFTER=$(roc_hit)
14366         if ! let "AFTER - BEFORE == CPAGES"; then
14367                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14368         else
14369                 log "cache hits:: before: $BEFORE, after: $AFTER"
14370         fi
14371
14372         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14373                 # > 2.12.56 uses pagecache if cached
14374                 log "Read again; it should not be satisfied from the cache."
14375                 BEFORE=$AFTER
14376                 cancel_lru_locks osc
14377                 cat $file >/dev/null
14378                 AFTER=$(roc_hit)
14379                 if ! let "AFTER - BEFORE == 0"; then
14380                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14381                 else
14382                         log "cache hits:: before: $BEFORE, after: $AFTER"
14383                 fi
14384         fi
14385
14386         log "Write data and read it back."
14387         log "Read should be satisfied from the cache."
14388         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14389         BEFORE=$(roc_hit)
14390         cancel_lru_locks osc
14391         cat $file >/dev/null
14392         AFTER=$(roc_hit)
14393         if ! let "AFTER - BEFORE == CPAGES"; then
14394                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14395         else
14396                 log "cache hits:: before: $BEFORE, after: $AFTER"
14397         fi
14398
14399         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14400                 # > 2.12.56 uses pagecache if cached
14401                 log "Read again; it should not be satisfied from the cache."
14402                 BEFORE=$AFTER
14403                 cancel_lru_locks osc
14404                 cat $file >/dev/null
14405                 AFTER=$(roc_hit)
14406                 if ! let "AFTER - BEFORE == 0"; then
14407                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14408                 else
14409                         log "cache hits:: before: $BEFORE, after: $AFTER"
14410                 fi
14411         fi
14412
14413         log "Turn off read and write cache"
14414         set_cache read off
14415         set_cache writethrough off
14416
14417         log "Write data and read it back"
14418         log "It should not be satisfied from the cache."
14419         rm -f $file
14420         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14421         cancel_lru_locks osc
14422         BEFORE=$(roc_hit)
14423         cat $file >/dev/null
14424         AFTER=$(roc_hit)
14425         if ! let "AFTER - BEFORE == 0"; then
14426                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14427         else
14428                 log "cache hits:: before: $BEFORE, after: $AFTER"
14429         fi
14430
14431         log "Turn on the read cache and turn off the write cache"
14432         set_cache read on
14433         set_cache writethrough off
14434
14435         log "Write data and read it back"
14436         log "It should not be satisfied from the cache."
14437         rm -f $file
14438         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14439         BEFORE=$(roc_hit)
14440         cancel_lru_locks osc
14441         cat $file >/dev/null
14442         AFTER=$(roc_hit)
14443         if ! let "AFTER - BEFORE == 0"; then
14444                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14445         else
14446                 log "cache hits:: before: $BEFORE, after: $AFTER"
14447         fi
14448
14449         log "Read again; it should be satisfied from the cache."
14450         BEFORE=$(roc_hit)
14451         cancel_lru_locks osc
14452         cat $file >/dev/null
14453         AFTER=$(roc_hit)
14454         if ! let "AFTER - BEFORE == CPAGES"; then
14455                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14456         else
14457                 log "cache hits:: before: $BEFORE, after: $AFTER"
14458         fi
14459
14460         restore_lustre_params < $p
14461         rm -f $p $file
14462 }
14463 run_test 156 "Verification of tunables"
14464
14465 test_160a() {
14466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14467         remote_mds_nodsh && skip "remote MDS with nodsh"
14468         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14469                 skip "Need MDS version at least 2.2.0"
14470
14471         changelog_register || error "changelog_register failed"
14472         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14473         changelog_users $SINGLEMDS | grep -q $cl_user ||
14474                 error "User $cl_user not found in changelog_users"
14475
14476         # change something
14477         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14478         changelog_clear 0 || error "changelog_clear failed"
14479         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14480         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14481         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14482         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14483         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14484         rm $DIR/$tdir/pics/desktop.jpg
14485
14486         changelog_dump | tail -10
14487
14488         echo "verifying changelog mask"
14489         changelog_chmask "-MKDIR"
14490         changelog_chmask "-CLOSE"
14491
14492         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14493         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14494
14495         changelog_chmask "+MKDIR"
14496         changelog_chmask "+CLOSE"
14497
14498         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14499         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14500
14501         changelog_dump | tail -10
14502         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14503         CLOSES=$(changelog_dump | grep -c "CLOSE")
14504         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14505         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14506
14507         # verify contents
14508         echo "verifying target fid"
14509         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14510         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14511         [ "$fidc" == "$fidf" ] ||
14512                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14513         echo "verifying parent fid"
14514         # The FID returned from the Changelog may be the directory shard on
14515         # a different MDT, and not the FID returned by path2fid on the parent.
14516         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14517         # since this is what will matter when recreating this file in the tree.
14518         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14519         local pathp=$($LFS fid2path $MOUNT "$fidp")
14520         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14521                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14522
14523         echo "getting records for $cl_user"
14524         changelog_users $SINGLEMDS
14525         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14526         local nclr=3
14527         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14528                 error "changelog_clear failed"
14529         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14530         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14531         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14532                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14533
14534         local min0_rec=$(changelog_users $SINGLEMDS |
14535                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14536         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14537                           awk '{ print $1; exit; }')
14538
14539         changelog_dump | tail -n 5
14540         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14541         [ $first_rec == $((min0_rec + 1)) ] ||
14542                 error "first index should be $min0_rec + 1 not $first_rec"
14543
14544         # LU-3446 changelog index reset on MDT restart
14545         local cur_rec1=$(changelog_users $SINGLEMDS |
14546                          awk '/^current.index:/ { print $NF }')
14547         changelog_clear 0 ||
14548                 error "clear all changelog records for $cl_user failed"
14549         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14550         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14551                 error "Fail to start $SINGLEMDS"
14552         local cur_rec2=$(changelog_users $SINGLEMDS |
14553                          awk '/^current.index:/ { print $NF }')
14554         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14555         [ $cur_rec1 == $cur_rec2 ] ||
14556                 error "current index should be $cur_rec1 not $cur_rec2"
14557
14558         echo "verifying users from this test are deregistered"
14559         changelog_deregister || error "changelog_deregister failed"
14560         changelog_users $SINGLEMDS | grep -q $cl_user &&
14561                 error "User '$cl_user' still in changelog_users"
14562
14563         # lctl get_param -n mdd.*.changelog_users
14564         # current index: 144
14565         # ID    index (idle seconds)
14566         # cl3   144 (2)
14567         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14568                 # this is the normal case where all users were deregistered
14569                 # make sure no new records are added when no users are present
14570                 local last_rec1=$(changelog_users $SINGLEMDS |
14571                                   awk '/^current.index:/ { print $NF }')
14572                 touch $DIR/$tdir/chloe
14573                 local last_rec2=$(changelog_users $SINGLEMDS |
14574                                   awk '/^current.index:/ { print $NF }')
14575                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14576                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14577         else
14578                 # any changelog users must be leftovers from a previous test
14579                 changelog_users $SINGLEMDS
14580                 echo "other changelog users; can't verify off"
14581         fi
14582 }
14583 run_test 160a "changelog sanity"
14584
14585 test_160b() { # LU-3587
14586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14587         remote_mds_nodsh && skip "remote MDS with nodsh"
14588         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14589                 skip "Need MDS version at least 2.2.0"
14590
14591         changelog_register || error "changelog_register failed"
14592         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14593         changelog_users $SINGLEMDS | grep -q $cl_user ||
14594                 error "User '$cl_user' not found in changelog_users"
14595
14596         local longname1=$(str_repeat a 255)
14597         local longname2=$(str_repeat b 255)
14598
14599         cd $DIR
14600         echo "creating very long named file"
14601         touch $longname1 || error "create of '$longname1' failed"
14602         echo "renaming very long named file"
14603         mv $longname1 $longname2
14604
14605         changelog_dump | grep RENME | tail -n 5
14606         rm -f $longname2
14607 }
14608 run_test 160b "Verify that very long rename doesn't crash in changelog"
14609
14610 test_160c() {
14611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14612         remote_mds_nodsh && skip "remote MDS with nodsh"
14613
14614         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14615                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14616                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14617                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14618
14619         local rc=0
14620
14621         # Registration step
14622         changelog_register || error "changelog_register failed"
14623
14624         rm -rf $DIR/$tdir
14625         mkdir -p $DIR/$tdir
14626         $MCREATE $DIR/$tdir/foo_160c
14627         changelog_chmask "-TRUNC"
14628         $TRUNCATE $DIR/$tdir/foo_160c 200
14629         changelog_chmask "+TRUNC"
14630         $TRUNCATE $DIR/$tdir/foo_160c 199
14631         changelog_dump | tail -n 5
14632         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14633         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14634 }
14635 run_test 160c "verify that changelog log catch the truncate event"
14636
14637 test_160d() {
14638         remote_mds_nodsh && skip "remote MDS with nodsh"
14639         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14641         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14642                 skip "Need MDS version at least 2.7.60"
14643
14644         # Registration step
14645         changelog_register || error "changelog_register failed"
14646
14647         mkdir -p $DIR/$tdir/migrate_dir
14648         changelog_clear 0 || error "changelog_clear failed"
14649
14650         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14651         changelog_dump | tail -n 5
14652         local migrates=$(changelog_dump | grep -c "MIGRT")
14653         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14654 }
14655 run_test 160d "verify that changelog log catch the migrate event"
14656
14657 test_160e() {
14658         remote_mds_nodsh && skip "remote MDS with nodsh"
14659
14660         # Create a user
14661         changelog_register || error "changelog_register failed"
14662
14663         # Delete a future user (expect fail)
14664         local MDT0=$(facet_svc $SINGLEMDS)
14665         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14666         local rc=$?
14667
14668         if [ $rc -eq 0 ]; then
14669                 error "Deleted non-existant user cl77"
14670         elif [ $rc -ne 2 ]; then
14671                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14672         fi
14673
14674         # Clear to a bad index (1 billion should be safe)
14675         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14676         rc=$?
14677
14678         if [ $rc -eq 0 ]; then
14679                 error "Successfully cleared to invalid CL index"
14680         elif [ $rc -ne 22 ]; then
14681                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14682         fi
14683 }
14684 run_test 160e "changelog negative testing (should return errors)"
14685
14686 test_160f() {
14687         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14688         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14689                 skip "Need MDS version at least 2.10.56"
14690
14691         local mdts=$(comma_list $(mdts_nodes))
14692
14693         # Create a user
14694         changelog_register || error "first changelog_register failed"
14695         changelog_register || error "second changelog_register failed"
14696         local cl_users
14697         declare -A cl_user1
14698         declare -A cl_user2
14699         local user_rec1
14700         local user_rec2
14701         local i
14702
14703         # generate some changelog records to accumulate on each MDT
14704         # use fnv1a because created files should be evenly distributed
14705         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14706                 error "test_mkdir $tdir failed"
14707         log "$(date +%s): creating first files"
14708         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14709                 error "create $DIR/$tdir/$tfile failed"
14710
14711         # check changelogs have been generated
14712         local start=$SECONDS
14713         local idle_time=$((MDSCOUNT * 5 + 5))
14714         local nbcl=$(changelog_dump | wc -l)
14715         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14716
14717         for param in "changelog_max_idle_time=$idle_time" \
14718                      "changelog_gc=1" \
14719                      "changelog_min_gc_interval=2" \
14720                      "changelog_min_free_cat_entries=3"; do
14721                 local MDT0=$(facet_svc $SINGLEMDS)
14722                 local var="${param%=*}"
14723                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14724
14725                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14726                 do_nodes $mdts $LCTL set_param mdd.*.$param
14727         done
14728
14729         # force cl_user2 to be idle (1st part), but also cancel the
14730         # cl_user1 records so that it is not evicted later in the test.
14731         local sleep1=$((idle_time / 2))
14732         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14733         sleep $sleep1
14734
14735         # simulate changelog catalog almost full
14736         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14737         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14738
14739         for i in $(seq $MDSCOUNT); do
14740                 cl_users=(${CL_USERS[mds$i]})
14741                 cl_user1[mds$i]="${cl_users[0]}"
14742                 cl_user2[mds$i]="${cl_users[1]}"
14743
14744                 [ -n "${cl_user1[mds$i]}" ] ||
14745                         error "mds$i: no user registered"
14746                 [ -n "${cl_user2[mds$i]}" ] ||
14747                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14748
14749                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14750                 [ -n "$user_rec1" ] ||
14751                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14752                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14753                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14754                 [ -n "$user_rec2" ] ||
14755                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14756                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14757                      "$user_rec1 + 2 == $user_rec2"
14758                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14759                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14760                               "$user_rec1 + 2, but is $user_rec2"
14761                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14762                 [ -n "$user_rec2" ] ||
14763                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14764                 [ $user_rec1 == $user_rec2 ] ||
14765                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14766                               "$user_rec1, but is $user_rec2"
14767         done
14768
14769         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14770         local sleep2=$((idle_time - (SECONDS - start) + 1))
14771         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14772         sleep $sleep2
14773
14774         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14775         # cl_user1 should be OK because it recently processed records.
14776         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14777         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14778                 error "create $DIR/$tdir/${tfile}b failed"
14779
14780         # ensure gc thread is done
14781         for i in $(mdts_nodes); do
14782                 wait_update $i \
14783                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14784                         error "$i: GC-thread not done"
14785         done
14786
14787         local first_rec
14788         for i in $(seq $MDSCOUNT); do
14789                 # check cl_user1 still registered
14790                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14791                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14792                 # check cl_user2 unregistered
14793                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14794                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14795
14796                 # check changelogs are present and starting at $user_rec1 + 1
14797                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14798                 [ -n "$user_rec1" ] ||
14799                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14800                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14801                             awk '{ print $1; exit; }')
14802
14803                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14804                 [ $((user_rec1 + 1)) == $first_rec ] ||
14805                         error "mds$i: first index should be $user_rec1 + 1, " \
14806                               "but is $first_rec"
14807         done
14808 }
14809 run_test 160f "changelog garbage collect (timestamped users)"
14810
14811 test_160g() {
14812         remote_mds_nodsh && skip "remote MDS with nodsh"
14813         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14814                 skip "Need MDS version at least 2.10.56"
14815
14816         local mdts=$(comma_list $(mdts_nodes))
14817
14818         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14819         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14820
14821         # Create a user
14822         changelog_register || error "first changelog_register failed"
14823         changelog_register || error "second changelog_register failed"
14824         local cl_users
14825         declare -A cl_user1
14826         declare -A cl_user2
14827         local user_rec1
14828         local user_rec2
14829         local i
14830
14831         # generate some changelog records to accumulate on each MDT
14832         # use fnv1a because created files should be evenly distributed
14833         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14834                 error "mkdir $tdir failed"
14835         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14836                 error "create $DIR/$tdir/$tfile failed"
14837
14838         # check changelogs have been generated
14839         local nbcl=$(changelog_dump | wc -l)
14840         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14841
14842         # reduce the max_idle_indexes value to make sure we exceed it
14843         max_ndx=$((nbcl / 2 - 1))
14844
14845         for param in "changelog_max_idle_indexes=$max_ndx" \
14846                      "changelog_gc=1" \
14847                      "changelog_min_gc_interval=2" \
14848                      "changelog_min_free_cat_entries=3"; do
14849                 local MDT0=$(facet_svc $SINGLEMDS)
14850                 local var="${param%=*}"
14851                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14852
14853                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14854                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14855                         error "unable to set mdd.*.$param"
14856         done
14857
14858         # simulate changelog catalog almost full
14859         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14860         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14861
14862         for i in $(seq $MDSCOUNT); do
14863                 cl_users=(${CL_USERS[mds$i]})
14864                 cl_user1[mds$i]="${cl_users[0]}"
14865                 cl_user2[mds$i]="${cl_users[1]}"
14866
14867                 [ -n "${cl_user1[mds$i]}" ] ||
14868                         error "mds$i: no user registered"
14869                 [ -n "${cl_user2[mds$i]}" ] ||
14870                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14871
14872                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14873                 [ -n "$user_rec1" ] ||
14874                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14875                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14876                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14877                 [ -n "$user_rec2" ] ||
14878                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14879                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14880                      "$user_rec1 + 2 == $user_rec2"
14881                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14882                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14883                               "$user_rec1 + 2, but is $user_rec2"
14884                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14885                 [ -n "$user_rec2" ] ||
14886                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14887                 [ $user_rec1 == $user_rec2 ] ||
14888                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14889                               "$user_rec1, but is $user_rec2"
14890         done
14891
14892         # ensure we are past the previous changelog_min_gc_interval set above
14893         sleep 2
14894
14895         # generate one more changelog to trigger fail_loc
14896         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14897                 error "create $DIR/$tdir/${tfile}bis failed"
14898
14899         # ensure gc thread is done
14900         for i in $(mdts_nodes); do
14901                 wait_update $i \
14902                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14903                         error "$i: GC-thread not done"
14904         done
14905
14906         local first_rec
14907         for i in $(seq $MDSCOUNT); do
14908                 # check cl_user1 still registered
14909                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14910                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14911                 # check cl_user2 unregistered
14912                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14913                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14914
14915                 # check changelogs are present and starting at $user_rec1 + 1
14916                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14917                 [ -n "$user_rec1" ] ||
14918                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14919                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14920                             awk '{ print $1; exit; }')
14921
14922                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14923                 [ $((user_rec1 + 1)) == $first_rec ] ||
14924                         error "mds$i: first index should be $user_rec1 + 1, " \
14925                               "but is $first_rec"
14926         done
14927 }
14928 run_test 160g "changelog garbage collect (old users)"
14929
14930 test_160h() {
14931         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14932         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14933                 skip "Need MDS version at least 2.10.56"
14934
14935         local mdts=$(comma_list $(mdts_nodes))
14936
14937         # Create a user
14938         changelog_register || error "first changelog_register failed"
14939         changelog_register || error "second changelog_register failed"
14940         local cl_users
14941         declare -A cl_user1
14942         declare -A cl_user2
14943         local user_rec1
14944         local user_rec2
14945         local i
14946
14947         # generate some changelog records to accumulate on each MDT
14948         # use fnv1a because created files should be evenly distributed
14949         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14950                 error "test_mkdir $tdir failed"
14951         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14952                 error "create $DIR/$tdir/$tfile failed"
14953
14954         # check changelogs have been generated
14955         local nbcl=$(changelog_dump | wc -l)
14956         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14957
14958         for param in "changelog_max_idle_time=10" \
14959                      "changelog_gc=1" \
14960                      "changelog_min_gc_interval=2"; do
14961                 local MDT0=$(facet_svc $SINGLEMDS)
14962                 local var="${param%=*}"
14963                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14964
14965                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14966                 do_nodes $mdts $LCTL set_param mdd.*.$param
14967         done
14968
14969         # force cl_user2 to be idle (1st part)
14970         sleep 9
14971
14972         for i in $(seq $MDSCOUNT); do
14973                 cl_users=(${CL_USERS[mds$i]})
14974                 cl_user1[mds$i]="${cl_users[0]}"
14975                 cl_user2[mds$i]="${cl_users[1]}"
14976
14977                 [ -n "${cl_user1[mds$i]}" ] ||
14978                         error "mds$i: no user registered"
14979                 [ -n "${cl_user2[mds$i]}" ] ||
14980                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14981
14982                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14983                 [ -n "$user_rec1" ] ||
14984                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14985                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14986                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14987                 [ -n "$user_rec2" ] ||
14988                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14989                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14990                      "$user_rec1 + 2 == $user_rec2"
14991                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14992                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14993                               "$user_rec1 + 2, but is $user_rec2"
14994                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14995                 [ -n "$user_rec2" ] ||
14996                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14997                 [ $user_rec1 == $user_rec2 ] ||
14998                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14999                               "$user_rec1, but is $user_rec2"
15000         done
15001
15002         # force cl_user2 to be idle (2nd part) and to reach
15003         # changelog_max_idle_time
15004         sleep 2
15005
15006         # force each GC-thread start and block then
15007         # one per MDT/MDD, set fail_val accordingly
15008         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15009         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15010
15011         # generate more changelogs to trigger fail_loc
15012         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15013                 error "create $DIR/$tdir/${tfile}bis failed"
15014
15015         # stop MDT to stop GC-thread, should be done in back-ground as it will
15016         # block waiting for the thread to be released and exit
15017         declare -A stop_pids
15018         for i in $(seq $MDSCOUNT); do
15019                 stop mds$i &
15020                 stop_pids[mds$i]=$!
15021         done
15022
15023         for i in $(mdts_nodes); do
15024                 local facet
15025                 local nb=0
15026                 local facets=$(facets_up_on_host $i)
15027
15028                 for facet in ${facets//,/ }; do
15029                         if [[ $facet == mds* ]]; then
15030                                 nb=$((nb + 1))
15031                         fi
15032                 done
15033                 # ensure each MDS's gc threads are still present and all in "R"
15034                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15035                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15036                         error "$i: expected $nb GC-thread"
15037                 wait_update $i \
15038                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15039                         "R" 20 ||
15040                         error "$i: GC-thread not found in R-state"
15041                 # check umounts of each MDT on MDS have reached kthread_stop()
15042                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15043                         error "$i: expected $nb umount"
15044                 wait_update $i \
15045                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15046                         error "$i: umount not found in D-state"
15047         done
15048
15049         # release all GC-threads
15050         do_nodes $mdts $LCTL set_param fail_loc=0
15051
15052         # wait for MDT stop to complete
15053         for i in $(seq $MDSCOUNT); do
15054                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15055         done
15056
15057         # XXX
15058         # may try to check if any orphan changelog records are present
15059         # via ldiskfs/zfs and llog_reader...
15060
15061         # re-start/mount MDTs
15062         for i in $(seq $MDSCOUNT); do
15063                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15064                         error "Fail to start mds$i"
15065         done
15066
15067         local first_rec
15068         for i in $(seq $MDSCOUNT); do
15069                 # check cl_user1 still registered
15070                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15071                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15072                 # check cl_user2 unregistered
15073                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15074                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15075
15076                 # check changelogs are present and starting at $user_rec1 + 1
15077                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15078                 [ -n "$user_rec1" ] ||
15079                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15080                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15081                             awk '{ print $1; exit; }')
15082
15083                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15084                 [ $((user_rec1 + 1)) == $first_rec ] ||
15085                         error "mds$i: first index should be $user_rec1 + 1, " \
15086                               "but is $first_rec"
15087         done
15088 }
15089 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15090               "during mount"
15091
15092 test_160i() {
15093
15094         local mdts=$(comma_list $(mdts_nodes))
15095
15096         changelog_register || error "first changelog_register failed"
15097
15098         # generate some changelog records to accumulate on each MDT
15099         # use fnv1a because created files should be evenly distributed
15100         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15101                 error "mkdir $tdir failed"
15102         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15103                 error "create $DIR/$tdir/$tfile failed"
15104
15105         # check changelogs have been generated
15106         local nbcl=$(changelog_dump | wc -l)
15107         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15108
15109         # simulate race between register and unregister
15110         # XXX as fail_loc is set per-MDS, with DNE configs the race
15111         # simulation will only occur for one MDT per MDS and for the
15112         # others the normal race scenario will take place
15113         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15114         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15115         do_nodes $mdts $LCTL set_param fail_val=1
15116
15117         # unregister 1st user
15118         changelog_deregister &
15119         local pid1=$!
15120         # wait some time for deregister work to reach race rdv
15121         sleep 2
15122         # register 2nd user
15123         changelog_register || error "2nd user register failed"
15124
15125         wait $pid1 || error "1st user deregister failed"
15126
15127         local i
15128         local last_rec
15129         declare -A LAST_REC
15130         for i in $(seq $MDSCOUNT); do
15131                 if changelog_users mds$i | grep "^cl"; then
15132                         # make sure new records are added with one user present
15133                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15134                                           awk '/^current.index:/ { print $NF }')
15135                 else
15136                         error "mds$i has no user registered"
15137                 fi
15138         done
15139
15140         # generate more changelog records to accumulate on each MDT
15141         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15142                 error "create $DIR/$tdir/${tfile}bis failed"
15143
15144         for i in $(seq $MDSCOUNT); do
15145                 last_rec=$(changelog_users $SINGLEMDS |
15146                            awk '/^current.index:/ { print $NF }')
15147                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15148                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15149                         error "changelogs are off on mds$i"
15150         done
15151 }
15152 run_test 160i "changelog user register/unregister race"
15153
15154 test_160j() {
15155         remote_mds_nodsh && skip "remote MDS with nodsh"
15156         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15157                 skip "Need MDS version at least 2.12.56"
15158
15159         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15160         stack_trap "umount $MOUNT2" EXIT
15161
15162         changelog_register || error "first changelog_register failed"
15163         stack_trap "changelog_deregister" EXIT
15164
15165         # generate some changelog
15166         # use fnv1a because created files should be evenly distributed
15167         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15168                 error "mkdir $tdir failed"
15169         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15170                 error "create $DIR/$tdir/${tfile}bis failed"
15171
15172         # open the changelog device
15173         exec 3>/dev/changelog-$FSNAME-MDT0000
15174         stack_trap "exec 3>&-" EXIT
15175         exec 4</dev/changelog-$FSNAME-MDT0000
15176         stack_trap "exec 4<&-" EXIT
15177
15178         # umount the first lustre mount
15179         umount $MOUNT
15180         stack_trap "mount_client $MOUNT" EXIT
15181
15182         # read changelog, which may or may not fail, but should not crash
15183         cat <&4 >/dev/null
15184
15185         # clear changelog
15186         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15187         changelog_users $SINGLEMDS | grep -q $cl_user ||
15188                 error "User $cl_user not found in changelog_users"
15189
15190         printf 'clear:'$cl_user':0' >&3
15191 }
15192 run_test 160j "client can be umounted while its chanangelog is being used"
15193
15194 test_160k() {
15195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15196         remote_mds_nodsh && skip "remote MDS with nodsh"
15197
15198         mkdir -p $DIR/$tdir/1/1
15199
15200         changelog_register || error "changelog_register failed"
15201         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15202
15203         changelog_users $SINGLEMDS | grep -q $cl_user ||
15204                 error "User '$cl_user' not found in changelog_users"
15205 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15206         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15207         rmdir $DIR/$tdir/1/1 & sleep 1
15208         mkdir $DIR/$tdir/2
15209         touch $DIR/$tdir/2/2
15210         rm -rf $DIR/$tdir/2
15211
15212         wait
15213         sleep 4
15214
15215         changelog_dump | grep rmdir || error "rmdir not recorded"
15216
15217         rm -rf $DIR/$tdir
15218         changelog_deregister
15219 }
15220 run_test 160k "Verify that changelog records are not lost"
15221
15222 # Verifies that a file passed as a parameter has recently had an operation
15223 # performed on it that has generated an MTIME changelog which contains the
15224 # correct parent FID. As files might reside on a different MDT from the
15225 # parent directory in DNE configurations, the FIDs are translated to paths
15226 # before being compared, which should be identical
15227 compare_mtime_changelog() {
15228         local file="${1}"
15229         local mdtidx
15230         local mtime
15231         local cl_fid
15232         local pdir
15233         local dir
15234
15235         mdtidx=$($LFS getstripe --mdt-index $file)
15236         mdtidx=$(printf "%04x" $mdtidx)
15237
15238         # Obtain the parent FID from the MTIME changelog
15239         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15240         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15241
15242         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15243         [ -z "$cl_fid" ] && error "parent FID not present"
15244
15245         # Verify that the path for the parent FID is the same as the path for
15246         # the test directory
15247         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15248
15249         dir=$(dirname $1)
15250
15251         [[ "${pdir%/}" == "$dir" ]] ||
15252                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15253 }
15254
15255 test_160l() {
15256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15257
15258         remote_mds_nodsh && skip "remote MDS with nodsh"
15259         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15260                 skip "Need MDS version at least 2.13.55"
15261
15262         local cl_user
15263
15264         changelog_register || error "changelog_register failed"
15265         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15266
15267         changelog_users $SINGLEMDS | grep -q $cl_user ||
15268                 error "User '$cl_user' not found in changelog_users"
15269
15270         # Clear some types so that MTIME changelogs are generated
15271         changelog_chmask "-CREAT"
15272         changelog_chmask "-CLOSE"
15273
15274         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15275
15276         # Test CL_MTIME during setattr
15277         touch $DIR/$tdir/$tfile
15278         compare_mtime_changelog $DIR/$tdir/$tfile
15279
15280         # Test CL_MTIME during close
15281         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15282         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15283 }
15284 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15285
15286 test_161a() {
15287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15288
15289         test_mkdir -c1 $DIR/$tdir
15290         cp /etc/hosts $DIR/$tdir/$tfile
15291         test_mkdir -c1 $DIR/$tdir/foo1
15292         test_mkdir -c1 $DIR/$tdir/foo2
15293         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15294         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15295         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15296         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15297         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15298         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15299                 $LFS fid2path $DIR $FID
15300                 error "bad link ea"
15301         fi
15302         # middle
15303         rm $DIR/$tdir/foo2/zachary
15304         # last
15305         rm $DIR/$tdir/foo2/thor
15306         # first
15307         rm $DIR/$tdir/$tfile
15308         # rename
15309         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15310         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15311                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15312         rm $DIR/$tdir/foo2/maggie
15313
15314         # overflow the EA
15315         local longname=$tfile.avg_len_is_thirty_two_
15316         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15317                 error_noexit 'failed to unlink many hardlinks'" EXIT
15318         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15319                 error "failed to hardlink many files"
15320         links=$($LFS fid2path $DIR $FID | wc -l)
15321         echo -n "${links}/1000 links in link EA"
15322         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15323 }
15324 run_test 161a "link ea sanity"
15325
15326 test_161b() {
15327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15328         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15329
15330         local MDTIDX=1
15331         local remote_dir=$DIR/$tdir/remote_dir
15332
15333         mkdir -p $DIR/$tdir
15334         $LFS mkdir -i $MDTIDX $remote_dir ||
15335                 error "create remote directory failed"
15336
15337         cp /etc/hosts $remote_dir/$tfile
15338         mkdir -p $remote_dir/foo1
15339         mkdir -p $remote_dir/foo2
15340         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15341         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15342         ln $remote_dir/$tfile $remote_dir/foo1/luna
15343         ln $remote_dir/$tfile $remote_dir/foo2/thor
15344
15345         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15346                      tr -d ']')
15347         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15348                 $LFS fid2path $DIR $FID
15349                 error "bad link ea"
15350         fi
15351         # middle
15352         rm $remote_dir/foo2/zachary
15353         # last
15354         rm $remote_dir/foo2/thor
15355         # first
15356         rm $remote_dir/$tfile
15357         # rename
15358         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15359         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15360         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15361                 $LFS fid2path $DIR $FID
15362                 error "bad link rename"
15363         fi
15364         rm $remote_dir/foo2/maggie
15365
15366         # overflow the EA
15367         local longname=filename_avg_len_is_thirty_two_
15368         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15369                 error "failed to hardlink many files"
15370         links=$($LFS fid2path $DIR $FID | wc -l)
15371         echo -n "${links}/1000 links in link EA"
15372         [[ ${links} -gt 60 ]] ||
15373                 error "expected at least 60 links in link EA"
15374         unlinkmany $remote_dir/foo2/$longname 1000 ||
15375         error "failed to unlink many hardlinks"
15376 }
15377 run_test 161b "link ea sanity under remote directory"
15378
15379 test_161c() {
15380         remote_mds_nodsh && skip "remote MDS with nodsh"
15381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15382         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15383                 skip "Need MDS version at least 2.1.5"
15384
15385         # define CLF_RENAME_LAST 0x0001
15386         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15387         changelog_register || error "changelog_register failed"
15388
15389         rm -rf $DIR/$tdir
15390         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15391         touch $DIR/$tdir/foo_161c
15392         touch $DIR/$tdir/bar_161c
15393         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15394         changelog_dump | grep RENME | tail -n 5
15395         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15396         changelog_clear 0 || error "changelog_clear failed"
15397         if [ x$flags != "x0x1" ]; then
15398                 error "flag $flags is not 0x1"
15399         fi
15400
15401         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15402         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15403         touch $DIR/$tdir/foo_161c
15404         touch $DIR/$tdir/bar_161c
15405         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15406         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15407         changelog_dump | grep RENME | tail -n 5
15408         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15409         changelog_clear 0 || error "changelog_clear failed"
15410         if [ x$flags != "x0x0" ]; then
15411                 error "flag $flags is not 0x0"
15412         fi
15413         echo "rename overwrite a target having nlink > 1," \
15414                 "changelog record has flags of $flags"
15415
15416         # rename doesn't overwrite a target (changelog flag 0x0)
15417         touch $DIR/$tdir/foo_161c
15418         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15419         changelog_dump | grep RENME | tail -n 5
15420         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15421         changelog_clear 0 || error "changelog_clear failed"
15422         if [ x$flags != "x0x0" ]; then
15423                 error "flag $flags is not 0x0"
15424         fi
15425         echo "rename doesn't overwrite a target," \
15426                 "changelog record has flags of $flags"
15427
15428         # define CLF_UNLINK_LAST 0x0001
15429         # unlink a file having nlink = 1 (changelog flag 0x1)
15430         rm -f $DIR/$tdir/foo2_161c
15431         changelog_dump | grep UNLNK | tail -n 5
15432         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15433         changelog_clear 0 || error "changelog_clear failed"
15434         if [ x$flags != "x0x1" ]; then
15435                 error "flag $flags is not 0x1"
15436         fi
15437         echo "unlink a file having nlink = 1," \
15438                 "changelog record has flags of $flags"
15439
15440         # unlink a file having nlink > 1 (changelog flag 0x0)
15441         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15442         rm -f $DIR/$tdir/foobar_161c
15443         changelog_dump | grep UNLNK | tail -n 5
15444         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15445         changelog_clear 0 || error "changelog_clear failed"
15446         if [ x$flags != "x0x0" ]; then
15447                 error "flag $flags is not 0x0"
15448         fi
15449         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15450 }
15451 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15452
15453 test_161d() {
15454         remote_mds_nodsh && skip "remote MDS with nodsh"
15455         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15456
15457         local pid
15458         local fid
15459
15460         changelog_register || error "changelog_register failed"
15461
15462         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15463         # interfer with $MOUNT/.lustre/fid/ access
15464         mkdir $DIR/$tdir
15465         [[ $? -eq 0 ]] || error "mkdir failed"
15466
15467         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15468         $LCTL set_param fail_loc=0x8000140c
15469         # 5s pause
15470         $LCTL set_param fail_val=5
15471
15472         # create file
15473         echo foofoo > $DIR/$tdir/$tfile &
15474         pid=$!
15475
15476         # wait for create to be delayed
15477         sleep 2
15478
15479         ps -p $pid
15480         [[ $? -eq 0 ]] || error "create should be blocked"
15481
15482         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15483         stack_trap "rm -f $tempfile"
15484         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15485         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15486         # some delay may occur during ChangeLog publishing and file read just
15487         # above, that could allow file write to happen finally
15488         [[ -s $tempfile ]] && echo "file should be empty"
15489
15490         $LCTL set_param fail_loc=0
15491
15492         wait $pid
15493         [[ $? -eq 0 ]] || error "create failed"
15494 }
15495 run_test 161d "create with concurrent .lustre/fid access"
15496
15497 check_path() {
15498         local expected="$1"
15499         shift
15500         local fid="$2"
15501
15502         local path
15503         path=$($LFS fid2path "$@")
15504         local rc=$?
15505
15506         if [ $rc -ne 0 ]; then
15507                 error "path looked up of '$expected' failed: rc=$rc"
15508         elif [ "$path" != "$expected" ]; then
15509                 error "path looked up '$path' instead of '$expected'"
15510         else
15511                 echo "FID '$fid' resolves to path '$path' as expected"
15512         fi
15513 }
15514
15515 test_162a() { # was test_162
15516         test_mkdir -p -c1 $DIR/$tdir/d2
15517         touch $DIR/$tdir/d2/$tfile
15518         touch $DIR/$tdir/d2/x1
15519         touch $DIR/$tdir/d2/x2
15520         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15521         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15522         # regular file
15523         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15524         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15525
15526         # softlink
15527         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15528         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15529         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15530
15531         # softlink to wrong file
15532         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15533         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15534         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15535
15536         # hardlink
15537         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15538         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15539         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15540         # fid2path dir/fsname should both work
15541         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15542         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15543
15544         # hardlink count: check that there are 2 links
15545         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15546         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15547
15548         # hardlink indexing: remove the first link
15549         rm $DIR/$tdir/d2/p/q/r/hlink
15550         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15551 }
15552 run_test 162a "path lookup sanity"
15553
15554 test_162b() {
15555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15556         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15557
15558         mkdir $DIR/$tdir
15559         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15560                                 error "create striped dir failed"
15561
15562         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15563                                         tail -n 1 | awk '{print $2}')
15564         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15565
15566         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15567         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15568
15569         # regular file
15570         for ((i=0;i<5;i++)); do
15571                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15572                         error "get fid for f$i failed"
15573                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15574
15575                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15576                         error "get fid for d$i failed"
15577                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15578         done
15579
15580         return 0
15581 }
15582 run_test 162b "striped directory path lookup sanity"
15583
15584 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15585 test_162c() {
15586         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15587                 skip "Need MDS version at least 2.7.51"
15588
15589         local lpath=$tdir.local
15590         local rpath=$tdir.remote
15591
15592         test_mkdir $DIR/$lpath
15593         test_mkdir $DIR/$rpath
15594
15595         for ((i = 0; i <= 101; i++)); do
15596                 lpath="$lpath/$i"
15597                 mkdir $DIR/$lpath
15598                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15599                         error "get fid for local directory $DIR/$lpath failed"
15600                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15601
15602                 rpath="$rpath/$i"
15603                 test_mkdir $DIR/$rpath
15604                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15605                         error "get fid for remote directory $DIR/$rpath failed"
15606                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15607         done
15608
15609         return 0
15610 }
15611 run_test 162c "fid2path works with paths 100 or more directories deep"
15612
15613 oalr_event_count() {
15614         local event="${1}"
15615         local trace="${2}"
15616
15617         awk -v name="${FSNAME}-OST0000" \
15618             -v event="${event}" \
15619             '$1 == "TRACE" && $2 == event && $3 == name' \
15620             "${trace}" |
15621         wc -l
15622 }
15623
15624 oalr_expect_event_count() {
15625         local event="${1}"
15626         local trace="${2}"
15627         local expect="${3}"
15628         local count
15629
15630         count=$(oalr_event_count "${event}" "${trace}")
15631         if ((count == expect)); then
15632                 return 0
15633         fi
15634
15635         error_noexit "${event} event count was '${count}', expected ${expect}"
15636         cat "${trace}" >&2
15637         exit 1
15638 }
15639
15640 cleanup_165() {
15641         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15642         stop ost1
15643         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15644 }
15645
15646 setup_165() {
15647         sync # Flush previous IOs so we can count log entries.
15648         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15649         stack_trap cleanup_165 EXIT
15650 }
15651
15652 test_165a() {
15653         local trace="/tmp/${tfile}.trace"
15654         local rc
15655         local count
15656
15657         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15658                 skip "OFD access log unsupported"
15659
15660         setup_165
15661         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15662         sleep 5
15663
15664         do_facet ost1 ofd_access_log_reader --list
15665         stop ost1
15666
15667         do_facet ost1 killall -TERM ofd_access_log_reader
15668         wait
15669         rc=$?
15670
15671         if ((rc != 0)); then
15672                 error "ofd_access_log_reader exited with rc = '${rc}'"
15673         fi
15674
15675         # Parse trace file for discovery events:
15676         oalr_expect_event_count alr_log_add "${trace}" 1
15677         oalr_expect_event_count alr_log_eof "${trace}" 1
15678         oalr_expect_event_count alr_log_free "${trace}" 1
15679 }
15680 run_test 165a "ofd access log discovery"
15681
15682 test_165b() {
15683         local trace="/tmp/${tfile}.trace"
15684         local file="${DIR}/${tfile}"
15685         local pfid1
15686         local pfid2
15687         local -a entry
15688         local rc
15689         local count
15690         local size
15691         local flags
15692
15693         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15694                 skip "OFD access log unsupported"
15695
15696         setup_165
15697         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15698         sleep 5
15699
15700         do_facet ost1 ofd_access_log_reader --list
15701
15702         lfs setstripe -c 1 -i 0 "${file}"
15703         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15704                 error "cannot create '${file}'"
15705
15706         sleep 5
15707         do_facet ost1 killall -TERM ofd_access_log_reader
15708         wait
15709         rc=$?
15710
15711         if ((rc != 0)); then
15712                 error "ofd_access_log_reader exited with rc = '${rc}'"
15713         fi
15714
15715         oalr_expect_event_count alr_log_entry "${trace}" 1
15716
15717         pfid1=$($LFS path2fid "${file}")
15718
15719         # 1     2             3   4    5     6   7    8    9     10
15720         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15721         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15722
15723         echo "entry = '${entry[*]}'" >&2
15724
15725         pfid2=${entry[4]}
15726         if [[ "${pfid1}" != "${pfid2}" ]]; then
15727                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15728         fi
15729
15730         size=${entry[8]}
15731         if ((size != 1048576)); then
15732                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15733         fi
15734
15735         flags=${entry[10]}
15736         if [[ "${flags}" != "w" ]]; then
15737                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15738         fi
15739
15740         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15741         sleep 5
15742
15743         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
15744                 error "cannot read '${file}'"
15745         sleep 5
15746
15747         do_facet ost1 killall -TERM ofd_access_log_reader
15748         wait
15749         rc=$?
15750
15751         if ((rc != 0)); then
15752                 error "ofd_access_log_reader exited with rc = '${rc}'"
15753         fi
15754
15755         oalr_expect_event_count alr_log_entry "${trace}" 1
15756
15757         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15758         echo "entry = '${entry[*]}'" >&2
15759
15760         pfid2=${entry[4]}
15761         if [[ "${pfid1}" != "${pfid2}" ]]; then
15762                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15763         fi
15764
15765         size=${entry[8]}
15766         if ((size != 524288)); then
15767                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15768         fi
15769
15770         flags=${entry[10]}
15771         if [[ "${flags}" != "r" ]]; then
15772                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15773         fi
15774 }
15775 run_test 165b "ofd access log entries are produced and consumed"
15776
15777 test_165c() {
15778         local trace="/tmp/${tfile}.trace"
15779         local file="${DIR}/${tdir}/${tfile}"
15780
15781         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15782                 skip "OFD access log unsupported"
15783
15784         test_mkdir "${DIR}/${tdir}"
15785
15786         setup_165
15787         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15788         sleep 5
15789
15790         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15791
15792         # 4096 / 64 = 64. Create twice as many entries.
15793         for ((i = 0; i < 128; i++)); do
15794                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
15795                         error "cannot create file"
15796         done
15797
15798         sync
15799
15800         do_facet ost1 killall -TERM ofd_access_log_reader
15801         wait
15802         rc=$?
15803         if ((rc != 0)); then
15804                 error "ofd_access_log_reader exited with rc = '${rc}'"
15805         fi
15806
15807         unlinkmany  "${file}-%d" 128
15808 }
15809 run_test 165c "full ofd access logs do not block IOs"
15810
15811 oal_get_read_count() {
15812         local stats="$1"
15813
15814         # STATS lustre-OST0001 alr_read_count 1
15815
15816         do_facet ost1 cat "${stats}" |
15817         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
15818              END { print count; }'
15819 }
15820
15821 oal_expect_read_count() {
15822         local stats="$1"
15823         local count
15824         local expect="$2"
15825
15826         # Ask ofd_access_log_reader to write stats.
15827         do_facet ost1 killall -USR1 ofd_access_log_reader
15828
15829         # Allow some time for things to happen.
15830         sleep 1
15831
15832         count=$(oal_get_read_count "${stats}")
15833         if ((count == expect)); then
15834                 return 0
15835         fi
15836
15837         error_noexit "bad read count, got ${count}, expected ${expect}"
15838         do_facet ost1 cat "${stats}" >&2
15839         exit 1
15840 }
15841
15842 test_165d() {
15843         local stats="/tmp/${tfile}.stats"
15844         local file="${DIR}/${tdir}/${tfile}"
15845         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15846
15847         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15848                 skip "OFD access log unsupported"
15849
15850         test_mkdir "${DIR}/${tdir}"
15851
15852         setup_165
15853         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
15854         sleep 5
15855
15856         lfs setstripe -c 1 -i 0 "${file}"
15857
15858         do_facet ost1 lctl set_param "${param}=rw"
15859         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15860                 error "cannot create '${file}'"
15861         oal_expect_read_count "${stats}" 1
15862
15863         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15864                 error "cannot read '${file}'"
15865         oal_expect_read_count "${stats}" 2
15866
15867         do_facet ost1 lctl set_param "${param}=r"
15868         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15869                 error "cannot create '${file}'"
15870         oal_expect_read_count "${stats}" 2
15871
15872         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15873                 error "cannot read '${file}'"
15874         oal_expect_read_count "${stats}" 3
15875
15876         do_facet ost1 lctl set_param "${param}=w"
15877         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15878                 error "cannot create '${file}'"
15879         oal_expect_read_count "${stats}" 4
15880
15881         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15882                 error "cannot read '${file}'"
15883         oal_expect_read_count "${stats}" 4
15884
15885         do_facet ost1 lctl set_param "${param}=0"
15886         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15887                 error "cannot create '${file}'"
15888         oal_expect_read_count "${stats}" 4
15889
15890         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15891                 error "cannot read '${file}'"
15892         oal_expect_read_count "${stats}" 4
15893
15894         do_facet ost1 killall -TERM ofd_access_log_reader
15895         wait
15896         rc=$?
15897         if ((rc != 0)); then
15898                 error "ofd_access_log_reader exited with rc = '${rc}'"
15899         fi
15900 }
15901 run_test 165d "ofd_access_log mask works"
15902
15903 test_165e() {
15904         local stats="/tmp/${tfile}.stats"
15905         local file0="${DIR}/${tdir}-0/${tfile}"
15906         local file1="${DIR}/${tdir}-1/${tfile}"
15907
15908         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15909                 skip "OFD access log unsupported"
15910
15911         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
15912
15913         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
15914         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
15915
15916         lfs setstripe -c 1 -i 0 "${file0}"
15917         lfs setstripe -c 1 -i 0 "${file1}"
15918
15919         setup_165
15920         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
15921         sleep 5
15922
15923         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
15924                 error "cannot create '${file0}'"
15925         sync
15926         oal_expect_read_count "${stats}" 0
15927
15928         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
15929                 error "cannot create '${file1}'"
15930         sync
15931         oal_expect_read_count "${stats}" 1
15932
15933         do_facet ost1 killall -TERM ofd_access_log_reader
15934         wait
15935         rc=$?
15936         if ((rc != 0)); then
15937                 error "ofd_access_log_reader exited with rc = '${rc}'"
15938         fi
15939 }
15940 run_test 165e "ofd_access_log MDT index filter works"
15941
15942 test_165f() {
15943         local trace="/tmp/${tfile}.trace"
15944         local rc
15945         local count
15946
15947         setup_165
15948         do_facet ost1 timeout 60 ofd_access_log_reader \
15949                 --exit-on-close --debug=- --trace=- > "${trace}" &
15950         sleep 5
15951         stop ost1
15952
15953         wait
15954         rc=$?
15955
15956         if ((rc != 0)); then
15957                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
15958                 cat "${trace}"
15959                 exit 1
15960         fi
15961 }
15962 run_test 165f "ofd_access_log_reader --exit-on-close works"
15963
15964 test_169() {
15965         # do directio so as not to populate the page cache
15966         log "creating a 10 Mb file"
15967         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
15968                 error "multiop failed while creating a file"
15969         log "starting reads"
15970         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15971         log "truncating the file"
15972         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
15973                 error "multiop failed while truncating the file"
15974         log "killing dd"
15975         kill %+ || true # reads might have finished
15976         echo "wait until dd is finished"
15977         wait
15978         log "removing the temporary file"
15979         rm -rf $DIR/$tfile || error "tmp file removal failed"
15980 }
15981 run_test 169 "parallel read and truncate should not deadlock"
15982
15983 test_170() {
15984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15985
15986         $LCTL clear     # bug 18514
15987         $LCTL debug_daemon start $TMP/${tfile}_log_good
15988         touch $DIR/$tfile
15989         $LCTL debug_daemon stop
15990         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15991                 error "sed failed to read log_good"
15992
15993         $LCTL debug_daemon start $TMP/${tfile}_log_good
15994         rm -rf $DIR/$tfile
15995         $LCTL debug_daemon stop
15996
15997         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15998                error "lctl df log_bad failed"
15999
16000         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16001         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16002
16003         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16004         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16005
16006         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16007                 error "bad_line good_line1 good_line2 are empty"
16008
16009         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16010         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16011         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16012
16013         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16014         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16015         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16016
16017         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16018                 error "bad_line_new good_line_new are empty"
16019
16020         local expected_good=$((good_line1 + good_line2*2))
16021
16022         rm -f $TMP/${tfile}*
16023         # LU-231, short malformed line may not be counted into bad lines
16024         if [ $bad_line -ne $bad_line_new ] &&
16025                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16026                 error "expected $bad_line bad lines, but got $bad_line_new"
16027                 return 1
16028         fi
16029
16030         if [ $expected_good -ne $good_line_new ]; then
16031                 error "expected $expected_good good lines, but got $good_line_new"
16032                 return 2
16033         fi
16034         true
16035 }
16036 run_test 170 "test lctl df to handle corrupted log ====================="
16037
16038 test_171() { # bug20592
16039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16040
16041         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16042         $LCTL set_param fail_loc=0x50e
16043         $LCTL set_param fail_val=3000
16044         multiop_bg_pause $DIR/$tfile O_s || true
16045         local MULTIPID=$!
16046         kill -USR1 $MULTIPID
16047         # cause log dump
16048         sleep 3
16049         wait $MULTIPID
16050         if dmesg | grep "recursive fault"; then
16051                 error "caught a recursive fault"
16052         fi
16053         $LCTL set_param fail_loc=0
16054         true
16055 }
16056 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16057
16058 # it would be good to share it with obdfilter-survey/iokit-libecho code
16059 setup_obdecho_osc () {
16060         local rc=0
16061         local ost_nid=$1
16062         local obdfilter_name=$2
16063         echo "Creating new osc for $obdfilter_name on $ost_nid"
16064         # make sure we can find loopback nid
16065         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16066
16067         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16068                            ${obdfilter_name}_osc_UUID || rc=2; }
16069         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16070                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16071         return $rc
16072 }
16073
16074 cleanup_obdecho_osc () {
16075         local obdfilter_name=$1
16076         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16077         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16078         return 0
16079 }
16080
16081 obdecho_test() {
16082         local OBD=$1
16083         local node=$2
16084         local pages=${3:-64}
16085         local rc=0
16086         local id
16087
16088         local count=10
16089         local obd_size=$(get_obd_size $node $OBD)
16090         local page_size=$(get_page_size $node)
16091         if [[ -n "$obd_size" ]]; then
16092                 local new_count=$((obd_size / (pages * page_size / 1024)))
16093                 [[ $new_count -ge $count ]] || count=$new_count
16094         fi
16095
16096         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16097         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16098                            rc=2; }
16099         if [ $rc -eq 0 ]; then
16100             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16101             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16102         fi
16103         echo "New object id is $id"
16104         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16105                            rc=4; }
16106         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16107                            "test_brw $count w v $pages $id" || rc=4; }
16108         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16109                            rc=4; }
16110         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16111                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16112         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16113                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16114         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16115         return $rc
16116 }
16117
16118 test_180a() {
16119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16120
16121         if ! [ -d /sys/fs/lustre/echo_client ] &&
16122            ! module_loaded obdecho; then
16123                 load_module obdecho/obdecho &&
16124                         stack_trap "rmmod obdecho" EXIT ||
16125                         error "unable to load obdecho on client"
16126         fi
16127
16128         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16129         local host=$($LCTL get_param -n osc.$osc.import |
16130                      awk '/current_connection:/ { print $2 }' )
16131         local target=$($LCTL get_param -n osc.$osc.import |
16132                        awk '/target:/ { print $2 }' )
16133         target=${target%_UUID}
16134
16135         if [ -n "$target" ]; then
16136                 setup_obdecho_osc $host $target &&
16137                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16138                         { error "obdecho setup failed with $?"; return; }
16139
16140                 obdecho_test ${target}_osc client ||
16141                         error "obdecho_test failed on ${target}_osc"
16142         else
16143                 $LCTL get_param osc.$osc.import
16144                 error "there is no osc.$osc.import target"
16145         fi
16146 }
16147 run_test 180a "test obdecho on osc"
16148
16149 test_180b() {
16150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16151         remote_ost_nodsh && skip "remote OST with nodsh"
16152
16153         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16154                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16155                 error "failed to load module obdecho"
16156
16157         local target=$(do_facet ost1 $LCTL dl |
16158                        awk '/obdfilter/ { print $4; exit; }')
16159
16160         if [ -n "$target" ]; then
16161                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16162         else
16163                 do_facet ost1 $LCTL dl
16164                 error "there is no obdfilter target on ost1"
16165         fi
16166 }
16167 run_test 180b "test obdecho directly on obdfilter"
16168
16169 test_180c() { # LU-2598
16170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16171         remote_ost_nodsh && skip "remote OST with nodsh"
16172         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16173                 skip "Need MDS version at least 2.4.0"
16174
16175         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16176                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16177                 error "failed to load module obdecho"
16178
16179         local target=$(do_facet ost1 $LCTL dl |
16180                        awk '/obdfilter/ { print $4; exit; }')
16181
16182         if [ -n "$target" ]; then
16183                 local pages=16384 # 64MB bulk I/O RPC size
16184
16185                 obdecho_test "$target" ost1 "$pages" ||
16186                         error "obdecho_test with pages=$pages failed with $?"
16187         else
16188                 do_facet ost1 $LCTL dl
16189                 error "there is no obdfilter target on ost1"
16190         fi
16191 }
16192 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16193
16194 test_181() { # bug 22177
16195         test_mkdir $DIR/$tdir
16196         # create enough files to index the directory
16197         createmany -o $DIR/$tdir/foobar 4000
16198         # print attributes for debug purpose
16199         lsattr -d .
16200         # open dir
16201         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16202         MULTIPID=$!
16203         # remove the files & current working dir
16204         unlinkmany $DIR/$tdir/foobar 4000
16205         rmdir $DIR/$tdir
16206         kill -USR1 $MULTIPID
16207         wait $MULTIPID
16208         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16209         return 0
16210 }
16211 run_test 181 "Test open-unlinked dir ========================"
16212
16213 test_182() {
16214         local fcount=1000
16215         local tcount=10
16216
16217         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16218
16219         $LCTL set_param mdc.*.rpc_stats=clear
16220
16221         for (( i = 0; i < $tcount; i++ )) ; do
16222                 mkdir $DIR/$tdir/$i
16223         done
16224
16225         for (( i = 0; i < $tcount; i++ )) ; do
16226                 createmany -o $DIR/$tdir/$i/f- $fcount &
16227         done
16228         wait
16229
16230         for (( i = 0; i < $tcount; i++ )) ; do
16231                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16232         done
16233         wait
16234
16235         $LCTL get_param mdc.*.rpc_stats
16236
16237         rm -rf $DIR/$tdir
16238 }
16239 run_test 182 "Test parallel modify metadata operations ================"
16240
16241 test_183() { # LU-2275
16242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16243         remote_mds_nodsh && skip "remote MDS with nodsh"
16244         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16245                 skip "Need MDS version at least 2.3.56"
16246
16247         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16248         echo aaa > $DIR/$tdir/$tfile
16249
16250 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16251         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16252
16253         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16254         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16255
16256         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16257
16258         # Flush negative dentry cache
16259         touch $DIR/$tdir/$tfile
16260
16261         # We are not checking for any leaked references here, they'll
16262         # become evident next time we do cleanup with module unload.
16263         rm -rf $DIR/$tdir
16264 }
16265 run_test 183 "No crash or request leak in case of strange dispositions ========"
16266
16267 # test suite 184 is for LU-2016, LU-2017
16268 test_184a() {
16269         check_swap_layouts_support
16270
16271         dir0=$DIR/$tdir/$testnum
16272         test_mkdir -p -c1 $dir0
16273         ref1=/etc/passwd
16274         ref2=/etc/group
16275         file1=$dir0/f1
16276         file2=$dir0/f2
16277         $LFS setstripe -c1 $file1
16278         cp $ref1 $file1
16279         $LFS setstripe -c2 $file2
16280         cp $ref2 $file2
16281         gen1=$($LFS getstripe -g $file1)
16282         gen2=$($LFS getstripe -g $file2)
16283
16284         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16285         gen=$($LFS getstripe -g $file1)
16286         [[ $gen1 != $gen ]] ||
16287                 "Layout generation on $file1 does not change"
16288         gen=$($LFS getstripe -g $file2)
16289         [[ $gen2 != $gen ]] ||
16290                 "Layout generation on $file2 does not change"
16291
16292         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16293         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16294
16295         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16296 }
16297 run_test 184a "Basic layout swap"
16298
16299 test_184b() {
16300         check_swap_layouts_support
16301
16302         dir0=$DIR/$tdir/$testnum
16303         mkdir -p $dir0 || error "creating dir $dir0"
16304         file1=$dir0/f1
16305         file2=$dir0/f2
16306         file3=$dir0/f3
16307         dir1=$dir0/d1
16308         dir2=$dir0/d2
16309         mkdir $dir1 $dir2
16310         $LFS setstripe -c1 $file1
16311         $LFS setstripe -c2 $file2
16312         $LFS setstripe -c1 $file3
16313         chown $RUNAS_ID $file3
16314         gen1=$($LFS getstripe -g $file1)
16315         gen2=$($LFS getstripe -g $file2)
16316
16317         $LFS swap_layouts $dir1 $dir2 &&
16318                 error "swap of directories layouts should fail"
16319         $LFS swap_layouts $dir1 $file1 &&
16320                 error "swap of directory and file layouts should fail"
16321         $RUNAS $LFS swap_layouts $file1 $file2 &&
16322                 error "swap of file we cannot write should fail"
16323         $LFS swap_layouts $file1 $file3 &&
16324                 error "swap of file with different owner should fail"
16325         /bin/true # to clear error code
16326 }
16327 run_test 184b "Forbidden layout swap (will generate errors)"
16328
16329 test_184c() {
16330         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16331         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16332         check_swap_layouts_support
16333         check_swap_layout_no_dom $DIR
16334
16335         local dir0=$DIR/$tdir/$testnum
16336         mkdir -p $dir0 || error "creating dir $dir0"
16337
16338         local ref1=$dir0/ref1
16339         local ref2=$dir0/ref2
16340         local file1=$dir0/file1
16341         local file2=$dir0/file2
16342         # create a file large enough for the concurrent test
16343         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16344         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16345         echo "ref file size: ref1($(stat -c %s $ref1))," \
16346              "ref2($(stat -c %s $ref2))"
16347
16348         cp $ref2 $file2
16349         dd if=$ref1 of=$file1 bs=16k &
16350         local DD_PID=$!
16351
16352         # Make sure dd starts to copy file, but wait at most 5 seconds
16353         local loops=0
16354         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16355
16356         $LFS swap_layouts $file1 $file2
16357         local rc=$?
16358         wait $DD_PID
16359         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16360         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16361
16362         # how many bytes copied before swapping layout
16363         local copied=$(stat -c %s $file2)
16364         local remaining=$(stat -c %s $ref1)
16365         remaining=$((remaining - copied))
16366         echo "Copied $copied bytes before swapping layout..."
16367
16368         cmp -n $copied $file1 $ref2 | grep differ &&
16369                 error "Content mismatch [0, $copied) of ref2 and file1"
16370         cmp -n $copied $file2 $ref1 ||
16371                 error "Content mismatch [0, $copied) of ref1 and file2"
16372         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16373                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16374
16375         # clean up
16376         rm -f $ref1 $ref2 $file1 $file2
16377 }
16378 run_test 184c "Concurrent write and layout swap"
16379
16380 test_184d() {
16381         check_swap_layouts_support
16382         check_swap_layout_no_dom $DIR
16383         [ -z "$(which getfattr 2>/dev/null)" ] &&
16384                 skip_env "no getfattr command"
16385
16386         local file1=$DIR/$tdir/$tfile-1
16387         local file2=$DIR/$tdir/$tfile-2
16388         local file3=$DIR/$tdir/$tfile-3
16389         local lovea1
16390         local lovea2
16391
16392         mkdir -p $DIR/$tdir
16393         touch $file1 || error "create $file1 failed"
16394         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16395                 error "create $file2 failed"
16396         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16397                 error "create $file3 failed"
16398         lovea1=$(get_layout_param $file1)
16399
16400         $LFS swap_layouts $file2 $file3 ||
16401                 error "swap $file2 $file3 layouts failed"
16402         $LFS swap_layouts $file1 $file2 ||
16403                 error "swap $file1 $file2 layouts failed"
16404
16405         lovea2=$(get_layout_param $file2)
16406         echo "$lovea1"
16407         echo "$lovea2"
16408         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16409
16410         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16411         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16412 }
16413 run_test 184d "allow stripeless layouts swap"
16414
16415 test_184e() {
16416         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16417                 skip "Need MDS version at least 2.6.94"
16418         check_swap_layouts_support
16419         check_swap_layout_no_dom $DIR
16420         [ -z "$(which getfattr 2>/dev/null)" ] &&
16421                 skip_env "no getfattr command"
16422
16423         local file1=$DIR/$tdir/$tfile-1
16424         local file2=$DIR/$tdir/$tfile-2
16425         local file3=$DIR/$tdir/$tfile-3
16426         local lovea
16427
16428         mkdir -p $DIR/$tdir
16429         touch $file1 || error "create $file1 failed"
16430         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16431                 error "create $file2 failed"
16432         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16433                 error "create $file3 failed"
16434
16435         $LFS swap_layouts $file1 $file2 ||
16436                 error "swap $file1 $file2 layouts failed"
16437
16438         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16439         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16440
16441         echo 123 > $file1 || error "Should be able to write into $file1"
16442
16443         $LFS swap_layouts $file1 $file3 ||
16444                 error "swap $file1 $file3 layouts failed"
16445
16446         echo 123 > $file1 || error "Should be able to write into $file1"
16447
16448         rm -rf $file1 $file2 $file3
16449 }
16450 run_test 184e "Recreate layout after stripeless layout swaps"
16451
16452 test_184f() {
16453         # Create a file with name longer than sizeof(struct stat) ==
16454         # 144 to see if we can get chars from the file name to appear
16455         # in the returned striping. Note that 'f' == 0x66.
16456         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16457
16458         mkdir -p $DIR/$tdir
16459         mcreate $DIR/$tdir/$file
16460         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16461                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16462         fi
16463 }
16464 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16465
16466 test_185() { # LU-2441
16467         # LU-3553 - no volatile file support in old servers
16468         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16469                 skip "Need MDS version at least 2.3.60"
16470
16471         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16472         touch $DIR/$tdir/spoo
16473         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16474         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16475                 error "cannot create/write a volatile file"
16476         [ "$FILESET" == "" ] &&
16477         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16478                 error "FID is still valid after close"
16479
16480         multiop_bg_pause $DIR/$tdir vVw4096_c
16481         local multi_pid=$!
16482
16483         local OLD_IFS=$IFS
16484         IFS=":"
16485         local fidv=($fid)
16486         IFS=$OLD_IFS
16487         # assume that the next FID for this client is sequential, since stdout
16488         # is unfortunately eaten by multiop_bg_pause
16489         local n=$((${fidv[1]} + 1))
16490         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16491         if [ "$FILESET" == "" ]; then
16492                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16493                         error "FID is missing before close"
16494         fi
16495         kill -USR1 $multi_pid
16496         # 1 second delay, so if mtime change we will see it
16497         sleep 1
16498         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16499         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16500 }
16501 run_test 185 "Volatile file support"
16502
16503 function create_check_volatile() {
16504         local idx=$1
16505         local tgt
16506
16507         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16508         local PID=$!
16509         sleep 1
16510         local FID=$(cat /tmp/${tfile}.fid)
16511         [ "$FID" == "" ] && error "can't get FID for volatile"
16512         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16513         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16514         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16515         kill -USR1 $PID
16516         wait
16517         sleep 1
16518         cancel_lru_locks mdc # flush opencache
16519         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16520         return 0
16521 }
16522
16523 test_185a(){
16524         # LU-12516 - volatile creation via .lustre
16525         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16526                 skip "Need MDS version at least 2.3.55"
16527
16528         create_check_volatile 0
16529         [ $MDSCOUNT -lt 2 ] && return 0
16530
16531         # DNE case
16532         create_check_volatile 1
16533
16534         return 0
16535 }
16536 run_test 185a "Volatile file creation in .lustre/fid/"
16537
16538 test_187a() {
16539         remote_mds_nodsh && skip "remote MDS with nodsh"
16540         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16541                 skip "Need MDS version at least 2.3.0"
16542
16543         local dir0=$DIR/$tdir/$testnum
16544         mkdir -p $dir0 || error "creating dir $dir0"
16545
16546         local file=$dir0/file1
16547         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16548         local dv1=$($LFS data_version $file)
16549         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16550         local dv2=$($LFS data_version $file)
16551         [[ $dv1 != $dv2 ]] ||
16552                 error "data version did not change on write $dv1 == $dv2"
16553
16554         # clean up
16555         rm -f $file1
16556 }
16557 run_test 187a "Test data version change"
16558
16559 test_187b() {
16560         remote_mds_nodsh && skip "remote MDS with nodsh"
16561         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16562                 skip "Need MDS version at least 2.3.0"
16563
16564         local dir0=$DIR/$tdir/$testnum
16565         mkdir -p $dir0 || error "creating dir $dir0"
16566
16567         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16568         [[ ${DV[0]} != ${DV[1]} ]] ||
16569                 error "data version did not change on write"\
16570                       " ${DV[0]} == ${DV[1]}"
16571
16572         # clean up
16573         rm -f $file1
16574 }
16575 run_test 187b "Test data version change on volatile file"
16576
16577 test_200() {
16578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16579         remote_mgs_nodsh && skip "remote MGS with nodsh"
16580         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16581
16582         local POOL=${POOL:-cea1}
16583         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16584         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16585         # Pool OST targets
16586         local first_ost=0
16587         local last_ost=$(($OSTCOUNT - 1))
16588         local ost_step=2
16589         local ost_list=$(seq $first_ost $ost_step $last_ost)
16590         local ost_range="$first_ost $last_ost $ost_step"
16591         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16592         local file_dir=$POOL_ROOT/file_tst
16593         local subdir=$test_path/subdir
16594         local rc=0
16595
16596         while : ; do
16597                 # former test_200a test_200b
16598                 pool_add $POOL                          || { rc=$? ; break; }
16599                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16600                 # former test_200c test_200d
16601                 mkdir -p $test_path
16602                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16603                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16604                 mkdir -p $subdir
16605                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16606                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16607                                                         || { rc=$? ; break; }
16608                 # former test_200e test_200f
16609                 local files=$((OSTCOUNT*3))
16610                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16611                                                         || { rc=$? ; break; }
16612                 pool_create_files $POOL $file_dir $files "$ost_list" \
16613                                                         || { rc=$? ; break; }
16614                 # former test_200g test_200h
16615                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16616                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16617
16618                 # former test_201a test_201b test_201c
16619                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16620
16621                 local f=$test_path/$tfile
16622                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16623                 pool_remove $POOL $f                    || { rc=$? ; break; }
16624                 break
16625         done
16626
16627         destroy_test_pools
16628
16629         return $rc
16630 }
16631 run_test 200 "OST pools"
16632
16633 # usage: default_attr <count | size | offset>
16634 default_attr() {
16635         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16636 }
16637
16638 # usage: check_default_stripe_attr
16639 check_default_stripe_attr() {
16640         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16641         case $1 in
16642         --stripe-count|-c)
16643                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16644         --stripe-size|-S)
16645                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16646         --stripe-index|-i)
16647                 EXPECTED=-1;;
16648         *)
16649                 error "unknown getstripe attr '$1'"
16650         esac
16651
16652         [ $ACTUAL == $EXPECTED ] ||
16653                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16654 }
16655
16656 test_204a() {
16657         test_mkdir $DIR/$tdir
16658         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16659
16660         check_default_stripe_attr --stripe-count
16661         check_default_stripe_attr --stripe-size
16662         check_default_stripe_attr --stripe-index
16663 }
16664 run_test 204a "Print default stripe attributes"
16665
16666 test_204b() {
16667         test_mkdir $DIR/$tdir
16668         $LFS setstripe --stripe-count 1 $DIR/$tdir
16669
16670         check_default_stripe_attr --stripe-size
16671         check_default_stripe_attr --stripe-index
16672 }
16673 run_test 204b "Print default stripe size and offset"
16674
16675 test_204c() {
16676         test_mkdir $DIR/$tdir
16677         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16678
16679         check_default_stripe_attr --stripe-count
16680         check_default_stripe_attr --stripe-index
16681 }
16682 run_test 204c "Print default stripe count and offset"
16683
16684 test_204d() {
16685         test_mkdir $DIR/$tdir
16686         $LFS setstripe --stripe-index 0 $DIR/$tdir
16687
16688         check_default_stripe_attr --stripe-count
16689         check_default_stripe_attr --stripe-size
16690 }
16691 run_test 204d "Print default stripe count and size"
16692
16693 test_204e() {
16694         test_mkdir $DIR/$tdir
16695         $LFS setstripe -d $DIR/$tdir
16696
16697         check_default_stripe_attr --stripe-count --raw
16698         check_default_stripe_attr --stripe-size --raw
16699         check_default_stripe_attr --stripe-index --raw
16700 }
16701 run_test 204e "Print raw stripe attributes"
16702
16703 test_204f() {
16704         test_mkdir $DIR/$tdir
16705         $LFS setstripe --stripe-count 1 $DIR/$tdir
16706
16707         check_default_stripe_attr --stripe-size --raw
16708         check_default_stripe_attr --stripe-index --raw
16709 }
16710 run_test 204f "Print raw stripe size and offset"
16711
16712 test_204g() {
16713         test_mkdir $DIR/$tdir
16714         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16715
16716         check_default_stripe_attr --stripe-count --raw
16717         check_default_stripe_attr --stripe-index --raw
16718 }
16719 run_test 204g "Print raw stripe count and offset"
16720
16721 test_204h() {
16722         test_mkdir $DIR/$tdir
16723         $LFS setstripe --stripe-index 0 $DIR/$tdir
16724
16725         check_default_stripe_attr --stripe-count --raw
16726         check_default_stripe_attr --stripe-size --raw
16727 }
16728 run_test 204h "Print raw stripe count and size"
16729
16730 # Figure out which job scheduler is being used, if any,
16731 # or use a fake one
16732 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16733         JOBENV=SLURM_JOB_ID
16734 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16735         JOBENV=LSB_JOBID
16736 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16737         JOBENV=PBS_JOBID
16738 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16739         JOBENV=LOADL_STEP_ID
16740 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16741         JOBENV=JOB_ID
16742 else
16743         $LCTL list_param jobid_name > /dev/null 2>&1
16744         if [ $? -eq 0 ]; then
16745                 JOBENV=nodelocal
16746         else
16747                 JOBENV=FAKE_JOBID
16748         fi
16749 fi
16750 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16751
16752 verify_jobstats() {
16753         local cmd=($1)
16754         shift
16755         local facets="$@"
16756
16757 # we don't really need to clear the stats for this test to work, since each
16758 # command has a unique jobid, but it makes debugging easier if needed.
16759 #       for facet in $facets; do
16760 #               local dev=$(convert_facet2label $facet)
16761 #               # clear old jobstats
16762 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16763 #       done
16764
16765         # use a new JobID for each test, or we might see an old one
16766         [ "$JOBENV" = "FAKE_JOBID" ] &&
16767                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16768
16769         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16770
16771         [ "$JOBENV" = "nodelocal" ] && {
16772                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16773                 $LCTL set_param jobid_name=$FAKE_JOBID
16774                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16775         }
16776
16777         log "Test: ${cmd[*]}"
16778         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16779
16780         if [ $JOBENV = "FAKE_JOBID" ]; then
16781                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16782         else
16783                 ${cmd[*]}
16784         fi
16785
16786         # all files are created on OST0000
16787         for facet in $facets; do
16788                 local stats="*.$(convert_facet2label $facet).job_stats"
16789
16790                 # strip out libtool wrappers for in-tree executables
16791                 if [ $(do_facet $facet lctl get_param $stats |
16792                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16793                         do_facet $facet lctl get_param $stats
16794                         error "No jobstats for $JOBVAL found on $facet::$stats"
16795                 fi
16796         done
16797 }
16798
16799 jobstats_set() {
16800         local new_jobenv=$1
16801
16802         set_persistent_param_and_check client "jobid_var" \
16803                 "$FSNAME.sys.jobid_var" $new_jobenv
16804 }
16805
16806 test_205a() { # Job stats
16807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16808         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16809                 skip "Need MDS version with at least 2.7.1"
16810         remote_mgs_nodsh && skip "remote MGS with nodsh"
16811         remote_mds_nodsh && skip "remote MDS with nodsh"
16812         remote_ost_nodsh && skip "remote OST with nodsh"
16813         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16814                 skip "Server doesn't support jobstats"
16815         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16816
16817         local old_jobenv=$($LCTL get_param -n jobid_var)
16818         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16819
16820         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16821                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16822         else
16823                 stack_trap "do_facet mgs $PERM_CMD \
16824                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16825         fi
16826         changelog_register
16827
16828         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16829                                 mdt.*.job_cleanup_interval | head -n 1)
16830         local new_interval=5
16831         do_facet $SINGLEMDS \
16832                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16833         stack_trap "do_facet $SINGLEMDS \
16834                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16835         local start=$SECONDS
16836
16837         local cmd
16838         # mkdir
16839         cmd="mkdir $DIR/$tdir"
16840         verify_jobstats "$cmd" "$SINGLEMDS"
16841         # rmdir
16842         cmd="rmdir $DIR/$tdir"
16843         verify_jobstats "$cmd" "$SINGLEMDS"
16844         # mkdir on secondary MDT
16845         if [ $MDSCOUNT -gt 1 ]; then
16846                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16847                 verify_jobstats "$cmd" "mds2"
16848         fi
16849         # mknod
16850         cmd="mknod $DIR/$tfile c 1 3"
16851         verify_jobstats "$cmd" "$SINGLEMDS"
16852         # unlink
16853         cmd="rm -f $DIR/$tfile"
16854         verify_jobstats "$cmd" "$SINGLEMDS"
16855         # create all files on OST0000 so verify_jobstats can find OST stats
16856         # open & close
16857         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16858         verify_jobstats "$cmd" "$SINGLEMDS"
16859         # setattr
16860         cmd="touch $DIR/$tfile"
16861         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16862         # write
16863         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16864         verify_jobstats "$cmd" "ost1"
16865         # read
16866         cancel_lru_locks osc
16867         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16868         verify_jobstats "$cmd" "ost1"
16869         # truncate
16870         cmd="$TRUNCATE $DIR/$tfile 0"
16871         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16872         # rename
16873         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16874         verify_jobstats "$cmd" "$SINGLEMDS"
16875         # jobstats expiry - sleep until old stats should be expired
16876         local left=$((new_interval + 5 - (SECONDS - start)))
16877         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16878                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16879                         "0" $left
16880         cmd="mkdir $DIR/$tdir.expire"
16881         verify_jobstats "$cmd" "$SINGLEMDS"
16882         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16883             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16884
16885         # Ensure that jobid are present in changelog (if supported by MDS)
16886         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16887                 changelog_dump | tail -10
16888                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16889                 [ $jobids -eq 9 ] ||
16890                         error "Wrong changelog jobid count $jobids != 9"
16891
16892                 # LU-5862
16893                 JOBENV="disable"
16894                 jobstats_set $JOBENV
16895                 touch $DIR/$tfile
16896                 changelog_dump | grep $tfile
16897                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16898                 [ $jobids -eq 0 ] ||
16899                         error "Unexpected jobids when jobid_var=$JOBENV"
16900         fi
16901
16902         # test '%j' access to environment variable - if supported
16903         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16904                 JOBENV="JOBCOMPLEX"
16905                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16906
16907                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16908         fi
16909
16910         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
16911                 JOBENV="JOBCOMPLEX"
16912                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
16913
16914                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16915         fi
16916
16917         # test '%j' access to per-session jobid - if supported
16918         if lctl list_param jobid_this_session > /dev/null 2>&1
16919         then
16920                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16921                 lctl set_param jobid_this_session=$USER
16922
16923                 JOBENV="JOBCOMPLEX"
16924                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16925
16926                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16927         fi
16928 }
16929 run_test 205a "Verify job stats"
16930
16931 # LU-13117, LU-13597
16932 test_205b() {
16933         job_stats="mdt.*.job_stats"
16934         $LCTL set_param $job_stats=clear
16935         # Setting jobid_var to USER might not be supported
16936         $LCTL set_param jobid_var=USER || true
16937         $LCTL set_param jobid_name="%e.%u"
16938         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16939         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16940                 grep "job_id:.*foolish" &&
16941                         error "Unexpected jobid found"
16942         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16943                 grep "open:.*min.*max.*sum" ||
16944                         error "wrong job_stats format found"
16945 }
16946 run_test 205b "Verify job stats jobid and output format"
16947
16948 # LU-13733
16949 test_205c() {
16950         $LCTL set_param llite.*.stats=0
16951         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16952         $LCTL get_param llite.*.stats
16953         $LCTL get_param llite.*.stats | grep \
16954                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16955                         error "wrong client stats format found"
16956 }
16957 run_test 205c "Verify client stats format"
16958
16959 # LU-1480, LU-1773 and LU-1657
16960 test_206() {
16961         mkdir -p $DIR/$tdir
16962         $LFS setstripe -c -1 $DIR/$tdir
16963 #define OBD_FAIL_LOV_INIT 0x1403
16964         $LCTL set_param fail_loc=0xa0001403
16965         $LCTL set_param fail_val=1
16966         touch $DIR/$tdir/$tfile || true
16967 }
16968 run_test 206 "fail lov_init_raid0() doesn't lbug"
16969
16970 test_207a() {
16971         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16972         local fsz=`stat -c %s $DIR/$tfile`
16973         cancel_lru_locks mdc
16974
16975         # do not return layout in getattr intent
16976 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16977         $LCTL set_param fail_loc=0x170
16978         local sz=`stat -c %s $DIR/$tfile`
16979
16980         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16981
16982         rm -rf $DIR/$tfile
16983 }
16984 run_test 207a "can refresh layout at glimpse"
16985
16986 test_207b() {
16987         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16988         local cksum=`md5sum $DIR/$tfile`
16989         local fsz=`stat -c %s $DIR/$tfile`
16990         cancel_lru_locks mdc
16991         cancel_lru_locks osc
16992
16993         # do not return layout in getattr intent
16994 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16995         $LCTL set_param fail_loc=0x171
16996
16997         # it will refresh layout after the file is opened but before read issues
16998         echo checksum is "$cksum"
16999         echo "$cksum" |md5sum -c --quiet || error "file differs"
17000
17001         rm -rf $DIR/$tfile
17002 }
17003 run_test 207b "can refresh layout at open"
17004
17005 test_208() {
17006         # FIXME: in this test suite, only RD lease is used. This is okay
17007         # for now as only exclusive open is supported. After generic lease
17008         # is done, this test suite should be revised. - Jinshan
17009
17010         remote_mds_nodsh && skip "remote MDS with nodsh"
17011         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17012                 skip "Need MDS version at least 2.4.52"
17013
17014         echo "==== test 1: verify get lease work"
17015         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17016
17017         echo "==== test 2: verify lease can be broken by upcoming open"
17018         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17019         local PID=$!
17020         sleep 1
17021
17022         $MULTIOP $DIR/$tfile oO_RDONLY:c
17023         kill -USR1 $PID && wait $PID || error "break lease error"
17024
17025         echo "==== test 3: verify lease can't be granted if an open already exists"
17026         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17027         local PID=$!
17028         sleep 1
17029
17030         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17031         kill -USR1 $PID && wait $PID || error "open file error"
17032
17033         echo "==== test 4: lease can sustain over recovery"
17034         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17035         PID=$!
17036         sleep 1
17037
17038         fail mds1
17039
17040         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17041
17042         echo "==== test 5: lease broken can't be regained by replay"
17043         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17044         PID=$!
17045         sleep 1
17046
17047         # open file to break lease and then recovery
17048         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17049         fail mds1
17050
17051         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17052
17053         rm -f $DIR/$tfile
17054 }
17055 run_test 208 "Exclusive open"
17056
17057 test_209() {
17058         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17059                 skip_env "must have disp_stripe"
17060
17061         touch $DIR/$tfile
17062         sync; sleep 5; sync;
17063
17064         echo 3 > /proc/sys/vm/drop_caches
17065         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17066                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17067         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17068
17069         # open/close 500 times
17070         for i in $(seq 500); do
17071                 cat $DIR/$tfile
17072         done
17073
17074         echo 3 > /proc/sys/vm/drop_caches
17075         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17076                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17077         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17078
17079         echo "before: $req_before, after: $req_after"
17080         [ $((req_after - req_before)) -ge 300 ] &&
17081                 error "open/close requests are not freed"
17082         return 0
17083 }
17084 run_test 209 "read-only open/close requests should be freed promptly"
17085
17086 test_210() {
17087         local pid
17088
17089         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17090         pid=$!
17091         sleep 1
17092
17093         $LFS getstripe $DIR/$tfile
17094         kill -USR1 $pid
17095         wait $pid || error "multiop failed"
17096
17097         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17098         pid=$!
17099         sleep 1
17100
17101         $LFS getstripe $DIR/$tfile
17102         kill -USR1 $pid
17103         wait $pid || error "multiop failed"
17104 }
17105 run_test 210 "lfs getstripe does not break leases"
17106
17107 test_212() {
17108         size=`date +%s`
17109         size=$((size % 8192 + 1))
17110         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17111         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17112         rm -f $DIR/f212 $DIR/f212.xyz
17113 }
17114 run_test 212 "Sendfile test ============================================"
17115
17116 test_213() {
17117         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17118         cancel_lru_locks osc
17119         lctl set_param fail_loc=0x8000040f
17120         # generate a read lock
17121         cat $DIR/$tfile > /dev/null
17122         # write to the file, it will try to cancel the above read lock.
17123         cat /etc/hosts >> $DIR/$tfile
17124 }
17125 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17126
17127 test_214() { # for bug 20133
17128         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17129         for (( i=0; i < 340; i++ )) ; do
17130                 touch $DIR/$tdir/d214c/a$i
17131         done
17132
17133         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17134         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17135         ls $DIR/d214c || error "ls $DIR/d214c failed"
17136         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17137         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17138 }
17139 run_test 214 "hash-indexed directory test - bug 20133"
17140
17141 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17142 create_lnet_proc_files() {
17143         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17144 }
17145
17146 # counterpart of create_lnet_proc_files
17147 remove_lnet_proc_files() {
17148         rm -f $TMP/lnet_$1.sys
17149 }
17150
17151 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17152 # 3rd arg as regexp for body
17153 check_lnet_proc_stats() {
17154         local l=$(cat "$TMP/lnet_$1" |wc -l)
17155         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17156
17157         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17158 }
17159
17160 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17161 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17162 # optional and can be regexp for 2nd line (lnet.routes case)
17163 check_lnet_proc_entry() {
17164         local blp=2          # blp stands for 'position of 1st line of body'
17165         [ -z "$5" ] || blp=3 # lnet.routes case
17166
17167         local l=$(cat "$TMP/lnet_$1" |wc -l)
17168         # subtracting one from $blp because the body can be empty
17169         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17170
17171         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17172                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17173
17174         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17175                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17176
17177         # bail out if any unexpected line happened
17178         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17179         [ "$?" != 0 ] || error "$2 misformatted"
17180 }
17181
17182 test_215() { # for bugs 18102, 21079, 21517
17183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17184
17185         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17186         local P='[1-9][0-9]*'           # positive numeric
17187         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17188         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17189         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17190         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17191
17192         local L1 # regexp for 1st line
17193         local L2 # regexp for 2nd line (optional)
17194         local BR # regexp for the rest (body)
17195
17196         # lnet.stats should look as 11 space-separated non-negative numerics
17197         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17198         create_lnet_proc_files "stats"
17199         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17200         remove_lnet_proc_files "stats"
17201
17202         # lnet.routes should look like this:
17203         # Routing disabled/enabled
17204         # net hops priority state router
17205         # where net is a string like tcp0, hops > 0, priority >= 0,
17206         # state is up/down,
17207         # router is a string like 192.168.1.1@tcp2
17208         L1="^Routing (disabled|enabled)$"
17209         L2="^net +hops +priority +state +router$"
17210         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17211         create_lnet_proc_files "routes"
17212         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17213         remove_lnet_proc_files "routes"
17214
17215         # lnet.routers should look like this:
17216         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17217         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17218         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17219         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17220         L1="^ref +rtr_ref +alive +router$"
17221         BR="^$P +$P +(up|down) +$NID$"
17222         create_lnet_proc_files "routers"
17223         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17224         remove_lnet_proc_files "routers"
17225
17226         # lnet.peers should look like this:
17227         # nid refs state last max rtr min tx min queue
17228         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17229         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17230         # numeric (0 or >0 or <0), queue >= 0.
17231         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17232         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17233         create_lnet_proc_files "peers"
17234         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17235         remove_lnet_proc_files "peers"
17236
17237         # lnet.buffers  should look like this:
17238         # pages count credits min
17239         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17240         L1="^pages +count +credits +min$"
17241         BR="^ +$N +$N +$I +$I$"
17242         create_lnet_proc_files "buffers"
17243         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17244         remove_lnet_proc_files "buffers"
17245
17246         # lnet.nis should look like this:
17247         # nid status alive refs peer rtr max tx min
17248         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17249         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17250         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17251         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17252         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17253         create_lnet_proc_files "nis"
17254         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17255         remove_lnet_proc_files "nis"
17256
17257         # can we successfully write to lnet.stats?
17258         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17259 }
17260 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17261
17262 test_216() { # bug 20317
17263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17264         remote_ost_nodsh && skip "remote OST with nodsh"
17265
17266         local node
17267         local facets=$(get_facets OST)
17268         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17269
17270         save_lustre_params client "osc.*.contention_seconds" > $p
17271         save_lustre_params $facets \
17272                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17273         save_lustre_params $facets \
17274                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17275         save_lustre_params $facets \
17276                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17277         clear_stats osc.*.osc_stats
17278
17279         # agressive lockless i/o settings
17280         do_nodes $(comma_list $(osts_nodes)) \
17281                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17282                         ldlm.namespaces.filter-*.contended_locks=0 \
17283                         ldlm.namespaces.filter-*.contention_seconds=60"
17284         lctl set_param -n osc.*.contention_seconds=60
17285
17286         $DIRECTIO write $DIR/$tfile 0 10 4096
17287         $CHECKSTAT -s 40960 $DIR/$tfile
17288
17289         # disable lockless i/o
17290         do_nodes $(comma_list $(osts_nodes)) \
17291                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17292                         ldlm.namespaces.filter-*.contended_locks=32 \
17293                         ldlm.namespaces.filter-*.contention_seconds=0"
17294         lctl set_param -n osc.*.contention_seconds=0
17295         clear_stats osc.*.osc_stats
17296
17297         dd if=/dev/zero of=$DIR/$tfile count=0
17298         $CHECKSTAT -s 0 $DIR/$tfile
17299
17300         restore_lustre_params <$p
17301         rm -f $p
17302         rm $DIR/$tfile
17303 }
17304 run_test 216 "check lockless direct write updates file size and kms correctly"
17305
17306 test_217() { # bug 22430
17307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17308
17309         local node
17310         local nid
17311
17312         for node in $(nodes_list); do
17313                 nid=$(host_nids_address $node $NETTYPE)
17314                 if [[ $nid = *-* ]] ; then
17315                         echo "lctl ping $(h2nettype $nid)"
17316                         lctl ping $(h2nettype $nid)
17317                 else
17318                         echo "skipping $node (no hyphen detected)"
17319                 fi
17320         done
17321 }
17322 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17323
17324 test_218() {
17325        # do directio so as not to populate the page cache
17326        log "creating a 10 Mb file"
17327        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17328        log "starting reads"
17329        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17330        log "truncating the file"
17331        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17332        log "killing dd"
17333        kill %+ || true # reads might have finished
17334        echo "wait until dd is finished"
17335        wait
17336        log "removing the temporary file"
17337        rm -rf $DIR/$tfile || error "tmp file removal failed"
17338 }
17339 run_test 218 "parallel read and truncate should not deadlock"
17340
17341 test_219() {
17342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17343
17344         # write one partial page
17345         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17346         # set no grant so vvp_io_commit_write will do sync write
17347         $LCTL set_param fail_loc=0x411
17348         # write a full page at the end of file
17349         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17350
17351         $LCTL set_param fail_loc=0
17352         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17353         $LCTL set_param fail_loc=0x411
17354         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17355
17356         # LU-4201
17357         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17358         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17359 }
17360 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17361
17362 test_220() { #LU-325
17363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17364         remote_ost_nodsh && skip "remote OST with nodsh"
17365         remote_mds_nodsh && skip "remote MDS with nodsh"
17366         remote_mgs_nodsh && skip "remote MGS with nodsh"
17367
17368         local OSTIDX=0
17369
17370         # create on MDT0000 so the last_id and next_id are correct
17371         mkdir $DIR/$tdir
17372         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17373         OST=${OST%_UUID}
17374
17375         # on the mdt's osc
17376         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17377         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17378                         osp.$mdtosc_proc1.prealloc_last_id)
17379         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17380                         osp.$mdtosc_proc1.prealloc_next_id)
17381
17382         $LFS df -i
17383
17384         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17385         #define OBD_FAIL_OST_ENOINO              0x229
17386         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17387         create_pool $FSNAME.$TESTNAME || return 1
17388         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17389
17390         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17391
17392         MDSOBJS=$((last_id - next_id))
17393         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17394
17395         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17396         echo "OST still has $count kbytes free"
17397
17398         echo "create $MDSOBJS files @next_id..."
17399         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17400
17401         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17402                         osp.$mdtosc_proc1.prealloc_last_id)
17403         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17404                         osp.$mdtosc_proc1.prealloc_next_id)
17405
17406         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17407         $LFS df -i
17408
17409         echo "cleanup..."
17410
17411         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17412         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17413
17414         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17415                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17416         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17417                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17418         echo "unlink $MDSOBJS files @$next_id..."
17419         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17420 }
17421 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17422
17423 test_221() {
17424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17425
17426         dd if=`which date` of=$MOUNT/date oflag=sync
17427         chmod +x $MOUNT/date
17428
17429         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17430         $LCTL set_param fail_loc=0x80001401
17431
17432         $MOUNT/date > /dev/null
17433         rm -f $MOUNT/date
17434 }
17435 run_test 221 "make sure fault and truncate race to not cause OOM"
17436
17437 test_222a () {
17438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17439
17440         rm -rf $DIR/$tdir
17441         test_mkdir $DIR/$tdir
17442         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17443         createmany -o $DIR/$tdir/$tfile 10
17444         cancel_lru_locks mdc
17445         cancel_lru_locks osc
17446         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17447         $LCTL set_param fail_loc=0x31a
17448         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17449         $LCTL set_param fail_loc=0
17450         rm -r $DIR/$tdir
17451 }
17452 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17453
17454 test_222b () {
17455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17456
17457         rm -rf $DIR/$tdir
17458         test_mkdir $DIR/$tdir
17459         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17460         createmany -o $DIR/$tdir/$tfile 10
17461         cancel_lru_locks mdc
17462         cancel_lru_locks osc
17463         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17464         $LCTL set_param fail_loc=0x31a
17465         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17466         $LCTL set_param fail_loc=0
17467 }
17468 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17469
17470 test_223 () {
17471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17472
17473         rm -rf $DIR/$tdir
17474         test_mkdir $DIR/$tdir
17475         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17476         createmany -o $DIR/$tdir/$tfile 10
17477         cancel_lru_locks mdc
17478         cancel_lru_locks osc
17479         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17480         $LCTL set_param fail_loc=0x31b
17481         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17482         $LCTL set_param fail_loc=0
17483         rm -r $DIR/$tdir
17484 }
17485 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17486
17487 test_224a() { # LU-1039, MRP-303
17488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17489
17490         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17491         $LCTL set_param fail_loc=0x508
17492         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17493         $LCTL set_param fail_loc=0
17494         df $DIR
17495 }
17496 run_test 224a "Don't panic on bulk IO failure"
17497
17498 test_224b() { # LU-1039, MRP-303
17499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17500
17501         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17502         cancel_lru_locks osc
17503         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17504         $LCTL set_param fail_loc=0x515
17505         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17506         $LCTL set_param fail_loc=0
17507         df $DIR
17508 }
17509 run_test 224b "Don't panic on bulk IO failure"
17510
17511 test_224c() { # LU-6441
17512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17513         remote_mds_nodsh && skip "remote MDS with nodsh"
17514
17515         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17516         save_writethrough $p
17517         set_cache writethrough on
17518
17519         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17520         local at_max=$($LCTL get_param -n at_max)
17521         local timeout=$($LCTL get_param -n timeout)
17522         local test_at="at_max"
17523         local param_at="$FSNAME.sys.at_max"
17524         local test_timeout="timeout"
17525         local param_timeout="$FSNAME.sys.timeout"
17526
17527         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17528
17529         set_persistent_param_and_check client "$test_at" "$param_at" 0
17530         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17531
17532         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17533         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17534         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17535         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17536         sync
17537         do_facet ost1 "$LCTL set_param fail_loc=0"
17538
17539         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17540         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17541                 $timeout
17542
17543         $LCTL set_param -n $pages_per_rpc
17544         restore_lustre_params < $p
17545         rm -f $p
17546 }
17547 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17548
17549 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17550 test_225a () {
17551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17552         if [ -z ${MDSSURVEY} ]; then
17553                 skip_env "mds-survey not found"
17554         fi
17555         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17556                 skip "Need MDS version at least 2.2.51"
17557
17558         local mds=$(facet_host $SINGLEMDS)
17559         local target=$(do_nodes $mds 'lctl dl' |
17560                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17561
17562         local cmd1="file_count=1000 thrhi=4"
17563         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17564         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17565         local cmd="$cmd1 $cmd2 $cmd3"
17566
17567         rm -f ${TMP}/mds_survey*
17568         echo + $cmd
17569         eval $cmd || error "mds-survey with zero-stripe failed"
17570         cat ${TMP}/mds_survey*
17571         rm -f ${TMP}/mds_survey*
17572 }
17573 run_test 225a "Metadata survey sanity with zero-stripe"
17574
17575 test_225b () {
17576         if [ -z ${MDSSURVEY} ]; then
17577                 skip_env "mds-survey not found"
17578         fi
17579         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17580                 skip "Need MDS version at least 2.2.51"
17581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17582         remote_mds_nodsh && skip "remote MDS with nodsh"
17583         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17584                 skip_env "Need to mount OST to test"
17585         fi
17586
17587         local mds=$(facet_host $SINGLEMDS)
17588         local target=$(do_nodes $mds 'lctl dl' |
17589                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17590
17591         local cmd1="file_count=1000 thrhi=4"
17592         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17593         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17594         local cmd="$cmd1 $cmd2 $cmd3"
17595
17596         rm -f ${TMP}/mds_survey*
17597         echo + $cmd
17598         eval $cmd || error "mds-survey with stripe_count failed"
17599         cat ${TMP}/mds_survey*
17600         rm -f ${TMP}/mds_survey*
17601 }
17602 run_test 225b "Metadata survey sanity with stripe_count = 1"
17603
17604 mcreate_path2fid () {
17605         local mode=$1
17606         local major=$2
17607         local minor=$3
17608         local name=$4
17609         local desc=$5
17610         local path=$DIR/$tdir/$name
17611         local fid
17612         local rc
17613         local fid_path
17614
17615         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17616                 error "cannot create $desc"
17617
17618         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17619         rc=$?
17620         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17621
17622         fid_path=$($LFS fid2path $MOUNT $fid)
17623         rc=$?
17624         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17625
17626         [ "$path" == "$fid_path" ] ||
17627                 error "fid2path returned $fid_path, expected $path"
17628
17629         echo "pass with $path and $fid"
17630 }
17631
17632 test_226a () {
17633         rm -rf $DIR/$tdir
17634         mkdir -p $DIR/$tdir
17635
17636         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17637         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17638         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17639         mcreate_path2fid 0040666 0 0 dir "directory"
17640         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17641         mcreate_path2fid 0100666 0 0 file "regular file"
17642         mcreate_path2fid 0120666 0 0 link "symbolic link"
17643         mcreate_path2fid 0140666 0 0 sock "socket"
17644 }
17645 run_test 226a "call path2fid and fid2path on files of all type"
17646
17647 test_226b () {
17648         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17649
17650         local MDTIDX=1
17651
17652         rm -rf $DIR/$tdir
17653         mkdir -p $DIR/$tdir
17654         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17655                 error "create remote directory failed"
17656         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17657         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17658                                 "character special file (null)"
17659         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17660                                 "character special file (no device)"
17661         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17662         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17663                                 "block special file (loop)"
17664         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17665         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17666         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17667 }
17668 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17669
17670 test_226c () {
17671         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17672         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17673                 skip "Need MDS version at least 2.13.55"
17674
17675         local submnt=/mnt/submnt
17676         local srcfile=/etc/passwd
17677         local dstfile=$submnt/passwd
17678         local path
17679         local fid
17680
17681         rm -rf $DIR/$tdir
17682         rm -rf $submnt
17683         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17684                 error "create remote directory failed"
17685         mkdir -p $submnt || error "create $submnt failed"
17686         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17687                 error "mount $submnt failed"
17688         stack_trap "umount $submnt" EXIT
17689
17690         cp $srcfile $dstfile
17691         fid=$($LFS path2fid $dstfile)
17692         path=$($LFS fid2path $submnt "$fid")
17693         [ "$path" = "$dstfile" ] ||
17694                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17695 }
17696 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17697
17698 # LU-1299 Executing or running ldd on a truncated executable does not
17699 # cause an out-of-memory condition.
17700 test_227() {
17701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17702         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17703
17704         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17705         chmod +x $MOUNT/date
17706
17707         $MOUNT/date > /dev/null
17708         ldd $MOUNT/date > /dev/null
17709         rm -f $MOUNT/date
17710 }
17711 run_test 227 "running truncated executable does not cause OOM"
17712
17713 # LU-1512 try to reuse idle OI blocks
17714 test_228a() {
17715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17716         remote_mds_nodsh && skip "remote MDS with nodsh"
17717         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17718
17719         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17720         local myDIR=$DIR/$tdir
17721
17722         mkdir -p $myDIR
17723         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17724         $LCTL set_param fail_loc=0x80001002
17725         createmany -o $myDIR/t- 10000
17726         $LCTL set_param fail_loc=0
17727         # The guard is current the largest FID holder
17728         touch $myDIR/guard
17729         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17730                     tr -d '[')
17731         local IDX=$(($SEQ % 64))
17732
17733         do_facet $SINGLEMDS sync
17734         # Make sure journal flushed.
17735         sleep 6
17736         local blk1=$(do_facet $SINGLEMDS \
17737                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17738                      grep Blockcount | awk '{print $4}')
17739
17740         # Remove old files, some OI blocks will become idle.
17741         unlinkmany $myDIR/t- 10000
17742         # Create new files, idle OI blocks should be reused.
17743         createmany -o $myDIR/t- 2000
17744         do_facet $SINGLEMDS sync
17745         # Make sure journal flushed.
17746         sleep 6
17747         local blk2=$(do_facet $SINGLEMDS \
17748                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17749                      grep Blockcount | awk '{print $4}')
17750
17751         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17752 }
17753 run_test 228a "try to reuse idle OI blocks"
17754
17755 test_228b() {
17756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17757         remote_mds_nodsh && skip "remote MDS with nodsh"
17758         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17759
17760         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17761         local myDIR=$DIR/$tdir
17762
17763         mkdir -p $myDIR
17764         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17765         $LCTL set_param fail_loc=0x80001002
17766         createmany -o $myDIR/t- 10000
17767         $LCTL set_param fail_loc=0
17768         # The guard is current the largest FID holder
17769         touch $myDIR/guard
17770         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17771                     tr -d '[')
17772         local IDX=$(($SEQ % 64))
17773
17774         do_facet $SINGLEMDS sync
17775         # Make sure journal flushed.
17776         sleep 6
17777         local blk1=$(do_facet $SINGLEMDS \
17778                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17779                      grep Blockcount | awk '{print $4}')
17780
17781         # Remove old files, some OI blocks will become idle.
17782         unlinkmany $myDIR/t- 10000
17783
17784         # stop the MDT
17785         stop $SINGLEMDS || error "Fail to stop MDT."
17786         # remount the MDT
17787         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17788
17789         df $MOUNT || error "Fail to df."
17790         # Create new files, idle OI blocks should be reused.
17791         createmany -o $myDIR/t- 2000
17792         do_facet $SINGLEMDS sync
17793         # Make sure journal flushed.
17794         sleep 6
17795         local blk2=$(do_facet $SINGLEMDS \
17796                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17797                      grep Blockcount | awk '{print $4}')
17798
17799         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17800 }
17801 run_test 228b "idle OI blocks can be reused after MDT restart"
17802
17803 #LU-1881
17804 test_228c() {
17805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17806         remote_mds_nodsh && skip "remote MDS with nodsh"
17807         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17808
17809         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17810         local myDIR=$DIR/$tdir
17811
17812         mkdir -p $myDIR
17813         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17814         $LCTL set_param fail_loc=0x80001002
17815         # 20000 files can guarantee there are index nodes in the OI file
17816         createmany -o $myDIR/t- 20000
17817         $LCTL set_param fail_loc=0
17818         # The guard is current the largest FID holder
17819         touch $myDIR/guard
17820         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17821                     tr -d '[')
17822         local IDX=$(($SEQ % 64))
17823
17824         do_facet $SINGLEMDS sync
17825         # Make sure journal flushed.
17826         sleep 6
17827         local blk1=$(do_facet $SINGLEMDS \
17828                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17829                      grep Blockcount | awk '{print $4}')
17830
17831         # Remove old files, some OI blocks will become idle.
17832         unlinkmany $myDIR/t- 20000
17833         rm -f $myDIR/guard
17834         # The OI file should become empty now
17835
17836         # Create new files, idle OI blocks should be reused.
17837         createmany -o $myDIR/t- 2000
17838         do_facet $SINGLEMDS sync
17839         # Make sure journal flushed.
17840         sleep 6
17841         local blk2=$(do_facet $SINGLEMDS \
17842                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17843                      grep Blockcount | awk '{print $4}')
17844
17845         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17846 }
17847 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17848
17849 test_229() { # LU-2482, LU-3448
17850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17851         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17852         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17853                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17854
17855         rm -f $DIR/$tfile
17856
17857         # Create a file with a released layout and stripe count 2.
17858         $MULTIOP $DIR/$tfile H2c ||
17859                 error "failed to create file with released layout"
17860
17861         $LFS getstripe -v $DIR/$tfile
17862
17863         local pattern=$($LFS getstripe -L $DIR/$tfile)
17864         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17865
17866         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17867                 error "getstripe"
17868         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17869         stat $DIR/$tfile || error "failed to stat released file"
17870
17871         chown $RUNAS_ID $DIR/$tfile ||
17872                 error "chown $RUNAS_ID $DIR/$tfile failed"
17873
17874         chgrp $RUNAS_ID $DIR/$tfile ||
17875                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17876
17877         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17878         rm $DIR/$tfile || error "failed to remove released file"
17879 }
17880 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17881
17882 test_230a() {
17883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17884         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17885         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17886                 skip "Need MDS version at least 2.11.52"
17887
17888         local MDTIDX=1
17889
17890         test_mkdir $DIR/$tdir
17891         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17892         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17893         [ $mdt_idx -ne 0 ] &&
17894                 error "create local directory on wrong MDT $mdt_idx"
17895
17896         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17897                         error "create remote directory failed"
17898         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17899         [ $mdt_idx -ne $MDTIDX ] &&
17900                 error "create remote directory on wrong MDT $mdt_idx"
17901
17902         createmany -o $DIR/$tdir/test_230/t- 10 ||
17903                 error "create files on remote directory failed"
17904         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17905         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17906         rm -r $DIR/$tdir || error "unlink remote directory failed"
17907 }
17908 run_test 230a "Create remote directory and files under the remote directory"
17909
17910 test_230b() {
17911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17912         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17913         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17914                 skip "Need MDS version at least 2.11.52"
17915
17916         local MDTIDX=1
17917         local mdt_index
17918         local i
17919         local file
17920         local pid
17921         local stripe_count
17922         local migrate_dir=$DIR/$tdir/migrate_dir
17923         local other_dir=$DIR/$tdir/other_dir
17924
17925         test_mkdir $DIR/$tdir
17926         test_mkdir -i0 -c1 $migrate_dir
17927         test_mkdir -i0 -c1 $other_dir
17928         for ((i=0; i<10; i++)); do
17929                 mkdir -p $migrate_dir/dir_${i}
17930                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17931                         error "create files under remote dir failed $i"
17932         done
17933
17934         cp /etc/passwd $migrate_dir/$tfile
17935         cp /etc/passwd $other_dir/$tfile
17936         chattr +SAD $migrate_dir
17937         chattr +SAD $migrate_dir/$tfile
17938
17939         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17940         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17941         local old_dir_mode=$(stat -c%f $migrate_dir)
17942         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17943
17944         mkdir -p $migrate_dir/dir_default_stripe2
17945         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17946         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17947
17948         mkdir -p $other_dir
17949         ln $migrate_dir/$tfile $other_dir/luna
17950         ln $migrate_dir/$tfile $migrate_dir/sofia
17951         ln $other_dir/$tfile $migrate_dir/david
17952         ln -s $migrate_dir/$tfile $other_dir/zachary
17953         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17954         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17955
17956         local len
17957         local lnktgt
17958
17959         # inline symlink
17960         for len in 58 59 60; do
17961                 lnktgt=$(str_repeat 'l' $len)
17962                 touch $migrate_dir/$lnktgt
17963                 ln -s $lnktgt $migrate_dir/${len}char_ln
17964         done
17965
17966         # PATH_MAX
17967         for len in 4094 4095; do
17968                 lnktgt=$(str_repeat 'l' $len)
17969                 ln -s $lnktgt $migrate_dir/${len}char_ln
17970         done
17971
17972         # NAME_MAX
17973         for len in 254 255; do
17974                 touch $migrate_dir/$(str_repeat 'l' $len)
17975         done
17976
17977         $LFS migrate -m $MDTIDX $migrate_dir ||
17978                 error "fails on migrating remote dir to MDT1"
17979
17980         echo "migratate to MDT1, then checking.."
17981         for ((i = 0; i < 10; i++)); do
17982                 for file in $(find $migrate_dir/dir_${i}); do
17983                         mdt_index=$($LFS getstripe -m $file)
17984                         # broken symlink getstripe will fail
17985                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17986                                 error "$file is not on MDT${MDTIDX}"
17987                 done
17988         done
17989
17990         # the multiple link file should still in MDT0
17991         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17992         [ $mdt_index == 0 ] ||
17993                 error "$file is not on MDT${MDTIDX}"
17994
17995         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17996         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17997                 error " expect $old_dir_flag get $new_dir_flag"
17998
17999         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18000         [ "$old_file_flag" = "$new_file_flag" ] ||
18001                 error " expect $old_file_flag get $new_file_flag"
18002
18003         local new_dir_mode=$(stat -c%f $migrate_dir)
18004         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18005                 error "expect mode $old_dir_mode get $new_dir_mode"
18006
18007         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18008         [ "$old_file_mode" = "$new_file_mode" ] ||
18009                 error "expect mode $old_file_mode get $new_file_mode"
18010
18011         diff /etc/passwd $migrate_dir/$tfile ||
18012                 error "$tfile different after migration"
18013
18014         diff /etc/passwd $other_dir/luna ||
18015                 error "luna different after migration"
18016
18017         diff /etc/passwd $migrate_dir/sofia ||
18018                 error "sofia different after migration"
18019
18020         diff /etc/passwd $migrate_dir/david ||
18021                 error "david different after migration"
18022
18023         diff /etc/passwd $other_dir/zachary ||
18024                 error "zachary different after migration"
18025
18026         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18027                 error "${tfile}_ln different after migration"
18028
18029         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18030                 error "${tfile}_ln_other different after migration"
18031
18032         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18033         [ $stripe_count = 2 ] ||
18034                 error "dir strpe_count $d != 2 after migration."
18035
18036         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18037         [ $stripe_count = 2 ] ||
18038                 error "file strpe_count $d != 2 after migration."
18039
18040         #migrate back to MDT0
18041         MDTIDX=0
18042
18043         $LFS migrate -m $MDTIDX $migrate_dir ||
18044                 error "fails on migrating remote dir to MDT0"
18045
18046         echo "migrate back to MDT0, checking.."
18047         for file in $(find $migrate_dir); do
18048                 mdt_index=$($LFS getstripe -m $file)
18049                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18050                         error "$file is not on MDT${MDTIDX}"
18051         done
18052
18053         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18054         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18055                 error " expect $old_dir_flag get $new_dir_flag"
18056
18057         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18058         [ "$old_file_flag" = "$new_file_flag" ] ||
18059                 error " expect $old_file_flag get $new_file_flag"
18060
18061         local new_dir_mode=$(stat -c%f $migrate_dir)
18062         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18063                 error "expect mode $old_dir_mode get $new_dir_mode"
18064
18065         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18066         [ "$old_file_mode" = "$new_file_mode" ] ||
18067                 error "expect mode $old_file_mode get $new_file_mode"
18068
18069         diff /etc/passwd ${migrate_dir}/$tfile ||
18070                 error "$tfile different after migration"
18071
18072         diff /etc/passwd ${other_dir}/luna ||
18073                 error "luna different after migration"
18074
18075         diff /etc/passwd ${migrate_dir}/sofia ||
18076                 error "sofia different after migration"
18077
18078         diff /etc/passwd ${other_dir}/zachary ||
18079                 error "zachary different after migration"
18080
18081         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18082                 error "${tfile}_ln different after migration"
18083
18084         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18085                 error "${tfile}_ln_other different after migration"
18086
18087         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18088         [ $stripe_count = 2 ] ||
18089                 error "dir strpe_count $d != 2 after migration."
18090
18091         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18092         [ $stripe_count = 2 ] ||
18093                 error "file strpe_count $d != 2 after migration."
18094
18095         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18096 }
18097 run_test 230b "migrate directory"
18098
18099 test_230c() {
18100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18101         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18102         remote_mds_nodsh && skip "remote MDS with nodsh"
18103         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18104                 skip "Need MDS version at least 2.11.52"
18105
18106         local MDTIDX=1
18107         local total=3
18108         local mdt_index
18109         local file
18110         local migrate_dir=$DIR/$tdir/migrate_dir
18111
18112         #If migrating directory fails in the middle, all entries of
18113         #the directory is still accessiable.
18114         test_mkdir $DIR/$tdir
18115         test_mkdir -i0 -c1 $migrate_dir
18116         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18117         stat $migrate_dir
18118         createmany -o $migrate_dir/f $total ||
18119                 error "create files under ${migrate_dir} failed"
18120
18121         # fail after migrating top dir, and this will fail only once, so the
18122         # first sub file migration will fail (currently f3), others succeed.
18123         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18124         do_facet mds1 lctl set_param fail_loc=0x1801
18125         local t=$(ls $migrate_dir | wc -l)
18126         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18127                 error "migrate should fail"
18128         local u=$(ls $migrate_dir | wc -l)
18129         [ "$u" == "$t" ] || error "$u != $t during migration"
18130
18131         # add new dir/file should succeed
18132         mkdir $migrate_dir/dir ||
18133                 error "mkdir failed under migrating directory"
18134         touch $migrate_dir/file ||
18135                 error "create file failed under migrating directory"
18136
18137         # add file with existing name should fail
18138         for file in $migrate_dir/f*; do
18139                 stat $file > /dev/null || error "stat $file failed"
18140                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18141                         error "open(O_CREAT|O_EXCL) $file should fail"
18142                 $MULTIOP $file m && error "create $file should fail"
18143                 touch $DIR/$tdir/remote_dir/$tfile ||
18144                         error "touch $tfile failed"
18145                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18146                         error "link $file should fail"
18147                 mdt_index=$($LFS getstripe -m $file)
18148                 if [ $mdt_index == 0 ]; then
18149                         # file failed to migrate is not allowed to rename to
18150                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18151                                 error "rename to $file should fail"
18152                 else
18153                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18154                                 error "rename to $file failed"
18155                 fi
18156                 echo hello >> $file || error "write $file failed"
18157         done
18158
18159         # resume migration with different options should fail
18160         $LFS migrate -m 0 $migrate_dir &&
18161                 error "migrate -m 0 $migrate_dir should fail"
18162
18163         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18164                 error "migrate -c 2 $migrate_dir should fail"
18165
18166         # resume migration should succeed
18167         $LFS migrate -m $MDTIDX $migrate_dir ||
18168                 error "migrate $migrate_dir failed"
18169
18170         echo "Finish migration, then checking.."
18171         for file in $(find $migrate_dir); do
18172                 mdt_index=$($LFS getstripe -m $file)
18173                 [ $mdt_index == $MDTIDX ] ||
18174                         error "$file is not on MDT${MDTIDX}"
18175         done
18176
18177         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18178 }
18179 run_test 230c "check directory accessiblity if migration failed"
18180
18181 test_230d() {
18182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18183         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18184         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18185                 skip "Need MDS version at least 2.11.52"
18186         # LU-11235
18187         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18188
18189         local migrate_dir=$DIR/$tdir/migrate_dir
18190         local old_index
18191         local new_index
18192         local old_count
18193         local new_count
18194         local new_hash
18195         local mdt_index
18196         local i
18197         local j
18198
18199         old_index=$((RANDOM % MDSCOUNT))
18200         old_count=$((MDSCOUNT - old_index))
18201         new_index=$((RANDOM % MDSCOUNT))
18202         new_count=$((MDSCOUNT - new_index))
18203         new_hash=1 # for all_char
18204
18205         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18206         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18207
18208         test_mkdir $DIR/$tdir
18209         test_mkdir -i $old_index -c $old_count $migrate_dir
18210
18211         for ((i=0; i<100; i++)); do
18212                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18213                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18214                         error "create files under remote dir failed $i"
18215         done
18216
18217         echo -n "Migrate from MDT$old_index "
18218         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18219         echo -n "to MDT$new_index"
18220         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18221         echo
18222
18223         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18224         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18225                 error "migrate remote dir error"
18226
18227         echo "Finish migration, then checking.."
18228         for file in $(find $migrate_dir); do
18229                 mdt_index=$($LFS getstripe -m $file)
18230                 if [ $mdt_index -lt $new_index ] ||
18231                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18232                         error "$file is on MDT$mdt_index"
18233                 fi
18234         done
18235
18236         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18237 }
18238 run_test 230d "check migrate big directory"
18239
18240 test_230e() {
18241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18242         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18243         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18244                 skip "Need MDS version at least 2.11.52"
18245
18246         local i
18247         local j
18248         local a_fid
18249         local b_fid
18250
18251         mkdir -p $DIR/$tdir
18252         mkdir $DIR/$tdir/migrate_dir
18253         mkdir $DIR/$tdir/other_dir
18254         touch $DIR/$tdir/migrate_dir/a
18255         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18256         ls $DIR/$tdir/other_dir
18257
18258         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18259                 error "migrate dir fails"
18260
18261         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18262         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18263
18264         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18265         [ $mdt_index == 0 ] || error "a is not on MDT0"
18266
18267         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18268                 error "migrate dir fails"
18269
18270         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18271         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18272
18273         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18274         [ $mdt_index == 1 ] || error "a is not on MDT1"
18275
18276         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18277         [ $mdt_index == 1 ] || error "b is not on MDT1"
18278
18279         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18280         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18281
18282         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18283
18284         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18285 }
18286 run_test 230e "migrate mulitple local link files"
18287
18288 test_230f() {
18289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18290         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18291         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18292                 skip "Need MDS version at least 2.11.52"
18293
18294         local a_fid
18295         local ln_fid
18296
18297         mkdir -p $DIR/$tdir
18298         mkdir $DIR/$tdir/migrate_dir
18299         $LFS mkdir -i1 $DIR/$tdir/other_dir
18300         touch $DIR/$tdir/migrate_dir/a
18301         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18302         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18303         ls $DIR/$tdir/other_dir
18304
18305         # a should be migrated to MDT1, since no other links on MDT0
18306         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18307                 error "#1 migrate dir fails"
18308         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18309         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18310         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18311         [ $mdt_index == 1 ] || error "a is not on MDT1"
18312
18313         # a should stay on MDT1, because it is a mulitple link file
18314         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18315                 error "#2 migrate dir fails"
18316         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18317         [ $mdt_index == 1 ] || error "a is not on MDT1"
18318
18319         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18320                 error "#3 migrate dir fails"
18321
18322         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18323         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18324         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18325
18326         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18327         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18328
18329         # a should be migrated to MDT0, since no other links on MDT1
18330         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18331                 error "#4 migrate dir fails"
18332         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18333         [ $mdt_index == 0 ] || error "a is not on MDT0"
18334
18335         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18336 }
18337 run_test 230f "migrate mulitple remote link files"
18338
18339 test_230g() {
18340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18341         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18342         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18343                 skip "Need MDS version at least 2.11.52"
18344
18345         mkdir -p $DIR/$tdir/migrate_dir
18346
18347         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18348                 error "migrating dir to non-exist MDT succeeds"
18349         true
18350 }
18351 run_test 230g "migrate dir to non-exist MDT"
18352
18353 test_230h() {
18354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18355         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18356         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18357                 skip "Need MDS version at least 2.11.52"
18358
18359         local mdt_index
18360
18361         mkdir -p $DIR/$tdir/migrate_dir
18362
18363         $LFS migrate -m1 $DIR &&
18364                 error "migrating mountpoint1 should fail"
18365
18366         $LFS migrate -m1 $DIR/$tdir/.. &&
18367                 error "migrating mountpoint2 should fail"
18368
18369         # same as mv
18370         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18371                 error "migrating $tdir/migrate_dir/.. should fail"
18372
18373         true
18374 }
18375 run_test 230h "migrate .. and root"
18376
18377 test_230i() {
18378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18380         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18381                 skip "Need MDS version at least 2.11.52"
18382
18383         mkdir -p $DIR/$tdir/migrate_dir
18384
18385         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18386                 error "migration fails with a tailing slash"
18387
18388         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18389                 error "migration fails with two tailing slashes"
18390 }
18391 run_test 230i "lfs migrate -m tolerates trailing slashes"
18392
18393 test_230j() {
18394         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18395         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18396                 skip "Need MDS version at least 2.11.52"
18397
18398         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18399         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18400                 error "create $tfile failed"
18401         cat /etc/passwd > $DIR/$tdir/$tfile
18402
18403         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18404
18405         cmp /etc/passwd $DIR/$tdir/$tfile ||
18406                 error "DoM file mismatch after migration"
18407 }
18408 run_test 230j "DoM file data not changed after dir migration"
18409
18410 test_230k() {
18411         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18412         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18413                 skip "Need MDS version at least 2.11.56"
18414
18415         local total=20
18416         local files_on_starting_mdt=0
18417
18418         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18419         $LFS getdirstripe $DIR/$tdir
18420         for i in $(seq $total); do
18421                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18422                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18423                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18424         done
18425
18426         echo "$files_on_starting_mdt files on MDT0"
18427
18428         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18429         $LFS getdirstripe $DIR/$tdir
18430
18431         files_on_starting_mdt=0
18432         for i in $(seq $total); do
18433                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18434                         error "file $tfile.$i mismatch after migration"
18435                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18436                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18437         done
18438
18439         echo "$files_on_starting_mdt files on MDT1 after migration"
18440         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18441
18442         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18443         $LFS getdirstripe $DIR/$tdir
18444
18445         files_on_starting_mdt=0
18446         for i in $(seq $total); do
18447                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18448                         error "file $tfile.$i mismatch after 2nd migration"
18449                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18450                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18451         done
18452
18453         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18454         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18455
18456         true
18457 }
18458 run_test 230k "file data not changed after dir migration"
18459
18460 test_230l() {
18461         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18462         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18463                 skip "Need MDS version at least 2.11.56"
18464
18465         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18466         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18467                 error "create files under remote dir failed $i"
18468         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18469 }
18470 run_test 230l "readdir between MDTs won't crash"
18471
18472 test_230m() {
18473         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18474         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18475                 skip "Need MDS version at least 2.11.56"
18476
18477         local MDTIDX=1
18478         local mig_dir=$DIR/$tdir/migrate_dir
18479         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18480         local shortstr="b"
18481         local val
18482
18483         echo "Creating files and dirs with xattrs"
18484         test_mkdir $DIR/$tdir
18485         test_mkdir -i0 -c1 $mig_dir
18486         mkdir $mig_dir/dir
18487         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18488                 error "cannot set xattr attr1 on dir"
18489         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18490                 error "cannot set xattr attr2 on dir"
18491         touch $mig_dir/dir/f0
18492         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18493                 error "cannot set xattr attr1 on file"
18494         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18495                 error "cannot set xattr attr2 on file"
18496         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18497         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18498         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18499         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18500         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18501         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18502         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18503         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18504         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18505
18506         echo "Migrating to MDT1"
18507         $LFS migrate -m $MDTIDX $mig_dir ||
18508                 error "fails on migrating dir to MDT1"
18509
18510         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18511         echo "Checking xattrs"
18512         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18513         [ "$val" = $longstr ] ||
18514                 error "expecting xattr1 $longstr on dir, found $val"
18515         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18516         [ "$val" = $shortstr ] ||
18517                 error "expecting xattr2 $shortstr on dir, found $val"
18518         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18519         [ "$val" = $longstr ] ||
18520                 error "expecting xattr1 $longstr on file, found $val"
18521         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18522         [ "$val" = $shortstr ] ||
18523                 error "expecting xattr2 $shortstr on file, found $val"
18524 }
18525 run_test 230m "xattrs not changed after dir migration"
18526
18527 test_230n() {
18528         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18529         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18530                 skip "Need MDS version at least 2.13.53"
18531
18532         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18533         cat /etc/hosts > $DIR/$tdir/$tfile
18534         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18535         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18536
18537         cmp /etc/hosts $DIR/$tdir/$tfile ||
18538                 error "File data mismatch after migration"
18539 }
18540 run_test 230n "Dir migration with mirrored file"
18541
18542 test_230o() {
18543         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18544         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18545                 skip "Need MDS version at least 2.13.52"
18546
18547         local mdts=$(comma_list $(mdts_nodes))
18548         local timeout=100
18549
18550         local restripe_status
18551         local delta
18552         local i
18553         local j
18554
18555         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18556
18557         # in case "crush" hash type is not set
18558         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18559
18560         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18561                            mdt.*MDT0000.enable_dir_restripe)
18562         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18563         stack_trap "do_nodes $mdts $LCTL set_param \
18564                     mdt.*.enable_dir_restripe=$restripe_status"
18565
18566         mkdir $DIR/$tdir
18567         createmany -m $DIR/$tdir/f 100 ||
18568                 error "create files under remote dir failed $i"
18569         createmany -d $DIR/$tdir/d 100 ||
18570                 error "create dirs under remote dir failed $i"
18571
18572         for i in $(seq 2 $MDSCOUNT); do
18573                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18574                 $LFS setdirstripe -c $i $DIR/$tdir ||
18575                         error "split -c $i $tdir failed"
18576                 wait_update $HOSTNAME \
18577                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18578                         error "dir split not finished"
18579                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18580                         awk '/migrate/ {sum += $2} END { print sum }')
18581                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18582                 # delta is around total_files/stripe_count
18583                 [ $delta -lt $((200 /(i - 1))) ] ||
18584                         error "$delta files migrated"
18585         done
18586 }
18587 run_test 230o "dir split"
18588
18589 test_230p() {
18590         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18591         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18592                 skip "Need MDS version at least 2.13.52"
18593
18594         local mdts=$(comma_list $(mdts_nodes))
18595         local timeout=100
18596
18597         local restripe_status
18598         local delta
18599         local i
18600         local j
18601
18602         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18603
18604         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18605
18606         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18607                            mdt.*MDT0000.enable_dir_restripe)
18608         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18609         stack_trap "do_nodes $mdts $LCTL set_param \
18610                     mdt.*.enable_dir_restripe=$restripe_status"
18611
18612         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18613         createmany -m $DIR/$tdir/f 100 ||
18614                 error "create files under remote dir failed $i"
18615         createmany -d $DIR/$tdir/d 100 ||
18616                 error "create dirs under remote dir failed $i"
18617
18618         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18619                 local mdt_hash="crush"
18620
18621                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18622                 $LFS setdirstripe -c $i $DIR/$tdir ||
18623                         error "split -c $i $tdir failed"
18624                 [ $i -eq 1 ] && mdt_hash="none"
18625                 wait_update $HOSTNAME \
18626                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18627                         error "dir merge not finished"
18628                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18629                         awk '/migrate/ {sum += $2} END { print sum }')
18630                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18631                 # delta is around total_files/stripe_count
18632                 [ $delta -lt $((200 / i)) ] ||
18633                         error "$delta files migrated"
18634         done
18635 }
18636 run_test 230p "dir merge"
18637
18638 test_230q() {
18639         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18640         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18641                 skip "Need MDS version at least 2.13.52"
18642
18643         local mdts=$(comma_list $(mdts_nodes))
18644         local saved_threshold=$(do_facet mds1 \
18645                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18646         local saved_delta=$(do_facet mds1 \
18647                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18648         local threshold=100
18649         local delta=2
18650         local total=0
18651         local stripe_count=0
18652         local stripe_index
18653         local nr_files
18654
18655         # test with fewer files on ZFS
18656         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18657
18658         stack_trap "do_nodes $mdts $LCTL set_param \
18659                     mdt.*.dir_split_count=$saved_threshold"
18660         stack_trap "do_nodes $mdts $LCTL set_param \
18661                     mdt.*.dir_split_delta=$saved_delta"
18662         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18663         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18664         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18665         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18666         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18667         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18668
18669         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18670         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18671
18672         while [ $stripe_count -lt $MDSCOUNT ]; do
18673                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18674                         error "create sub files failed"
18675                 stat $DIR/$tdir > /dev/null
18676                 total=$((total + threshold * 3 / 2))
18677                 stripe_count=$((stripe_count + delta))
18678                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18679
18680                 wait_update $HOSTNAME \
18681                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18682                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18683
18684                 wait_update $HOSTNAME \
18685                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18686                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18687
18688                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18689                            grep -w $stripe_index | wc -l)
18690                 echo "$nr_files files on MDT$stripe_index after split"
18691                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18692                         error "$nr_files files on MDT$stripe_index after split"
18693
18694                 nr_files=$(ls $DIR/$tdir | wc -w)
18695                 [ $nr_files -eq $total ] ||
18696                         error "total sub files $nr_files != $total"
18697         done
18698 }
18699 run_test 230q "dir auto split"
18700
18701 test_230r() {
18702         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18703         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18704         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18705                 skip "Need MDS version at least 2.13.54"
18706
18707         # maximum amount of local locks:
18708         # parent striped dir - 2 locks
18709         # new stripe in parent to migrate to - 1 lock
18710         # source and target - 2 locks
18711         # Total 5 locks for regular file
18712         mkdir -p $DIR/$tdir
18713         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18714         touch $DIR/$tdir/dir1/eee
18715
18716         # create 4 hardlink for 4 more locks
18717         # Total: 9 locks > RS_MAX_LOCKS (8)
18718         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18719         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18720         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18721         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18722         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18723         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18724         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18725         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18726
18727         cancel_lru_locks mdc
18728
18729         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18730                 error "migrate dir fails"
18731
18732         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18733 }
18734 run_test 230r "migrate with too many local locks"
18735
18736 test_231a()
18737 {
18738         # For simplicity this test assumes that max_pages_per_rpc
18739         # is the same across all OSCs
18740         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18741         local bulk_size=$((max_pages * PAGE_SIZE))
18742         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18743                                        head -n 1)
18744
18745         mkdir -p $DIR/$tdir
18746         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18747                 error "failed to set stripe with -S ${brw_size}M option"
18748
18749         # clear the OSC stats
18750         $LCTL set_param osc.*.stats=0 &>/dev/null
18751         stop_writeback
18752
18753         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18754         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18755                 oflag=direct &>/dev/null || error "dd failed"
18756
18757         sync; sleep 1; sync # just to be safe
18758         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18759         if [ x$nrpcs != "x1" ]; then
18760                 $LCTL get_param osc.*.stats
18761                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18762         fi
18763
18764         start_writeback
18765         # Drop the OSC cache, otherwise we will read from it
18766         cancel_lru_locks osc
18767
18768         # clear the OSC stats
18769         $LCTL set_param osc.*.stats=0 &>/dev/null
18770
18771         # Client reads $bulk_size.
18772         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18773                 iflag=direct &>/dev/null || error "dd failed"
18774
18775         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18776         if [ x$nrpcs != "x1" ]; then
18777                 $LCTL get_param osc.*.stats
18778                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18779         fi
18780 }
18781 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18782
18783 test_231b() {
18784         mkdir -p $DIR/$tdir
18785         local i
18786         for i in {0..1023}; do
18787                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18788                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18789                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18790         done
18791         sync
18792 }
18793 run_test 231b "must not assert on fully utilized OST request buffer"
18794
18795 test_232a() {
18796         mkdir -p $DIR/$tdir
18797         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18798
18799         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18800         do_facet ost1 $LCTL set_param fail_loc=0x31c
18801
18802         # ignore dd failure
18803         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18804
18805         do_facet ost1 $LCTL set_param fail_loc=0
18806         umount_client $MOUNT || error "umount failed"
18807         mount_client $MOUNT || error "mount failed"
18808         stop ost1 || error "cannot stop ost1"
18809         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18810 }
18811 run_test 232a "failed lock should not block umount"
18812
18813 test_232b() {
18814         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18815                 skip "Need MDS version at least 2.10.58"
18816
18817         mkdir -p $DIR/$tdir
18818         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18819         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18820         sync
18821         cancel_lru_locks osc
18822
18823         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18824         do_facet ost1 $LCTL set_param fail_loc=0x31c
18825
18826         # ignore failure
18827         $LFS data_version $DIR/$tdir/$tfile || true
18828
18829         do_facet ost1 $LCTL set_param fail_loc=0
18830         umount_client $MOUNT || error "umount failed"
18831         mount_client $MOUNT || error "mount failed"
18832         stop ost1 || error "cannot stop ost1"
18833         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18834 }
18835 run_test 232b "failed data version lock should not block umount"
18836
18837 test_233a() {
18838         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18839                 skip "Need MDS version at least 2.3.64"
18840         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18841
18842         local fid=$($LFS path2fid $MOUNT)
18843
18844         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18845                 error "cannot access $MOUNT using its FID '$fid'"
18846 }
18847 run_test 233a "checking that OBF of the FS root succeeds"
18848
18849 test_233b() {
18850         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18851                 skip "Need MDS version at least 2.5.90"
18852         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18853
18854         local fid=$($LFS path2fid $MOUNT/.lustre)
18855
18856         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18857                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18858
18859         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18860         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18861                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18862 }
18863 run_test 233b "checking that OBF of the FS .lustre succeeds"
18864
18865 test_234() {
18866         local p="$TMP/sanityN-$TESTNAME.parameters"
18867         save_lustre_params client "llite.*.xattr_cache" > $p
18868         lctl set_param llite.*.xattr_cache 1 ||
18869                 skip_env "xattr cache is not supported"
18870
18871         mkdir -p $DIR/$tdir || error "mkdir failed"
18872         touch $DIR/$tdir/$tfile || error "touch failed"
18873         # OBD_FAIL_LLITE_XATTR_ENOMEM
18874         $LCTL set_param fail_loc=0x1405
18875         getfattr -n user.attr $DIR/$tdir/$tfile &&
18876                 error "getfattr should have failed with ENOMEM"
18877         $LCTL set_param fail_loc=0x0
18878         rm -rf $DIR/$tdir
18879
18880         restore_lustre_params < $p
18881         rm -f $p
18882 }
18883 run_test 234 "xattr cache should not crash on ENOMEM"
18884
18885 test_235() {
18886         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18887                 skip "Need MDS version at least 2.4.52"
18888
18889         flock_deadlock $DIR/$tfile
18890         local RC=$?
18891         case $RC in
18892                 0)
18893                 ;;
18894                 124) error "process hangs on a deadlock"
18895                 ;;
18896                 *) error "error executing flock_deadlock $DIR/$tfile"
18897                 ;;
18898         esac
18899 }
18900 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18901
18902 #LU-2935
18903 test_236() {
18904         check_swap_layouts_support
18905
18906         local ref1=/etc/passwd
18907         local ref2=/etc/group
18908         local file1=$DIR/$tdir/f1
18909         local file2=$DIR/$tdir/f2
18910
18911         test_mkdir -c1 $DIR/$tdir
18912         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18913         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18914         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18915         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18916         local fd=$(free_fd)
18917         local cmd="exec $fd<>$file2"
18918         eval $cmd
18919         rm $file2
18920         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18921                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18922         cmd="exec $fd>&-"
18923         eval $cmd
18924         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18925
18926         #cleanup
18927         rm -rf $DIR/$tdir
18928 }
18929 run_test 236 "Layout swap on open unlinked file"
18930
18931 # LU-4659 linkea consistency
18932 test_238() {
18933         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18934                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18935                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18936                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18937
18938         touch $DIR/$tfile
18939         ln $DIR/$tfile $DIR/$tfile.lnk
18940         touch $DIR/$tfile.new
18941         mv $DIR/$tfile.new $DIR/$tfile
18942         local fid1=$($LFS path2fid $DIR/$tfile)
18943         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18944         local path1=$($LFS fid2path $FSNAME "$fid1")
18945         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18946         local path2=$($LFS fid2path $FSNAME "$fid2")
18947         [ $tfile.lnk == $path2 ] ||
18948                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18949         rm -f $DIR/$tfile*
18950 }
18951 run_test 238 "Verify linkea consistency"
18952
18953 test_239A() { # was test_239
18954         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18955                 skip "Need MDS version at least 2.5.60"
18956
18957         local list=$(comma_list $(mdts_nodes))
18958
18959         mkdir -p $DIR/$tdir
18960         createmany -o $DIR/$tdir/f- 5000
18961         unlinkmany $DIR/$tdir/f- 5000
18962         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18963                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18964         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18965                         osp.*MDT*.sync_in_flight" | calc_sum)
18966         [ "$changes" -eq 0 ] || error "$changes not synced"
18967 }
18968 run_test 239A "osp_sync test"
18969
18970 test_239a() { #LU-5297
18971         remote_mds_nodsh && skip "remote MDS with nodsh"
18972
18973         touch $DIR/$tfile
18974         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18975         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18976         chgrp $RUNAS_GID $DIR/$tfile
18977         wait_delete_completed
18978 }
18979 run_test 239a "process invalid osp sync record correctly"
18980
18981 test_239b() { #LU-5297
18982         remote_mds_nodsh && skip "remote MDS with nodsh"
18983
18984         touch $DIR/$tfile1
18985         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18986         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18987         chgrp $RUNAS_GID $DIR/$tfile1
18988         wait_delete_completed
18989         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18990         touch $DIR/$tfile2
18991         chgrp $RUNAS_GID $DIR/$tfile2
18992         wait_delete_completed
18993 }
18994 run_test 239b "process osp sync record with ENOMEM error correctly"
18995
18996 test_240() {
18997         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18998         remote_mds_nodsh && skip "remote MDS with nodsh"
18999
19000         mkdir -p $DIR/$tdir
19001
19002         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19003                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19004         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19005                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19006
19007         umount_client $MOUNT || error "umount failed"
19008         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19009         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19010         mount_client $MOUNT || error "failed to mount client"
19011
19012         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19013         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19014 }
19015 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19016
19017 test_241_bio() {
19018         local count=$1
19019         local bsize=$2
19020
19021         for LOOP in $(seq $count); do
19022                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19023                 cancel_lru_locks $OSC || true
19024         done
19025 }
19026
19027 test_241_dio() {
19028         local count=$1
19029         local bsize=$2
19030
19031         for LOOP in $(seq $1); do
19032                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19033                         2>/dev/null
19034         done
19035 }
19036
19037 test_241a() { # was test_241
19038         local bsize=$PAGE_SIZE
19039
19040         (( bsize < 40960 )) && bsize=40960
19041         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19042         ls -la $DIR/$tfile
19043         cancel_lru_locks $OSC
19044         test_241_bio 1000 $bsize &
19045         PID=$!
19046         test_241_dio 1000 $bsize
19047         wait $PID
19048 }
19049 run_test 241a "bio vs dio"
19050
19051 test_241b() {
19052         local bsize=$PAGE_SIZE
19053
19054         (( bsize < 40960 )) && bsize=40960
19055         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19056         ls -la $DIR/$tfile
19057         test_241_dio 1000 $bsize &
19058         PID=$!
19059         test_241_dio 1000 $bsize
19060         wait $PID
19061 }
19062 run_test 241b "dio vs dio"
19063
19064 test_242() {
19065         remote_mds_nodsh && skip "remote MDS with nodsh"
19066
19067         mkdir -p $DIR/$tdir
19068         touch $DIR/$tdir/$tfile
19069
19070         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19071         do_facet mds1 lctl set_param fail_loc=0x105
19072         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19073
19074         do_facet mds1 lctl set_param fail_loc=0
19075         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19076 }
19077 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19078
19079 test_243()
19080 {
19081         test_mkdir $DIR/$tdir
19082         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19083 }
19084 run_test 243 "various group lock tests"
19085
19086 test_244a()
19087 {
19088         test_mkdir $DIR/$tdir
19089         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19090         sendfile_grouplock $DIR/$tdir/$tfile || \
19091                 error "sendfile+grouplock failed"
19092         rm -rf $DIR/$tdir
19093 }
19094 run_test 244a "sendfile with group lock tests"
19095
19096 test_244b()
19097 {
19098         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19099
19100         local threads=50
19101         local size=$((1024*1024))
19102
19103         test_mkdir $DIR/$tdir
19104         for i in $(seq 1 $threads); do
19105                 local file=$DIR/$tdir/file_$((i / 10))
19106                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19107                 local pids[$i]=$!
19108         done
19109         for i in $(seq 1 $threads); do
19110                 wait ${pids[$i]}
19111         done
19112 }
19113 run_test 244b "multi-threaded write with group lock"
19114
19115 test_245() {
19116         local flagname="multi_mod_rpcs"
19117         local connect_data_name="max_mod_rpcs"
19118         local out
19119
19120         # check if multiple modify RPCs flag is set
19121         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19122                 grep "connect_flags:")
19123         echo "$out"
19124
19125         echo "$out" | grep -qw $flagname
19126         if [ $? -ne 0 ]; then
19127                 echo "connect flag $flagname is not set"
19128                 return
19129         fi
19130
19131         # check if multiple modify RPCs data is set
19132         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19133         echo "$out"
19134
19135         echo "$out" | grep -qw $connect_data_name ||
19136                 error "import should have connect data $connect_data_name"
19137 }
19138 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19139
19140 cleanup_247() {
19141         local submount=$1
19142
19143         trap 0
19144         umount_client $submount
19145         rmdir $submount
19146 }
19147
19148 test_247a() {
19149         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19150                 grep -q subtree ||
19151                 skip_env "Fileset feature is not supported"
19152
19153         local submount=${MOUNT}_$tdir
19154
19155         mkdir $MOUNT/$tdir
19156         mkdir -p $submount || error "mkdir $submount failed"
19157         FILESET="$FILESET/$tdir" mount_client $submount ||
19158                 error "mount $submount failed"
19159         trap "cleanup_247 $submount" EXIT
19160         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19161         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19162                 error "read $MOUNT/$tdir/$tfile failed"
19163         cleanup_247 $submount
19164 }
19165 run_test 247a "mount subdir as fileset"
19166
19167 test_247b() {
19168         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19169                 skip_env "Fileset feature is not supported"
19170
19171         local submount=${MOUNT}_$tdir
19172
19173         rm -rf $MOUNT/$tdir
19174         mkdir -p $submount || error "mkdir $submount failed"
19175         SKIP_FILESET=1
19176         FILESET="$FILESET/$tdir" mount_client $submount &&
19177                 error "mount $submount should fail"
19178         rmdir $submount
19179 }
19180 run_test 247b "mount subdir that dose not exist"
19181
19182 test_247c() {
19183         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19184                 skip_env "Fileset feature is not supported"
19185
19186         local submount=${MOUNT}_$tdir
19187
19188         mkdir -p $MOUNT/$tdir/dir1
19189         mkdir -p $submount || error "mkdir $submount failed"
19190         trap "cleanup_247 $submount" EXIT
19191         FILESET="$FILESET/$tdir" mount_client $submount ||
19192                 error "mount $submount failed"
19193         local fid=$($LFS path2fid $MOUNT/)
19194         $LFS fid2path $submount $fid && error "fid2path should fail"
19195         cleanup_247 $submount
19196 }
19197 run_test 247c "running fid2path outside subdirectory root"
19198
19199 test_247d() {
19200         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19201                 skip "Fileset feature is not supported"
19202
19203         local submount=${MOUNT}_$tdir
19204
19205         mkdir -p $MOUNT/$tdir/dir1
19206         mkdir -p $submount || error "mkdir $submount failed"
19207         FILESET="$FILESET/$tdir" mount_client $submount ||
19208                 error "mount $submount failed"
19209         trap "cleanup_247 $submount" EXIT
19210
19211         local td=$submount/dir1
19212         local fid=$($LFS path2fid $td)
19213         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19214
19215         # check that we get the same pathname back
19216         local rootpath
19217         local found
19218         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19219                 echo "$rootpath $fid"
19220                 found=$($LFS fid2path $rootpath "$fid")
19221                 [ -n "found" ] || error "fid2path should succeed"
19222                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19223         done
19224         # check wrong root path format
19225         rootpath=$submount"_wrong"
19226         found=$($LFS fid2path $rootpath "$fid")
19227         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19228
19229         cleanup_247 $submount
19230 }
19231 run_test 247d "running fid2path inside subdirectory root"
19232
19233 # LU-8037
19234 test_247e() {
19235         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19236                 grep -q subtree ||
19237                 skip "Fileset feature is not supported"
19238
19239         local submount=${MOUNT}_$tdir
19240
19241         mkdir $MOUNT/$tdir
19242         mkdir -p $submount || error "mkdir $submount failed"
19243         FILESET="$FILESET/.." mount_client $submount &&
19244                 error "mount $submount should fail"
19245         rmdir $submount
19246 }
19247 run_test 247e "mount .. as fileset"
19248
19249 test_247f() {
19250         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19251         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19252                 skip "Need at least version 2.13.52"
19253         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19254                 grep -q subtree ||
19255                 skip "Fileset feature is not supported"
19256
19257         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19258         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19259                 error "mkdir remote failed"
19260         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19261         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19262                 error "mkdir striped failed"
19263         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19264
19265         local submount=${MOUNT}_$tdir
19266
19267         mkdir -p $submount || error "mkdir $submount failed"
19268
19269         local dir
19270         local fileset=$FILESET
19271
19272         for dir in $tdir/remote $tdir/remote/subdir \
19273                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19274                 FILESET="$fileset/$dir" mount_client $submount ||
19275                         error "mount $dir failed"
19276                 umount_client $submount
19277         done
19278 }
19279 run_test 247f "mount striped or remote directory as fileset"
19280
19281 test_248a() {
19282         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19283         [ -z "$fast_read_sav" ] && skip "no fast read support"
19284
19285         # create a large file for fast read verification
19286         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19287
19288         # make sure the file is created correctly
19289         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19290                 { rm -f $DIR/$tfile; skip "file creation error"; }
19291
19292         echo "Test 1: verify that fast read is 4 times faster on cache read"
19293
19294         # small read with fast read enabled
19295         $LCTL set_param -n llite.*.fast_read=1
19296         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19297                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19298                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19299         # small read with fast read disabled
19300         $LCTL set_param -n llite.*.fast_read=0
19301         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19302                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19303                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19304
19305         # verify that fast read is 4 times faster for cache read
19306         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19307                 error_not_in_vm "fast read was not 4 times faster: " \
19308                            "$t_fast vs $t_slow"
19309
19310         echo "Test 2: verify the performance between big and small read"
19311         $LCTL set_param -n llite.*.fast_read=1
19312
19313         # 1k non-cache read
19314         cancel_lru_locks osc
19315         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19316                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19317                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19318
19319         # 1M non-cache read
19320         cancel_lru_locks osc
19321         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19322                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19323                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19324
19325         # verify that big IO is not 4 times faster than small IO
19326         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19327                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19328
19329         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19330         rm -f $DIR/$tfile
19331 }
19332 run_test 248a "fast read verification"
19333
19334 test_248b() {
19335         # Default short_io_bytes=16384, try both smaller and larger sizes.
19336         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19337         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19338         echo "bs=53248 count=113 normal buffered write"
19339         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19340                 error "dd of initial data file failed"
19341         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19342
19343         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19344         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19345                 error "dd with sync normal writes failed"
19346         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19347
19348         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19349         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19350                 error "dd with sync small writes failed"
19351         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19352
19353         cancel_lru_locks osc
19354
19355         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19356         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19357         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19358         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19359                 iflag=direct || error "dd with O_DIRECT small read failed"
19360         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19361         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19362                 error "compare $TMP/$tfile.1 failed"
19363
19364         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19365         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19366
19367         # just to see what the maximum tunable value is, and test parsing
19368         echo "test invalid parameter 2MB"
19369         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19370                 error "too-large short_io_bytes allowed"
19371         echo "test maximum parameter 512KB"
19372         # if we can set a larger short_io_bytes, run test regardless of version
19373         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19374                 # older clients may not allow setting it this large, that's OK
19375                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19376                         skip "Need at least client version 2.13.50"
19377                 error "medium short_io_bytes failed"
19378         fi
19379         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19380         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19381
19382         echo "test large parameter 64KB"
19383         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19384         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19385
19386         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19387         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19388                 error "dd with sync large writes failed"
19389         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19390
19391         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19392         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19393         num=$((113 * 4096 / PAGE_SIZE))
19394         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19395         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19396                 error "dd with O_DIRECT large writes failed"
19397         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19398                 error "compare $DIR/$tfile.3 failed"
19399
19400         cancel_lru_locks osc
19401
19402         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19403         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19404                 error "dd with O_DIRECT large read failed"
19405         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19406                 error "compare $TMP/$tfile.2 failed"
19407
19408         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19409         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19410                 error "dd with O_DIRECT large read failed"
19411         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19412                 error "compare $TMP/$tfile.3 failed"
19413 }
19414 run_test 248b "test short_io read and write for both small and large sizes"
19415
19416 test_249() { # LU-7890
19417         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19418                 skip "Need at least version 2.8.54"
19419
19420         rm -f $DIR/$tfile
19421         $LFS setstripe -c 1 $DIR/$tfile
19422         # Offset 2T == 4k * 512M
19423         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19424                 error "dd to 2T offset failed"
19425 }
19426 run_test 249 "Write above 2T file size"
19427
19428 test_250() {
19429         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19430          && skip "no 16TB file size limit on ZFS"
19431
19432         $LFS setstripe -c 1 $DIR/$tfile
19433         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19434         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19435         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19436         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19437                 conv=notrunc,fsync && error "append succeeded"
19438         return 0
19439 }
19440 run_test 250 "Write above 16T limit"
19441
19442 test_251() {
19443         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19444
19445         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19446         #Skip once - writing the first stripe will succeed
19447         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19448         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19449                 error "short write happened"
19450
19451         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19452         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19453                 error "short read happened"
19454
19455         rm -f $DIR/$tfile
19456 }
19457 run_test 251 "Handling short read and write correctly"
19458
19459 test_252() {
19460         remote_mds_nodsh && skip "remote MDS with nodsh"
19461         remote_ost_nodsh && skip "remote OST with nodsh"
19462         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19463                 skip_env "ldiskfs only test"
19464         fi
19465
19466         local tgt
19467         local dev
19468         local out
19469         local uuid
19470         local num
19471         local gen
19472
19473         # check lr_reader on OST0000
19474         tgt=ost1
19475         dev=$(facet_device $tgt)
19476         out=$(do_facet $tgt $LR_READER $dev)
19477         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19478         echo "$out"
19479         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19480         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19481                 error "Invalid uuid returned by $LR_READER on target $tgt"
19482         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19483
19484         # check lr_reader -c on MDT0000
19485         tgt=mds1
19486         dev=$(facet_device $tgt)
19487         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19488                 skip "$LR_READER does not support additional options"
19489         fi
19490         out=$(do_facet $tgt $LR_READER -c $dev)
19491         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19492         echo "$out"
19493         num=$(echo "$out" | grep -c "mdtlov")
19494         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19495                 error "Invalid number of mdtlov clients returned by $LR_READER"
19496         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19497
19498         # check lr_reader -cr on MDT0000
19499         out=$(do_facet $tgt $LR_READER -cr $dev)
19500         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19501         echo "$out"
19502         echo "$out" | grep -q "^reply_data:$" ||
19503                 error "$LR_READER should have returned 'reply_data' section"
19504         num=$(echo "$out" | grep -c "client_generation")
19505         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19506 }
19507 run_test 252 "check lr_reader tool"
19508
19509 test_253() {
19510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19511         remote_mds_nodsh && skip "remote MDS with nodsh"
19512         remote_mgs_nodsh && skip "remote MGS with nodsh"
19513
19514         local ostidx=0
19515         local rc=0
19516         local ost_name=$(ostname_from_index $ostidx)
19517
19518         # on the mdt's osc
19519         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19520         do_facet $SINGLEMDS $LCTL get_param -n \
19521                 osp.$mdtosc_proc1.reserved_mb_high ||
19522                 skip  "remote MDS does not support reserved_mb_high"
19523
19524         rm -rf $DIR/$tdir
19525         wait_mds_ost_sync
19526         wait_delete_completed
19527         mkdir $DIR/$tdir
19528
19529         pool_add $TESTNAME || error "Pool creation failed"
19530         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19531
19532         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19533                 error "Setstripe failed"
19534
19535         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19536
19537         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19538                     grep "watermarks")
19539         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19540
19541         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19542                         osp.$mdtosc_proc1.prealloc_status)
19543         echo "prealloc_status $oa_status"
19544
19545         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19546                 error "File creation should fail"
19547
19548         #object allocation was stopped, but we still able to append files
19549         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19550                 oflag=append || error "Append failed"
19551
19552         rm -f $DIR/$tdir/$tfile.0
19553
19554         # For this test, we want to delete the files we created to go out of
19555         # space but leave the watermark, so we remain nearly out of space
19556         ost_watermarks_enospc_delete_files $tfile $ostidx
19557
19558         wait_delete_completed
19559
19560         sleep_maxage
19561
19562         for i in $(seq 10 12); do
19563                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19564                         2>/dev/null || error "File creation failed after rm"
19565         done
19566
19567         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19568                         osp.$mdtosc_proc1.prealloc_status)
19569         echo "prealloc_status $oa_status"
19570
19571         if (( oa_status != 0 )); then
19572                 error "Object allocation still disable after rm"
19573         fi
19574 }
19575 run_test 253 "Check object allocation limit"
19576
19577 test_254() {
19578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19579         remote_mds_nodsh && skip "remote MDS with nodsh"
19580         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19581                 skip "MDS does not support changelog_size"
19582
19583         local cl_user
19584         local MDT0=$(facet_svc $SINGLEMDS)
19585
19586         changelog_register || error "changelog_register failed"
19587
19588         changelog_clear 0 || error "changelog_clear failed"
19589
19590         local size1=$(do_facet $SINGLEMDS \
19591                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19592         echo "Changelog size $size1"
19593
19594         rm -rf $DIR/$tdir
19595         $LFS mkdir -i 0 $DIR/$tdir
19596         # change something
19597         mkdir -p $DIR/$tdir/pics/2008/zachy
19598         touch $DIR/$tdir/pics/2008/zachy/timestamp
19599         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19600         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19601         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19602         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19603         rm $DIR/$tdir/pics/desktop.jpg
19604
19605         local size2=$(do_facet $SINGLEMDS \
19606                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19607         echo "Changelog size after work $size2"
19608
19609         (( $size2 > $size1 )) ||
19610                 error "new Changelog size=$size2 less than old size=$size1"
19611 }
19612 run_test 254 "Check changelog size"
19613
19614 ladvise_no_type()
19615 {
19616         local type=$1
19617         local file=$2
19618
19619         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19620                 awk -F: '{print $2}' | grep $type > /dev/null
19621         if [ $? -ne 0 ]; then
19622                 return 0
19623         fi
19624         return 1
19625 }
19626
19627 ladvise_no_ioctl()
19628 {
19629         local file=$1
19630
19631         lfs ladvise -a willread $file > /dev/null 2>&1
19632         if [ $? -eq 0 ]; then
19633                 return 1
19634         fi
19635
19636         lfs ladvise -a willread $file 2>&1 |
19637                 grep "Inappropriate ioctl for device" > /dev/null
19638         if [ $? -eq 0 ]; then
19639                 return 0
19640         fi
19641         return 1
19642 }
19643
19644 percent() {
19645         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19646 }
19647
19648 # run a random read IO workload
19649 # usage: random_read_iops <filename> <filesize> <iosize>
19650 random_read_iops() {
19651         local file=$1
19652         local fsize=$2
19653         local iosize=${3:-4096}
19654
19655         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19656                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19657 }
19658
19659 drop_file_oss_cache() {
19660         local file="$1"
19661         local nodes="$2"
19662
19663         $LFS ladvise -a dontneed $file 2>/dev/null ||
19664                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19665 }
19666
19667 ladvise_willread_performance()
19668 {
19669         local repeat=10
19670         local average_origin=0
19671         local average_cache=0
19672         local average_ladvise=0
19673
19674         for ((i = 1; i <= $repeat; i++)); do
19675                 echo "Iter $i/$repeat: reading without willread hint"
19676                 cancel_lru_locks osc
19677                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19678                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19679                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19680                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19681
19682                 cancel_lru_locks osc
19683                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19684                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19685                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19686
19687                 cancel_lru_locks osc
19688                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19689                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19690                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19691                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19692                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19693         done
19694         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19695         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19696         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19697
19698         speedup_cache=$(percent $average_cache $average_origin)
19699         speedup_ladvise=$(percent $average_ladvise $average_origin)
19700
19701         echo "Average uncached read: $average_origin"
19702         echo "Average speedup with OSS cached read: " \
19703                 "$average_cache = +$speedup_cache%"
19704         echo "Average speedup with ladvise willread: " \
19705                 "$average_ladvise = +$speedup_ladvise%"
19706
19707         local lowest_speedup=20
19708         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19709                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19710                         "got $average_cache%. Skipping ladvise willread check."
19711                 return 0
19712         fi
19713
19714         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19715         # it is still good to run until then to exercise 'ladvise willread'
19716         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19717                 [ "$ost1_FSTYPE" = "zfs" ] &&
19718                 echo "osd-zfs does not support dontneed or drop_caches" &&
19719                 return 0
19720
19721         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19722         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19723                 error_not_in_vm "Speedup with willread is less than " \
19724                         "$lowest_speedup%, got $average_ladvise%"
19725 }
19726
19727 test_255a() {
19728         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19729                 skip "lustre < 2.8.54 does not support ladvise "
19730         remote_ost_nodsh && skip "remote OST with nodsh"
19731
19732         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19733
19734         ladvise_no_type willread $DIR/$tfile &&
19735                 skip "willread ladvise is not supported"
19736
19737         ladvise_no_ioctl $DIR/$tfile &&
19738                 skip "ladvise ioctl is not supported"
19739
19740         local size_mb=100
19741         local size=$((size_mb * 1048576))
19742         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19743                 error "dd to $DIR/$tfile failed"
19744
19745         lfs ladvise -a willread $DIR/$tfile ||
19746                 error "Ladvise failed with no range argument"
19747
19748         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19749                 error "Ladvise failed with no -l or -e argument"
19750
19751         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19752                 error "Ladvise failed with only -e argument"
19753
19754         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19755                 error "Ladvise failed with only -l argument"
19756
19757         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19758                 error "End offset should not be smaller than start offset"
19759
19760         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19761                 error "End offset should not be equal to start offset"
19762
19763         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19764                 error "Ladvise failed with overflowing -s argument"
19765
19766         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19767                 error "Ladvise failed with overflowing -e argument"
19768
19769         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19770                 error "Ladvise failed with overflowing -l argument"
19771
19772         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19773                 error "Ladvise succeeded with conflicting -l and -e arguments"
19774
19775         echo "Synchronous ladvise should wait"
19776         local delay=4
19777 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19778         do_nodes $(comma_list $(osts_nodes)) \
19779                 $LCTL set_param fail_val=$delay fail_loc=0x237
19780
19781         local start_ts=$SECONDS
19782         lfs ladvise -a willread $DIR/$tfile ||
19783                 error "Ladvise failed with no range argument"
19784         local end_ts=$SECONDS
19785         local inteval_ts=$((end_ts - start_ts))
19786
19787         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19788                 error "Synchronous advice didn't wait reply"
19789         fi
19790
19791         echo "Asynchronous ladvise shouldn't wait"
19792         local start_ts=$SECONDS
19793         lfs ladvise -a willread -b $DIR/$tfile ||
19794                 error "Ladvise failed with no range argument"
19795         local end_ts=$SECONDS
19796         local inteval_ts=$((end_ts - start_ts))
19797
19798         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19799                 error "Asynchronous advice blocked"
19800         fi
19801
19802         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19803         ladvise_willread_performance
19804 }
19805 run_test 255a "check 'lfs ladvise -a willread'"
19806
19807 facet_meminfo() {
19808         local facet=$1
19809         local info=$2
19810
19811         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19812 }
19813
19814 test_255b() {
19815         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19816                 skip "lustre < 2.8.54 does not support ladvise "
19817         remote_ost_nodsh && skip "remote OST with nodsh"
19818
19819         lfs setstripe -c 1 -i 0 $DIR/$tfile
19820
19821         ladvise_no_type dontneed $DIR/$tfile &&
19822                 skip "dontneed ladvise is not supported"
19823
19824         ladvise_no_ioctl $DIR/$tfile &&
19825                 skip "ladvise ioctl is not supported"
19826
19827         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19828                 [ "$ost1_FSTYPE" = "zfs" ] &&
19829                 skip "zfs-osd does not support 'ladvise dontneed'"
19830
19831         local size_mb=100
19832         local size=$((size_mb * 1048576))
19833         # In order to prevent disturbance of other processes, only check 3/4
19834         # of the memory usage
19835         local kibibytes=$((size_mb * 1024 * 3 / 4))
19836
19837         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19838                 error "dd to $DIR/$tfile failed"
19839
19840         #force write to complete before dropping OST cache & checking memory
19841         sync
19842
19843         local total=$(facet_meminfo ost1 MemTotal)
19844         echo "Total memory: $total KiB"
19845
19846         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19847         local before_read=$(facet_meminfo ost1 Cached)
19848         echo "Cache used before read: $before_read KiB"
19849
19850         lfs ladvise -a willread $DIR/$tfile ||
19851                 error "Ladvise willread failed"
19852         local after_read=$(facet_meminfo ost1 Cached)
19853         echo "Cache used after read: $after_read KiB"
19854
19855         lfs ladvise -a dontneed $DIR/$tfile ||
19856                 error "Ladvise dontneed again failed"
19857         local no_read=$(facet_meminfo ost1 Cached)
19858         echo "Cache used after dontneed ladvise: $no_read KiB"
19859
19860         if [ $total -lt $((before_read + kibibytes)) ]; then
19861                 echo "Memory is too small, abort checking"
19862                 return 0
19863         fi
19864
19865         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19866                 error "Ladvise willread should use more memory" \
19867                         "than $kibibytes KiB"
19868         fi
19869
19870         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19871                 error "Ladvise dontneed should release more memory" \
19872                         "than $kibibytes KiB"
19873         fi
19874 }
19875 run_test 255b "check 'lfs ladvise -a dontneed'"
19876
19877 test_255c() {
19878         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19879                 skip "lustre < 2.10.50 does not support lockahead"
19880
19881         local count
19882         local new_count
19883         local difference
19884         local i
19885         local rc
19886
19887         test_mkdir -p $DIR/$tdir
19888         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19889
19890         #test 10 returns only success/failure
19891         i=10
19892         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19893         rc=$?
19894         if [ $rc -eq 255 ]; then
19895                 error "Ladvise test${i} failed, ${rc}"
19896         fi
19897
19898         #test 11 counts lock enqueue requests, all others count new locks
19899         i=11
19900         count=$(do_facet ost1 \
19901                 $LCTL get_param -n ost.OSS.ost.stats)
19902         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19903
19904         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19905         rc=$?
19906         if [ $rc -eq 255 ]; then
19907                 error "Ladvise test${i} failed, ${rc}"
19908         fi
19909
19910         new_count=$(do_facet ost1 \
19911                 $LCTL get_param -n ost.OSS.ost.stats)
19912         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19913                    awk '{ print $2 }')
19914
19915         difference="$((new_count - count))"
19916         if [ $difference -ne $rc ]; then
19917                 error "Ladvise test${i}, bad enqueue count, returned " \
19918                       "${rc}, actual ${difference}"
19919         fi
19920
19921         for i in $(seq 12 21); do
19922                 # If we do not do this, we run the risk of having too many
19923                 # locks and starting lock cancellation while we are checking
19924                 # lock counts.
19925                 cancel_lru_locks osc
19926
19927                 count=$($LCTL get_param -n \
19928                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19929
19930                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19931                 rc=$?
19932                 if [ $rc -eq 255 ]; then
19933                         error "Ladvise test ${i} failed, ${rc}"
19934                 fi
19935
19936                 new_count=$($LCTL get_param -n \
19937                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19938                 difference="$((new_count - count))"
19939
19940                 # Test 15 output is divided by 100 to map down to valid return
19941                 if [ $i -eq 15 ]; then
19942                         rc="$((rc * 100))"
19943                 fi
19944
19945                 if [ $difference -ne $rc ]; then
19946                         error "Ladvise test ${i}, bad lock count, returned " \
19947                               "${rc}, actual ${difference}"
19948                 fi
19949         done
19950
19951         #test 22 returns only success/failure
19952         i=22
19953         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19954         rc=$?
19955         if [ $rc -eq 255 ]; then
19956                 error "Ladvise test${i} failed, ${rc}"
19957         fi
19958 }
19959 run_test 255c "suite of ladvise lockahead tests"
19960
19961 test_256() {
19962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19963         remote_mds_nodsh && skip "remote MDS with nodsh"
19964         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19965         changelog_users $SINGLEMDS | grep "^cl" &&
19966                 skip "active changelog user"
19967
19968         local cl_user
19969         local cat_sl
19970         local mdt_dev
19971
19972         mdt_dev=$(mdsdevname 1)
19973         echo $mdt_dev
19974
19975         changelog_register || error "changelog_register failed"
19976
19977         rm -rf $DIR/$tdir
19978         mkdir -p $DIR/$tdir
19979
19980         changelog_clear 0 || error "changelog_clear failed"
19981
19982         # change something
19983         touch $DIR/$tdir/{1..10}
19984
19985         # stop the MDT
19986         stop $SINGLEMDS || error "Fail to stop MDT"
19987
19988         # remount the MDT
19989
19990         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19991
19992         #after mount new plainllog is used
19993         touch $DIR/$tdir/{11..19}
19994         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19995         stack_trap "rm -f $tmpfile"
19996         cat_sl=$(do_facet $SINGLEMDS "sync; \
19997                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19998                  llog_reader $tmpfile | grep -c type=1064553b")
19999         do_facet $SINGLEMDS llog_reader $tmpfile
20000
20001         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20002
20003         changelog_clear 0 || error "changelog_clear failed"
20004
20005         cat_sl=$(do_facet $SINGLEMDS "sync; \
20006                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20007                  llog_reader $tmpfile | grep -c type=1064553b")
20008
20009         if (( cat_sl == 2 )); then
20010                 error "Empty plain llog was not deleted from changelog catalog"
20011         elif (( cat_sl != 1 )); then
20012                 error "Active plain llog shouldn't be deleted from catalog"
20013         fi
20014 }
20015 run_test 256 "Check llog delete for empty and not full state"
20016
20017 test_257() {
20018         remote_mds_nodsh && skip "remote MDS with nodsh"
20019         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20020                 skip "Need MDS version at least 2.8.55"
20021
20022         test_mkdir $DIR/$tdir
20023
20024         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20025                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20026         stat $DIR/$tdir
20027
20028 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20029         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20030         local facet=mds$((mdtidx + 1))
20031         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20032         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20033
20034         stop $facet || error "stop MDS failed"
20035         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20036                 error "start MDS fail"
20037         wait_recovery_complete $facet
20038 }
20039 run_test 257 "xattr locks are not lost"
20040
20041 # Verify we take the i_mutex when security requires it
20042 test_258a() {
20043 #define OBD_FAIL_IMUTEX_SEC 0x141c
20044         $LCTL set_param fail_loc=0x141c
20045         touch $DIR/$tfile
20046         chmod u+s $DIR/$tfile
20047         chmod a+rwx $DIR/$tfile
20048         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20049         RC=$?
20050         if [ $RC -ne 0 ]; then
20051                 error "error, failed to take i_mutex, rc=$?"
20052         fi
20053         rm -f $DIR/$tfile
20054 }
20055 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20056
20057 # Verify we do NOT take the i_mutex in the normal case
20058 test_258b() {
20059 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20060         $LCTL set_param fail_loc=0x141d
20061         touch $DIR/$tfile
20062         chmod a+rwx $DIR
20063         chmod a+rw $DIR/$tfile
20064         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20065         RC=$?
20066         if [ $RC -ne 0 ]; then
20067                 error "error, took i_mutex unnecessarily, rc=$?"
20068         fi
20069         rm -f $DIR/$tfile
20070
20071 }
20072 run_test 258b "verify i_mutex security behavior"
20073
20074 test_259() {
20075         local file=$DIR/$tfile
20076         local before
20077         local after
20078
20079         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20080
20081         stack_trap "rm -f $file" EXIT
20082
20083         wait_delete_completed
20084         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20085         echo "before: $before"
20086
20087         $LFS setstripe -i 0 -c 1 $file
20088         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20089         sync_all_data
20090         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20091         echo "after write: $after"
20092
20093 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20094         do_facet ost1 $LCTL set_param fail_loc=0x2301
20095         $TRUNCATE $file 0
20096         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20097         echo "after truncate: $after"
20098
20099         stop ost1
20100         do_facet ost1 $LCTL set_param fail_loc=0
20101         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20102         sleep 2
20103         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20104         echo "after restart: $after"
20105         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20106                 error "missing truncate?"
20107
20108         return 0
20109 }
20110 run_test 259 "crash at delayed truncate"
20111
20112 test_260() {
20113 #define OBD_FAIL_MDC_CLOSE               0x806
20114         $LCTL set_param fail_loc=0x80000806
20115         touch $DIR/$tfile
20116
20117 }
20118 run_test 260 "Check mdc_close fail"
20119
20120 ### Data-on-MDT sanity tests ###
20121 test_270a() {
20122         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20123                 skip "Need MDS version at least 2.10.55 for DoM"
20124
20125         # create DoM file
20126         local dom=$DIR/$tdir/dom_file
20127         local tmp=$DIR/$tdir/tmp_file
20128
20129         mkdir -p $DIR/$tdir
20130
20131         # basic checks for DoM component creation
20132         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20133                 error "Can set MDT layout to non-first entry"
20134
20135         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20136                 error "Can define multiple entries as MDT layout"
20137
20138         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20139
20140         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20141         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20142         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20143
20144         local mdtidx=$($LFS getstripe -m $dom)
20145         local mdtname=MDT$(printf %04x $mdtidx)
20146         local facet=mds$((mdtidx + 1))
20147         local space_check=1
20148
20149         # Skip free space checks with ZFS
20150         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20151
20152         # write
20153         sync
20154         local size_tmp=$((65536 * 3))
20155         local mdtfree1=$(do_facet $facet \
20156                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20157
20158         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20159         # check also direct IO along write
20160         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20161         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20162         sync
20163         cmp $tmp $dom || error "file data is different"
20164         [ $(stat -c%s $dom) == $size_tmp ] ||
20165                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20166         if [ $space_check == 1 ]; then
20167                 local mdtfree2=$(do_facet $facet \
20168                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20169
20170                 # increase in usage from by $size_tmp
20171                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20172                         error "MDT free space wrong after write: " \
20173                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20174         fi
20175
20176         # truncate
20177         local size_dom=10000
20178
20179         $TRUNCATE $dom $size_dom
20180         [ $(stat -c%s $dom) == $size_dom ] ||
20181                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20182         if [ $space_check == 1 ]; then
20183                 mdtfree1=$(do_facet $facet \
20184                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20185                 # decrease in usage from $size_tmp to new $size_dom
20186                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20187                   $(((size_tmp - size_dom) / 1024)) ] ||
20188                         error "MDT free space is wrong after truncate: " \
20189                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20190         fi
20191
20192         # append
20193         cat $tmp >> $dom
20194         sync
20195         size_dom=$((size_dom + size_tmp))
20196         [ $(stat -c%s $dom) == $size_dom ] ||
20197                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20198         if [ $space_check == 1 ]; then
20199                 mdtfree2=$(do_facet $facet \
20200                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20201                 # increase in usage by $size_tmp from previous
20202                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20203                         error "MDT free space is wrong after append: " \
20204                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20205         fi
20206
20207         # delete
20208         rm $dom
20209         if [ $space_check == 1 ]; then
20210                 mdtfree1=$(do_facet $facet \
20211                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20212                 # decrease in usage by $size_dom from previous
20213                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20214                         error "MDT free space is wrong after removal: " \
20215                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20216         fi
20217
20218         # combined striping
20219         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20220                 error "Can't create DoM + OST striping"
20221
20222         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20223         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20224         # check also direct IO along write
20225         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20226         sync
20227         cmp $tmp $dom || error "file data is different"
20228         [ $(stat -c%s $dom) == $size_tmp ] ||
20229                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20230         rm $dom $tmp
20231
20232         return 0
20233 }
20234 run_test 270a "DoM: basic functionality tests"
20235
20236 test_270b() {
20237         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20238                 skip "Need MDS version at least 2.10.55"
20239
20240         local dom=$DIR/$tdir/dom_file
20241         local max_size=1048576
20242
20243         mkdir -p $DIR/$tdir
20244         $LFS setstripe -E $max_size -L mdt $dom
20245
20246         # truncate over the limit
20247         $TRUNCATE $dom $(($max_size + 1)) &&
20248                 error "successful truncate over the maximum size"
20249         # write over the limit
20250         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20251                 error "successful write over the maximum size"
20252         # append over the limit
20253         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20254         echo "12345" >> $dom && error "successful append over the maximum size"
20255         rm $dom
20256
20257         return 0
20258 }
20259 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20260
20261 test_270c() {
20262         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20263                 skip "Need MDS version at least 2.10.55"
20264
20265         mkdir -p $DIR/$tdir
20266         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20267
20268         # check files inherit DoM EA
20269         touch $DIR/$tdir/first
20270         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20271                 error "bad pattern"
20272         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20273                 error "bad stripe count"
20274         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20275                 error "bad stripe size"
20276
20277         # check directory inherits DoM EA and uses it as default
20278         mkdir $DIR/$tdir/subdir
20279         touch $DIR/$tdir/subdir/second
20280         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20281                 error "bad pattern in sub-directory"
20282         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20283                 error "bad stripe count in sub-directory"
20284         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20285                 error "bad stripe size in sub-directory"
20286         return 0
20287 }
20288 run_test 270c "DoM: DoM EA inheritance tests"
20289
20290 test_270d() {
20291         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20292                 skip "Need MDS version at least 2.10.55"
20293
20294         mkdir -p $DIR/$tdir
20295         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20296
20297         # inherit default DoM striping
20298         mkdir $DIR/$tdir/subdir
20299         touch $DIR/$tdir/subdir/f1
20300
20301         # change default directory striping
20302         $LFS setstripe -c 1 $DIR/$tdir/subdir
20303         touch $DIR/$tdir/subdir/f2
20304         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20305                 error "wrong default striping in file 2"
20306         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20307                 error "bad pattern in file 2"
20308         return 0
20309 }
20310 run_test 270d "DoM: change striping from DoM to RAID0"
20311
20312 test_270e() {
20313         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20314                 skip "Need MDS version at least 2.10.55"
20315
20316         mkdir -p $DIR/$tdir/dom
20317         mkdir -p $DIR/$tdir/norm
20318         DOMFILES=20
20319         NORMFILES=10
20320         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20321         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20322
20323         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20324         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20325
20326         # find DoM files by layout
20327         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20328         [ $NUM -eq  $DOMFILES ] ||
20329                 error "lfs find -L: found $NUM, expected $DOMFILES"
20330         echo "Test 1: lfs find 20 DOM files by layout: OK"
20331
20332         # there should be 1 dir with default DOM striping
20333         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20334         [ $NUM -eq  1 ] ||
20335                 error "lfs find -L: found $NUM, expected 1 dir"
20336         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20337
20338         # find DoM files by stripe size
20339         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20340         [ $NUM -eq  $DOMFILES ] ||
20341                 error "lfs find -S: found $NUM, expected $DOMFILES"
20342         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20343
20344         # find files by stripe offset except DoM files
20345         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20346         [ $NUM -eq  $NORMFILES ] ||
20347                 error "lfs find -i: found $NUM, expected $NORMFILES"
20348         echo "Test 5: lfs find no DOM files by stripe index: OK"
20349         return 0
20350 }
20351 run_test 270e "DoM: lfs find with DoM files test"
20352
20353 test_270f() {
20354         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20355                 skip "Need MDS version at least 2.10.55"
20356
20357         local mdtname=${FSNAME}-MDT0000-mdtlov
20358         local dom=$DIR/$tdir/dom_file
20359         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20360                                                 lod.$mdtname.dom_stripesize)
20361         local dom_limit=131072
20362
20363         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20364         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20365                                                 lod.$mdtname.dom_stripesize)
20366         [ ${dom_limit} -eq ${dom_current} ] ||
20367                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20368
20369         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20370         $LFS setstripe -d $DIR/$tdir
20371         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20372                 error "Can't set directory default striping"
20373
20374         # exceed maximum stripe size
20375         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20376                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20377         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20378                 error "Able to create DoM component size more than LOD limit"
20379
20380         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20381         dom_current=$(do_facet mds1 $LCTL get_param -n \
20382                                                 lod.$mdtname.dom_stripesize)
20383         [ 0 -eq ${dom_current} ] ||
20384                 error "Can't set zero DoM stripe limit"
20385         rm $dom
20386
20387         # attempt to create DoM file on server with disabled DoM should
20388         # remove DoM entry from layout and be succeed
20389         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20390                 error "Can't create DoM file (DoM is disabled)"
20391         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20392                 error "File has DoM component while DoM is disabled"
20393         rm $dom
20394
20395         # attempt to create DoM file with only DoM stripe should return error
20396         $LFS setstripe -E $dom_limit -L mdt $dom &&
20397                 error "Able to create DoM-only file while DoM is disabled"
20398
20399         # too low values to be aligned with smallest stripe size 64K
20400         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20401         dom_current=$(do_facet mds1 $LCTL get_param -n \
20402                                                 lod.$mdtname.dom_stripesize)
20403         [ 30000 -eq ${dom_current} ] &&
20404                 error "Can set too small DoM stripe limit"
20405
20406         # 64K is a minimal stripe size in Lustre, expect limit of that size
20407         [ 65536 -eq ${dom_current} ] ||
20408                 error "Limit is not set to 64K but ${dom_current}"
20409
20410         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20411         dom_current=$(do_facet mds1 $LCTL get_param -n \
20412                                                 lod.$mdtname.dom_stripesize)
20413         echo $dom_current
20414         [ 2147483648 -eq ${dom_current} ] &&
20415                 error "Can set too large DoM stripe limit"
20416
20417         do_facet mds1 $LCTL set_param -n \
20418                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20419         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20420                 error "Can't create DoM component size after limit change"
20421         do_facet mds1 $LCTL set_param -n \
20422                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20423         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20424                 error "Can't create DoM file after limit decrease"
20425         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20426                 error "Can create big DoM component after limit decrease"
20427         touch ${dom}_def ||
20428                 error "Can't create file with old default layout"
20429
20430         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20431         return 0
20432 }
20433 run_test 270f "DoM: maximum DoM stripe size checks"
20434
20435 test_270g() {
20436         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20437                 skip "Need MDS version at least 2.13.52"
20438         local dom=$DIR/$tdir/$tfile
20439
20440         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20441         local lodname=${FSNAME}-MDT0000-mdtlov
20442
20443         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20444         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20445         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20446         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20447
20448         local dom_limit=1024
20449         local dom_threshold="50%"
20450
20451         $LFS setstripe -d $DIR/$tdir
20452         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20453                 error "Can't set directory default striping"
20454
20455         do_facet mds1 $LCTL set_param -n \
20456                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20457         # set 0 threshold and create DOM file to change tunable stripesize
20458         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20459         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20460                 error "Failed to create $dom file"
20461         # now tunable dom_cur_stripesize should reach maximum
20462         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20463                                         lod.${lodname}.dom_stripesize_cur_kb)
20464         [[ $dom_current == $dom_limit ]] ||
20465                 error "Current DOM stripesize is not maximum"
20466         rm $dom
20467
20468         # set threshold for further tests
20469         do_facet mds1 $LCTL set_param -n \
20470                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20471         echo "DOM threshold is $dom_threshold free space"
20472         local dom_def
20473         local dom_set
20474         # Spoof bfree to exceed threshold
20475         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20476         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20477         for spfree in 40 20 0 15 30 55; do
20478                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20479                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20480                         error "Failed to create $dom file"
20481                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20482                                         lod.${lodname}.dom_stripesize_cur_kb)
20483                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20484                 [[ $dom_def != $dom_current ]] ||
20485                         error "Default stripe size was not changed"
20486                 if [[ $spfree > 0 ]] ; then
20487                         dom_set=$($LFS getstripe -S $dom)
20488                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20489                                 error "DOM component size is still old"
20490                 else
20491                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20492                                 error "DoM component is set with no free space"
20493                 fi
20494                 rm $dom
20495                 dom_current=$dom_def
20496         done
20497 }
20498 run_test 270g "DoM: default DoM stripe size depends on free space"
20499
20500 test_270h() {
20501         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20502                 skip "Need MDS version at least 2.13.53"
20503
20504         local mdtname=${FSNAME}-MDT0000-mdtlov
20505         local dom=$DIR/$tdir/$tfile
20506         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20507
20508         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20509         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20510
20511         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20512         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20513                 error "can't create OST file"
20514         # mirrored file with DOM entry in the second mirror
20515         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20516                 error "can't create mirror with DoM component"
20517
20518         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20519
20520         # DOM component in the middle and has other enries in the same mirror,
20521         # should succeed but lost DoM component
20522         $LFS setstripe --copy=${dom}_1 $dom ||
20523                 error "Can't create file from OST|DOM mirror layout"
20524         # check new file has no DoM layout after all
20525         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20526                 error "File has DoM component while DoM is disabled"
20527 }
20528 run_test 270h "DoM: DoM stripe removal when disabled on server"
20529
20530 test_271a() {
20531         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20532                 skip "Need MDS version at least 2.10.55"
20533
20534         local dom=$DIR/$tdir/dom
20535
20536         mkdir -p $DIR/$tdir
20537
20538         $LFS setstripe -E 1024K -L mdt $dom
20539
20540         lctl set_param -n mdc.*.stats=clear
20541         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20542         cat $dom > /dev/null
20543         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20544         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20545         ls $dom
20546         rm -f $dom
20547 }
20548 run_test 271a "DoM: data is cached for read after write"
20549
20550 test_271b() {
20551         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20552                 skip "Need MDS version at least 2.10.55"
20553
20554         local dom=$DIR/$tdir/dom
20555
20556         mkdir -p $DIR/$tdir
20557
20558         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20559
20560         lctl set_param -n mdc.*.stats=clear
20561         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20562         cancel_lru_locks mdc
20563         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20564         # second stat to check size is cached on client
20565         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20566         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20567         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20568         rm -f $dom
20569 }
20570 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20571
20572 test_271ba() {
20573         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20574                 skip "Need MDS version at least 2.10.55"
20575
20576         local dom=$DIR/$tdir/dom
20577
20578         mkdir -p $DIR/$tdir
20579
20580         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20581
20582         lctl set_param -n mdc.*.stats=clear
20583         lctl set_param -n osc.*.stats=clear
20584         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20585         cancel_lru_locks mdc
20586         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20587         # second stat to check size is cached on client
20588         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20589         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20590         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20591         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20592         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20593         rm -f $dom
20594 }
20595 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20596
20597
20598 get_mdc_stats() {
20599         local mdtidx=$1
20600         local param=$2
20601         local mdt=MDT$(printf %04x $mdtidx)
20602
20603         if [ -z $param ]; then
20604                 lctl get_param -n mdc.*$mdt*.stats
20605         else
20606                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20607         fi
20608 }
20609
20610 test_271c() {
20611         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20612                 skip "Need MDS version at least 2.10.55"
20613
20614         local dom=$DIR/$tdir/dom
20615
20616         mkdir -p $DIR/$tdir
20617
20618         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20619
20620         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20621         local facet=mds$((mdtidx + 1))
20622
20623         cancel_lru_locks mdc
20624         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20625         createmany -o $dom 1000
20626         lctl set_param -n mdc.*.stats=clear
20627         smalliomany -w $dom 1000 200
20628         get_mdc_stats $mdtidx
20629         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20630         # Each file has 1 open, 1 IO enqueues, total 2000
20631         # but now we have also +1 getxattr for security.capability, total 3000
20632         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20633         unlinkmany $dom 1000
20634
20635         cancel_lru_locks mdc
20636         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20637         createmany -o $dom 1000
20638         lctl set_param -n mdc.*.stats=clear
20639         smalliomany -w $dom 1000 200
20640         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20641         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20642         # for OPEN and IO lock.
20643         [ $((enq - enq_2)) -ge 1000 ] ||
20644                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20645         unlinkmany $dom 1000
20646         return 0
20647 }
20648 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20649
20650 cleanup_271def_tests() {
20651         trap 0
20652         rm -f $1
20653 }
20654
20655 test_271d() {
20656         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20657                 skip "Need MDS version at least 2.10.57"
20658
20659         local dom=$DIR/$tdir/dom
20660         local tmp=$TMP/$tfile
20661         trap "cleanup_271def_tests $tmp" EXIT
20662
20663         mkdir -p $DIR/$tdir
20664
20665         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20666
20667         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20668
20669         cancel_lru_locks mdc
20670         dd if=/dev/urandom of=$tmp bs=1000 count=1
20671         dd if=$tmp of=$dom bs=1000 count=1
20672         cancel_lru_locks mdc
20673
20674         cat /etc/hosts >> $tmp
20675         lctl set_param -n mdc.*.stats=clear
20676
20677         # append data to the same file it should update local page
20678         echo "Append to the same page"
20679         cat /etc/hosts >> $dom
20680         local num=$(get_mdc_stats $mdtidx ost_read)
20681         local ra=$(get_mdc_stats $mdtidx req_active)
20682         local rw=$(get_mdc_stats $mdtidx req_waittime)
20683
20684         [ -z $num ] || error "$num READ RPC occured"
20685         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20686         echo "... DONE"
20687
20688         # compare content
20689         cmp $tmp $dom || error "file miscompare"
20690
20691         cancel_lru_locks mdc
20692         lctl set_param -n mdc.*.stats=clear
20693
20694         echo "Open and read file"
20695         cat $dom > /dev/null
20696         local num=$(get_mdc_stats $mdtidx ost_read)
20697         local ra=$(get_mdc_stats $mdtidx req_active)
20698         local rw=$(get_mdc_stats $mdtidx req_waittime)
20699
20700         [ -z $num ] || error "$num READ RPC occured"
20701         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20702         echo "... DONE"
20703
20704         # compare content
20705         cmp $tmp $dom || error "file miscompare"
20706
20707         return 0
20708 }
20709 run_test 271d "DoM: read on open (1K file in reply buffer)"
20710
20711 test_271f() {
20712         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20713                 skip "Need MDS version at least 2.10.57"
20714
20715         local dom=$DIR/$tdir/dom
20716         local tmp=$TMP/$tfile
20717         trap "cleanup_271def_tests $tmp" EXIT
20718
20719         mkdir -p $DIR/$tdir
20720
20721         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20722
20723         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20724
20725         cancel_lru_locks mdc
20726         dd if=/dev/urandom of=$tmp bs=265000 count=1
20727         dd if=$tmp of=$dom bs=265000 count=1
20728         cancel_lru_locks mdc
20729         cat /etc/hosts >> $tmp
20730         lctl set_param -n mdc.*.stats=clear
20731
20732         echo "Append to the same page"
20733         cat /etc/hosts >> $dom
20734         local num=$(get_mdc_stats $mdtidx ost_read)
20735         local ra=$(get_mdc_stats $mdtidx req_active)
20736         local rw=$(get_mdc_stats $mdtidx req_waittime)
20737
20738         [ -z $num ] || error "$num READ RPC occured"
20739         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20740         echo "... DONE"
20741
20742         # compare content
20743         cmp $tmp $dom || error "file miscompare"
20744
20745         cancel_lru_locks mdc
20746         lctl set_param -n mdc.*.stats=clear
20747
20748         echo "Open and read file"
20749         cat $dom > /dev/null
20750         local num=$(get_mdc_stats $mdtidx ost_read)
20751         local ra=$(get_mdc_stats $mdtidx req_active)
20752         local rw=$(get_mdc_stats $mdtidx req_waittime)
20753
20754         [ -z $num ] && num=0
20755         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20756         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20757         echo "... DONE"
20758
20759         # compare content
20760         cmp $tmp $dom || error "file miscompare"
20761
20762         return 0
20763 }
20764 run_test 271f "DoM: read on open (200K file and read tail)"
20765
20766 test_271g() {
20767         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20768                 skip "Skipping due to old client or server version"
20769
20770         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20771         # to get layout
20772         $CHECKSTAT -t file $DIR1/$tfile
20773
20774         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20775         MULTIOP_PID=$!
20776         sleep 1
20777         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20778         $LCTL set_param fail_loc=0x80000314
20779         rm $DIR1/$tfile || error "Unlink fails"
20780         RC=$?
20781         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20782         [ $RC -eq 0 ] || error "Failed write to stale object"
20783 }
20784 run_test 271g "Discard DoM data vs client flush race"
20785
20786 test_272a() {
20787         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20788                 skip "Need MDS version at least 2.11.50"
20789
20790         local dom=$DIR/$tdir/dom
20791         mkdir -p $DIR/$tdir
20792
20793         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20794         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20795                 error "failed to write data into $dom"
20796         local old_md5=$(md5sum $dom)
20797
20798         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20799                 error "failed to migrate to the same DoM component"
20800
20801         local new_md5=$(md5sum $dom)
20802
20803         [ "$old_md5" == "$new_md5" ] ||
20804                 error "md5sum differ: $old_md5, $new_md5"
20805
20806         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20807                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20808 }
20809 run_test 272a "DoM migration: new layout with the same DOM component"
20810
20811 test_272b() {
20812         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20813                 skip "Need MDS version at least 2.11.50"
20814
20815         local dom=$DIR/$tdir/dom
20816         mkdir -p $DIR/$tdir
20817         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20818
20819         local mdtidx=$($LFS getstripe -m $dom)
20820         local mdtname=MDT$(printf %04x $mdtidx)
20821         local facet=mds$((mdtidx + 1))
20822
20823         local mdtfree1=$(do_facet $facet \
20824                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20825         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20826                 error "failed to write data into $dom"
20827         local old_md5=$(md5sum $dom)
20828         cancel_lru_locks mdc
20829         local mdtfree1=$(do_facet $facet \
20830                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20831
20832         $LFS migrate -c2 $dom ||
20833                 error "failed to migrate to the new composite layout"
20834         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20835                 error "MDT stripe was not removed"
20836
20837         cancel_lru_locks mdc
20838         local new_md5=$(md5sum $dom)
20839         [ "$old_md5" == "$new_md5" ] ||
20840                 error "$old_md5 != $new_md5"
20841
20842         # Skip free space checks with ZFS
20843         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20844                 local mdtfree2=$(do_facet $facet \
20845                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20846                 [ $mdtfree2 -gt $mdtfree1 ] ||
20847                         error "MDT space is not freed after migration"
20848         fi
20849         return 0
20850 }
20851 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20852
20853 test_272c() {
20854         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20855                 skip "Need MDS version at least 2.11.50"
20856
20857         local dom=$DIR/$tdir/$tfile
20858         mkdir -p $DIR/$tdir
20859         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20860
20861         local mdtidx=$($LFS getstripe -m $dom)
20862         local mdtname=MDT$(printf %04x $mdtidx)
20863         local facet=mds$((mdtidx + 1))
20864
20865         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20866                 error "failed to write data into $dom"
20867         local old_md5=$(md5sum $dom)
20868         cancel_lru_locks mdc
20869         local mdtfree1=$(do_facet $facet \
20870                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20871
20872         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20873                 error "failed to migrate to the new composite layout"
20874         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20875                 error "MDT stripe was not removed"
20876
20877         cancel_lru_locks mdc
20878         local new_md5=$(md5sum $dom)
20879         [ "$old_md5" == "$new_md5" ] ||
20880                 error "$old_md5 != $new_md5"
20881
20882         # Skip free space checks with ZFS
20883         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20884                 local mdtfree2=$(do_facet $facet \
20885                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20886                 [ $mdtfree2 -gt $mdtfree1 ] ||
20887                         error "MDS space is not freed after migration"
20888         fi
20889         return 0
20890 }
20891 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20892
20893 test_272d() {
20894         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20895                 skip "Need MDS version at least 2.12.55"
20896
20897         local dom=$DIR/$tdir/$tfile
20898         mkdir -p $DIR/$tdir
20899         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20900
20901         local mdtidx=$($LFS getstripe -m $dom)
20902         local mdtname=MDT$(printf %04x $mdtidx)
20903         local facet=mds$((mdtidx + 1))
20904
20905         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20906                 error "failed to write data into $dom"
20907         local old_md5=$(md5sum $dom)
20908         cancel_lru_locks mdc
20909         local mdtfree1=$(do_facet $facet \
20910                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20911
20912         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20913                 error "failed mirroring to the new composite layout"
20914         $LFS mirror resync $dom ||
20915                 error "failed mirror resync"
20916         $LFS mirror split --mirror-id 1 -d $dom ||
20917                 error "failed mirror split"
20918
20919         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20920                 error "MDT stripe was not removed"
20921
20922         cancel_lru_locks mdc
20923         local new_md5=$(md5sum $dom)
20924         [ "$old_md5" == "$new_md5" ] ||
20925                 error "$old_md5 != $new_md5"
20926
20927         # Skip free space checks with ZFS
20928         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20929                 local mdtfree2=$(do_facet $facet \
20930                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20931                 [ $mdtfree2 -gt $mdtfree1 ] ||
20932                         error "MDS space is not freed after DOM mirror deletion"
20933         fi
20934         return 0
20935 }
20936 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20937
20938 test_272e() {
20939         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20940                 skip "Need MDS version at least 2.12.55"
20941
20942         local dom=$DIR/$tdir/$tfile
20943         mkdir -p $DIR/$tdir
20944         $LFS setstripe -c 2 $dom
20945
20946         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20947                 error "failed to write data into $dom"
20948         local old_md5=$(md5sum $dom)
20949         cancel_lru_locks mdc
20950
20951         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20952                 error "failed mirroring to the DOM layout"
20953         $LFS mirror resync $dom ||
20954                 error "failed mirror resync"
20955         $LFS mirror split --mirror-id 1 -d $dom ||
20956                 error "failed mirror split"
20957
20958         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20959                 error "MDT stripe was not removed"
20960
20961         cancel_lru_locks mdc
20962         local new_md5=$(md5sum $dom)
20963         [ "$old_md5" == "$new_md5" ] ||
20964                 error "$old_md5 != $new_md5"
20965
20966         return 0
20967 }
20968 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20969
20970 test_272f() {
20971         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20972                 skip "Need MDS version at least 2.12.55"
20973
20974         local dom=$DIR/$tdir/$tfile
20975         mkdir -p $DIR/$tdir
20976         $LFS setstripe -c 2 $dom
20977
20978         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20979                 error "failed to write data into $dom"
20980         local old_md5=$(md5sum $dom)
20981         cancel_lru_locks mdc
20982
20983         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20984                 error "failed migrating to the DOM file"
20985
20986         cancel_lru_locks mdc
20987         local new_md5=$(md5sum $dom)
20988         [ "$old_md5" != "$new_md5" ] &&
20989                 error "$old_md5 != $new_md5"
20990
20991         return 0
20992 }
20993 run_test 272f "DoM migration: OST-striped file to DOM file"
20994
20995 test_273a() {
20996         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20997                 skip "Need MDS version at least 2.11.50"
20998
20999         # Layout swap cannot be done if either file has DOM component,
21000         # this will never be supported, migration should be used instead
21001
21002         local dom=$DIR/$tdir/$tfile
21003         mkdir -p $DIR/$tdir
21004
21005         $LFS setstripe -c2 ${dom}_plain
21006         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21007         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21008                 error "can swap layout with DoM component"
21009         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21010                 error "can swap layout with DoM component"
21011
21012         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21013         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21014                 error "can swap layout with DoM component"
21015         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21016                 error "can swap layout with DoM component"
21017         return 0
21018 }
21019 run_test 273a "DoM: layout swapping should fail with DOM"
21020
21021 test_275() {
21022         remote_ost_nodsh && skip "remote OST with nodsh"
21023         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21024                 skip "Need OST version >= 2.10.57"
21025
21026         local file=$DIR/$tfile
21027         local oss
21028
21029         oss=$(comma_list $(osts_nodes))
21030
21031         dd if=/dev/urandom of=$file bs=1M count=2 ||
21032                 error "failed to create a file"
21033         cancel_lru_locks osc
21034
21035         #lock 1
21036         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21037                 error "failed to read a file"
21038
21039 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21040         $LCTL set_param fail_loc=0x8000031f
21041
21042         cancel_lru_locks osc &
21043         sleep 1
21044
21045 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21046         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21047         #IO takes another lock, but matches the PENDING one
21048         #and places it to the IO RPC
21049         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21050                 error "failed to read a file with PENDING lock"
21051 }
21052 run_test 275 "Read on a canceled duplicate lock"
21053
21054 test_276() {
21055         remote_ost_nodsh && skip "remote OST with nodsh"
21056         local pid
21057
21058         do_facet ost1 "(while true; do \
21059                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21060                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21061         pid=$!
21062
21063         for LOOP in $(seq 20); do
21064                 stop ost1
21065                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21066         done
21067         kill -9 $pid
21068         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21069                 rm $TMP/sanity_276_pid"
21070 }
21071 run_test 276 "Race between mount and obd_statfs"
21072
21073 test_277() {
21074         $LCTL set_param ldlm.namespaces.*.lru_size=0
21075         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21076         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21077                         grep ^used_mb | awk '{print $2}')
21078         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21079         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21080                 oflag=direct conv=notrunc
21081         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21082                         grep ^used_mb | awk '{print $2}')
21083         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21084 }
21085 run_test 277 "Direct IO shall drop page cache"
21086
21087 test_278() {
21088         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21089         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21090         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21091                 skip "needs the same host for mdt1 mdt2" && return
21092
21093         local pid1
21094         local pid2
21095
21096 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21097         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21098         stop mds2 &
21099         pid2=$!
21100
21101         stop mds1
21102
21103         echo "Starting MDTs"
21104         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21105         wait $pid2
21106 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21107 #will return NULL
21108         do_facet mds2 $LCTL set_param fail_loc=0
21109
21110         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21111         wait_recovery_complete mds2
21112 }
21113 run_test 278 "Race starting MDS between MDTs stop/start"
21114
21115 test_280() {
21116         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21117                 skip "Need MGS version at least 2.13.52"
21118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21119         combined_mgs_mds || skip "needs combined MGS/MDT"
21120
21121         umount_client $MOUNT
21122 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21123         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21124
21125         mount_client $MOUNT &
21126         sleep 1
21127         stop mgs || error "stop mgs failed"
21128         #for a race mgs would crash
21129         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21130         mount_client $MOUNT || error "mount client failed"
21131 }
21132 run_test 280 "Race between MGS umount and client llog processing"
21133
21134 cleanup_test_300() {
21135         trap 0
21136         umask $SAVE_UMASK
21137 }
21138 test_striped_dir() {
21139         local mdt_index=$1
21140         local stripe_count
21141         local stripe_index
21142
21143         mkdir -p $DIR/$tdir
21144
21145         SAVE_UMASK=$(umask)
21146         trap cleanup_test_300 RETURN EXIT
21147
21148         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21149                                                 $DIR/$tdir/striped_dir ||
21150                 error "set striped dir error"
21151
21152         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21153         [ "$mode" = "755" ] || error "expect 755 got $mode"
21154
21155         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21156                 error "getdirstripe failed"
21157         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21158         if [ "$stripe_count" != "2" ]; then
21159                 error "1:stripe_count is $stripe_count, expect 2"
21160         fi
21161         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21162         if [ "$stripe_count" != "2" ]; then
21163                 error "2:stripe_count is $stripe_count, expect 2"
21164         fi
21165
21166         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21167         if [ "$stripe_index" != "$mdt_index" ]; then
21168                 error "stripe_index is $stripe_index, expect $mdt_index"
21169         fi
21170
21171         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21172                 error "nlink error after create striped dir"
21173
21174         mkdir $DIR/$tdir/striped_dir/a
21175         mkdir $DIR/$tdir/striped_dir/b
21176
21177         stat $DIR/$tdir/striped_dir/a ||
21178                 error "create dir under striped dir failed"
21179         stat $DIR/$tdir/striped_dir/b ||
21180                 error "create dir under striped dir failed"
21181
21182         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21183                 error "nlink error after mkdir"
21184
21185         rmdir $DIR/$tdir/striped_dir/a
21186         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21187                 error "nlink error after rmdir"
21188
21189         rmdir $DIR/$tdir/striped_dir/b
21190         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21191                 error "nlink error after rmdir"
21192
21193         chattr +i $DIR/$tdir/striped_dir
21194         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21195                 error "immutable flags not working under striped dir!"
21196         chattr -i $DIR/$tdir/striped_dir
21197
21198         rmdir $DIR/$tdir/striped_dir ||
21199                 error "rmdir striped dir error"
21200
21201         cleanup_test_300
21202
21203         true
21204 }
21205
21206 test_300a() {
21207         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21208                 skip "skipped for lustre < 2.7.0"
21209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21210         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21211
21212         test_striped_dir 0 || error "failed on striped dir on MDT0"
21213         test_striped_dir 1 || error "failed on striped dir on MDT0"
21214 }
21215 run_test 300a "basic striped dir sanity test"
21216
21217 test_300b() {
21218         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21219                 skip "skipped for lustre < 2.7.0"
21220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21221         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21222
21223         local i
21224         local mtime1
21225         local mtime2
21226         local mtime3
21227
21228         test_mkdir $DIR/$tdir || error "mkdir fail"
21229         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21230                 error "set striped dir error"
21231         for i in {0..9}; do
21232                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21233                 sleep 1
21234                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21235                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21236                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21237                 sleep 1
21238                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21239                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21240                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21241         done
21242         true
21243 }
21244 run_test 300b "check ctime/mtime for striped dir"
21245
21246 test_300c() {
21247         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21248                 skip "skipped for lustre < 2.7.0"
21249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21250         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21251
21252         local file_count
21253
21254         mkdir -p $DIR/$tdir
21255         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21256                 error "set striped dir error"
21257
21258         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21259                 error "chown striped dir failed"
21260
21261         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21262                 error "create 5k files failed"
21263
21264         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21265
21266         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21267
21268         rm -rf $DIR/$tdir
21269 }
21270 run_test 300c "chown && check ls under striped directory"
21271
21272 test_300d() {
21273         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21274                 skip "skipped for lustre < 2.7.0"
21275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21276         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21277
21278         local stripe_count
21279         local file
21280
21281         mkdir -p $DIR/$tdir
21282         $LFS setstripe -c 2 $DIR/$tdir
21283
21284         #local striped directory
21285         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21286                 error "set striped dir error"
21287         #look at the directories for debug purposes
21288         ls -l $DIR/$tdir
21289         $LFS getdirstripe $DIR/$tdir
21290         ls -l $DIR/$tdir/striped_dir
21291         $LFS getdirstripe $DIR/$tdir/striped_dir
21292         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21293                 error "create 10 files failed"
21294
21295         #remote striped directory
21296         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21297                 error "set striped dir error"
21298         #look at the directories for debug purposes
21299         ls -l $DIR/$tdir
21300         $LFS getdirstripe $DIR/$tdir
21301         ls -l $DIR/$tdir/remote_striped_dir
21302         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21303         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21304                 error "create 10 files failed"
21305
21306         for file in $(find $DIR/$tdir); do
21307                 stripe_count=$($LFS getstripe -c $file)
21308                 [ $stripe_count -eq 2 ] ||
21309                         error "wrong stripe $stripe_count for $file"
21310         done
21311
21312         rm -rf $DIR/$tdir
21313 }
21314 run_test 300d "check default stripe under striped directory"
21315
21316 test_300e() {
21317         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21318                 skip "Need MDS version at least 2.7.55"
21319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21321
21322         local stripe_count
21323         local file
21324
21325         mkdir -p $DIR/$tdir
21326
21327         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21328                 error "set striped dir error"
21329
21330         touch $DIR/$tdir/striped_dir/a
21331         touch $DIR/$tdir/striped_dir/b
21332         touch $DIR/$tdir/striped_dir/c
21333
21334         mkdir $DIR/$tdir/striped_dir/dir_a
21335         mkdir $DIR/$tdir/striped_dir/dir_b
21336         mkdir $DIR/$tdir/striped_dir/dir_c
21337
21338         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21339                 error "set striped adir under striped dir error"
21340
21341         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21342                 error "set striped bdir under striped dir error"
21343
21344         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21345                 error "set striped cdir under striped dir error"
21346
21347         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21348                 error "rename dir under striped dir fails"
21349
21350         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21351                 error "rename dir under different stripes fails"
21352
21353         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21354                 error "rename file under striped dir should succeed"
21355
21356         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21357                 error "rename dir under striped dir should succeed"
21358
21359         rm -rf $DIR/$tdir
21360 }
21361 run_test 300e "check rename under striped directory"
21362
21363 test_300f() {
21364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21366         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21367                 skip "Need MDS version at least 2.7.55"
21368
21369         local stripe_count
21370         local file
21371
21372         rm -rf $DIR/$tdir
21373         mkdir -p $DIR/$tdir
21374
21375         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21376                 error "set striped dir error"
21377
21378         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21379                 error "set striped dir error"
21380
21381         touch $DIR/$tdir/striped_dir/a
21382         mkdir $DIR/$tdir/striped_dir/dir_a
21383         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21384                 error "create striped dir under striped dir fails"
21385
21386         touch $DIR/$tdir/striped_dir1/b
21387         mkdir $DIR/$tdir/striped_dir1/dir_b
21388         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21389                 error "create striped dir under striped dir fails"
21390
21391         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21392                 error "rename dir under different striped dir should fail"
21393
21394         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21395                 error "rename striped dir under diff striped dir should fail"
21396
21397         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21398                 error "rename file under diff striped dirs fails"
21399
21400         rm -rf $DIR/$tdir
21401 }
21402 run_test 300f "check rename cross striped directory"
21403
21404 test_300_check_default_striped_dir()
21405 {
21406         local dirname=$1
21407         local default_count=$2
21408         local default_index=$3
21409         local stripe_count
21410         local stripe_index
21411         local dir_stripe_index
21412         local dir
21413
21414         echo "checking $dirname $default_count $default_index"
21415         $LFS setdirstripe -D -c $default_count -i $default_index \
21416                                 -t all_char $DIR/$tdir/$dirname ||
21417                 error "set default stripe on striped dir error"
21418         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21419         [ $stripe_count -eq $default_count ] ||
21420                 error "expect $default_count get $stripe_count for $dirname"
21421
21422         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21423         [ $stripe_index -eq $default_index ] ||
21424                 error "expect $default_index get $stripe_index for $dirname"
21425
21426         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21427                                                 error "create dirs failed"
21428
21429         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21430         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21431         for dir in $(find $DIR/$tdir/$dirname/*); do
21432                 stripe_count=$($LFS getdirstripe -c $dir)
21433                 [ $stripe_count -eq $default_count ] ||
21434                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21435                 error "stripe count $default_count != $stripe_count for $dir"
21436
21437                 stripe_index=$($LFS getdirstripe -i $dir)
21438                 [ $default_index -eq -1 ] ||
21439                         [ $stripe_index -eq $default_index ] ||
21440                         error "$stripe_index != $default_index for $dir"
21441
21442                 #check default stripe
21443                 stripe_count=$($LFS getdirstripe -D -c $dir)
21444                 [ $stripe_count -eq $default_count ] ||
21445                 error "default count $default_count != $stripe_count for $dir"
21446
21447                 stripe_index=$($LFS getdirstripe -D -i $dir)
21448                 [ $stripe_index -eq $default_index ] ||
21449                 error "default index $default_index != $stripe_index for $dir"
21450         done
21451         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21452 }
21453
21454 test_300g() {
21455         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21456         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21457                 skip "Need MDS version at least 2.7.55"
21458
21459         local dir
21460         local stripe_count
21461         local stripe_index
21462
21463         mkdir $DIR/$tdir
21464         mkdir $DIR/$tdir/normal_dir
21465
21466         #Checking when client cache stripe index
21467         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21468         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21469                 error "create striped_dir failed"
21470
21471         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21472                 error "create dir0 fails"
21473         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21474         [ $stripe_index -eq 0 ] ||
21475                 error "dir0 expect index 0 got $stripe_index"
21476
21477         mkdir $DIR/$tdir/striped_dir/dir1 ||
21478                 error "create dir1 fails"
21479         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21480         [ $stripe_index -eq 1 ] ||
21481                 error "dir1 expect index 1 got $stripe_index"
21482
21483         #check default stripe count/stripe index
21484         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21485         test_300_check_default_striped_dir normal_dir 1 0
21486         test_300_check_default_striped_dir normal_dir 2 1
21487         test_300_check_default_striped_dir normal_dir 2 -1
21488
21489         #delete default stripe information
21490         echo "delete default stripeEA"
21491         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21492                 error "set default stripe on striped dir error"
21493
21494         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21495         for dir in $(find $DIR/$tdir/normal_dir/*); do
21496                 stripe_count=$($LFS getdirstripe -c $dir)
21497                 [ $stripe_count -eq 0 ] ||
21498                         error "expect 1 get $stripe_count for $dir"
21499                 stripe_index=$($LFS getdirstripe -i $dir)
21500                 [ $stripe_index -eq 0 ] ||
21501                         error "expect 0 get $stripe_index for $dir"
21502         done
21503 }
21504 run_test 300g "check default striped directory for normal directory"
21505
21506 test_300h() {
21507         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21508         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21509                 skip "Need MDS version at least 2.7.55"
21510
21511         local dir
21512         local stripe_count
21513
21514         mkdir $DIR/$tdir
21515         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21516                 error "set striped dir error"
21517
21518         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21519         test_300_check_default_striped_dir striped_dir 1 0
21520         test_300_check_default_striped_dir striped_dir 2 1
21521         test_300_check_default_striped_dir striped_dir 2 -1
21522
21523         #delete default stripe information
21524         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21525                 error "set default stripe on striped dir error"
21526
21527         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21528         for dir in $(find $DIR/$tdir/striped_dir/*); do
21529                 stripe_count=$($LFS getdirstripe -c $dir)
21530                 [ $stripe_count -eq 0 ] ||
21531                         error "expect 1 get $stripe_count for $dir"
21532         done
21533 }
21534 run_test 300h "check default striped directory for striped directory"
21535
21536 test_300i() {
21537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21538         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21539         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21540                 skip "Need MDS version at least 2.7.55"
21541
21542         local stripe_count
21543         local file
21544
21545         mkdir $DIR/$tdir
21546
21547         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21548                 error "set striped dir error"
21549
21550         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21551                 error "create files under striped dir failed"
21552
21553         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21554                 error "set striped hashdir error"
21555
21556         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21557                 error "create dir0 under hash dir failed"
21558         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21559                 error "create dir1 under hash dir failed"
21560
21561         # unfortunately, we need to umount to clear dir layout cache for now
21562         # once we fully implement dir layout, we can drop this
21563         umount_client $MOUNT || error "umount failed"
21564         mount_client $MOUNT || error "mount failed"
21565
21566         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21567         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21568         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21569
21570         #set the stripe to be unknown hash type
21571         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21572         $LCTL set_param fail_loc=0x1901
21573         for ((i = 0; i < 10; i++)); do
21574                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21575                         error "stat f-$i failed"
21576                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21577         done
21578
21579         touch $DIR/$tdir/striped_dir/f0 &&
21580                 error "create under striped dir with unknown hash should fail"
21581
21582         $LCTL set_param fail_loc=0
21583
21584         umount_client $MOUNT || error "umount failed"
21585         mount_client $MOUNT || error "mount failed"
21586
21587         return 0
21588 }
21589 run_test 300i "client handle unknown hash type striped directory"
21590
21591 test_300j() {
21592         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21594         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21595                 skip "Need MDS version at least 2.7.55"
21596
21597         local stripe_count
21598         local file
21599
21600         mkdir $DIR/$tdir
21601
21602         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21603         $LCTL set_param fail_loc=0x1702
21604         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21605                 error "set striped dir error"
21606
21607         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21608                 error "create files under striped dir failed"
21609
21610         $LCTL set_param fail_loc=0
21611
21612         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21613
21614         return 0
21615 }
21616 run_test 300j "test large update record"
21617
21618 test_300k() {
21619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21620         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21621         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21622                 skip "Need MDS version at least 2.7.55"
21623
21624         # this test needs a huge transaction
21625         local kb
21626         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21627              osd*.$FSNAME-MDT0000.kbytestotal")
21628         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21629
21630         local stripe_count
21631         local file
21632
21633         mkdir $DIR/$tdir
21634
21635         #define OBD_FAIL_LARGE_STRIPE   0x1703
21636         $LCTL set_param fail_loc=0x1703
21637         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21638                 error "set striped dir error"
21639         $LCTL set_param fail_loc=0
21640
21641         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21642                 error "getstripeddir fails"
21643         rm -rf $DIR/$tdir/striped_dir ||
21644                 error "unlink striped dir fails"
21645
21646         return 0
21647 }
21648 run_test 300k "test large striped directory"
21649
21650 test_300l() {
21651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21652         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21653         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21654                 skip "Need MDS version at least 2.7.55"
21655
21656         local stripe_index
21657
21658         test_mkdir -p $DIR/$tdir/striped_dir
21659         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21660                         error "chown $RUNAS_ID failed"
21661         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21662                 error "set default striped dir failed"
21663
21664         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21665         $LCTL set_param fail_loc=0x80000158
21666         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21667
21668         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21669         [ $stripe_index -eq 1 ] ||
21670                 error "expect 1 get $stripe_index for $dir"
21671 }
21672 run_test 300l "non-root user to create dir under striped dir with stale layout"
21673
21674 test_300m() {
21675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21676         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21677         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21678                 skip "Need MDS version at least 2.7.55"
21679
21680         mkdir -p $DIR/$tdir/striped_dir
21681         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21682                 error "set default stripes dir error"
21683
21684         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21685
21686         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21687         [ $stripe_count -eq 0 ] ||
21688                         error "expect 0 get $stripe_count for a"
21689
21690         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21691                 error "set default stripes dir error"
21692
21693         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21694
21695         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21696         [ $stripe_count -eq 0 ] ||
21697                         error "expect 0 get $stripe_count for b"
21698
21699         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21700                 error "set default stripes dir error"
21701
21702         mkdir $DIR/$tdir/striped_dir/c &&
21703                 error "default stripe_index is invalid, mkdir c should fails"
21704
21705         rm -rf $DIR/$tdir || error "rmdir fails"
21706 }
21707 run_test 300m "setstriped directory on single MDT FS"
21708
21709 cleanup_300n() {
21710         local list=$(comma_list $(mdts_nodes))
21711
21712         trap 0
21713         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21714 }
21715
21716 test_300n() {
21717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21718         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21719         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21720                 skip "Need MDS version at least 2.7.55"
21721         remote_mds_nodsh && skip "remote MDS with nodsh"
21722
21723         local stripe_index
21724         local list=$(comma_list $(mdts_nodes))
21725
21726         trap cleanup_300n RETURN EXIT
21727         mkdir -p $DIR/$tdir
21728         chmod 777 $DIR/$tdir
21729         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21730                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21731                 error "create striped dir succeeds with gid=0"
21732
21733         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21734         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21735                 error "create striped dir fails with gid=-1"
21736
21737         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21738         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21739                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21740                 error "set default striped dir succeeds with gid=0"
21741
21742
21743         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21744         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21745                 error "set default striped dir fails with gid=-1"
21746
21747
21748         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21749         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21750                                         error "create test_dir fails"
21751         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21752                                         error "create test_dir1 fails"
21753         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21754                                         error "create test_dir2 fails"
21755         cleanup_300n
21756 }
21757 run_test 300n "non-root user to create dir under striped dir with default EA"
21758
21759 test_300o() {
21760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21761         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21762         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21763                 skip "Need MDS version at least 2.7.55"
21764
21765         local numfree1
21766         local numfree2
21767
21768         mkdir -p $DIR/$tdir
21769
21770         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21771         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21772         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21773                 skip "not enough free inodes $numfree1 $numfree2"
21774         fi
21775
21776         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21777         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21778         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21779                 skip "not enough free space $numfree1 $numfree2"
21780         fi
21781
21782         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21783                 error "setdirstripe fails"
21784
21785         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21786                 error "create dirs fails"
21787
21788         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21789         ls $DIR/$tdir/striped_dir > /dev/null ||
21790                 error "ls striped dir fails"
21791         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21792                 error "unlink big striped dir fails"
21793 }
21794 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21795
21796 test_300p() {
21797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21798         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21799         remote_mds_nodsh && skip "remote MDS with nodsh"
21800
21801         mkdir -p $DIR/$tdir
21802
21803         #define OBD_FAIL_OUT_ENOSPC     0x1704
21804         do_facet mds2 lctl set_param fail_loc=0x80001704
21805         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21806                  && error "create striped directory should fail"
21807
21808         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21809
21810         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21811         true
21812 }
21813 run_test 300p "create striped directory without space"
21814
21815 test_300q() {
21816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21817         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21818
21819         local fd=$(free_fd)
21820         local cmd="exec $fd<$tdir"
21821         cd $DIR
21822         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21823         eval $cmd
21824         cmd="exec $fd<&-"
21825         trap "eval $cmd" EXIT
21826         cd $tdir || error "cd $tdir fails"
21827         rmdir  ../$tdir || error "rmdir $tdir fails"
21828         mkdir local_dir && error "create dir succeeds"
21829         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21830         eval $cmd
21831         return 0
21832 }
21833 run_test 300q "create remote directory under orphan directory"
21834
21835 test_300r() {
21836         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21837                 skip "Need MDS version at least 2.7.55" && return
21838         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21839
21840         mkdir $DIR/$tdir
21841
21842         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21843                 error "set striped dir error"
21844
21845         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21846                 error "getstripeddir fails"
21847
21848         local stripe_count
21849         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21850                       awk '/lmv_stripe_count:/ { print $2 }')
21851
21852         [ $MDSCOUNT -ne $stripe_count ] &&
21853                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21854
21855         rm -rf $DIR/$tdir/striped_dir ||
21856                 error "unlink striped dir fails"
21857 }
21858 run_test 300r "test -1 striped directory"
21859
21860 test_300s_helper() {
21861         local count=$1
21862
21863         local stripe_dir=$DIR/$tdir/striped_dir.$count
21864
21865         $LFS mkdir -c $count $stripe_dir ||
21866                 error "lfs mkdir -c error"
21867
21868         $LFS getdirstripe $stripe_dir ||
21869                 error "lfs getdirstripe fails"
21870
21871         local stripe_count
21872         stripe_count=$($LFS getdirstripe $stripe_dir |
21873                       awk '/lmv_stripe_count:/ { print $2 }')
21874
21875         [ $count -ne $stripe_count ] &&
21876                 error_noexit "bad stripe count $stripe_count expected $count"
21877
21878         local dupe_stripes
21879         dupe_stripes=$($LFS getdirstripe $stripe_dir |
21880                 awk '/0x/ {count[$1] += 1}; END {
21881                         for (idx in count) {
21882                                 if (count[idx]>1) {
21883                                         print "index " idx " count " count[idx]
21884                                 }
21885                         }
21886                 }')
21887
21888         if [[ -n "$dupe_stripes" ]] ; then
21889                 lfs getdirstripe $stripe_dir
21890                 error_noexit "Dupe MDT above: $dupe_stripes "
21891         fi
21892
21893         rm -rf $stripe_dir ||
21894                 error_noexit "unlink $stripe_dir fails"
21895 }
21896
21897 test_300s() {
21898         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21899                 skip "Need MDS version at least 2.7.55" && return
21900         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21901
21902         mkdir $DIR/$tdir
21903         for count in $(seq 2 $MDSCOUNT); do
21904                 test_300s_helper $count
21905         done
21906 }
21907 run_test 300s "test lfs mkdir -c without -i"
21908
21909
21910 prepare_remote_file() {
21911         mkdir $DIR/$tdir/src_dir ||
21912                 error "create remote source failed"
21913
21914         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21915                  error "cp to remote source failed"
21916         touch $DIR/$tdir/src_dir/a
21917
21918         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21919                 error "create remote target dir failed"
21920
21921         touch $DIR/$tdir/tgt_dir/b
21922
21923         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21924                 error "rename dir cross MDT failed!"
21925
21926         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21927                 error "src_child still exists after rename"
21928
21929         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21930                 error "missing file(a) after rename"
21931
21932         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21933                 error "diff after rename"
21934 }
21935
21936 test_310a() {
21937         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21939
21940         local remote_file=$DIR/$tdir/tgt_dir/b
21941
21942         mkdir -p $DIR/$tdir
21943
21944         prepare_remote_file || error "prepare remote file failed"
21945
21946         #open-unlink file
21947         $OPENUNLINK $remote_file $remote_file ||
21948                 error "openunlink $remote_file failed"
21949         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21950 }
21951 run_test 310a "open unlink remote file"
21952
21953 test_310b() {
21954         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21956
21957         local remote_file=$DIR/$tdir/tgt_dir/b
21958
21959         mkdir -p $DIR/$tdir
21960
21961         prepare_remote_file || error "prepare remote file failed"
21962
21963         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21964         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21965         $CHECKSTAT -t file $remote_file || error "check file failed"
21966 }
21967 run_test 310b "unlink remote file with multiple links while open"
21968
21969 test_310c() {
21970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21971         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21972
21973         local remote_file=$DIR/$tdir/tgt_dir/b
21974
21975         mkdir -p $DIR/$tdir
21976
21977         prepare_remote_file || error "prepare remote file failed"
21978
21979         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21980         multiop_bg_pause $remote_file O_uc ||
21981                         error "mulitop failed for remote file"
21982         MULTIPID=$!
21983         $MULTIOP $DIR/$tfile Ouc
21984         kill -USR1 $MULTIPID
21985         wait $MULTIPID
21986 }
21987 run_test 310c "open-unlink remote file with multiple links"
21988
21989 #LU-4825
21990 test_311() {
21991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21992         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21993         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21994                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21995         remote_mds_nodsh && skip "remote MDS with nodsh"
21996
21997         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21998         local mdts=$(comma_list $(mdts_nodes))
21999
22000         mkdir -p $DIR/$tdir
22001         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22002         createmany -o $DIR/$tdir/$tfile. 1000
22003
22004         # statfs data is not real time, let's just calculate it
22005         old_iused=$((old_iused + 1000))
22006
22007         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22008                         osp.*OST0000*MDT0000.create_count")
22009         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22010                                 osp.*OST0000*MDT0000.max_create_count")
22011         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22012
22013         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22014         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22015         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22016
22017         unlinkmany $DIR/$tdir/$tfile. 1000
22018
22019         do_nodes $mdts "$LCTL set_param -n \
22020                         osp.*OST0000*.max_create_count=$max_count"
22021         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22022                 do_nodes $mdts "$LCTL set_param -n \
22023                                 osp.*OST0000*.create_count=$count"
22024         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22025                         grep "=0" && error "create_count is zero"
22026
22027         local new_iused
22028         for i in $(seq 120); do
22029                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
22030                 # system may be too busy to destroy all objs in time, use
22031                 # a somewhat small value to not fail autotest
22032                 [ $((old_iused - new_iused)) -gt 400 ] && break
22033                 sleep 1
22034         done
22035
22036         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22037         [ $((old_iused - new_iused)) -gt 400 ] ||
22038                 error "objs not destroyed after unlink"
22039 }
22040 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22041
22042 zfs_oid_to_objid()
22043 {
22044         local ost=$1
22045         local objid=$2
22046
22047         local vdevdir=$(dirname $(facet_vdevice $ost))
22048         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22049         local zfs_zapid=$(do_facet $ost $cmd |
22050                           grep -w "/O/0/d$((objid%32))" -C 5 |
22051                           awk '/Object/{getline; print $1}')
22052         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22053                           awk "/$objid = /"'{printf $3}')
22054
22055         echo $zfs_objid
22056 }
22057
22058 zfs_object_blksz() {
22059         local ost=$1
22060         local objid=$2
22061
22062         local vdevdir=$(dirname $(facet_vdevice $ost))
22063         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22064         local blksz=$(do_facet $ost $cmd $objid |
22065                       awk '/dblk/{getline; printf $4}')
22066
22067         case "${blksz: -1}" in
22068                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22069                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22070                 *) ;;
22071         esac
22072
22073         echo $blksz
22074 }
22075
22076 test_312() { # LU-4856
22077         remote_ost_nodsh && skip "remote OST with nodsh"
22078         [ "$ost1_FSTYPE" = "zfs" ] ||
22079                 skip_env "the test only applies to zfs"
22080
22081         local max_blksz=$(do_facet ost1 \
22082                           $ZFS get -p recordsize $(facet_device ost1) |
22083                           awk '!/VALUE/{print $3}')
22084
22085         # to make life a little bit easier
22086         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22087         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22088
22089         local tf=$DIR/$tdir/$tfile
22090         touch $tf
22091         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22092
22093         # Get ZFS object id
22094         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22095         # block size change by sequential overwrite
22096         local bs
22097
22098         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22099                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22100
22101                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22102                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22103         done
22104         rm -f $tf
22105
22106         # block size change by sequential append write
22107         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22108         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22109         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22110         local count
22111
22112         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22113                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22114                         oflag=sync conv=notrunc
22115
22116                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22117                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22118                         error "blksz error, actual $blksz, " \
22119                                 "expected: 2 * $count * $PAGE_SIZE"
22120         done
22121         rm -f $tf
22122
22123         # random write
22124         touch $tf
22125         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22126         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22127
22128         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22129         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22130         [ $blksz -eq $PAGE_SIZE ] ||
22131                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22132
22133         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22134         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22135         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22136
22137         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22138         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22139         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22140 }
22141 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22142
22143 test_313() {
22144         remote_ost_nodsh && skip "remote OST with nodsh"
22145
22146         local file=$DIR/$tfile
22147
22148         rm -f $file
22149         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22150
22151         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22152         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22153         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22154                 error "write should failed"
22155         do_facet ost1 "$LCTL set_param fail_loc=0"
22156         rm -f $file
22157 }
22158 run_test 313 "io should fail after last_rcvd update fail"
22159
22160 test_314() {
22161         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22162
22163         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22164         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22165         rm -f $DIR/$tfile
22166         wait_delete_completed
22167         do_facet ost1 "$LCTL set_param fail_loc=0"
22168 }
22169 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22170
22171 test_315() { # LU-618
22172         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22173
22174         local file=$DIR/$tfile
22175         rm -f $file
22176
22177         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22178                 error "multiop file write failed"
22179         $MULTIOP $file oO_RDONLY:r4063232_c &
22180         PID=$!
22181
22182         sleep 2
22183
22184         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22185         kill -USR1 $PID
22186
22187         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22188         rm -f $file
22189 }
22190 run_test 315 "read should be accounted"
22191
22192 test_316() {
22193         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22194         large_xattr_enabled || skip_env "ea_inode feature disabled"
22195
22196         rm -rf $DIR/$tdir/d
22197         mkdir -p $DIR/$tdir/d
22198         chown nobody $DIR/$tdir/d
22199         touch $DIR/$tdir/d/file
22200
22201         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22202 }
22203 run_test 316 "lfs mv"
22204
22205 test_317() {
22206         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22207                 skip "Need MDS version at least 2.11.53"
22208         if [ "$ost1_FSTYPE" == "zfs" ]; then
22209                 skip "LU-10370: no implementation for ZFS"
22210         fi
22211
22212         local trunc_sz
22213         local grant_blk_size
22214
22215         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22216                         awk '/grant_block_size:/ { print $2; exit; }')
22217         #
22218         # Create File of size 5M. Truncate it to below size's and verify
22219         # blocks count.
22220         #
22221         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22222                 error "Create file $DIR/$tfile failed"
22223         stack_trap "rm -f $DIR/$tfile" EXIT
22224
22225         for trunc_sz in 2097152 4097 4000 509 0; do
22226                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22227                         error "truncate $tfile to $trunc_sz failed"
22228                 local sz=$(stat --format=%s $DIR/$tfile)
22229                 local blk=$(stat --format=%b $DIR/$tfile)
22230                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22231                                      grant_blk_size) * 8))
22232
22233                 if [[ $blk -ne $trunc_blk ]]; then
22234                         $(which stat) $DIR/$tfile
22235                         error "Expected Block $trunc_blk got $blk for $tfile"
22236                 fi
22237
22238                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22239                         error "Expected Size $trunc_sz got $sz for $tfile"
22240         done
22241
22242         #
22243         # sparse file test
22244         # Create file with a hole and write actual two blocks. Block count
22245         # must be 16.
22246         #
22247         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22248                 conv=fsync || error "Create file : $DIR/$tfile"
22249
22250         # Calculate the final truncate size.
22251         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22252
22253         #
22254         # truncate to size $trunc_sz bytes. Strip the last block
22255         # The block count must drop to 8
22256         #
22257         $TRUNCATE $DIR/$tfile $trunc_sz ||
22258                 error "truncate $tfile to $trunc_sz failed"
22259
22260         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22261         sz=$(stat --format=%s $DIR/$tfile)
22262         blk=$(stat --format=%b $DIR/$tfile)
22263
22264         if [[ $blk -ne $trunc_bsz ]]; then
22265                 $(which stat) $DIR/$tfile
22266                 error "Expected Block $trunc_bsz got $blk for $tfile"
22267         fi
22268
22269         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22270                 error "Expected Size $trunc_sz got $sz for $tfile"
22271 }
22272 run_test 317 "Verify blocks get correctly update after truncate"
22273
22274 test_318() {
22275         local old_max_active=$($LCTL get_param -n \
22276                             llite.*.max_read_ahead_async_active 2>/dev/null)
22277
22278         $LCTL set_param llite.*.max_read_ahead_async_active=256
22279         local max_active=$($LCTL get_param -n \
22280                            llite.*.max_read_ahead_async_active 2>/dev/null)
22281         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22282
22283         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22284                 error "set max_read_ahead_async_active should succeed"
22285
22286         $LCTL set_param llite.*.max_read_ahead_async_active=512
22287         max_active=$($LCTL get_param -n \
22288                      llite.*.max_read_ahead_async_active 2>/dev/null)
22289         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22290
22291         # restore @max_active
22292         [ $old_max_active -ne 0 ] && $LCTL set_param \
22293                 llite.*.max_read_ahead_async_active=$old_max_active
22294
22295         local old_threshold=$($LCTL get_param -n \
22296                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22297         local max_per_file_mb=$($LCTL get_param -n \
22298                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22299
22300         local invalid=$(($max_per_file_mb + 1))
22301         $LCTL set_param \
22302                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22303                         && error "set $invalid should fail"
22304
22305         local valid=$(($invalid - 1))
22306         $LCTL set_param \
22307                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22308                         error "set $valid should succeed"
22309         local threshold=$($LCTL get_param -n \
22310                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22311         [ $threshold -eq $valid ] || error \
22312                 "expect threshold $valid got $threshold"
22313         $LCTL set_param \
22314                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22315 }
22316 run_test 318 "Verify async readahead tunables"
22317
22318 test_319() {
22319         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22320
22321         local before=$(date +%s)
22322         local evict
22323         local mdir=$DIR/$tdir
22324         local file=$mdir/xxx
22325
22326         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22327         touch $file
22328
22329 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22330         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22331         $LFS mv -m1 $file &
22332
22333         sleep 1
22334         dd if=$file of=/dev/null
22335         wait
22336         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22337           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22338
22339         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22340 }
22341 run_test 319 "lost lease lock on migrate error"
22342
22343 test_398a() { # LU-4198
22344         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22345         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22346
22347         # request a new lock on client
22348         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22349
22350         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22351         local lock_count=$($LCTL get_param -n \
22352                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22353         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22354
22355         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22356
22357         # no lock cached, should use lockless IO and not enqueue new lock
22358         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22359         lock_count=$($LCTL get_param -n \
22360                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22361         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22362 }
22363 run_test 398a "direct IO should cancel lock otherwise lockless"
22364
22365 test_398b() { # LU-4198
22366         which fio || skip_env "no fio installed"
22367         $LFS setstripe -c -1 $DIR/$tfile
22368
22369         local size=12
22370         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22371
22372         local njobs=4
22373         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22374         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22375                 --numjobs=$njobs --fallocate=none \
22376                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22377                 --filename=$DIR/$tfile &
22378         bg_pid=$!
22379
22380         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22381         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22382                 --numjobs=$njobs --fallocate=none \
22383                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22384                 --filename=$DIR/$tfile || true
22385         wait $bg_pid
22386
22387         rm -rf $DIR/$tfile
22388 }
22389 run_test 398b "DIO and buffer IO race"
22390
22391 test_398c() { # LU-4198
22392         which fio || skip_env "no fio installed"
22393
22394         saved_debug=$($LCTL get_param -n debug)
22395         $LCTL set_param debug=0
22396
22397         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22398         ((size /= 1024)) # by megabytes
22399         ((size /= 2)) # write half of the OST at most
22400         [ $size -gt 40 ] && size=40 #reduce test time anyway
22401
22402         $LFS setstripe -c 1 $DIR/$tfile
22403
22404         # it seems like ldiskfs reserves more space than necessary if the
22405         # writing blocks are not mapped, so it extends the file firstly
22406         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22407         cancel_lru_locks osc
22408
22409         # clear and verify rpc_stats later
22410         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22411
22412         local njobs=4
22413         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22414         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22415                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22416                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22417                 --filename=$DIR/$tfile
22418         [ $? -eq 0 ] || error "fio write error"
22419
22420         [ $($LCTL get_param -n \
22421          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22422                 error "Locks were requested while doing AIO"
22423
22424         # get the percentage of 1-page I/O
22425         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22426                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22427                 awk '{print $7}')
22428         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22429
22430         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22431         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22432                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22433                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22434                 --filename=$DIR/$tfile
22435         [ $? -eq 0 ] || error "fio mixed read write error"
22436
22437         echo "AIO with large block size ${size}M"
22438         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22439                 --numjobs=1 --fallocate=none --ioengine=libaio \
22440                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22441                 --filename=$DIR/$tfile
22442         [ $? -eq 0 ] || error "fio large block size failed"
22443
22444         rm -rf $DIR/$tfile
22445         $LCTL set_param debug="$saved_debug"
22446 }
22447 run_test 398c "run fio to test AIO"
22448
22449 test_398d() { #  LU-13846
22450         test -f aiocp || skip_env "no aiocp installed"
22451         local aio_file=$DIR/aio_file
22452
22453         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22454
22455         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22456         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22457
22458         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22459
22460         # make sure we don't crash and fail properly
22461         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22462                 error "aio not aligned with PAGE SIZE should fail"
22463
22464         rm -rf $DIR/$tfile $aio_file
22465 }
22466 run_test 398d "run aiocp to verify block size > stripe size"
22467
22468 test_398e() {
22469         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
22470         touch $DIR/$tfile.new
22471         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
22472 }
22473 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
22474
22475 test_fake_rw() {
22476         local read_write=$1
22477         if [ "$read_write" = "write" ]; then
22478                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22479         elif [ "$read_write" = "read" ]; then
22480                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22481         else
22482                 error "argument error"
22483         fi
22484
22485         # turn off debug for performance testing
22486         local saved_debug=$($LCTL get_param -n debug)
22487         $LCTL set_param debug=0
22488
22489         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22490
22491         # get ost1 size - $FSNAME-OST0000
22492         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22493         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22494         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22495
22496         if [ "$read_write" = "read" ]; then
22497                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22498         fi
22499
22500         local start_time=$(date +%s.%N)
22501         $dd_cmd bs=1M count=$blocks oflag=sync ||
22502                 error "real dd $read_write error"
22503         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22504
22505         if [ "$read_write" = "write" ]; then
22506                 rm -f $DIR/$tfile
22507         fi
22508
22509         # define OBD_FAIL_OST_FAKE_RW           0x238
22510         do_facet ost1 $LCTL set_param fail_loc=0x238
22511
22512         local start_time=$(date +%s.%N)
22513         $dd_cmd bs=1M count=$blocks oflag=sync ||
22514                 error "fake dd $read_write error"
22515         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22516
22517         if [ "$read_write" = "write" ]; then
22518                 # verify file size
22519                 cancel_lru_locks osc
22520                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22521                         error "$tfile size not $blocks MB"
22522         fi
22523         do_facet ost1 $LCTL set_param fail_loc=0
22524
22525         echo "fake $read_write $duration_fake vs. normal $read_write" \
22526                 "$duration in seconds"
22527         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22528                 error_not_in_vm "fake write is slower"
22529
22530         $LCTL set_param -n debug="$saved_debug"
22531         rm -f $DIR/$tfile
22532 }
22533 test_399a() { # LU-7655 for OST fake write
22534         remote_ost_nodsh && skip "remote OST with nodsh"
22535
22536         test_fake_rw write
22537 }
22538 run_test 399a "fake write should not be slower than normal write"
22539
22540 test_399b() { # LU-8726 for OST fake read
22541         remote_ost_nodsh && skip "remote OST with nodsh"
22542         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22543                 skip_env "ldiskfs only test"
22544         fi
22545
22546         test_fake_rw read
22547 }
22548 run_test 399b "fake read should not be slower than normal read"
22549
22550 test_400a() { # LU-1606, was conf-sanity test_74
22551         if ! which $CC > /dev/null 2>&1; then
22552                 skip_env "$CC is not installed"
22553         fi
22554
22555         local extra_flags=''
22556         local out=$TMP/$tfile
22557         local prefix=/usr/include/lustre
22558         local prog
22559
22560         # Oleg removes c files in his test rig so test if any c files exist
22561         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22562                 skip_env "Needed c test files are missing"
22563
22564         if ! [[ -d $prefix ]]; then
22565                 # Assume we're running in tree and fixup the include path.
22566                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22567                 extra_flags+=" -L$LUSTRE/utils/.lib"
22568         fi
22569
22570         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22571                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22572                         error "client api broken"
22573         done
22574         rm -f $out
22575 }
22576 run_test 400a "Lustre client api program can compile and link"
22577
22578 test_400b() { # LU-1606, LU-5011
22579         local header
22580         local out=$TMP/$tfile
22581         local prefix=/usr/include/linux/lustre
22582
22583         # We use a hard coded prefix so that this test will not fail
22584         # when run in tree. There are headers in lustre/include/lustre/
22585         # that are not packaged (like lustre_idl.h) and have more
22586         # complicated include dependencies (like config.h and lnet/types.h).
22587         # Since this test about correct packaging we just skip them when
22588         # they don't exist (see below) rather than try to fixup cppflags.
22589
22590         if ! which $CC > /dev/null 2>&1; then
22591                 skip_env "$CC is not installed"
22592         fi
22593
22594         for header in $prefix/*.h; do
22595                 if ! [[ -f "$header" ]]; then
22596                         continue
22597                 fi
22598
22599                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22600                         continue # lustre_ioctl.h is internal header
22601                 fi
22602
22603                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22604                         error "cannot compile '$header'"
22605         done
22606         rm -f $out
22607 }
22608 run_test 400b "packaged headers can be compiled"
22609
22610 test_401a() { #LU-7437
22611         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22612         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22613
22614         #count the number of parameters by "list_param -R"
22615         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22616         #count the number of parameters by listing proc files
22617         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22618         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22619         echo "proc_dirs='$proc_dirs'"
22620         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22621         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22622                       sort -u | wc -l)
22623
22624         [ $params -eq $procs ] ||
22625                 error "found $params parameters vs. $procs proc files"
22626
22627         # test the list_param -D option only returns directories
22628         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22629         #count the number of parameters by listing proc directories
22630         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22631                 sort -u | wc -l)
22632
22633         [ $params -eq $procs ] ||
22634                 error "found $params parameters vs. $procs proc files"
22635 }
22636 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22637
22638 test_401b() {
22639         # jobid_var may not allow arbitrary values, so use jobid_name
22640         # if available
22641         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22642                 local testname=jobid_name tmp='testing%p'
22643         else
22644                 local testname=jobid_var tmp=testing
22645         fi
22646
22647         local save=$($LCTL get_param -n $testname)
22648
22649         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22650                 error "no error returned when setting bad parameters"
22651
22652         local jobid_new=$($LCTL get_param -n foe $testname baz)
22653         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22654
22655         $LCTL set_param -n fog=bam $testname=$save bat=fog
22656         local jobid_old=$($LCTL get_param -n foe $testname bag)
22657         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22658 }
22659 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22660
22661 test_401c() {
22662         # jobid_var may not allow arbitrary values, so use jobid_name
22663         # if available
22664         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22665                 local testname=jobid_name
22666         else
22667                 local testname=jobid_var
22668         fi
22669
22670         local jobid_var_old=$($LCTL get_param -n $testname)
22671         local jobid_var_new
22672
22673         $LCTL set_param $testname= &&
22674                 error "no error returned for 'set_param a='"
22675
22676         jobid_var_new=$($LCTL get_param -n $testname)
22677         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22678                 error "$testname was changed by setting without value"
22679
22680         $LCTL set_param $testname &&
22681                 error "no error returned for 'set_param a'"
22682
22683         jobid_var_new=$($LCTL get_param -n $testname)
22684         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22685                 error "$testname was changed by setting without value"
22686 }
22687 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22688
22689 test_401d() {
22690         # jobid_var may not allow arbitrary values, so use jobid_name
22691         # if available
22692         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22693                 local testname=jobid_name new_value='foo=bar%p'
22694         else
22695                 local testname=jobid_var new_valuie=foo=bar
22696         fi
22697
22698         local jobid_var_old=$($LCTL get_param -n $testname)
22699         local jobid_var_new
22700
22701         $LCTL set_param $testname=$new_value ||
22702                 error "'set_param a=b' did not accept a value containing '='"
22703
22704         jobid_var_new=$($LCTL get_param -n $testname)
22705         [[ "$jobid_var_new" == "$new_value" ]] ||
22706                 error "'set_param a=b' failed on a value containing '='"
22707
22708         # Reset the $testname to test the other format
22709         $LCTL set_param $testname=$jobid_var_old
22710         jobid_var_new=$($LCTL get_param -n $testname)
22711         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22712                 error "failed to reset $testname"
22713
22714         $LCTL set_param $testname $new_value ||
22715                 error "'set_param a b' did not accept a value containing '='"
22716
22717         jobid_var_new=$($LCTL get_param -n $testname)
22718         [[ "$jobid_var_new" == "$new_value" ]] ||
22719                 error "'set_param a b' failed on a value containing '='"
22720
22721         $LCTL set_param $testname $jobid_var_old
22722         jobid_var_new=$($LCTL get_param -n $testname)
22723         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22724                 error "failed to reset $testname"
22725 }
22726 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22727
22728 test_402() {
22729         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22730         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22731                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22732         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22733                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22734                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22735         remote_mds_nodsh && skip "remote MDS with nodsh"
22736
22737         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22738 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22739         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22740         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22741                 echo "Touch failed - OK"
22742 }
22743 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22744
22745 test_403() {
22746         local file1=$DIR/$tfile.1
22747         local file2=$DIR/$tfile.2
22748         local tfile=$TMP/$tfile
22749
22750         rm -f $file1 $file2 $tfile
22751
22752         touch $file1
22753         ln $file1 $file2
22754
22755         # 30 sec OBD_TIMEOUT in ll_getattr()
22756         # right before populating st_nlink
22757         $LCTL set_param fail_loc=0x80001409
22758         stat -c %h $file1 > $tfile &
22759
22760         # create an alias, drop all locks and reclaim the dentry
22761         < $file2
22762         cancel_lru_locks mdc
22763         cancel_lru_locks osc
22764         sysctl -w vm.drop_caches=2
22765
22766         wait
22767
22768         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22769
22770         rm -f $tfile $file1 $file2
22771 }
22772 run_test 403 "i_nlink should not drop to zero due to aliasing"
22773
22774 test_404() { # LU-6601
22775         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22776                 skip "Need server version newer than 2.8.52"
22777         remote_mds_nodsh && skip "remote MDS with nodsh"
22778
22779         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22780                 awk '/osp .*-osc-MDT/ { print $4}')
22781
22782         local osp
22783         for osp in $mosps; do
22784                 echo "Deactivate: " $osp
22785                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22786                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22787                         awk -vp=$osp '$4 == p { print $2 }')
22788                 [ $stat = IN ] || {
22789                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22790                         error "deactivate error"
22791                 }
22792                 echo "Activate: " $osp
22793                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22794                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22795                         awk -vp=$osp '$4 == p { print $2 }')
22796                 [ $stat = UP ] || {
22797                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22798                         error "activate error"
22799                 }
22800         done
22801 }
22802 run_test 404 "validate manual {de}activated works properly for OSPs"
22803
22804 test_405() {
22805         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22806         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22807                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22808                         skip "Layout swap lock is not supported"
22809
22810         check_swap_layouts_support
22811         check_swap_layout_no_dom $DIR
22812
22813         test_mkdir $DIR/$tdir
22814         swap_lock_test -d $DIR/$tdir ||
22815                 error "One layout swap locked test failed"
22816 }
22817 run_test 405 "Various layout swap lock tests"
22818
22819 test_406() {
22820         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22821         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22822         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22824         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22825                 skip "Need MDS version at least 2.8.50"
22826
22827         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22828         local test_pool=$TESTNAME
22829
22830         pool_add $test_pool || error "pool_add failed"
22831         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22832                 error "pool_add_targets failed"
22833
22834         save_layout_restore_at_exit $MOUNT
22835
22836         # parent set default stripe count only, child will stripe from both
22837         # parent and fs default
22838         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22839                 error "setstripe $MOUNT failed"
22840         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22841         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22842         for i in $(seq 10); do
22843                 local f=$DIR/$tdir/$tfile.$i
22844                 touch $f || error "touch failed"
22845                 local count=$($LFS getstripe -c $f)
22846                 [ $count -eq $OSTCOUNT ] ||
22847                         error "$f stripe count $count != $OSTCOUNT"
22848                 local offset=$($LFS getstripe -i $f)
22849                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22850                 local size=$($LFS getstripe -S $f)
22851                 [ $size -eq $((def_stripe_size * 2)) ] ||
22852                         error "$f stripe size $size != $((def_stripe_size * 2))"
22853                 local pool=$($LFS getstripe -p $f)
22854                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22855         done
22856
22857         # change fs default striping, delete parent default striping, now child
22858         # will stripe from new fs default striping only
22859         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22860                 error "change $MOUNT default stripe failed"
22861         $LFS setstripe -c 0 $DIR/$tdir ||
22862                 error "delete $tdir default stripe failed"
22863         for i in $(seq 11 20); do
22864                 local f=$DIR/$tdir/$tfile.$i
22865                 touch $f || error "touch $f failed"
22866                 local count=$($LFS getstripe -c $f)
22867                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22868                 local offset=$($LFS getstripe -i $f)
22869                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22870                 local size=$($LFS getstripe -S $f)
22871                 [ $size -eq $def_stripe_size ] ||
22872                         error "$f stripe size $size != $def_stripe_size"
22873                 local pool=$($LFS getstripe -p $f)
22874                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22875         done
22876
22877         unlinkmany $DIR/$tdir/$tfile. 1 20
22878
22879         local f=$DIR/$tdir/$tfile
22880         pool_remove_all_targets $test_pool $f
22881         pool_remove $test_pool $f
22882 }
22883 run_test 406 "DNE support fs default striping"
22884
22885 test_407() {
22886         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22887         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22888                 skip "Need MDS version at least 2.8.55"
22889         remote_mds_nodsh && skip "remote MDS with nodsh"
22890
22891         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22892                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22893         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22894                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22895         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22896
22897         #define OBD_FAIL_DT_TXN_STOP    0x2019
22898         for idx in $(seq $MDSCOUNT); do
22899                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22900         done
22901         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22902         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22903                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22904         true
22905 }
22906 run_test 407 "transaction fail should cause operation fail"
22907
22908 test_408() {
22909         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22910
22911         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22912         lctl set_param fail_loc=0x8000040a
22913         # let ll_prepare_partial_page() fail
22914         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22915
22916         rm -f $DIR/$tfile
22917
22918         # create at least 100 unused inodes so that
22919         # shrink_icache_memory(0) should not return 0
22920         touch $DIR/$tfile-{0..100}
22921         rm -f $DIR/$tfile-{0..100}
22922         sync
22923
22924         echo 2 > /proc/sys/vm/drop_caches
22925 }
22926 run_test 408 "drop_caches should not hang due to page leaks"
22927
22928 test_409()
22929 {
22930         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22931
22932         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22933         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22934         touch $DIR/$tdir/guard || error "(2) Fail to create"
22935
22936         local PREFIX=$(str_repeat 'A' 128)
22937         echo "Create 1K hard links start at $(date)"
22938         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22939                 error "(3) Fail to hard link"
22940
22941         echo "Links count should be right although linkEA overflow"
22942         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22943         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22944         [ $linkcount -eq 1001 ] ||
22945                 error "(5) Unexpected hard links count: $linkcount"
22946
22947         echo "List all links start at $(date)"
22948         ls -l $DIR/$tdir/foo > /dev/null ||
22949                 error "(6) Fail to list $DIR/$tdir/foo"
22950
22951         echo "Unlink hard links start at $(date)"
22952         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22953                 error "(7) Fail to unlink"
22954         echo "Unlink hard links finished at $(date)"
22955 }
22956 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22957
22958 test_410()
22959 {
22960         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22961                 skip "Need client version at least 2.9.59"
22962         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22963                 skip "Need MODULES build"
22964
22965         # Create a file, and stat it from the kernel
22966         local testfile=$DIR/$tfile
22967         touch $testfile
22968
22969         local run_id=$RANDOM
22970         local my_ino=$(stat --format "%i" $testfile)
22971
22972         # Try to insert the module. This will always fail as the
22973         # module is designed to not be inserted.
22974         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22975             &> /dev/null
22976
22977         # Anything but success is a test failure
22978         dmesg | grep -q \
22979             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22980             error "no inode match"
22981 }
22982 run_test 410 "Test inode number returned from kernel thread"
22983
22984 cleanup_test411_cgroup() {
22985         trap 0
22986         rmdir "$1"
22987 }
22988
22989 test_411() {
22990         local cg_basedir=/sys/fs/cgroup/memory
22991         # LU-9966
22992         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22993                 skip "no setup for cgroup"
22994
22995         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22996                 error "test file creation failed"
22997         cancel_lru_locks osc
22998
22999         # Create a very small memory cgroup to force a slab allocation error
23000         local cgdir=$cg_basedir/osc_slab_alloc
23001         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23002         trap "cleanup_test411_cgroup $cgdir" EXIT
23003         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23004         echo 1M > $cgdir/memory.limit_in_bytes
23005
23006         # Should not LBUG, just be killed by oom-killer
23007         # dd will return 0 even allocation failure in some environment.
23008         # So don't check return value
23009         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23010         cleanup_test411_cgroup $cgdir
23011
23012         return 0
23013 }
23014 run_test 411 "Slab allocation error with cgroup does not LBUG"
23015
23016 test_412() {
23017         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23018         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23019                 skip "Need server version at least 2.10.55"
23020         fi
23021
23022         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23023                 error "mkdir failed"
23024         $LFS getdirstripe $DIR/$tdir
23025         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23026         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23027                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23028         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23029         [ $stripe_count -eq 2 ] ||
23030                 error "expect 2 get $stripe_count"
23031 }
23032 run_test 412 "mkdir on specific MDTs"
23033
23034 test_qos_mkdir() {
23035         local mkdir_cmd=$1
23036         local stripe_count=$2
23037         local mdts=$(comma_list $(mdts_nodes))
23038
23039         local testdir
23040         local lmv_qos_prio_free
23041         local lmv_qos_threshold_rr
23042         local lmv_qos_maxage
23043         local lod_qos_prio_free
23044         local lod_qos_threshold_rr
23045         local lod_qos_maxage
23046         local count
23047         local i
23048
23049         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23050         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23051         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23052                 head -n1)
23053         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23054         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23055         stack_trap "$LCTL set_param \
23056                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23057         stack_trap "$LCTL set_param \
23058                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23059         stack_trap "$LCTL set_param \
23060                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23061
23062         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23063                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23064         lod_qos_prio_free=${lod_qos_prio_free%%%}
23065         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23066                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23067         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23068         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23069                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23070         stack_trap "do_nodes $mdts $LCTL set_param \
23071                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23072         stack_trap "do_nodes $mdts $LCTL set_param \
23073                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23074                 EXIT
23075         stack_trap "do_nodes $mdts $LCTL set_param \
23076                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23077
23078         echo
23079         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23080
23081         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23082         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23083
23084         testdir=$DIR/$tdir-s$stripe_count/rr
23085
23086         for i in $(seq $((100 * MDSCOUNT))); do
23087                 eval $mkdir_cmd $testdir/subdir$i ||
23088                         error "$mkdir_cmd subdir$i failed"
23089         done
23090
23091         for i in $(seq $MDSCOUNT); do
23092                 count=$($LFS getdirstripe -i $testdir/* |
23093                                 grep ^$((i - 1))$ | wc -l)
23094                 echo "$count directories created on MDT$((i - 1))"
23095                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23096
23097                 if [ $stripe_count -gt 1 ]; then
23098                         count=$($LFS getdirstripe $testdir/* |
23099                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23100                         echo "$count stripes created on MDT$((i - 1))"
23101                         # deviation should < 5% of average
23102                         [ $count -lt $((95 * stripe_count)) ] ||
23103                         [ $count -gt $((105 * stripe_count)) ] &&
23104                                 error "stripes are not evenly distributed"
23105                 fi
23106         done
23107
23108         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23109         do_nodes $mdts $LCTL set_param \
23110                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23111
23112         echo
23113         echo "Check for uneven MDTs: "
23114
23115         local ffree
23116         local bavail
23117         local max
23118         local min
23119         local max_index
23120         local min_index
23121         local tmp
23122
23123         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23124         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23125         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23126
23127         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23128         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23129         max_index=0
23130         min_index=0
23131         for ((i = 1; i < ${#ffree[@]}; i++)); do
23132                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23133                 if [ $tmp -gt $max ]; then
23134                         max=$tmp
23135                         max_index=$i
23136                 fi
23137                 if [ $tmp -lt $min ]; then
23138                         min=$tmp
23139                         min_index=$i
23140                 fi
23141         done
23142
23143         [ ${ffree[min_index]} -eq 0 ] &&
23144                 skip "no free files in MDT$min_index"
23145         [ ${ffree[min_index]} -gt 100000000 ] &&
23146                 skip "too much free files in MDT$min_index"
23147
23148         # Check if we need to generate uneven MDTs
23149         local threshold=50
23150         local diff=$(((max - min) * 100 / min))
23151         local value="$(generate_string 1024)"
23152
23153         while [ $diff -lt $threshold ]; do
23154                 # generate uneven MDTs, create till $threshold% diff
23155                 echo -n "weight diff=$diff% must be > $threshold% ..."
23156                 count=$((${ffree[min_index]} / 10))
23157                 # 50 sec per 10000 files in vm
23158                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23159                         skip "$count files to create"
23160                 echo "Fill MDT$min_index with $count files"
23161                 [ -d $DIR/$tdir-MDT$min_index ] ||
23162                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23163                         error "mkdir $tdir-MDT$min_index failed"
23164                 for i in $(seq $count); do
23165                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23166                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23167                                 error "create f$j_$i failed"
23168                         setfattr -n user.413b -v $value \
23169                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23170                                 error "setfattr f$j_$i failed"
23171                 done
23172
23173                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23174                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23175                 max=$(((${ffree[max_index]} >> 8) * \
23176                         (${bavail[max_index]} * bsize >> 16)))
23177                 min=$(((${ffree[min_index]} >> 8) * \
23178                         (${bavail[min_index]} * bsize >> 16)))
23179                 diff=$(((max - min) * 100 / min))
23180         done
23181
23182         echo "MDT filesfree available: ${ffree[@]}"
23183         echo "MDT blocks available: ${bavail[@]}"
23184         echo "weight diff=$diff%"
23185
23186         echo
23187         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23188
23189         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23190         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23191         # decrease statfs age, so that it can be updated in time
23192         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23193         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23194
23195         sleep 1
23196
23197         testdir=$DIR/$tdir-s$stripe_count/qos
23198
23199         for i in $(seq $((100 * MDSCOUNT))); do
23200                 eval $mkdir_cmd $testdir/subdir$i ||
23201                         error "$mkdir_cmd subdir$i failed"
23202         done
23203
23204         for i in $(seq $MDSCOUNT); do
23205                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23206                         wc -l)
23207                 echo "$count directories created on MDT$((i - 1))"
23208
23209                 if [ $stripe_count -gt 1 ]; then
23210                         count=$($LFS getdirstripe $testdir/* |
23211                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23212                         echo "$count stripes created on MDT$((i - 1))"
23213                 fi
23214         done
23215
23216         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23217         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23218
23219         # D-value should > 10% of averge
23220         [ $((max - min)) -lt 10 ] &&
23221                 error "subdirs shouldn't be evenly distributed"
23222
23223         # ditto
23224         if [ $stripe_count -gt 1 ]; then
23225                 max=$($LFS getdirstripe $testdir/* |
23226                         grep -P "^\s+$max_index\t" | wc -l)
23227                 min=$($LFS getdirstripe $testdir/* |
23228                         grep -P "^\s+$min_index\t" | wc -l)
23229                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23230                         error "stripes shouldn't be evenly distributed"|| true
23231         fi
23232 }
23233
23234 test_413a() {
23235         [ $MDSCOUNT -lt 2 ] &&
23236                 skip "We need at least 2 MDTs for this test"
23237
23238         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23239                 skip "Need server version at least 2.12.52"
23240
23241         local stripe_count
23242
23243         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23244                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23245                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23246                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23247                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23248         done
23249 }
23250 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23251
23252 test_413b() {
23253         [ $MDSCOUNT -lt 2 ] &&
23254                 skip "We need at least 2 MDTs for this test"
23255
23256         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23257                 skip "Need server version at least 2.12.52"
23258
23259         local stripe_count
23260
23261         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23262                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23263                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23264                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23265                 $LFS setdirstripe -D -c $stripe_count \
23266                         $DIR/$tdir-s$stripe_count/rr ||
23267                         error "setdirstripe failed"
23268                 $LFS setdirstripe -D -c $stripe_count \
23269                         $DIR/$tdir-s$stripe_count/qos ||
23270                         error "setdirstripe failed"
23271                 test_qos_mkdir "mkdir" $stripe_count
23272         done
23273 }
23274 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23275
23276 test_414() {
23277 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23278         $LCTL set_param fail_loc=0x80000521
23279         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23280         rm -f $DIR/$tfile
23281 }
23282 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23283
23284 test_415() {
23285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23286         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23287                 skip "Need server version at least 2.11.52"
23288
23289         # LU-11102
23290         local total
23291         local setattr_pid
23292         local start_time
23293         local end_time
23294         local duration
23295
23296         total=500
23297         # this test may be slow on ZFS
23298         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23299
23300         # though this test is designed for striped directory, let's test normal
23301         # directory too since lock is always saved as CoS lock.
23302         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23303         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23304
23305         (
23306                 while true; do
23307                         touch $DIR/$tdir
23308                 done
23309         ) &
23310         setattr_pid=$!
23311
23312         start_time=$(date +%s)
23313         for i in $(seq $total); do
23314                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23315                         > /dev/null
23316         done
23317         end_time=$(date +%s)
23318         duration=$((end_time - start_time))
23319
23320         kill -9 $setattr_pid
23321
23322         echo "rename $total files took $duration sec"
23323         [ $duration -lt 100 ] || error "rename took $duration sec"
23324 }
23325 run_test 415 "lock revoke is not missing"
23326
23327 test_416() {
23328         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23329                 skip "Need server version at least 2.11.55"
23330
23331         # define OBD_FAIL_OSD_TXN_START    0x19a
23332         do_facet mds1 lctl set_param fail_loc=0x19a
23333
23334         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23335
23336         true
23337 }
23338 run_test 416 "transaction start failure won't cause system hung"
23339
23340 cleanup_417() {
23341         trap 0
23342         do_nodes $(comma_list $(mdts_nodes)) \
23343                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23344         do_nodes $(comma_list $(mdts_nodes)) \
23345                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23346         do_nodes $(comma_list $(mdts_nodes)) \
23347                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23348 }
23349
23350 test_417() {
23351         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23352         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23353                 skip "Need MDS version at least 2.11.56"
23354
23355         trap cleanup_417 RETURN EXIT
23356
23357         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23358         do_nodes $(comma_list $(mdts_nodes)) \
23359                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23360         $LFS migrate -m 0 $DIR/$tdir.1 &&
23361                 error "migrate dir $tdir.1 should fail"
23362
23363         do_nodes $(comma_list $(mdts_nodes)) \
23364                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23365         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23366                 error "create remote dir $tdir.2 should fail"
23367
23368         do_nodes $(comma_list $(mdts_nodes)) \
23369                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23370         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23371                 error "create striped dir $tdir.3 should fail"
23372         true
23373 }
23374 run_test 417 "disable remote dir, striped dir and dir migration"
23375
23376 # Checks that the outputs of df [-i] and lfs df [-i] match
23377 #
23378 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23379 check_lfs_df() {
23380         local dir=$2
23381         local inodes
23382         local df_out
23383         local lfs_df_out
23384         local count
23385         local passed=false
23386
23387         # blocks or inodes
23388         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23389
23390         for count in {1..100}; do
23391                 cancel_lru_locks
23392                 sync; sleep 0.2
23393
23394                 # read the lines of interest
23395                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23396                         error "df $inodes $dir | tail -n +2 failed"
23397                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23398                         error "lfs df $inodes $dir | grep summary: failed"
23399
23400                 # skip first substrings of each output as they are different
23401                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23402                 # compare the two outputs
23403                 passed=true
23404                 for i in {1..5}; do
23405                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23406                 done
23407                 $passed && break
23408         done
23409
23410         if ! $passed; then
23411                 df -P $inodes $dir
23412                 echo
23413                 lfs df $inodes $dir
23414                 error "df and lfs df $1 output mismatch: "      \
23415                       "df ${inodes}: ${df_out[*]}, "            \
23416                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23417         fi
23418 }
23419
23420 test_418() {
23421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23422
23423         local dir=$DIR/$tdir
23424         local numfiles=$((RANDOM % 4096 + 2))
23425         local numblocks=$((RANDOM % 256 + 1))
23426
23427         wait_delete_completed
23428         test_mkdir $dir
23429
23430         # check block output
23431         check_lfs_df blocks $dir
23432         # check inode output
23433         check_lfs_df inodes $dir
23434
23435         # create a single file and retest
23436         echo "Creating a single file and testing"
23437         createmany -o $dir/$tfile- 1 &>/dev/null ||
23438                 error "creating 1 file in $dir failed"
23439         check_lfs_df blocks $dir
23440         check_lfs_df inodes $dir
23441
23442         # create a random number of files
23443         echo "Creating $((numfiles - 1)) files and testing"
23444         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23445                 error "creating $((numfiles - 1)) files in $dir failed"
23446
23447         # write a random number of blocks to the first test file
23448         echo "Writing $numblocks 4K blocks and testing"
23449         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23450                 count=$numblocks &>/dev/null ||
23451                 error "dd to $dir/${tfile}-0 failed"
23452
23453         # retest
23454         check_lfs_df blocks $dir
23455         check_lfs_df inodes $dir
23456
23457         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23458                 error "unlinking $numfiles files in $dir failed"
23459 }
23460 run_test 418 "df and lfs df outputs match"
23461
23462 test_419()
23463 {
23464         local dir=$DIR/$tdir
23465
23466         mkdir -p $dir
23467         touch $dir/file
23468
23469         cancel_lru_locks mdc
23470
23471         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23472         $LCTL set_param fail_loc=0x1410
23473         cat $dir/file
23474         $LCTL set_param fail_loc=0
23475         rm -rf $dir
23476 }
23477 run_test 419 "Verify open file by name doesn't crash kernel"
23478
23479 test_420()
23480 {
23481         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23482                 skip "Need MDS version at least 2.12.53"
23483
23484         local SAVE_UMASK=$(umask)
23485         local dir=$DIR/$tdir
23486         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23487
23488         mkdir -p $dir
23489         umask 0000
23490         mkdir -m03777 $dir/testdir
23491         ls -dn $dir/testdir
23492         # Need to remove trailing '.' when SELinux is enabled
23493         local dirperms=$(ls -dn $dir/testdir |
23494                          awk '{ sub(/\.$/, "", $1); print $1}')
23495         [ $dirperms == "drwxrwsrwt" ] ||
23496                 error "incorrect perms on $dir/testdir"
23497
23498         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23499                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23500         ls -n $dir/testdir/testfile
23501         local fileperms=$(ls -n $dir/testdir/testfile |
23502                           awk '{ sub(/\.$/, "", $1); print $1}')
23503         [ $fileperms == "-rwxr-xr-x" ] ||
23504                 error "incorrect perms on $dir/testdir/testfile"
23505
23506         umask $SAVE_UMASK
23507 }
23508 run_test 420 "clear SGID bit on non-directories for non-members"
23509
23510 test_421a() {
23511         local cnt
23512         local fid1
23513         local fid2
23514
23515         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23516                 skip "Need MDS version at least 2.12.54"
23517
23518         test_mkdir $DIR/$tdir
23519         createmany -o $DIR/$tdir/f 3
23520         cnt=$(ls -1 $DIR/$tdir | wc -l)
23521         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23522
23523         fid1=$(lfs path2fid $DIR/$tdir/f1)
23524         fid2=$(lfs path2fid $DIR/$tdir/f2)
23525         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23526
23527         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23528         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23529
23530         cnt=$(ls -1 $DIR/$tdir | wc -l)
23531         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23532
23533         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23534         createmany -o $DIR/$tdir/f 3
23535         cnt=$(ls -1 $DIR/$tdir | wc -l)
23536         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23537
23538         fid1=$(lfs path2fid $DIR/$tdir/f1)
23539         fid2=$(lfs path2fid $DIR/$tdir/f2)
23540         echo "remove using fsname $FSNAME"
23541         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23542
23543         cnt=$(ls -1 $DIR/$tdir | wc -l)
23544         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23545 }
23546 run_test 421a "simple rm by fid"
23547
23548 test_421b() {
23549         local cnt
23550         local FID1
23551         local FID2
23552
23553         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23554                 skip "Need MDS version at least 2.12.54"
23555
23556         test_mkdir $DIR/$tdir
23557         createmany -o $DIR/$tdir/f 3
23558         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23559         MULTIPID=$!
23560
23561         FID1=$(lfs path2fid $DIR/$tdir/f1)
23562         FID2=$(lfs path2fid $DIR/$tdir/f2)
23563         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23564
23565         kill -USR1 $MULTIPID
23566         wait
23567
23568         cnt=$(ls $DIR/$tdir | wc -l)
23569         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23570 }
23571 run_test 421b "rm by fid on open file"
23572
23573 test_421c() {
23574         local cnt
23575         local FIDS
23576
23577         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23578                 skip "Need MDS version at least 2.12.54"
23579
23580         test_mkdir $DIR/$tdir
23581         createmany -o $DIR/$tdir/f 3
23582         touch $DIR/$tdir/$tfile
23583         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23584         cnt=$(ls -1 $DIR/$tdir | wc -l)
23585         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23586
23587         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23588         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23589
23590         cnt=$(ls $DIR/$tdir | wc -l)
23591         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23592 }
23593 run_test 421c "rm by fid against hardlinked files"
23594
23595 test_421d() {
23596         local cnt
23597         local FIDS
23598
23599         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23600                 skip "Need MDS version at least 2.12.54"
23601
23602         test_mkdir $DIR/$tdir
23603         createmany -o $DIR/$tdir/f 4097
23604         cnt=$(ls -1 $DIR/$tdir | wc -l)
23605         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23606
23607         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23608         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23609
23610         cnt=$(ls $DIR/$tdir | wc -l)
23611         rm -rf $DIR/$tdir
23612         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23613 }
23614 run_test 421d "rmfid en masse"
23615
23616 test_421e() {
23617         local cnt
23618         local FID
23619
23620         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23621         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23622                 skip "Need MDS version at least 2.12.54"
23623
23624         mkdir -p $DIR/$tdir
23625         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23626         createmany -o $DIR/$tdir/striped_dir/f 512
23627         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23628         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23629
23630         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23631                 sed "s/[/][^:]*://g")
23632         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23633
23634         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23635         rm -rf $DIR/$tdir
23636         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23637 }
23638 run_test 421e "rmfid in DNE"
23639
23640 test_421f() {
23641         local cnt
23642         local FID
23643
23644         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23645                 skip "Need MDS version at least 2.12.54"
23646
23647         test_mkdir $DIR/$tdir
23648         touch $DIR/$tdir/f
23649         cnt=$(ls -1 $DIR/$tdir | wc -l)
23650         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23651
23652         FID=$(lfs path2fid $DIR/$tdir/f)
23653         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23654         # rmfid should fail
23655         cnt=$(ls -1 $DIR/$tdir | wc -l)
23656         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23657
23658         chmod a+rw $DIR/$tdir
23659         ls -la $DIR/$tdir
23660         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23661         # rmfid should fail
23662         cnt=$(ls -1 $DIR/$tdir | wc -l)
23663         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23664
23665         rm -f $DIR/$tdir/f
23666         $RUNAS touch $DIR/$tdir/f
23667         FID=$(lfs path2fid $DIR/$tdir/f)
23668         echo "rmfid as root"
23669         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23670         cnt=$(ls -1 $DIR/$tdir | wc -l)
23671         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23672
23673         rm -f $DIR/$tdir/f
23674         $RUNAS touch $DIR/$tdir/f
23675         cnt=$(ls -1 $DIR/$tdir | wc -l)
23676         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23677         FID=$(lfs path2fid $DIR/$tdir/f)
23678         # rmfid w/o user_fid2path mount option should fail
23679         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23680         cnt=$(ls -1 $DIR/$tdir | wc -l)
23681         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23682
23683         umount_client $MOUNT || error "failed to umount client"
23684         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23685                 error "failed to mount client'"
23686
23687         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23688         # rmfid should succeed
23689         cnt=$(ls -1 $DIR/$tdir | wc -l)
23690         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23691
23692         # rmfid shouldn't allow to remove files due to dir's permission
23693         chmod a+rwx $DIR/$tdir
23694         touch $DIR/$tdir/f
23695         ls -la $DIR/$tdir
23696         FID=$(lfs path2fid $DIR/$tdir/f)
23697         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23698
23699         umount_client $MOUNT || error "failed to umount client"
23700         mount_client $MOUNT "$MOUNT_OPTS" ||
23701                 error "failed to mount client'"
23702
23703 }
23704 run_test 421f "rmfid checks permissions"
23705
23706 test_421g() {
23707         local cnt
23708         local FIDS
23709
23710         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23711         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23712                 skip "Need MDS version at least 2.12.54"
23713
23714         mkdir -p $DIR/$tdir
23715         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23716         createmany -o $DIR/$tdir/striped_dir/f 512
23717         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23718         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23719
23720         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23721                 sed "s/[/][^:]*://g")
23722
23723         rm -f $DIR/$tdir/striped_dir/f1*
23724         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23725         removed=$((512 - cnt))
23726
23727         # few files have been just removed, so we expect
23728         # rmfid to fail on their fids
23729         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23730         [ $removed != $errors ] && error "$errors != $removed"
23731
23732         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23733         rm -rf $DIR/$tdir
23734         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23735 }
23736 run_test 421g "rmfid to return errors properly"
23737
23738 test_422() {
23739         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23740         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23741         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23742         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23743         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23744
23745         local amc=$(at_max_get client)
23746         local amo=$(at_max_get mds1)
23747         local timeout=`lctl get_param -n timeout`
23748
23749         at_max_set 0 client
23750         at_max_set 0 mds1
23751
23752 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23753         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23754                         fail_val=$(((2*timeout + 10)*1000))
23755         touch $DIR/$tdir/d3/file &
23756         sleep 2
23757 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23758         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23759                         fail_val=$((2*timeout + 5))
23760         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23761         local pid=$!
23762         sleep 1
23763         kill -9 $pid
23764         sleep $((2 * timeout))
23765         echo kill $pid
23766         kill -9 $pid
23767         lctl mark touch
23768         touch $DIR/$tdir/d2/file3
23769         touch $DIR/$tdir/d2/file4
23770         touch $DIR/$tdir/d2/file5
23771
23772         wait
23773         at_max_set $amc client
23774         at_max_set $amo mds1
23775
23776         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23777         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23778                 error "Watchdog is always throttled"
23779 }
23780 run_test 422 "kill a process with RPC in progress"
23781
23782 stat_test() {
23783     df -h $MOUNT &
23784     df -h $MOUNT &
23785     df -h $MOUNT &
23786     df -h $MOUNT &
23787     df -h $MOUNT &
23788     df -h $MOUNT &
23789 }
23790
23791 test_423() {
23792     local _stats
23793     # ensure statfs cache is expired
23794     sleep 2;
23795
23796     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23797     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23798
23799     return 0
23800 }
23801 run_test 423 "statfs should return a right data"
23802
23803 test_424() {
23804 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23805         $LCTL set_param fail_loc=0x80000522
23806         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23807         rm -f $DIR/$tfile
23808 }
23809 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23810
23811 test_425() {
23812         test_mkdir -c -1 $DIR/$tdir
23813         $LFS setstripe -c -1 $DIR/$tdir
23814
23815         lru_resize_disable "" 100
23816         stack_trap "lru_resize_enable" EXIT
23817
23818         sleep 5
23819
23820         for i in $(seq $((MDSCOUNT * 125))); do
23821                 local t=$DIR/$tdir/$tfile_$i
23822
23823                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23824                         error_noexit "Create file $t"
23825         done
23826         stack_trap "rm -rf $DIR/$tdir" EXIT
23827
23828         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23829                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23830                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23831
23832                 [ $lock_count -le $lru_size ] ||
23833                         error "osc lock count $lock_count > lru size $lru_size"
23834         done
23835
23836         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23837                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23838                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23839
23840                 [ $lock_count -le $lru_size ] ||
23841                         error "mdc lock count $lock_count > lru size $lru_size"
23842         done
23843 }
23844 run_test 425 "lock count should not exceed lru size"
23845
23846 test_426() {
23847         splice-test -r $DIR/$tfile
23848         splice-test -rd $DIR/$tfile
23849         splice-test $DIR/$tfile
23850         splice-test -d $DIR/$tfile
23851 }
23852 run_test 426 "splice test on Lustre"
23853
23854 lseek_test_430() {
23855         local offset
23856         local file=$1
23857
23858         # data at [200K, 400K)
23859         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
23860                 error "256K->512K dd fails"
23861         # data at [2M, 3M)
23862         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
23863                 error "2M->3M dd fails"
23864         # data at [4M, 5M)
23865         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
23866                 error "4M->5M dd fails"
23867         echo "Data at 256K...512K, 2M...3M and 4M...5M"
23868         # start at first component hole #1
23869         printf "Seeking hole from 1000 ... "
23870         offset=$(lseek_test -l 1000 $file)
23871         echo $offset
23872         [[ $offset == 1000 ]] || error "offset $offset != 1000"
23873         printf "Seeking data from 1000 ... "
23874         offset=$(lseek_test -d 1000 $file)
23875         echo $offset
23876         [[ $offset == 262144 ]] || error "offset $offset != 262144"
23877
23878         # start at first component data block
23879         printf "Seeking hole from 300000 ... "
23880         offset=$(lseek_test -l 300000 $file)
23881         echo $offset
23882         [[ $offset == 524288 ]] || error "offset $offset != 524288"
23883         printf "Seeking data from 300000 ... "
23884         offset=$(lseek_test -d 300000 $file)
23885         echo $offset
23886         [[ $offset == 300000 ]] || error "offset $offset != 300000"
23887
23888         # start at the first component but beyond end of object size
23889         printf "Seeking hole from 1000000 ... "
23890         offset=$(lseek_test -l 1000000 $file)
23891         echo $offset
23892         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23893         printf "Seeking data from 1000000 ... "
23894         offset=$(lseek_test -d 1000000 $file)
23895         echo $offset
23896         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23897
23898         # start at second component stripe 2 (empty file)
23899         printf "Seeking hole from 1500000 ... "
23900         offset=$(lseek_test -l 1500000 $file)
23901         echo $offset
23902         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
23903         printf "Seeking data from 1500000 ... "
23904         offset=$(lseek_test -d 1500000 $file)
23905         echo $offset
23906         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23907
23908         # start at second component stripe 1 (all data)
23909         printf "Seeking hole from 3000000 ... "
23910         offset=$(lseek_test -l 3000000 $file)
23911         echo $offset
23912         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
23913         printf "Seeking data from 3000000 ... "
23914         offset=$(lseek_test -d 3000000 $file)
23915         echo $offset
23916         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
23917
23918         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
23919                 error "2nd dd fails"
23920         echo "Add data block at 640K...1280K"
23921
23922         # start at before new data block, in hole
23923         printf "Seeking hole from 600000 ... "
23924         offset=$(lseek_test -l 600000 $file)
23925         echo $offset
23926         [[ $offset == 600000 ]] || error "offset $offset != 600000"
23927         printf "Seeking data from 600000 ... "
23928         offset=$(lseek_test -d 600000 $file)
23929         echo $offset
23930         [[ $offset == 655360 ]] || error "offset $offset != 655360"
23931
23932         # start at the first component new data block
23933         printf "Seeking hole from 1000000 ... "
23934         offset=$(lseek_test -l 1000000 $file)
23935         echo $offset
23936         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23937         printf "Seeking data from 1000000 ... "
23938         offset=$(lseek_test -d 1000000 $file)
23939         echo $offset
23940         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23941
23942         # start at second component stripe 2, new data
23943         printf "Seeking hole from 1200000 ... "
23944         offset=$(lseek_test -l 1200000 $file)
23945         echo $offset
23946         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23947         printf "Seeking data from 1200000 ... "
23948         offset=$(lseek_test -d 1200000 $file)
23949         echo $offset
23950         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
23951
23952         # start beyond file end
23953         printf "Using offset > filesize ... "
23954         lseek_test -l 4000000 $file && error "lseek should fail"
23955         printf "Using offset > filesize ... "
23956         lseek_test -d 4000000 $file && error "lseek should fail"
23957
23958         printf "Done\n\n"
23959 }
23960
23961 test_430a() {
23962         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
23963                 skip "MDT does not support SEEK_HOLE"
23964
23965         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23966                 skip "OST does not support SEEK_HOLE"
23967
23968         local file=$DIR/$tdir/$tfile
23969
23970         mkdir -p $DIR/$tdir
23971
23972         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
23973         # OST stripe #1 will have continuous data at [1M, 3M)
23974         # OST stripe #2 is empty
23975         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
23976         lseek_test_430 $file
23977         rm $file
23978         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
23979         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
23980         lseek_test_430 $file
23981         rm $file
23982         $LFS setstripe -c2 -S 512K $file
23983         echo "Two stripes, stripe size 512K"
23984         lseek_test_430 $file
23985         rm $file
23986         # FLR with stale mirror
23987         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
23988                        -N -c2 -S 1M $file
23989         echo "Mirrored file:"
23990         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
23991         echo "Plain 2 stripes 1M"
23992         lseek_test_430 $file
23993         rm $file
23994 }
23995 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
23996
23997 test_430b() {
23998         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23999                 skip "OST does not support SEEK_HOLE"
24000
24001         local offset
24002         local file=$DIR/$tdir/$tfile
24003
24004         mkdir -p $DIR/$tdir
24005         # Empty layout lseek should fail
24006         $MCREATE $file
24007         # seek from 0
24008         printf "Seeking hole from 0 ... "
24009         lseek_test -l 0 $file && error "lseek should fail"
24010         printf "Seeking data from 0 ... "
24011         lseek_test -d 0 $file && error "lseek should fail"
24012         rm $file
24013
24014         # 1M-hole file
24015         $LFS setstripe -E 1M -c2 -E eof $file
24016         $TRUNCATE $file 1048576
24017         printf "Seeking hole from 1000000 ... "
24018         offset=$(lseek_test -l 1000000 $file)
24019         echo $offset
24020         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24021         printf "Seeking data from 1000000 ... "
24022         lseek_test -d 1000000 $file && error "lseek should fail"
24023         rm $file
24024
24025         # full component followed by non-inited one
24026         $LFS setstripe -E 1M -c2 -E eof $file
24027         dd if=/dev/urandom of=$file bs=1M count=1
24028         printf "Seeking hole from 1000000 ... "
24029         offset=$(lseek_test -l 1000000 $file)
24030         echo $offset
24031         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24032         printf "Seeking hole from 1048576 ... "
24033         lseek_test -l 1048576 $file && error "lseek should fail"
24034         # init second component and truncate back
24035         echo "123" >> $file
24036         $TRUNCATE $file 1048576
24037         printf "Seeking hole from 1000000 ... "
24038         offset=$(lseek_test -l 1000000 $file)
24039         echo $offset
24040         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24041         printf "Seeking hole from 1048576 ... "
24042         lseek_test -l 1048576 $file && error "lseek should fail"
24043         # boundary checks for big values
24044         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
24045         offset=$(lseek_test -d 0 $file.10g)
24046         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
24047         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
24048         offset=$(lseek_test -d 0 $file.100g)
24049         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
24050         return 0
24051 }
24052 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
24053
24054 test_430c() {
24055         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24056                 skip "OST does not support SEEK_HOLE"
24057
24058         local file=$DIR/$tdir/$tfile
24059         local start
24060
24061         mkdir -p $DIR/$tdir
24062         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
24063
24064         # cp version 8.33+ prefers lseek over fiemap
24065         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
24066                 start=$SECONDS
24067                 time cp $file /dev/null
24068                 (( SECONDS - start < 5 )) ||
24069                         error "cp: too long runtime $((SECONDS - start))"
24070
24071         fi
24072         # tar version 1.29+ supports SEEK_HOLE/DATA
24073         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
24074                 start=$SECONDS
24075                 time tar cS $file - | cat > /dev/null
24076                 (( SECONDS - start < 5 )) ||
24077                         error "tar: too long runtime $((SECONDS - start))"
24078         fi
24079 }
24080 run_test 430c "lseek: external tools check"
24081
24082 test_431() { # LU-14187
24083         local file=$DIR/$tdir/$tfile
24084
24085         mkdir -p $DIR/$tdir
24086         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
24087         dd if=/dev/urandom of=$file bs=4k count=1
24088         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
24089         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
24090         #define OBD_FAIL_OST_RESTART_IO 0x251
24091         do_facet ost1 "$LCTL set_param fail_loc=0x251"
24092         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
24093         cp $file $file.0
24094         cancel_lru_locks
24095         sync_all_data
24096         echo 3 > /proc/sys/vm/drop_caches
24097         diff  $file $file.0 || error "data diff"
24098 }
24099 run_test 431 "Restart transaction for IO"
24100
24101 prep_801() {
24102         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24103         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24104                 skip "Need server version at least 2.9.55"
24105
24106         start_full_debug_logging
24107 }
24108
24109 post_801() {
24110         stop_full_debug_logging
24111 }
24112
24113 barrier_stat() {
24114         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24115                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24116                            awk '/The barrier for/ { print $7 }')
24117                 echo $st
24118         else
24119                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24120                 echo \'$st\'
24121         fi
24122 }
24123
24124 barrier_expired() {
24125         local expired
24126
24127         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24128                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24129                           awk '/will be expired/ { print $7 }')
24130         else
24131                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24132         fi
24133
24134         echo $expired
24135 }
24136
24137 test_801a() {
24138         prep_801
24139
24140         echo "Start barrier_freeze at: $(date)"
24141         #define OBD_FAIL_BARRIER_DELAY          0x2202
24142         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24143         # Do not reduce barrier time - See LU-11873
24144         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24145
24146         sleep 2
24147         local b_status=$(barrier_stat)
24148         echo "Got barrier status at: $(date)"
24149         [ "$b_status" = "'freezing_p1'" ] ||
24150                 error "(1) unexpected barrier status $b_status"
24151
24152         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24153         wait
24154         b_status=$(barrier_stat)
24155         [ "$b_status" = "'frozen'" ] ||
24156                 error "(2) unexpected barrier status $b_status"
24157
24158         local expired=$(barrier_expired)
24159         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24160         sleep $((expired + 3))
24161
24162         b_status=$(barrier_stat)
24163         [ "$b_status" = "'expired'" ] ||
24164                 error "(3) unexpected barrier status $b_status"
24165
24166         # Do not reduce barrier time - See LU-11873
24167         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24168                 error "(4) fail to freeze barrier"
24169
24170         b_status=$(barrier_stat)
24171         [ "$b_status" = "'frozen'" ] ||
24172                 error "(5) unexpected barrier status $b_status"
24173
24174         echo "Start barrier_thaw at: $(date)"
24175         #define OBD_FAIL_BARRIER_DELAY          0x2202
24176         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24177         do_facet mgs $LCTL barrier_thaw $FSNAME &
24178
24179         sleep 2
24180         b_status=$(barrier_stat)
24181         echo "Got barrier status at: $(date)"
24182         [ "$b_status" = "'thawing'" ] ||
24183                 error "(6) unexpected barrier status $b_status"
24184
24185         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24186         wait
24187         b_status=$(barrier_stat)
24188         [ "$b_status" = "'thawed'" ] ||
24189                 error "(7) unexpected barrier status $b_status"
24190
24191         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24192         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24193         do_facet mgs $LCTL barrier_freeze $FSNAME
24194
24195         b_status=$(barrier_stat)
24196         [ "$b_status" = "'failed'" ] ||
24197                 error "(8) unexpected barrier status $b_status"
24198
24199         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24200         do_facet mgs $LCTL barrier_thaw $FSNAME
24201
24202         post_801
24203 }
24204 run_test 801a "write barrier user interfaces and stat machine"
24205
24206 test_801b() {
24207         prep_801
24208
24209         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24210         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24211         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24212         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24213         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24214
24215         cancel_lru_locks mdc
24216
24217         # 180 seconds should be long enough
24218         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24219
24220         local b_status=$(barrier_stat)
24221         [ "$b_status" = "'frozen'" ] ||
24222                 error "(6) unexpected barrier status $b_status"
24223
24224         mkdir $DIR/$tdir/d0/d10 &
24225         mkdir_pid=$!
24226
24227         touch $DIR/$tdir/d1/f13 &
24228         touch_pid=$!
24229
24230         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24231         ln_pid=$!
24232
24233         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24234         mv_pid=$!
24235
24236         rm -f $DIR/$tdir/d4/f12 &
24237         rm_pid=$!
24238
24239         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24240
24241         # To guarantee taht the 'stat' is not blocked
24242         b_status=$(barrier_stat)
24243         [ "$b_status" = "'frozen'" ] ||
24244                 error "(8) unexpected barrier status $b_status"
24245
24246         # let above commands to run at background
24247         sleep 5
24248
24249         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24250         ps -p $touch_pid || error "(10) touch should be blocked"
24251         ps -p $ln_pid || error "(11) link should be blocked"
24252         ps -p $mv_pid || error "(12) rename should be blocked"
24253         ps -p $rm_pid || error "(13) unlink should be blocked"
24254
24255         b_status=$(barrier_stat)
24256         [ "$b_status" = "'frozen'" ] ||
24257                 error "(14) unexpected barrier status $b_status"
24258
24259         do_facet mgs $LCTL barrier_thaw $FSNAME
24260         b_status=$(barrier_stat)
24261         [ "$b_status" = "'thawed'" ] ||
24262                 error "(15) unexpected barrier status $b_status"
24263
24264         wait $mkdir_pid || error "(16) mkdir should succeed"
24265         wait $touch_pid || error "(17) touch should succeed"
24266         wait $ln_pid || error "(18) link should succeed"
24267         wait $mv_pid || error "(19) rename should succeed"
24268         wait $rm_pid || error "(20) unlink should succeed"
24269
24270         post_801
24271 }
24272 run_test 801b "modification will be blocked by write barrier"
24273
24274 test_801c() {
24275         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24276
24277         prep_801
24278
24279         stop mds2 || error "(1) Fail to stop mds2"
24280
24281         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24282
24283         local b_status=$(barrier_stat)
24284         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24285                 do_facet mgs $LCTL barrier_thaw $FSNAME
24286                 error "(2) unexpected barrier status $b_status"
24287         }
24288
24289         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24290                 error "(3) Fail to rescan barrier bitmap"
24291
24292         # Do not reduce barrier time - See LU-11873
24293         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24294
24295         b_status=$(barrier_stat)
24296         [ "$b_status" = "'frozen'" ] ||
24297                 error "(4) unexpected barrier status $b_status"
24298
24299         do_facet mgs $LCTL barrier_thaw $FSNAME
24300         b_status=$(barrier_stat)
24301         [ "$b_status" = "'thawed'" ] ||
24302                 error "(5) unexpected barrier status $b_status"
24303
24304         local devname=$(mdsdevname 2)
24305
24306         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24307
24308         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24309                 error "(7) Fail to rescan barrier bitmap"
24310
24311         post_801
24312 }
24313 run_test 801c "rescan barrier bitmap"
24314
24315 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24316 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24317 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24318 saved_MOUNT_OPTS=$MOUNT_OPTS
24319
24320 cleanup_802a() {
24321         trap 0
24322
24323         stopall
24324         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24325         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24326         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24327         MOUNT_OPTS=$saved_MOUNT_OPTS
24328         setupall
24329 }
24330
24331 test_802a() {
24332         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24333         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24334         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24335                 skip "Need server version at least 2.9.55"
24336
24337         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24338
24339         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24340
24341         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24342                 error "(2) Fail to copy"
24343
24344         trap cleanup_802a EXIT
24345
24346         # sync by force before remount as readonly
24347         sync; sync_all_data; sleep 3; sync_all_data
24348
24349         stopall
24350
24351         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24352         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24353         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24354
24355         echo "Mount the server as read only"
24356         setupall server_only || error "(3) Fail to start servers"
24357
24358         echo "Mount client without ro should fail"
24359         mount_client $MOUNT &&
24360                 error "(4) Mount client without 'ro' should fail"
24361
24362         echo "Mount client with ro should succeed"
24363         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24364         mount_client $MOUNT ||
24365                 error "(5) Mount client with 'ro' should succeed"
24366
24367         echo "Modify should be refused"
24368         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24369
24370         echo "Read should be allowed"
24371         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24372                 error "(7) Read should succeed under ro mode"
24373
24374         cleanup_802a
24375 }
24376 run_test 802a "simulate readonly device"
24377
24378 test_802b() {
24379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24380         remote_mds_nodsh && skip "remote MDS with nodsh"
24381
24382         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24383                 skip "readonly option not available"
24384
24385         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24386
24387         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24388                 error "(2) Fail to copy"
24389
24390         # write back all cached data before setting MDT to readonly
24391         cancel_lru_locks
24392         sync_all_data
24393
24394         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24395         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24396
24397         echo "Modify should be refused"
24398         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24399
24400         echo "Read should be allowed"
24401         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24402                 error "(7) Read should succeed under ro mode"
24403
24404         # disable readonly
24405         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24406 }
24407 run_test 802b "be able to set MDTs to readonly"
24408
24409 test_803a() {
24410         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24411         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24412                 skip "MDS needs to be newer than 2.10.54"
24413
24414         mkdir -p $DIR/$tdir
24415         # Create some objects on all MDTs to trigger related logs objects
24416         for idx in $(seq $MDSCOUNT); do
24417                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24418                         $DIR/$tdir/dir${idx} ||
24419                         error "Fail to create $DIR/$tdir/dir${idx}"
24420         done
24421
24422         sync; sleep 3
24423         wait_delete_completed # ensure old test cleanups are finished
24424         echo "before create:"
24425         $LFS df -i $MOUNT
24426         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24427
24428         for i in {1..10}; do
24429                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24430                         error "Fail to create $DIR/$tdir/foo$i"
24431         done
24432
24433         sync; sleep 3
24434         echo "after create:"
24435         $LFS df -i $MOUNT
24436         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24437
24438         # allow for an llog to be cleaned up during the test
24439         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24440                 error "before ($before_used) + 10 > after ($after_used)"
24441
24442         for i in {1..10}; do
24443                 rm -rf $DIR/$tdir/foo$i ||
24444                         error "Fail to remove $DIR/$tdir/foo$i"
24445         done
24446
24447         sleep 3 # avoid MDT return cached statfs
24448         wait_delete_completed
24449         echo "after unlink:"
24450         $LFS df -i $MOUNT
24451         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24452
24453         # allow for an llog to be created during the test
24454         [ $after_used -le $((before_used + 1)) ] ||
24455                 error "after ($after_used) > before ($before_used) + 1"
24456 }
24457 run_test 803a "verify agent object for remote object"
24458
24459 test_803b() {
24460         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24461         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24462                 skip "MDS needs to be newer than 2.13.56"
24463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24464
24465         for i in $(seq 0 $((MDSCOUNT - 1))); do
24466                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24467         done
24468
24469         local before=0
24470         local after=0
24471
24472         local tmp
24473
24474         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24475         for i in $(seq 0 $((MDSCOUNT - 1))); do
24476                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24477                         awk '/getattr/ { print $2 }')
24478                 before=$((before + tmp))
24479         done
24480         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24481         for i in $(seq 0 $((MDSCOUNT - 1))); do
24482                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24483                         awk '/getattr/ { print $2 }')
24484                 after=$((after + tmp))
24485         done
24486
24487         [ $before -eq $after ] || error "getattr count $before != $after"
24488 }
24489 run_test 803b "remote object can getattr from cache"
24490
24491 test_804() {
24492         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24493         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24494                 skip "MDS needs to be newer than 2.10.54"
24495         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24496
24497         mkdir -p $DIR/$tdir
24498         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24499                 error "Fail to create $DIR/$tdir/dir0"
24500
24501         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24502         local dev=$(mdsdevname 2)
24503
24504         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24505                 grep ${fid} || error "NOT found agent entry for dir0"
24506
24507         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24508                 error "Fail to create $DIR/$tdir/dir1"
24509
24510         touch $DIR/$tdir/dir1/foo0 ||
24511                 error "Fail to create $DIR/$tdir/dir1/foo0"
24512         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24513         local rc=0
24514
24515         for idx in $(seq $MDSCOUNT); do
24516                 dev=$(mdsdevname $idx)
24517                 do_facet mds${idx} \
24518                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24519                         grep ${fid} && rc=$idx
24520         done
24521
24522         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24523                 error "Fail to rename foo0 to foo1"
24524         if [ $rc -eq 0 ]; then
24525                 for idx in $(seq $MDSCOUNT); do
24526                         dev=$(mdsdevname $idx)
24527                         do_facet mds${idx} \
24528                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24529                         grep ${fid} && rc=$idx
24530                 done
24531         fi
24532
24533         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24534                 error "Fail to rename foo1 to foo2"
24535         if [ $rc -eq 0 ]; then
24536                 for idx in $(seq $MDSCOUNT); do
24537                         dev=$(mdsdevname $idx)
24538                         do_facet mds${idx} \
24539                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24540                         grep ${fid} && rc=$idx
24541                 done
24542         fi
24543
24544         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24545
24546         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24547                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24548         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24549                 error "Fail to rename foo2 to foo0"
24550         unlink $DIR/$tdir/dir1/foo0 ||
24551                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24552         rm -rf $DIR/$tdir/dir0 ||
24553                 error "Fail to rm $DIR/$tdir/dir0"
24554
24555         for idx in $(seq $MDSCOUNT); do
24556                 dev=$(mdsdevname $idx)
24557                 rc=0
24558
24559                 stop mds${idx}
24560                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24561                         rc=$?
24562                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24563                         error "mount mds$idx failed"
24564                 df $MOUNT > /dev/null 2>&1
24565
24566                 # e2fsck should not return error
24567                 [ $rc -eq 0 ] ||
24568                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24569         done
24570 }
24571 run_test 804 "verify agent entry for remote entry"
24572
24573 cleanup_805() {
24574         do_facet $SINGLEMDS zfs set quota=$old $fsset
24575         unlinkmany $DIR/$tdir/f- 1000000
24576         trap 0
24577 }
24578
24579 test_805() {
24580         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24581         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24582         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24583                 skip "netfree not implemented before 0.7"
24584         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24585                 skip "Need MDS version at least 2.10.57"
24586
24587         local fsset
24588         local freekb
24589         local usedkb
24590         local old
24591         local quota
24592         local pref="osd-zfs.$FSNAME-MDT0000."
24593
24594         # limit available space on MDS dataset to meet nospace issue
24595         # quickly. then ZFS 0.7.2 can use reserved space if asked
24596         # properly (using netfree flag in osd_declare_destroy()
24597         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24598         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24599                 gawk '{print $3}')
24600         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24601         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24602         let "usedkb=usedkb-freekb"
24603         let "freekb=freekb/2"
24604         if let "freekb > 5000"; then
24605                 let "freekb=5000"
24606         fi
24607         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24608         trap cleanup_805 EXIT
24609         mkdir $DIR/$tdir
24610         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24611                 error "Can't set PFL layout"
24612         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24613         rm -rf $DIR/$tdir || error "not able to remove"
24614         do_facet $SINGLEMDS zfs set quota=$old $fsset
24615         trap 0
24616 }
24617 run_test 805 "ZFS can remove from full fs"
24618
24619 # Size-on-MDS test
24620 check_lsom_data()
24621 {
24622         local file=$1
24623         local size=$($LFS getsom -s $file)
24624         local expect=$(stat -c %s $file)
24625
24626         [[ $size == $expect ]] ||
24627                 error "$file expected size: $expect, got: $size"
24628
24629         local blocks=$($LFS getsom -b $file)
24630         expect=$(stat -c %b $file)
24631         [[ $blocks == $expect ]] ||
24632                 error "$file expected blocks: $expect, got: $blocks"
24633 }
24634
24635 check_lsom_size()
24636 {
24637         local size=$($LFS getsom -s $1)
24638         local expect=$2
24639
24640         [[ $size == $expect ]] ||
24641                 error "$file expected size: $expect, got: $size"
24642 }
24643
24644 test_806() {
24645         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24646                 skip "Need MDS version at least 2.11.52"
24647
24648         local bs=1048576
24649
24650         touch $DIR/$tfile || error "touch $tfile failed"
24651
24652         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24653         save_lustre_params client "llite.*.xattr_cache" > $save
24654         lctl set_param llite.*.xattr_cache=0
24655         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24656
24657         # single-threaded write
24658         echo "Test SOM for single-threaded write"
24659         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24660                 error "write $tfile failed"
24661         check_lsom_size $DIR/$tfile $bs
24662
24663         local num=32
24664         local size=$(($num * $bs))
24665         local offset=0
24666         local i
24667
24668         echo "Test SOM for single client multi-threaded($num) write"
24669         $TRUNCATE $DIR/$tfile 0
24670         for ((i = 0; i < $num; i++)); do
24671                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24672                 local pids[$i]=$!
24673                 offset=$((offset + $bs))
24674         done
24675         for (( i=0; i < $num; i++ )); do
24676                 wait ${pids[$i]}
24677         done
24678         check_lsom_size $DIR/$tfile $size
24679
24680         $TRUNCATE $DIR/$tfile 0
24681         for ((i = 0; i < $num; i++)); do
24682                 offset=$((offset - $bs))
24683                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24684                 local pids[$i]=$!
24685         done
24686         for (( i=0; i < $num; i++ )); do
24687                 wait ${pids[$i]}
24688         done
24689         check_lsom_size $DIR/$tfile $size
24690
24691         # multi-client writes
24692         num=$(get_node_count ${CLIENTS//,/ })
24693         size=$(($num * $bs))
24694         offset=0
24695         i=0
24696
24697         echo "Test SOM for multi-client ($num) writes"
24698         $TRUNCATE $DIR/$tfile 0
24699         for client in ${CLIENTS//,/ }; do
24700                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24701                 local pids[$i]=$!
24702                 i=$((i + 1))
24703                 offset=$((offset + $bs))
24704         done
24705         for (( i=0; i < $num; i++ )); do
24706                 wait ${pids[$i]}
24707         done
24708         check_lsom_size $DIR/$tfile $offset
24709
24710         i=0
24711         $TRUNCATE $DIR/$tfile 0
24712         for client in ${CLIENTS//,/ }; do
24713                 offset=$((offset - $bs))
24714                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24715                 local pids[$i]=$!
24716                 i=$((i + 1))
24717         done
24718         for (( i=0; i < $num; i++ )); do
24719                 wait ${pids[$i]}
24720         done
24721         check_lsom_size $DIR/$tfile $size
24722
24723         # verify truncate
24724         echo "Test SOM for truncate"
24725         $TRUNCATE $DIR/$tfile 1048576
24726         check_lsom_size $DIR/$tfile 1048576
24727         $TRUNCATE $DIR/$tfile 1234
24728         check_lsom_size $DIR/$tfile 1234
24729
24730         # verify SOM blocks count
24731         echo "Verify SOM block count"
24732         $TRUNCATE $DIR/$tfile 0
24733         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24734                 error "failed to write file $tfile"
24735         check_lsom_data $DIR/$tfile
24736 }
24737 run_test 806 "Verify Lazy Size on MDS"
24738
24739 test_807() {
24740         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24741         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24742                 skip "Need MDS version at least 2.11.52"
24743
24744         # Registration step
24745         changelog_register || error "changelog_register failed"
24746         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24747         changelog_users $SINGLEMDS | grep -q $cl_user ||
24748                 error "User $cl_user not found in changelog_users"
24749
24750         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24751         save_lustre_params client "llite.*.xattr_cache" > $save
24752         lctl set_param llite.*.xattr_cache=0
24753         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24754
24755         rm -rf $DIR/$tdir || error "rm $tdir failed"
24756         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24757         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24758         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24759         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24760                 error "truncate $tdir/trunc failed"
24761
24762         local bs=1048576
24763         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24764                 error "write $tfile failed"
24765
24766         # multi-client wirtes
24767         local num=$(get_node_count ${CLIENTS//,/ })
24768         local offset=0
24769         local i=0
24770
24771         echo "Test SOM for multi-client ($num) writes"
24772         touch $DIR/$tfile || error "touch $tfile failed"
24773         $TRUNCATE $DIR/$tfile 0
24774         for client in ${CLIENTS//,/ }; do
24775                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24776                 local pids[$i]=$!
24777                 i=$((i + 1))
24778                 offset=$((offset + $bs))
24779         done
24780         for (( i=0; i < $num; i++ )); do
24781                 wait ${pids[$i]}
24782         done
24783
24784         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24785         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24786         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24787         check_lsom_data $DIR/$tdir/trunc
24788         check_lsom_data $DIR/$tdir/single_dd
24789         check_lsom_data $DIR/$tfile
24790
24791         rm -rf $DIR/$tdir
24792         # Deregistration step
24793         changelog_deregister || error "changelog_deregister failed"
24794 }
24795 run_test 807 "verify LSOM syncing tool"
24796
24797 check_som_nologged()
24798 {
24799         local lines=$($LFS changelog $FSNAME-MDT0000 |
24800                 grep 'x=trusted.som' | wc -l)
24801         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24802 }
24803
24804 test_808() {
24805         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24806                 skip "Need MDS version at least 2.11.55"
24807
24808         # Registration step
24809         changelog_register || error "changelog_register failed"
24810
24811         touch $DIR/$tfile || error "touch $tfile failed"
24812         check_som_nologged
24813
24814         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24815                 error "write $tfile failed"
24816         check_som_nologged
24817
24818         $TRUNCATE $DIR/$tfile 1234
24819         check_som_nologged
24820
24821         $TRUNCATE $DIR/$tfile 1048576
24822         check_som_nologged
24823
24824         # Deregistration step
24825         changelog_deregister || error "changelog_deregister failed"
24826 }
24827 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24828
24829 check_som_nodata()
24830 {
24831         $LFS getsom $1
24832         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24833 }
24834
24835 test_809() {
24836         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24837                 skip "Need MDS version at least 2.11.56"
24838
24839         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24840                 error "failed to create DoM-only file $DIR/$tfile"
24841         touch $DIR/$tfile || error "touch $tfile failed"
24842         check_som_nodata $DIR/$tfile
24843
24844         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24845                 error "write $tfile failed"
24846         check_som_nodata $DIR/$tfile
24847
24848         $TRUNCATE $DIR/$tfile 1234
24849         check_som_nodata $DIR/$tfile
24850
24851         $TRUNCATE $DIR/$tfile 4097
24852         check_som_nodata $DIR/$file
24853 }
24854 run_test 809 "Verify no SOM xattr store for DoM-only files"
24855
24856 test_810() {
24857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24858         $GSS && skip_env "could not run with gss"
24859         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24860                 skip "OST < 2.12.58 doesn't align checksum"
24861
24862         set_checksums 1
24863         stack_trap "set_checksums $ORIG_CSUM" EXIT
24864         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24865
24866         local csum
24867         local before
24868         local after
24869         for csum in $CKSUM_TYPES; do
24870                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24871                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24872                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24873                         eval set -- $i
24874                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24875                         before=$(md5sum $DIR/$tfile)
24876                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24877                         after=$(md5sum $DIR/$tfile)
24878                         [ "$before" == "$after" ] ||
24879                                 error "$csum: $before != $after bs=$1 seek=$2"
24880                 done
24881         done
24882 }
24883 run_test 810 "partial page writes on ZFS (LU-11663)"
24884
24885 test_812a() {
24886         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24887                 skip "OST < 2.12.51 doesn't support this fail_loc"
24888
24889         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24890         # ensure ost1 is connected
24891         stat $DIR/$tfile >/dev/null || error "can't stat"
24892         wait_osc_import_state client ost1 FULL
24893         # no locks, no reqs to let the connection idle
24894         cancel_lru_locks osc
24895
24896         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24897 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24898         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24899         wait_osc_import_state client ost1 CONNECTING
24900         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24901
24902         stat $DIR/$tfile >/dev/null || error "can't stat file"
24903 }
24904 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24905
24906 test_812b() { # LU-12378
24907         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24908                 skip "OST < 2.12.51 doesn't support this fail_loc"
24909
24910         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24911         # ensure ost1 is connected
24912         stat $DIR/$tfile >/dev/null || error "can't stat"
24913         wait_osc_import_state client ost1 FULL
24914         # no locks, no reqs to let the connection idle
24915         cancel_lru_locks osc
24916
24917         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24918 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24919         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24920         wait_osc_import_state client ost1 CONNECTING
24921         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24922
24923         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24924         wait_osc_import_state client ost1 IDLE
24925 }
24926 run_test 812b "do not drop no resend request for idle connect"
24927
24928 test_813() {
24929         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24930         [ -z "$file_heat_sav" ] && skip "no file heat support"
24931
24932         local readsample
24933         local writesample
24934         local readbyte
24935         local writebyte
24936         local readsample1
24937         local writesample1
24938         local readbyte1
24939         local writebyte1
24940
24941         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24942         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24943
24944         $LCTL set_param -n llite.*.file_heat=1
24945         echo "Turn on file heat"
24946         echo "Period second: $period_second, Decay percentage: $decay_pct"
24947
24948         echo "QQQQ" > $DIR/$tfile
24949         echo "QQQQ" > $DIR/$tfile
24950         echo "QQQQ" > $DIR/$tfile
24951         cat $DIR/$tfile > /dev/null
24952         cat $DIR/$tfile > /dev/null
24953         cat $DIR/$tfile > /dev/null
24954         cat $DIR/$tfile > /dev/null
24955
24956         local out=$($LFS heat_get $DIR/$tfile)
24957
24958         $LFS heat_get $DIR/$tfile
24959         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24960         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24961         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24962         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24963
24964         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24965         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24966         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24967         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24968
24969         sleep $((period_second + 3))
24970         echo "Sleep $((period_second + 3)) seconds..."
24971         # The recursion formula to calculate the heat of the file f is as
24972         # follow:
24973         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24974         # Where Hi is the heat value in the period between time points i*I and
24975         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24976         # to the weight of Ci.
24977         out=$($LFS heat_get $DIR/$tfile)
24978         $LFS heat_get $DIR/$tfile
24979         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24980         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24981         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24982         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24983
24984         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24985                 error "read sample ($readsample) is wrong"
24986         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24987                 error "write sample ($writesample) is wrong"
24988         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24989                 error "read bytes ($readbyte) is wrong"
24990         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24991                 error "write bytes ($writebyte) is wrong"
24992
24993         echo "QQQQ" > $DIR/$tfile
24994         echo "QQQQ" > $DIR/$tfile
24995         echo "QQQQ" > $DIR/$tfile
24996         cat $DIR/$tfile > /dev/null
24997         cat $DIR/$tfile > /dev/null
24998         cat $DIR/$tfile > /dev/null
24999         cat $DIR/$tfile > /dev/null
25000
25001         sleep $((period_second + 3))
25002         echo "Sleep $((period_second + 3)) seconds..."
25003
25004         out=$($LFS heat_get $DIR/$tfile)
25005         $LFS heat_get $DIR/$tfile
25006         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25007         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25008         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25009         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25010
25011         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
25012                 4 * $decay_pct) / 100") -eq 1 ] ||
25013                 error "read sample ($readsample1) is wrong"
25014         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
25015                 3 * $decay_pct) / 100") -eq 1 ] ||
25016                 error "write sample ($writesample1) is wrong"
25017         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
25018                 20 * $decay_pct) / 100") -eq 1 ] ||
25019                 error "read bytes ($readbyte1) is wrong"
25020         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
25021                 15 * $decay_pct) / 100") -eq 1 ] ||
25022                 error "write bytes ($writebyte1) is wrong"
25023
25024         echo "Turn off file heat for the file $DIR/$tfile"
25025         $LFS heat_set -o $DIR/$tfile
25026
25027         echo "QQQQ" > $DIR/$tfile
25028         echo "QQQQ" > $DIR/$tfile
25029         echo "QQQQ" > $DIR/$tfile
25030         cat $DIR/$tfile > /dev/null
25031         cat $DIR/$tfile > /dev/null
25032         cat $DIR/$tfile > /dev/null
25033         cat $DIR/$tfile > /dev/null
25034
25035         out=$($LFS heat_get $DIR/$tfile)
25036         $LFS heat_get $DIR/$tfile
25037         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25038         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25039         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25040         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25041
25042         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25043         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25044         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25045         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25046
25047         echo "Trun on file heat for the file $DIR/$tfile"
25048         $LFS heat_set -O $DIR/$tfile
25049
25050         echo "QQQQ" > $DIR/$tfile
25051         echo "QQQQ" > $DIR/$tfile
25052         echo "QQQQ" > $DIR/$tfile
25053         cat $DIR/$tfile > /dev/null
25054         cat $DIR/$tfile > /dev/null
25055         cat $DIR/$tfile > /dev/null
25056         cat $DIR/$tfile > /dev/null
25057
25058         out=$($LFS heat_get $DIR/$tfile)
25059         $LFS heat_get $DIR/$tfile
25060         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25061         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25062         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25063         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25064
25065         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
25066         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
25067         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
25068         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
25069
25070         $LFS heat_set -c $DIR/$tfile
25071         $LCTL set_param -n llite.*.file_heat=0
25072         echo "Turn off file heat support for the Lustre filesystem"
25073
25074         echo "QQQQ" > $DIR/$tfile
25075         echo "QQQQ" > $DIR/$tfile
25076         echo "QQQQ" > $DIR/$tfile
25077         cat $DIR/$tfile > /dev/null
25078         cat $DIR/$tfile > /dev/null
25079         cat $DIR/$tfile > /dev/null
25080         cat $DIR/$tfile > /dev/null
25081
25082         out=$($LFS heat_get $DIR/$tfile)
25083         $LFS heat_get $DIR/$tfile
25084         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25085         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25086         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25087         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25088
25089         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25090         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25091         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25092         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25093
25094         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
25095         rm -f $DIR/$tfile
25096 }
25097 run_test 813 "File heat verfication"
25098
25099 test_814()
25100 {
25101         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25102         echo -n y >> $DIR/$tfile
25103         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25104         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25105 }
25106 run_test 814 "sparse cp works as expected (LU-12361)"
25107
25108 test_815()
25109 {
25110         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25111         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25112 }
25113 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25114
25115 test_816() {
25116         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25117         # ensure ost1 is connected
25118         stat $DIR/$tfile >/dev/null || error "can't stat"
25119         wait_osc_import_state client ost1 FULL
25120         # no locks, no reqs to let the connection idle
25121         cancel_lru_locks osc
25122         lru_resize_disable osc
25123         local before
25124         local now
25125         before=$($LCTL get_param -n \
25126                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25127
25128         wait_osc_import_state client ost1 IDLE
25129         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25130         now=$($LCTL get_param -n \
25131               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25132         [ $before == $now ] || error "lru_size changed $before != $now"
25133 }
25134 run_test 816 "do not reset lru_resize on idle reconnect"
25135
25136 cleanup_817() {
25137         umount $tmpdir
25138         exportfs -u localhost:$DIR/nfsexp
25139         rm -rf $DIR/nfsexp
25140 }
25141
25142 test_817() {
25143         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25144
25145         mkdir -p $DIR/nfsexp
25146         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25147                 error "failed to export nfs"
25148
25149         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25150         stack_trap cleanup_817 EXIT
25151
25152         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25153                 error "failed to mount nfs to $tmpdir"
25154
25155         cp /bin/true $tmpdir
25156         $DIR/nfsexp/true || error "failed to execute 'true' command"
25157 }
25158 run_test 817 "nfsd won't cache write lock for exec file"
25159
25160 test_818() {
25161         mkdir $DIR/$tdir
25162         $LFS setstripe -c1 -i0 $DIR/$tfile
25163         $LFS setstripe -c1 -i1 $DIR/$tfile
25164         stop $SINGLEMDS
25165         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25166         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25167         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25168                 error "start $SINGLEMDS failed"
25169         rm -rf $DIR/$tdir
25170 }
25171 run_test 818 "unlink with failed llog"
25172
25173 test_819a() {
25174         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25175         cancel_lru_locks osc
25176         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25177         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25178         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25179         rm -f $TDIR/$tfile
25180 }
25181 run_test 819a "too big niobuf in read"
25182
25183 test_819b() {
25184         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25185         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25186         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25187         cancel_lru_locks osc
25188         sleep 1
25189         rm -f $TDIR/$tfile
25190 }
25191 run_test 819b "too big niobuf in write"
25192
25193
25194 function test_820_start_ost() {
25195         sleep 5
25196
25197         for num in $(seq $OSTCOUNT); do
25198                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25199         done
25200 }
25201
25202 test_820() {
25203         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25204
25205         mkdir $DIR/$tdir
25206         umount_client $MOUNT || error "umount failed"
25207         for num in $(seq $OSTCOUNT); do
25208                 stop ost$num
25209         done
25210
25211         # mount client with no active OSTs
25212         # so that the client can't initialize max LOV EA size
25213         # from OSC notifications
25214         mount_client $MOUNT || error "mount failed"
25215         # delay OST starting to keep this 0 max EA size for a while
25216         test_820_start_ost &
25217
25218         # create a directory on MDS2
25219         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25220                 error "Failed to create directory"
25221         # open intent should update default EA size
25222         # see mdc_update_max_ea_from_body()
25223         # notice this is the very first RPC to MDS2
25224         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25225         ret=$?
25226         echo $out
25227         # With SSK, this situation can lead to -EPERM being returned.
25228         # In that case, simply retry.
25229         if [ $ret -ne 0 ] && $SHARED_KEY; then
25230                 if echo "$out" | grep -q "not permitted"; then
25231                         cp /etc/services $DIR/$tdir/mds2
25232                         ret=$?
25233                 fi
25234         fi
25235         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25236 }
25237 run_test 820 "update max EA from open intent"
25238
25239 #
25240 # tests that do cleanup/setup should be run at the end
25241 #
25242
25243 test_900() {
25244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25245         local ls
25246
25247         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25248         $LCTL set_param fail_loc=0x903
25249
25250         cancel_lru_locks MGC
25251
25252         FAIL_ON_ERROR=true cleanup
25253         FAIL_ON_ERROR=true setup
25254 }
25255 run_test 900 "umount should not race with any mgc requeue thread"
25256
25257 # LUS-6253/LU-11185
25258 test_901() {
25259         local oldc
25260         local newc
25261         local olds
25262         local news
25263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25264
25265         # some get_param have a bug to handle dot in param name
25266         cancel_lru_locks MGC
25267         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25268         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25269         umount_client $MOUNT || error "umount failed"
25270         mount_client $MOUNT || error "mount failed"
25271         cancel_lru_locks MGC
25272         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25273         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25274
25275         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25276         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25277
25278         return 0
25279 }
25280 run_test 901 "don't leak a mgc lock on client umount"
25281
25282 # LU-13377
25283 test_902() {
25284         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25285                 skip "client does not have LU-13377 fix"
25286         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25287         $LCTL set_param fail_loc=0x1415
25288         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25289         cancel_lru_locks osc
25290         rm -f $DIR/$tfile
25291 }
25292 run_test 902 "test short write doesn't hang lustre"
25293
25294 complete $SECONDS
25295 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25296 check_and_cleanup_lustre
25297 if [ "$I_MOUNTED" != "yes" ]; then
25298         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25299 fi
25300 exit_status