Whamcloud - gitweb
LU-12142 clio: fix hang on urgent cached pages
[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 -lt 159 ] || large_xattr_enabled ||
1645                 skip_env "ea_inode feature disabled"
1646
1647         test_mkdir -p $DIR/$tdir
1648         local osts=""
1649         for i in $(seq 0 $OSTCOUNT);
1650         do
1651                 osts=$osts"0"
1652                 if [ $i -ne $OSTCOUNT ]; then
1653                         osts=$osts","
1654                 fi
1655         done
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27ce "more stripes than OSTs with -o"
1669
1670 test_27cf() {
1671         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1672         local pid=0
1673
1674         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1675         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1676         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1677         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1678                 error "failed to set $osp_proc=0"
1679
1680         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1681         pid=$!
1682         sleep 1
1683         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1684         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1685                 error "failed to set $osp_proc=1"
1686         wait $pid
1687         [[ $pid -ne 0 ]] ||
1688                 error "should return error due to $osp_proc=0"
1689 }
1690 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1691
1692 test_27d() {
1693         test_mkdir $DIR/$tdir
1694         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1695                 error "setstripe failed"
1696         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1698 }
1699 run_test 27d "create file with default settings"
1700
1701 test_27e() {
1702         # LU-5839 adds check for existed layout before setting it
1703         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1704                 skip "Need MDS version at least 2.7.56"
1705
1706         test_mkdir $DIR/$tdir
1707         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1708         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1709         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1710 }
1711 run_test 27e "setstripe existing file (should return error)"
1712
1713 test_27f() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1716                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1718                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1719         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1720         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1721 }
1722 run_test 27f "setstripe with bad stripe size (should return error)"
1723
1724 test_27g() {
1725         test_mkdir $DIR/$tdir
1726         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1727         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1728                 error "$DIR/$tdir/$tfile has object"
1729 }
1730 run_test 27g "$LFS getstripe with no objects"
1731
1732 test_27ga() {
1733         test_mkdir $DIR/$tdir
1734         touch $DIR/$tdir/$tfile || error "touch failed"
1735         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1736         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1737         local rc=$?
1738         (( rc == 2 )) || error "getstripe did not return ENOENT"
1739 }
1740 run_test 27ga "$LFS getstripe with missing file (should return error)"
1741
1742 test_27i() {
1743         test_mkdir $DIR/$tdir
1744         touch $DIR/$tdir/$tfile || error "touch failed"
1745         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1746                 error "missing objects"
1747 }
1748 run_test 27i "$LFS getstripe with some objects"
1749
1750 test_27j() {
1751         test_mkdir $DIR/$tdir
1752         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1753                 error "setstripe failed" || true
1754 }
1755 run_test 27j "setstripe with bad stripe offset (should return error)"
1756
1757 test_27k() { # bug 2844
1758         test_mkdir $DIR/$tdir
1759         local file=$DIR/$tdir/$tfile
1760         local ll_max_blksize=$((4 * 1024 * 1024))
1761         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1762         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1763         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1764         dd if=/dev/zero of=$file bs=4k count=1
1765         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1766         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1767 }
1768 run_test 27k "limit i_blksize for broken user apps"
1769
1770 test_27l() {
1771         mcreate $DIR/$tfile || error "creating file"
1772         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1773                 error "setstripe should have failed" || true
1774 }
1775 run_test 27l "check setstripe permissions (should return error)"
1776
1777 test_27m() {
1778         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1779
1780         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1781                 skip_env "multiple clients -- skipping"
1782
1783         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1784                    head -n1)
1785         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1786                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1787         fi
1788         trap simple_cleanup_common EXIT
1789         test_mkdir $DIR/$tdir
1790         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1791         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1792                 error "dd should fill OST0"
1793         i=2
1794         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1795                 i=$((i + 1))
1796                 [ $i -gt 256 ] && break
1797         done
1798         i=$((i + 1))
1799         touch $DIR/$tdir/$tfile.$i
1800         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1801             awk '{print $1}'| grep -w "0") ] &&
1802                 error "OST0 was full but new created file still use it"
1803         i=$((i + 1))
1804         touch $DIR/$tdir/$tfile.$i
1805         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1806             awk '{print $1}'| grep -w "0") ] &&
1807                 error "OST0 was full but new created file still use it"
1808         simple_cleanup_common
1809 }
1810 run_test 27m "create file while OST0 was full"
1811
1812 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1813 # if the OST isn't full anymore.
1814 reset_enospc() {
1815         local ostidx=${1:-""}
1816         local delay
1817         local ready
1818         local get_prealloc
1819
1820         local list=$(comma_list $(osts_nodes))
1821         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1822
1823         do_nodes $list lctl set_param fail_loc=0
1824         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1825         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1826                 awk '{print $1 * 2;exit;}')
1827         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1828                         grep -v \"^0$\""
1829         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1830 }
1831
1832 __exhaust_precreations() {
1833         local OSTIDX=$1
1834         local FAILLOC=$2
1835         local FAILIDX=${3:-$OSTIDX}
1836         local ofacet=ost$((OSTIDX + 1))
1837
1838         test_mkdir -p -c1 $DIR/$tdir
1839         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1840         local mfacet=mds$((mdtidx + 1))
1841         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1842
1843         local OST=$(ostname_from_index $OSTIDX)
1844
1845         # on the mdt's osc
1846         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1847         local last_id=$(do_facet $mfacet lctl get_param -n \
1848                         osp.$mdtosc_proc1.prealloc_last_id)
1849         local next_id=$(do_facet $mfacet lctl get_param -n \
1850                         osp.$mdtosc_proc1.prealloc_next_id)
1851
1852         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1853         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1854
1855         test_mkdir -p $DIR/$tdir/${OST}
1856         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1857 #define OBD_FAIL_OST_ENOSPC              0x215
1858         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1859         echo "Creating to objid $last_id on ost $OST..."
1860         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1861         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1862         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1863 }
1864
1865 exhaust_precreations() {
1866         __exhaust_precreations $1 $2 $3
1867         sleep_maxage
1868 }
1869
1870 exhaust_all_precreations() {
1871         local i
1872         for (( i=0; i < OSTCOUNT; i++ )) ; do
1873                 __exhaust_precreations $i $1 -1
1874         done
1875         sleep_maxage
1876 }
1877
1878 test_27n() {
1879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1881         remote_mds_nodsh && skip "remote MDS with nodsh"
1882         remote_ost_nodsh && skip "remote OST with nodsh"
1883
1884         reset_enospc
1885         rm -f $DIR/$tdir/$tfile
1886         exhaust_precreations 0 0x80000215
1887         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1888         touch $DIR/$tdir/$tfile || error "touch failed"
1889         $LFS getstripe $DIR/$tdir/$tfile
1890         reset_enospc
1891 }
1892 run_test 27n "create file with some full OSTs"
1893
1894 test_27o() {
1895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899
1900         reset_enospc
1901         rm -f $DIR/$tdir/$tfile
1902         exhaust_all_precreations 0x215
1903
1904         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1905
1906         reset_enospc
1907         rm -rf $DIR/$tdir/*
1908 }
1909 run_test 27o "create file with all full OSTs (should error)"
1910
1911 function create_and_checktime() {
1912         local fname=$1
1913         local loops=$2
1914         local i
1915
1916         for ((i=0; i < $loops; i++)); do
1917                 local start=$SECONDS
1918                 multiop $fname-$i Oc
1919                 ((SECONDS-start < TIMEOUT)) ||
1920                         error "creation took " $((SECONDS-$start)) && return 1
1921         done
1922 }
1923
1924 test_27oo() {
1925         local mdts=$(comma_list $(mdts_nodes))
1926
1927         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1928                 skip "Need MDS version at least 2.13.57"
1929
1930         local f0=$DIR/${tfile}-0
1931         local f1=$DIR/${tfile}-1
1932
1933         wait_delete_completed
1934
1935         # refill precreated objects
1936         $LFS setstripe -i0 -c1 $f0
1937
1938         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1939         # force QoS allocation policy
1940         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1941         stack_trap "do_nodes $mdts $LCTL set_param \
1942                 lov.*.qos_threshold_rr=$saved" EXIT
1943         sleep_maxage
1944
1945         # one OST is unavailable, but still have few objects preallocated
1946         stop ost1
1947         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1948                 rm -rf $f1 $DIR/$tdir*" EXIT
1949
1950         for ((i=0; i < 7; i++)); do
1951                 mkdir $DIR/$tdir$i || error "can't create dir"
1952                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1953                         error "can't set striping"
1954         done
1955         for ((i=0; i < 7; i++)); do
1956                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1957         done
1958         wait
1959 }
1960 run_test 27oo "don't let few threads to reserve too many objects"
1961
1962 test_27p() {
1963         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1965         remote_mds_nodsh && skip "remote MDS with nodsh"
1966         remote_ost_nodsh && skip "remote OST with nodsh"
1967
1968         reset_enospc
1969         rm -f $DIR/$tdir/$tfile
1970         test_mkdir $DIR/$tdir
1971
1972         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1973         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1974         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1975
1976         exhaust_precreations 0 0x80000215
1977         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1978         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1979         $LFS getstripe $DIR/$tdir/$tfile
1980
1981         reset_enospc
1982 }
1983 run_test 27p "append to a truncated file with some full OSTs"
1984
1985 test_27q() {
1986         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1988         remote_mds_nodsh && skip "remote MDS with nodsh"
1989         remote_ost_nodsh && skip "remote OST with nodsh"
1990
1991         reset_enospc
1992         rm -f $DIR/$tdir/$tfile
1993
1994         test_mkdir $DIR/$tdir
1995         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1996         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1997                 error "truncate $DIR/$tdir/$tfile failed"
1998         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1999
2000         exhaust_all_precreations 0x215
2001
2002         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2003         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2004
2005         reset_enospc
2006 }
2007 run_test 27q "append to truncated file with all OSTs full (should error)"
2008
2009 test_27r() {
2010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2012         remote_mds_nodsh && skip "remote MDS with nodsh"
2013         remote_ost_nodsh && skip "remote OST with nodsh"
2014
2015         reset_enospc
2016         rm -f $DIR/$tdir/$tfile
2017         exhaust_precreations 0 0x80000215
2018
2019         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2020
2021         reset_enospc
2022 }
2023 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2024
2025 test_27s() { # bug 10725
2026         test_mkdir $DIR/$tdir
2027         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2028         local stripe_count=0
2029         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2030         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2031                 error "stripe width >= 2^32 succeeded" || true
2032
2033 }
2034 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2035
2036 test_27t() { # bug 10864
2037         WDIR=$(pwd)
2038         WLFS=$(which lfs)
2039         cd $DIR
2040         touch $tfile
2041         $WLFS getstripe $tfile
2042         cd $WDIR
2043 }
2044 run_test 27t "check that utils parse path correctly"
2045
2046 test_27u() { # bug 4900
2047         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2048         remote_mds_nodsh && skip "remote MDS with nodsh"
2049
2050         local index
2051         local list=$(comma_list $(mdts_nodes))
2052
2053 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2054         do_nodes $list $LCTL set_param fail_loc=0x139
2055         test_mkdir -p $DIR/$tdir
2056         trap simple_cleanup_common EXIT
2057         createmany -o $DIR/$tdir/t- 1000
2058         do_nodes $list $LCTL set_param fail_loc=0
2059
2060         TLOG=$TMP/$tfile.getstripe
2061         $LFS getstripe $DIR/$tdir > $TLOG
2062         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2063         unlinkmany $DIR/$tdir/t- 1000
2064         trap 0
2065         [[ $OBJS -gt 0 ]] &&
2066                 error "$OBJS objects created on OST-0. See $TLOG" ||
2067                 rm -f $TLOG
2068 }
2069 run_test 27u "skip object creation on OSC w/o objects"
2070
2071 test_27v() { # bug 4900
2072         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2074         remote_mds_nodsh && skip "remote MDS with nodsh"
2075         remote_ost_nodsh && skip "remote OST with nodsh"
2076
2077         exhaust_all_precreations 0x215
2078         reset_enospc
2079
2080         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2081
2082         touch $DIR/$tdir/$tfile
2083         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2084         # all except ost1
2085         for (( i=1; i < OSTCOUNT; i++ )); do
2086                 do_facet ost$i lctl set_param fail_loc=0x705
2087         done
2088         local START=`date +%s`
2089         createmany -o $DIR/$tdir/$tfile 32
2090
2091         local FINISH=`date +%s`
2092         local TIMEOUT=`lctl get_param -n timeout`
2093         local PROCESS=$((FINISH - START))
2094         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2095                error "$FINISH - $START >= $TIMEOUT / 2"
2096         sleep $((TIMEOUT / 2 - PROCESS))
2097         reset_enospc
2098 }
2099 run_test 27v "skip object creation on slow OST"
2100
2101 test_27w() { # bug 10997
2102         test_mkdir $DIR/$tdir
2103         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2104         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2105                 error "stripe size $size != 65536" || true
2106         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2107                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2108 }
2109 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2110
2111 test_27wa() {
2112         [[ $OSTCOUNT -lt 2 ]] &&
2113                 skip_env "skipping multiple stripe count/offset test"
2114
2115         test_mkdir $DIR/$tdir
2116         for i in $(seq 1 $OSTCOUNT); do
2117                 offset=$((i - 1))
2118                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2119                         error "setstripe -c $i -i $offset failed"
2120                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2121                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2122                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2123                 [ $index -ne $offset ] &&
2124                         error "stripe offset $index != $offset" || true
2125         done
2126 }
2127 run_test 27wa "check $LFS setstripe -c -i options"
2128
2129 test_27x() {
2130         remote_ost_nodsh && skip "remote OST with nodsh"
2131         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2133
2134         OFFSET=$(($OSTCOUNT - 1))
2135         OSTIDX=0
2136         local OST=$(ostname_from_index $OSTIDX)
2137
2138         test_mkdir $DIR/$tdir
2139         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2140         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2141         sleep_maxage
2142         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2143         for i in $(seq 0 $OFFSET); do
2144                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2145                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2146                 error "OST0 was degraded but new created file still use it"
2147         done
2148         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2149 }
2150 run_test 27x "create files while OST0 is degraded"
2151
2152 test_27y() {
2153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2154         remote_mds_nodsh && skip "remote MDS with nodsh"
2155         remote_ost_nodsh && skip "remote OST with nodsh"
2156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2157
2158         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2159         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2160                 osp.$mdtosc.prealloc_last_id)
2161         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2162                 osp.$mdtosc.prealloc_next_id)
2163         local fcount=$((last_id - next_id))
2164         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2165         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2166
2167         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2168                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2169         local OST_DEACTIVE_IDX=-1
2170         local OSC
2171         local OSTIDX
2172         local OST
2173
2174         for OSC in $MDS_OSCS; do
2175                 OST=$(osc_to_ost $OSC)
2176                 OSTIDX=$(index_from_ostuuid $OST)
2177                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2178                         OST_DEACTIVE_IDX=$OSTIDX
2179                 fi
2180                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2181                         echo $OSC "is Deactivated:"
2182                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2183                 fi
2184         done
2185
2186         OSTIDX=$(index_from_ostuuid $OST)
2187         test_mkdir $DIR/$tdir
2188         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2189
2190         for OSC in $MDS_OSCS; do
2191                 OST=$(osc_to_ost $OSC)
2192                 OSTIDX=$(index_from_ostuuid $OST)
2193                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2194                         echo $OST "is degraded:"
2195                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2196                                                 obdfilter.$OST.degraded=1
2197                 fi
2198         done
2199
2200         sleep_maxage
2201         createmany -o $DIR/$tdir/$tfile $fcount
2202
2203         for OSC in $MDS_OSCS; do
2204                 OST=$(osc_to_ost $OSC)
2205                 OSTIDX=$(index_from_ostuuid $OST)
2206                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2207                         echo $OST "is recovered from degraded:"
2208                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2209                                                 obdfilter.$OST.degraded=0
2210                 else
2211                         do_facet $SINGLEMDS lctl --device %$OSC activate
2212                 fi
2213         done
2214
2215         # all osp devices get activated, hence -1 stripe count restored
2216         local stripe_count=0
2217
2218         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2219         # devices get activated.
2220         sleep_maxage
2221         $LFS setstripe -c -1 $DIR/$tfile
2222         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2223         rm -f $DIR/$tfile
2224         [ $stripe_count -ne $OSTCOUNT ] &&
2225                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2226         return 0
2227 }
2228 run_test 27y "create files while OST0 is degraded and the rest inactive"
2229
2230 check_seq_oid()
2231 {
2232         log "check file $1"
2233
2234         lmm_count=$($LFS getstripe -c $1)
2235         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2236         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2237
2238         local old_ifs="$IFS"
2239         IFS=$'[:]'
2240         fid=($($LFS path2fid $1))
2241         IFS="$old_ifs"
2242
2243         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2244         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2245
2246         # compare lmm_seq and lu_fid->f_seq
2247         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2248         # compare lmm_object_id and lu_fid->oid
2249         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2250
2251         # check the trusted.fid attribute of the OST objects of the file
2252         local have_obdidx=false
2253         local stripe_nr=0
2254         $LFS getstripe $1 | while read obdidx oid hex seq; do
2255                 # skip lines up to and including "obdidx"
2256                 [ -z "$obdidx" ] && break
2257                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2258                 $have_obdidx || continue
2259
2260                 local ost=$((obdidx + 1))
2261                 local dev=$(ostdevname $ost)
2262                 local oid_hex
2263
2264                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2265
2266                 seq=$(echo $seq | sed -e "s/^0x//g")
2267                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2268                         oid_hex=$(echo $oid)
2269                 else
2270                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2271                 fi
2272                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2273
2274                 local ff=""
2275                 #
2276                 # Don't unmount/remount the OSTs if we don't need to do that.
2277                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2278                 # update too, until that use mount/ll_decode_filter_fid/mount.
2279                 # Re-enable when debugfs will understand new filter_fid.
2280                 #
2281                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2282                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2283                                 $dev 2>/dev/null" | grep "parent=")
2284                 fi
2285                 if [ -z "$ff" ]; then
2286                         stop ost$ost
2287                         mount_fstype ost$ost
2288                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2289                                 $(facet_mntpt ost$ost)/$obj_file)
2290                         unmount_fstype ost$ost
2291                         start ost$ost $dev $OST_MOUNT_OPTS
2292                         clients_up
2293                 fi
2294
2295                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2296
2297                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2298
2299                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2300                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2301                 #
2302                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2303                 #       stripe_size=1048576 component_id=1 component_start=0 \
2304                 #       component_end=33554432
2305                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2306                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2307                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2308                 local ff_pstripe
2309                 if grep -q 'stripe=' <<<$ff; then
2310                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2311                 else
2312                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2313                         # into f_ver in this case.  See comment on ff_parent.
2314                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2315                 fi
2316
2317                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2318                 [ $ff_pseq = $lmm_seq ] ||
2319                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2320                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2321                 [ $ff_poid = $lmm_oid ] ||
2322                         error "FF parent OID $ff_poid != $lmm_oid"
2323                 (($ff_pstripe == $stripe_nr)) ||
2324                         error "FF stripe $ff_pstripe != $stripe_nr"
2325
2326                 stripe_nr=$((stripe_nr + 1))
2327                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2328                         continue
2329                 if grep -q 'stripe_count=' <<<$ff; then
2330                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2331                                             -e 's/ .*//' <<<$ff)
2332                         [ $lmm_count = $ff_scnt ] ||
2333                                 error "FF stripe count $lmm_count != $ff_scnt"
2334                 fi
2335         done
2336 }
2337
2338 test_27z() {
2339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2340         remote_ost_nodsh && skip "remote OST with nodsh"
2341
2342         test_mkdir $DIR/$tdir
2343         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2344                 { error "setstripe -c -1 failed"; return 1; }
2345         # We need to send a write to every object to get parent FID info set.
2346         # This _should_ also work for setattr, but does not currently.
2347         # touch $DIR/$tdir/$tfile-1 ||
2348         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2349                 { error "dd $tfile-1 failed"; return 2; }
2350         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2351                 { error "setstripe -c -1 failed"; return 3; }
2352         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2353                 { error "dd $tfile-2 failed"; return 4; }
2354
2355         # make sure write RPCs have been sent to OSTs
2356         sync; sleep 5; sync
2357
2358         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2359         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2360 }
2361 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2362
2363 test_27A() { # b=19102
2364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2365
2366         save_layout_restore_at_exit $MOUNT
2367         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2368         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2369                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2370         local default_size=$($LFS getstripe -S $MOUNT)
2371         local default_offset=$($LFS getstripe -i $MOUNT)
2372         local dsize=$(do_facet $SINGLEMDS \
2373                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2374         [ $default_size -eq $dsize ] ||
2375                 error "stripe size $default_size != $dsize"
2376         [ $default_offset -eq -1 ] ||
2377                 error "stripe offset $default_offset != -1"
2378 }
2379 run_test 27A "check filesystem-wide default LOV EA values"
2380
2381 test_27B() { # LU-2523
2382         test_mkdir $DIR/$tdir
2383         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2384         touch $DIR/$tdir/f0
2385         # open f1 with O_LOV_DELAY_CREATE
2386         # rename f0 onto f1
2387         # call setstripe ioctl on open file descriptor for f1
2388         # close
2389         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2390                 $DIR/$tdir/f0
2391
2392         rm -f $DIR/$tdir/f1
2393         # open f1 with O_LOV_DELAY_CREATE
2394         # unlink f1
2395         # call setstripe ioctl on open file descriptor for f1
2396         # close
2397         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2398
2399         # Allow multiop to fail in imitation of NFS's busted semantics.
2400         true
2401 }
2402 run_test 27B "call setstripe on open unlinked file/rename victim"
2403
2404 # 27C family tests full striping and overstriping
2405 test_27Ca() { #LU-2871
2406         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2407
2408         declare -a ost_idx
2409         local index
2410         local found
2411         local i
2412         local j
2413
2414         test_mkdir $DIR/$tdir
2415         cd $DIR/$tdir
2416         for i in $(seq 0 $((OSTCOUNT - 1))); do
2417                 # set stripe across all OSTs starting from OST$i
2418                 $LFS setstripe -i $i -c -1 $tfile$i
2419                 # get striping information
2420                 ost_idx=($($LFS getstripe $tfile$i |
2421                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2422                 echo ${ost_idx[@]}
2423
2424                 # check the layout
2425                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2426                         error "${#ost_idx[@]} != $OSTCOUNT"
2427
2428                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2429                         found=0
2430                         for j in $(echo ${ost_idx[@]}); do
2431                                 if [ $index -eq $j ]; then
2432                                         found=1
2433                                         break
2434                                 fi
2435                         done
2436                         [ $found = 1 ] ||
2437                                 error "Can not find $index in ${ost_idx[@]}"
2438                 done
2439         done
2440 }
2441 run_test 27Ca "check full striping across all OSTs"
2442
2443 test_27Cb() {
2444         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2445                 skip "server does not support overstriping"
2446         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2447                 skip_env "too many osts, skipping"
2448
2449         test_mkdir -p $DIR/$tdir
2450         local setcount=$(($OSTCOUNT * 2))
2451         [ $setcount -lt 160 ] || large_xattr_enabled ||
2452                 skip_env "ea_inode feature disabled"
2453
2454         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2455                 error "setstripe failed"
2456
2457         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2458         [ $count -eq $setcount ] ||
2459                 error "stripe count $count, should be $setcount"
2460
2461         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2462                 error "overstriped should be set in pattern"
2463
2464         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2465                 error "dd failed"
2466 }
2467 run_test 27Cb "more stripes than OSTs with -C"
2468
2469 test_27Cc() {
2470         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2471                 skip "server does not support overstriping"
2472         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2473
2474         test_mkdir -p $DIR/$tdir
2475         local setcount=$(($OSTCOUNT - 1))
2476
2477         [ $setcount -lt 160 ] || large_xattr_enabled ||
2478                 skip_env "ea_inode feature disabled"
2479
2480         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2481                 error "setstripe failed"
2482
2483         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2484         [ $count -eq $setcount ] ||
2485                 error "stripe count $count, should be $setcount"
2486
2487         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2488                 error "overstriped should not be set in pattern"
2489
2490         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2491                 error "dd failed"
2492 }
2493 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2494
2495 test_27Cd() {
2496         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2497                 skip "server does not support overstriping"
2498         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2499         large_xattr_enabled || skip_env "ea_inode feature disabled"
2500
2501         test_mkdir -p $DIR/$tdir
2502         local setcount=$LOV_MAX_STRIPE_COUNT
2503
2504         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2505                 error "setstripe failed"
2506
2507         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2508         [ $count -eq $setcount ] ||
2509                 error "stripe count $count, should be $setcount"
2510
2511         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2512                 error "overstriped should be set in pattern"
2513
2514         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2515                 error "dd failed"
2516
2517         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2518 }
2519 run_test 27Cd "test maximum stripe count"
2520
2521 test_27Ce() {
2522         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2523                 skip "server does not support overstriping"
2524         test_mkdir -p $DIR/$tdir
2525
2526         pool_add $TESTNAME || error "Pool creation failed"
2527         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2528
2529         local setcount=8
2530
2531         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2532                 error "setstripe failed"
2533
2534         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2535         [ $count -eq $setcount ] ||
2536                 error "stripe count $count, should be $setcount"
2537
2538         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2539                 error "overstriped should be set in pattern"
2540
2541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2542                 error "dd failed"
2543
2544         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2545 }
2546 run_test 27Ce "test pool with overstriping"
2547
2548 test_27Cf() {
2549         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2550                 skip "server does not support overstriping"
2551         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2552                 skip_env "too many osts, skipping"
2553
2554         test_mkdir -p $DIR/$tdir
2555
2556         local setcount=$(($OSTCOUNT * 2))
2557         [ $setcount -lt 160 ] || large_xattr_enabled ||
2558                 skip_env "ea_inode feature disabled"
2559
2560         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2561                 error "setstripe failed"
2562
2563         echo 1 > $DIR/$tdir/$tfile
2564
2565         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2566         [ $count -eq $setcount ] ||
2567                 error "stripe count $count, should be $setcount"
2568
2569         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2570                 error "overstriped should be set in pattern"
2571
2572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2573                 error "dd failed"
2574
2575         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2576 }
2577 run_test 27Cf "test default inheritance with overstriping"
2578
2579 test_27D() {
2580         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2581         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2582         remote_mds_nodsh && skip "remote MDS with nodsh"
2583
2584         local POOL=${POOL:-testpool}
2585         local first_ost=0
2586         local last_ost=$(($OSTCOUNT - 1))
2587         local ost_step=1
2588         local ost_list=$(seq $first_ost $ost_step $last_ost)
2589         local ost_range="$first_ost $last_ost $ost_step"
2590
2591         test_mkdir $DIR/$tdir
2592         pool_add $POOL || error "pool_add failed"
2593         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2594
2595         local skip27D
2596         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2597                 skip27D+="-s 29"
2598         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2599                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2600                         skip27D+=" -s 30,31"
2601         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2602           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2603                 skip27D+=" -s 32,33"
2604         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2605                 skip27D+=" -s 34"
2606         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2607                 error "llapi_layout_test failed"
2608
2609         destroy_test_pools || error "destroy test pools failed"
2610 }
2611 run_test 27D "validate llapi_layout API"
2612
2613 # Verify that default_easize is increased from its initial value after
2614 # accessing a widely striped file.
2615 test_27E() {
2616         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2617         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2618                 skip "client does not have LU-3338 fix"
2619
2620         # 72 bytes is the minimum space required to store striping
2621         # information for a file striped across one OST:
2622         # (sizeof(struct lov_user_md_v3) +
2623         #  sizeof(struct lov_user_ost_data_v1))
2624         local min_easize=72
2625         $LCTL set_param -n llite.*.default_easize $min_easize ||
2626                 error "lctl set_param failed"
2627         local easize=$($LCTL get_param -n llite.*.default_easize)
2628
2629         [ $easize -eq $min_easize ] ||
2630                 error "failed to set default_easize"
2631
2632         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2633                 error "setstripe failed"
2634         # In order to ensure stat() call actually talks to MDS we need to
2635         # do something drastic to this file to shake off all lock, e.g.
2636         # rename it (kills lookup lock forcing cache cleaning)
2637         mv $DIR/$tfile $DIR/${tfile}-1
2638         ls -l $DIR/${tfile}-1
2639         rm $DIR/${tfile}-1
2640
2641         easize=$($LCTL get_param -n llite.*.default_easize)
2642
2643         [ $easize -gt $min_easize ] ||
2644                 error "default_easize not updated"
2645 }
2646 run_test 27E "check that default extended attribute size properly increases"
2647
2648 test_27F() { # LU-5346/LU-7975
2649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2650         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2651         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2652                 skip "Need MDS version at least 2.8.51"
2653         remote_ost_nodsh && skip "remote OST with nodsh"
2654
2655         test_mkdir $DIR/$tdir
2656         rm -f $DIR/$tdir/f0
2657         $LFS setstripe -c 2 $DIR/$tdir
2658
2659         # stop all OSTs to reproduce situation for LU-7975 ticket
2660         for num in $(seq $OSTCOUNT); do
2661                 stop ost$num
2662         done
2663
2664         # open/create f0 with O_LOV_DELAY_CREATE
2665         # truncate f0 to a non-0 size
2666         # close
2667         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2668
2669         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2670         # open/write it again to force delayed layout creation
2671         cat /etc/hosts > $DIR/$tdir/f0 &
2672         catpid=$!
2673
2674         # restart OSTs
2675         for num in $(seq $OSTCOUNT); do
2676                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2677                         error "ost$num failed to start"
2678         done
2679
2680         wait $catpid || error "cat failed"
2681
2682         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2683         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2684                 error "wrong stripecount"
2685
2686 }
2687 run_test 27F "Client resend delayed layout creation with non-zero size"
2688
2689 test_27G() { #LU-10629
2690         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2691                 skip "Need MDS version at least 2.11.51"
2692         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2693         remote_mds_nodsh && skip "remote MDS with nodsh"
2694         local POOL=${POOL:-testpool}
2695         local ostrange="0 0 1"
2696
2697         test_mkdir $DIR/$tdir
2698         touch $DIR/$tdir/$tfile.nopool
2699         pool_add $POOL || error "pool_add failed"
2700         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2701         $LFS setstripe -p $POOL $DIR/$tdir
2702
2703         local pool=$($LFS getstripe -p $DIR/$tdir)
2704
2705         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2706         touch $DIR/$tdir/$tfile.default
2707         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2708         $LFS find $DIR/$tdir -type f --pool $POOL
2709         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2710         [[ "$found" == "2" ]] ||
2711                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2712
2713         $LFS setstripe -d $DIR/$tdir
2714
2715         pool=$($LFS getstripe -p -d $DIR/$tdir)
2716
2717         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2718 }
2719 run_test 27G "Clear OST pool from stripe"
2720
2721 test_27H() {
2722         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2723                 skip "Need MDS version newer than 2.11.54"
2724         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2725         test_mkdir $DIR/$tdir
2726         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2727         touch $DIR/$tdir/$tfile
2728         $LFS getstripe -c $DIR/$tdir/$tfile
2729         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2730                 error "two-stripe file doesn't have two stripes"
2731
2732         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2733         $LFS getstripe -y $DIR/$tdir/$tfile
2734         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2735              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2736                 error "expected l_ost_idx: [02]$ not matched"
2737
2738         # make sure ost list has been cleared
2739         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2740         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2741                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2742         touch $DIR/$tdir/f3
2743         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2744 }
2745 run_test 27H "Set specific OSTs stripe"
2746
2747 test_27I() {
2748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2750         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2751                 skip "Need MDS version newer than 2.12.52"
2752         local pool=$TESTNAME
2753         local ostrange="1 1 1"
2754
2755         save_layout_restore_at_exit $MOUNT
2756         $LFS setstripe -c 2 -i 0 $MOUNT
2757         pool_add $pool || error "pool_add failed"
2758         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2759         test_mkdir $DIR/$tdir
2760         $LFS setstripe -p $pool $DIR/$tdir
2761         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2762         $LFS getstripe $DIR/$tdir/$tfile
2763 }
2764 run_test 27I "check that root dir striping does not break parent dir one"
2765
2766 test_27J() {
2767         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2768                 skip "Need MDS version newer than 2.12.51"
2769
2770         test_mkdir $DIR/$tdir
2771         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2772         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2773
2774         # create foreign file (raw way)
2775         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2776                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2777
2778         ! $LFS setstripe --foreign --flags foo \
2779                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2780                         error "creating $tfile with '--flags foo' should fail"
2781
2782         ! $LFS setstripe --foreign --flags 0xffffffff \
2783                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2784                         error "creating $tfile w/ 0xffffffff flags should fail"
2785
2786         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2787                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2788
2789         # verify foreign file (raw way)
2790         parse_foreign_file -f $DIR/$tdir/$tfile |
2791                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2792                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2793         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2794                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2795         parse_foreign_file -f $DIR/$tdir/$tfile |
2796                 grep "lov_foreign_size: 73" ||
2797                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2798         parse_foreign_file -f $DIR/$tdir/$tfile |
2799                 grep "lov_foreign_type: 1" ||
2800                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2801         parse_foreign_file -f $DIR/$tdir/$tfile |
2802                 grep "lov_foreign_flags: 0x0000DA08" ||
2803                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2804         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2805                 grep "lov_foreign_value: 0x" |
2806                 sed -e 's/lov_foreign_value: 0x//')
2807         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2808         [[ $lov = ${lov2// /} ]] ||
2809                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2810
2811         # create foreign file (lfs + API)
2812         $LFS setstripe --foreign=none --flags 0xda08 \
2813                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2814                 error "$DIR/$tdir/${tfile}2: create failed"
2815
2816         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2817                 grep "lfm_magic:.*0x0BD70BD0" ||
2818                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2819         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2820         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2821                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2822         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2823                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2824         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2825                 grep "lfm_flags:.*0x0000DA08" ||
2826                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2827         $LFS getstripe $DIR/$tdir/${tfile}2 |
2828                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2829                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2830
2831         # modify striping should fail
2832         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2833                 error "$DIR/$tdir/$tfile: setstripe should fail"
2834         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2835                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2836
2837         # R/W should fail
2838         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2839         cat $DIR/$tdir/${tfile}2 &&
2840                 error "$DIR/$tdir/${tfile}2: read should fail"
2841         cat /etc/passwd > $DIR/$tdir/$tfile &&
2842                 error "$DIR/$tdir/$tfile: write should fail"
2843         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2844                 error "$DIR/$tdir/${tfile}2: write should fail"
2845
2846         # chmod should work
2847         chmod 222 $DIR/$tdir/$tfile ||
2848                 error "$DIR/$tdir/$tfile: chmod failed"
2849         chmod 222 $DIR/$tdir/${tfile}2 ||
2850                 error "$DIR/$tdir/${tfile}2: chmod failed"
2851
2852         # chown should work
2853         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2854                 error "$DIR/$tdir/$tfile: chown failed"
2855         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2856                 error "$DIR/$tdir/${tfile}2: chown failed"
2857
2858         # rename should work
2859         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2860                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2861         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2862                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2863
2864         #remove foreign file
2865         rm $DIR/$tdir/${tfile}.new ||
2866                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2867         rm $DIR/$tdir/${tfile}2.new ||
2868                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2869 }
2870 run_test 27J "basic ops on file with foreign LOV"
2871
2872 test_27K() {
2873         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2874                 skip "Need MDS version newer than 2.12.49"
2875
2876         test_mkdir $DIR/$tdir
2877         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2878         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2879
2880         # create foreign dir (raw way)
2881         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2882                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2883
2884         ! $LFS setdirstripe --foreign --flags foo \
2885                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2886                         error "creating $tdir with '--flags foo' should fail"
2887
2888         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2889                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2890                         error "creating $tdir w/ 0xffffffff flags should fail"
2891
2892         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2893                 error "create_foreign_dir FAILED"
2894
2895         # verify foreign dir (raw way)
2896         parse_foreign_dir -d $DIR/$tdir/$tdir |
2897                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2898                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2899         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2900                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2901         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2902                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2903         parse_foreign_dir -d $DIR/$tdir/$tdir |
2904                 grep "lmv_foreign_flags: 55813$" ||
2905                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2906         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2907                 grep "lmv_foreign_value: 0x" |
2908                 sed 's/lmv_foreign_value: 0x//')
2909         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2910                 sed 's/ //g')
2911         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2912
2913         # create foreign dir (lfs + API)
2914         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2915                 $DIR/$tdir/${tdir}2 ||
2916                 error "$DIR/$tdir/${tdir}2: create failed"
2917
2918         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2919                 grep "lfm_magic:.*0x0CD50CD0" ||
2920                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2921         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2922         # - sizeof(lfm_type) - sizeof(lfm_flags)
2923         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2924                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2925         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2926                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2927         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2928                 grep "lfm_flags:.*0x0000DA05" ||
2929                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2930         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2931                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2932                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2933
2934         # file create in dir should fail
2935         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2936         touch $DIR/$tdir/${tdir}2/$tfile &&
2937                 "$DIR/${tdir}2: file create should fail"
2938
2939         # chmod should work
2940         chmod 777 $DIR/$tdir/$tdir ||
2941                 error "$DIR/$tdir: chmod failed"
2942         chmod 777 $DIR/$tdir/${tdir}2 ||
2943                 error "$DIR/${tdir}2: chmod failed"
2944
2945         # chown should work
2946         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2947                 error "$DIR/$tdir: chown failed"
2948         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2949                 error "$DIR/${tdir}2: chown failed"
2950
2951         # rename should work
2952         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2953                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2954         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2955                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2956
2957         #remove foreign dir
2958         rmdir $DIR/$tdir/${tdir}.new ||
2959                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2960         rmdir $DIR/$tdir/${tdir}2.new ||
2961                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2962 }
2963 run_test 27K "basic ops on dir with foreign LMV"
2964
2965 test_27L() {
2966         remote_mds_nodsh && skip "remote MDS with nodsh"
2967
2968         local POOL=${POOL:-$TESTNAME}
2969
2970         pool_add $POOL || error "pool_add failed"
2971
2972         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2973                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2974                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2975 }
2976 run_test 27L "lfs pool_list gives correct pool name"
2977
2978 test_27M() {
2979         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2980                 skip "Need MDS version >= than 2.12.57"
2981         remote_mds_nodsh && skip "remote MDS with nodsh"
2982         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2983
2984         test_mkdir $DIR/$tdir
2985
2986         # Set default striping on directory
2987         $LFS setstripe -C 4 $DIR/$tdir
2988
2989         echo 1 > $DIR/$tdir/${tfile}.1
2990         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2991         local setcount=4
2992         [ $count -eq $setcount ] ||
2993                 error "(1) stripe count $count, should be $setcount"
2994
2995         # Capture existing append_stripe_count setting for restore
2996         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2997         local mdts=$(comma_list $(mdts_nodes))
2998         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2999
3000         local appendcount=$orig_count
3001         echo 1 >> $DIR/$tdir/${tfile}.2_append
3002         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3003         [ $count -eq $appendcount ] ||
3004                 error "(2)stripe count $count, should be $appendcount for append"
3005
3006         # Disable O_APPEND striping, verify it works
3007         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3008
3009         # Should now get the default striping, which is 4
3010         setcount=4
3011         echo 1 >> $DIR/$tdir/${tfile}.3_append
3012         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3013         [ $count -eq $setcount ] ||
3014                 error "(3) stripe count $count, should be $setcount"
3015
3016         # Try changing the stripe count for append files
3017         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3018
3019         # Append striping is now 2 (directory default is still 4)
3020         appendcount=2
3021         echo 1 >> $DIR/$tdir/${tfile}.4_append
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3023         [ $count -eq $appendcount ] ||
3024                 error "(4) stripe count $count, should be $appendcount for append"
3025
3026         # Test append stripe count of -1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3028         appendcount=$OSTCOUNT
3029         echo 1 >> $DIR/$tdir/${tfile}.5
3030         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3031         [ $count -eq $appendcount ] ||
3032                 error "(5) stripe count $count, should be $appendcount for append"
3033
3034         # Set append striping back to default of 1
3035         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3036
3037         # Try a new default striping, PFL + DOM
3038         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3039
3040         # Create normal DOM file, DOM returns stripe count == 0
3041         setcount=0
3042         touch $DIR/$tdir/${tfile}.6
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3044         [ $count -eq $setcount ] ||
3045                 error "(6) stripe count $count, should be $setcount"
3046
3047         # Show
3048         appendcount=1
3049         echo 1 >> $DIR/$tdir/${tfile}.7_append
3050         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3051         [ $count -eq $appendcount ] ||
3052                 error "(7) stripe count $count, should be $appendcount for append"
3053
3054         # Clean up DOM layout
3055         $LFS setstripe -d $DIR/$tdir
3056
3057         # Now test that append striping works when layout is from root
3058         $LFS setstripe -c 2 $MOUNT
3059         # Make a special directory for this
3060         mkdir $DIR/${tdir}/${tdir}.2
3061         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3062
3063         # Verify for normal file
3064         setcount=2
3065         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3066         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3067         [ $count -eq $setcount ] ||
3068                 error "(8) stripe count $count, should be $setcount"
3069
3070         appendcount=1
3071         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3072         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3073         [ $count -eq $appendcount ] ||
3074                 error "(9) stripe count $count, should be $appendcount for append"
3075
3076         # Now test O_APPEND striping with pools
3077         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3078         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3079
3080         # Create the pool
3081         pool_add $TESTNAME || error "pool creation failed"
3082         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3083
3084         echo 1 >> $DIR/$tdir/${tfile}.10_append
3085
3086         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3087         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3088
3089         # Check that count is still correct
3090         appendcount=1
3091         echo 1 >> $DIR/$tdir/${tfile}.11_append
3092         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3093         [ $count -eq $appendcount ] ||
3094                 error "(11) stripe count $count, should be $appendcount for append"
3095
3096         # Disable O_APPEND stripe count, verify pool works separately
3097         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3098
3099         echo 1 >> $DIR/$tdir/${tfile}.12_append
3100
3101         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3102         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3103
3104         # Remove pool setting, verify it's not applied
3105         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.13_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3110         [ "$pool" = "" ] || error "(13) pool found: $pool"
3111 }
3112 run_test 27M "test O_APPEND striping"
3113
3114 test_27N() {
3115         combined_mgs_mds && skip "needs separate MGS/MDT"
3116
3117         pool_add $TESTNAME || error "pool_add failed"
3118         do_facet mgs "$LCTL pool_list $FSNAME" |
3119                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3120                 error "lctl pool_list on MGS failed"
3121 }
3122 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3123
3124 clean_foreign_symlink() {
3125         trap 0
3126         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3127         for i in $DIR/$tdir/* ; do
3128                 $LFS unlink_foreign $i || true
3129         done
3130 }
3131
3132 test_27O() {
3133         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3134                 skip "Need MDS version newer than 2.12.51"
3135
3136         test_mkdir $DIR/$tdir
3137         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3138         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3139
3140         trap clean_foreign_symlink EXIT
3141
3142         # enable foreign_symlink behaviour
3143         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3144
3145         # foreign symlink LOV format is a partial path by default
3146
3147         # create foreign file (lfs + API)
3148         $LFS setstripe --foreign=symlink --flags 0xda05 \
3149                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3150                 error "$DIR/$tdir/${tfile}: create failed"
3151
3152         $LFS getstripe -v $DIR/$tdir/${tfile} |
3153                 grep "lfm_magic:.*0x0BD70BD0" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3155         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3156                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3157         $LFS getstripe -v $DIR/$tdir/${tfile} |
3158                 grep "lfm_flags:.*0x0000DA05" ||
3159                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3160         $LFS getstripe $DIR/$tdir/${tfile} |
3161                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3163
3164         # modify striping should fail
3165         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3166                 error "$DIR/$tdir/$tfile: setstripe should fail"
3167
3168         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3169         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3170         cat /etc/passwd > $DIR/$tdir/$tfile &&
3171                 error "$DIR/$tdir/$tfile: write should fail"
3172
3173         # rename should succeed
3174         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3175                 error "$DIR/$tdir/$tfile: rename has failed"
3176
3177         #remove foreign_symlink file should fail
3178         rm $DIR/$tdir/${tfile}.new &&
3179                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3180
3181         #test fake symlink
3182         mkdir /tmp/${uuid1} ||
3183                 error "/tmp/${uuid1}: mkdir has failed"
3184         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3185                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3186         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3187         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3188                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3189         #read should succeed now
3190         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3191                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3192         #write should succeed now
3193         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3195         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3197         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3198                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3199
3200         #check that getstripe still works
3201         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3203
3204         # chmod should still succeed
3205         chmod 644 $DIR/$tdir/${tfile}.new ||
3206                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3207
3208         # chown should still succeed
3209         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3211
3212         # rename should still succeed
3213         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3214                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3215
3216         #remove foreign_symlink file should still fail
3217         rm $DIR/$tdir/${tfile} &&
3218                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3219
3220         #use special ioctl() to unlink foreign_symlink file
3221         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3222                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3223
3224 }
3225 run_test 27O "basic ops on foreign file of symlink type"
3226
3227 test_27P() {
3228         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3229                 skip "Need MDS version newer than 2.12.49"
3230
3231         test_mkdir $DIR/$tdir
3232         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3233         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3234
3235         trap clean_foreign_symlink EXIT
3236
3237         # enable foreign_symlink behaviour
3238         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3239
3240         # foreign symlink LMV format is a partial path by default
3241
3242         # create foreign dir (lfs + API)
3243         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3244                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3245                 error "$DIR/$tdir/${tdir}: create failed"
3246
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3248                 grep "lfm_magic:.*0x0CD50CD0" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3250         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3251                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3252         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3253                 grep "lfm_flags:.*0x0000DA05" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3255         $LFS getdirstripe $DIR/$tdir/${tdir} |
3256                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3258
3259         # file create in dir should fail
3260         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3261         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3262
3263         # rename should succeed
3264         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3265                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3266
3267         #remove foreign_symlink dir should fail
3268         rmdir $DIR/$tdir/${tdir}.new &&
3269                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3270
3271         #test fake symlink
3272         mkdir -p /tmp/${uuid1}/${uuid2} ||
3273                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3274         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3275                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3276         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3277         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3278                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3279         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3280                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3281
3282         #check that getstripe fails now that foreign_symlink enabled
3283         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3284                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3285
3286         # file create in dir should work now
3287         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3288                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3289         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3290                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3291         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3292                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3293
3294         # chmod should still succeed
3295         chmod 755 $DIR/$tdir/${tdir}.new ||
3296                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3297
3298         # chown should still succeed
3299         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3300                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3301
3302         # rename should still succeed
3303         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3305
3306         #remove foreign_symlink dir should still fail
3307         rmdir $DIR/$tdir/${tdir} &&
3308                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3309
3310         #use special ioctl() to unlink foreign_symlink file
3311         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3312                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3313
3314         #created file should still exist
3315         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3316                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3317         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3318                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3319 }
3320 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3321
3322 # createtest also checks that device nodes are created and
3323 # then visible correctly (#2091)
3324 test_28() { # bug 2091
3325         test_mkdir $DIR/d28
3326         $CREATETEST $DIR/d28/ct || error "createtest failed"
3327 }
3328 run_test 28 "create/mknod/mkdir with bad file types ============"
3329
3330 test_29() {
3331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3332
3333         sync; sleep 1; sync # flush out any dirty pages from previous tests
3334         cancel_lru_locks
3335         test_mkdir $DIR/d29
3336         touch $DIR/d29/foo
3337         log 'first d29'
3338         ls -l $DIR/d29
3339
3340         declare -i LOCKCOUNTORIG=0
3341         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3342                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3343         done
3344         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3345
3346         declare -i LOCKUNUSEDCOUNTORIG=0
3347         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3348                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3349         done
3350
3351         log 'second d29'
3352         ls -l $DIR/d29
3353         log 'done'
3354
3355         declare -i LOCKCOUNTCURRENT=0
3356         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3357                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3358         done
3359
3360         declare -i LOCKUNUSEDCOUNTCURRENT=0
3361         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3362                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3363         done
3364
3365         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3366                 $LCTL set_param -n ldlm.dump_namespaces ""
3367                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3368                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3369                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3370                 return 2
3371         fi
3372         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3373                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3374                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3375                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3376                 return 3
3377         fi
3378 }
3379 run_test 29 "IT_GETATTR regression  ============================"
3380
3381 test_30a() { # was test_30
3382         cp $(which ls) $DIR || cp /bin/ls $DIR
3383         $DIR/ls / || error "Can't execute binary from lustre"
3384         rm $DIR/ls
3385 }
3386 run_test 30a "execute binary from Lustre (execve) =============="
3387
3388 test_30b() {
3389         cp `which ls` $DIR || cp /bin/ls $DIR
3390         chmod go+rx $DIR/ls
3391         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3392         rm $DIR/ls
3393 }
3394 run_test 30b "execute binary from Lustre as non-root ==========="
3395
3396 test_30c() { # b=22376
3397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3398
3399         cp $(which ls) $DIR || cp /bin/ls $DIR
3400         chmod a-rw $DIR/ls
3401         cancel_lru_locks mdc
3402         cancel_lru_locks osc
3403         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3404         rm -f $DIR/ls
3405 }
3406 run_test 30c "execute binary from Lustre without read perms ===="
3407
3408 test_30d() {
3409         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3410
3411         for i in {1..10}; do
3412                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3413                 local PID=$!
3414                 sleep 1
3415                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3416                 wait $PID || error "executing dd from Lustre failed"
3417                 rm -f $DIR/$tfile
3418         done
3419
3420         rm -f $DIR/dd
3421 }
3422 run_test 30d "execute binary from Lustre while clear locks"
3423
3424 test_31a() {
3425         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3426         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3427 }
3428 run_test 31a "open-unlink file =================================="
3429
3430 test_31b() {
3431         touch $DIR/f31 || error "touch $DIR/f31 failed"
3432         ln $DIR/f31 $DIR/f31b || error "ln failed"
3433         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3434         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3435 }
3436 run_test 31b "unlink file with multiple links while open ======="
3437
3438 test_31c() {
3439         touch $DIR/f31 || error "touch $DIR/f31 failed"
3440         ln $DIR/f31 $DIR/f31c || error "ln failed"
3441         multiop_bg_pause $DIR/f31 O_uc ||
3442                 error "multiop_bg_pause for $DIR/f31 failed"
3443         MULTIPID=$!
3444         $MULTIOP $DIR/f31c Ouc
3445         kill -USR1 $MULTIPID
3446         wait $MULTIPID
3447 }
3448 run_test 31c "open-unlink file with multiple links ============="
3449
3450 test_31d() {
3451         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3452         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3453 }
3454 run_test 31d "remove of open directory ========================="
3455
3456 test_31e() { # bug 2904
3457         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3458 }
3459 run_test 31e "remove of open non-empty directory ==============="
3460
3461 test_31f() { # bug 4554
3462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3463
3464         set -vx
3465         test_mkdir $DIR/d31f
3466         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3467         cp /etc/hosts $DIR/d31f
3468         ls -l $DIR/d31f
3469         $LFS getstripe $DIR/d31f/hosts
3470         multiop_bg_pause $DIR/d31f D_c || return 1
3471         MULTIPID=$!
3472
3473         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3474         test_mkdir $DIR/d31f
3475         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3476         cp /etc/hosts $DIR/d31f
3477         ls -l $DIR/d31f
3478         $LFS getstripe $DIR/d31f/hosts
3479         multiop_bg_pause $DIR/d31f D_c || return 1
3480         MULTIPID2=$!
3481
3482         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3483         wait $MULTIPID || error "first opendir $MULTIPID failed"
3484
3485         sleep 6
3486
3487         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3488         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3489         set +vx
3490 }
3491 run_test 31f "remove of open directory with open-unlink file ==="
3492
3493 test_31g() {
3494         echo "-- cross directory link --"
3495         test_mkdir -c1 $DIR/${tdir}ga
3496         test_mkdir -c1 $DIR/${tdir}gb
3497         touch $DIR/${tdir}ga/f
3498         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3499         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3500         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3501         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3502         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3503 }
3504 run_test 31g "cross directory link==============="
3505
3506 test_31h() {
3507         echo "-- cross directory link --"
3508         test_mkdir -c1 $DIR/${tdir}
3509         test_mkdir -c1 $DIR/${tdir}/dir
3510         touch $DIR/${tdir}/f
3511         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3512         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3513         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3514         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3515         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3516 }
3517 run_test 31h "cross directory link under child==============="
3518
3519 test_31i() {
3520         echo "-- cross directory link --"
3521         test_mkdir -c1 $DIR/$tdir
3522         test_mkdir -c1 $DIR/$tdir/dir
3523         touch $DIR/$tdir/dir/f
3524         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3525         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3526         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3527         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3528         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3529 }
3530 run_test 31i "cross directory link under parent==============="
3531
3532 test_31j() {
3533         test_mkdir -c1 -p $DIR/$tdir
3534         test_mkdir -c1 -p $DIR/$tdir/dir1
3535         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3536         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3537         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3538         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3539         return 0
3540 }
3541 run_test 31j "link for directory==============="
3542
3543 test_31k() {
3544         test_mkdir -c1 -p $DIR/$tdir
3545         touch $DIR/$tdir/s
3546         touch $DIR/$tdir/exist
3547         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3548         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3549         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3550         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3551         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3552         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3553         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3554         return 0
3555 }
3556 run_test 31k "link to file: the same, non-existing, dir==============="
3557
3558 test_31m() {
3559         mkdir $DIR/d31m
3560         touch $DIR/d31m/s
3561         mkdir $DIR/d31m2
3562         touch $DIR/d31m2/exist
3563         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3564         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3565         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3566         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3567         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3568         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3569         return 0
3570 }
3571 run_test 31m "link to file: the same, non-existing, dir==============="
3572
3573 test_31n() {
3574         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3575         nlink=$(stat --format=%h $DIR/$tfile)
3576         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3577         local fd=$(free_fd)
3578         local cmd="exec $fd<$DIR/$tfile"
3579         eval $cmd
3580         cmd="exec $fd<&-"
3581         trap "eval $cmd" EXIT
3582         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3583         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3584         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3585         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3586         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3587         eval $cmd
3588 }
3589 run_test 31n "check link count of unlinked file"
3590
3591 link_one() {
3592         local tempfile=$(mktemp $1_XXXXXX)
3593         mlink $tempfile $1 2> /dev/null &&
3594                 echo "$BASHPID: link $tempfile to $1 succeeded"
3595         munlink $tempfile
3596 }
3597
3598 test_31o() { # LU-2901
3599         test_mkdir $DIR/$tdir
3600         for LOOP in $(seq 100); do
3601                 rm -f $DIR/$tdir/$tfile*
3602                 for THREAD in $(seq 8); do
3603                         link_one $DIR/$tdir/$tfile.$LOOP &
3604                 done
3605                 wait
3606                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3607                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3608                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3609                         break || true
3610         done
3611 }
3612 run_test 31o "duplicate hard links with same filename"
3613
3614 test_31p() {
3615         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3616
3617         test_mkdir $DIR/$tdir
3618         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3619         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3620
3621         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3622                 error "open unlink test1 failed"
3623         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3624                 error "open unlink test2 failed"
3625
3626         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3627                 error "test1 still exists"
3628         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3629                 error "test2 still exists"
3630 }
3631 run_test 31p "remove of open striped directory"
3632
3633 test_31q() {
3634         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3635
3636         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3637         index=$($LFS getdirstripe -i $DIR/$tdir)
3638         [ $index -eq 3 ] || error "first stripe index $index != 3"
3639         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3640         [ $index -eq 1 ] || error "second stripe index $index != 1"
3641
3642         # when "-c <stripe_count>" is set, the number of MDTs specified after
3643         # "-i" should equal to the stripe count
3644         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3645 }
3646 run_test 31q "create striped directory on specific MDTs"
3647
3648 cleanup_test32_mount() {
3649         local rc=0
3650         trap 0
3651         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3652         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3653         losetup -d $loopdev || true
3654         rm -rf $DIR/$tdir
3655         return $rc
3656 }
3657
3658 test_32a() {
3659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3660
3661         echo "== more mountpoints and symlinks ================="
3662         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3663         trap cleanup_test32_mount EXIT
3664         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3665         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3666                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3667         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3668                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3669         cleanup_test32_mount
3670 }
3671 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3672
3673 test_32b() {
3674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3675
3676         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3677         trap cleanup_test32_mount EXIT
3678         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3679         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3680                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3681         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3682                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3683         cleanup_test32_mount
3684 }
3685 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3686
3687 test_32c() {
3688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3689
3690         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3691         trap cleanup_test32_mount EXIT
3692         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3693         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3694                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3695         test_mkdir -p $DIR/$tdir/d2/test_dir
3696         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3697                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3698         cleanup_test32_mount
3699 }
3700 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3701
3702 test_32d() {
3703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3704
3705         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3706         trap cleanup_test32_mount EXIT
3707         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3708         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3709                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3710         test_mkdir -p $DIR/$tdir/d2/test_dir
3711         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3712                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3713         cleanup_test32_mount
3714 }
3715 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3716
3717 test_32e() {
3718         rm -fr $DIR/$tdir
3719         test_mkdir -p $DIR/$tdir/tmp
3720         local tmp_dir=$DIR/$tdir/tmp
3721         ln -s $DIR/$tdir $tmp_dir/symlink11
3722         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3723         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3724         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3725 }
3726 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3727
3728 test_32f() {
3729         rm -fr $DIR/$tdir
3730         test_mkdir -p $DIR/$tdir/tmp
3731         local tmp_dir=$DIR/$tdir/tmp
3732         ln -s $DIR/$tdir $tmp_dir/symlink11
3733         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3734         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3735         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3736 }
3737 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3738
3739 test_32g() {
3740         local tmp_dir=$DIR/$tdir/tmp
3741         test_mkdir -p $tmp_dir
3742         test_mkdir $DIR/${tdir}2
3743         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3744         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3745         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3746         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3747         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3748         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3749 }
3750 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3751
3752 test_32h() {
3753         rm -fr $DIR/$tdir $DIR/${tdir}2
3754         tmp_dir=$DIR/$tdir/tmp
3755         test_mkdir -p $tmp_dir
3756         test_mkdir $DIR/${tdir}2
3757         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3758         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3759         ls $tmp_dir/symlink12 || error "listing symlink12"
3760         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3761 }
3762 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3763
3764 test_32i() {
3765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3766
3767         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3768         trap cleanup_test32_mount EXIT
3769         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3770         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3771                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3772         touch $DIR/$tdir/test_file
3773         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3774                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3775         cleanup_test32_mount
3776 }
3777 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3778
3779 test_32j() {
3780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3781
3782         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3783         trap cleanup_test32_mount EXIT
3784         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3785         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3786                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3787         touch $DIR/$tdir/test_file
3788         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3789                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3790         cleanup_test32_mount
3791 }
3792 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3793
3794 test_32k() {
3795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3796
3797         rm -fr $DIR/$tdir
3798         trap cleanup_test32_mount EXIT
3799         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3800         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3801                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3802         test_mkdir -p $DIR/$tdir/d2
3803         touch $DIR/$tdir/d2/test_file || error "touch failed"
3804         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3805                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3806         cleanup_test32_mount
3807 }
3808 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3809
3810 test_32l() {
3811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3812
3813         rm -fr $DIR/$tdir
3814         trap cleanup_test32_mount EXIT
3815         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3816         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3817                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3818         test_mkdir -p $DIR/$tdir/d2
3819         touch $DIR/$tdir/d2/test_file || error "touch failed"
3820         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3821                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3822         cleanup_test32_mount
3823 }
3824 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3825
3826 test_32m() {
3827         rm -fr $DIR/d32m
3828         test_mkdir -p $DIR/d32m/tmp
3829         TMP_DIR=$DIR/d32m/tmp
3830         ln -s $DIR $TMP_DIR/symlink11
3831         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3832         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3833                 error "symlink11 not a link"
3834         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3835                 error "symlink01 not a link"
3836 }
3837 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3838
3839 test_32n() {
3840         rm -fr $DIR/d32n
3841         test_mkdir -p $DIR/d32n/tmp
3842         TMP_DIR=$DIR/d32n/tmp
3843         ln -s $DIR $TMP_DIR/symlink11
3844         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3845         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3846         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3847 }
3848 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3849
3850 test_32o() {
3851         touch $DIR/$tfile
3852         test_mkdir -p $DIR/d32o/tmp
3853         TMP_DIR=$DIR/d32o/tmp
3854         ln -s $DIR/$tfile $TMP_DIR/symlink12
3855         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3856         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3857                 error "symlink12 not a link"
3858         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3859         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3860                 error "$DIR/d32o/tmp/symlink12 not file type"
3861         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3862                 error "$DIR/d32o/symlink02 not file type"
3863 }
3864 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3865
3866 test_32p() {
3867         log 32p_1
3868         rm -fr $DIR/d32p
3869         log 32p_2
3870         rm -f $DIR/$tfile
3871         log 32p_3
3872         touch $DIR/$tfile
3873         log 32p_4
3874         test_mkdir -p $DIR/d32p/tmp
3875         log 32p_5
3876         TMP_DIR=$DIR/d32p/tmp
3877         log 32p_6
3878         ln -s $DIR/$tfile $TMP_DIR/symlink12
3879         log 32p_7
3880         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3881         log 32p_8
3882         cat $DIR/d32p/tmp/symlink12 ||
3883                 error "Can't open $DIR/d32p/tmp/symlink12"
3884         log 32p_9
3885         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3886         log 32p_10
3887 }
3888 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3889
3890 test_32q() {
3891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3892
3893         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3894         trap cleanup_test32_mount EXIT
3895         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3896         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3897         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3898                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3899         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3900         cleanup_test32_mount
3901 }
3902 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3903
3904 test_32r() {
3905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3906
3907         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3908         trap cleanup_test32_mount EXIT
3909         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3910         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3911         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3912                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3913         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3914         cleanup_test32_mount
3915 }
3916 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3917
3918 test_33aa() {
3919         rm -f $DIR/$tfile
3920         touch $DIR/$tfile
3921         chmod 444 $DIR/$tfile
3922         chown $RUNAS_ID $DIR/$tfile
3923         log 33_1
3924         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3925         log 33_2
3926 }
3927 run_test 33aa "write file with mode 444 (should return error)"
3928
3929 test_33a() {
3930         rm -fr $DIR/$tdir
3931         test_mkdir $DIR/$tdir
3932         chown $RUNAS_ID $DIR/$tdir
3933         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3934                 error "$RUNAS create $tdir/$tfile failed"
3935         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3936                 error "open RDWR" || true
3937 }
3938 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3939
3940 test_33b() {
3941         rm -fr $DIR/$tdir
3942         test_mkdir $DIR/$tdir
3943         chown $RUNAS_ID $DIR/$tdir
3944         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3945 }
3946 run_test 33b "test open file with malformed flags (No panic)"
3947
3948 test_33c() {
3949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3950         remote_ost_nodsh && skip "remote OST with nodsh"
3951
3952         local ostnum
3953         local ostname
3954         local write_bytes
3955         local all_zeros
3956
3957         all_zeros=:
3958         rm -fr $DIR/$tdir
3959         test_mkdir $DIR/$tdir
3960         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3961
3962         sync
3963         for ostnum in $(seq $OSTCOUNT); do
3964                 # test-framework's OST numbering is one-based, while Lustre's
3965                 # is zero-based
3966                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3967                 # Parsing llobdstat's output sucks; we could grep the /proc
3968                 # path, but that's likely to not be as portable as using the
3969                 # llobdstat utility.  So we parse lctl output instead.
3970                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3971                         obdfilter/$ostname/stats |
3972                         awk '/^write_bytes/ {print $7}' )
3973                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3974                 if (( ${write_bytes:-0} > 0 ))
3975                 then
3976                         all_zeros=false
3977                         break;
3978                 fi
3979         done
3980
3981         $all_zeros || return 0
3982
3983         # Write four bytes
3984         echo foo > $DIR/$tdir/bar
3985         # Really write them
3986         sync
3987
3988         # Total up write_bytes after writing.  We'd better find non-zeros.
3989         for ostnum in $(seq $OSTCOUNT); do
3990                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3991                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3992                         obdfilter/$ostname/stats |
3993                         awk '/^write_bytes/ {print $7}' )
3994                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3995                 if (( ${write_bytes:-0} > 0 ))
3996                 then
3997                         all_zeros=false
3998                         break;
3999                 fi
4000         done
4001
4002         if $all_zeros
4003         then
4004                 for ostnum in $(seq $OSTCOUNT); do
4005                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4006                         echo "Check that write_bytes is present in obdfilter/*/stats:"
4007                         do_facet ost$ostnum lctl get_param -n \
4008                                 obdfilter/$ostname/stats
4009                 done
4010                 error "OST not keeping write_bytes stats (b22312)"
4011         fi
4012 }
4013 run_test 33c "test llobdstat and write_bytes"
4014
4015 test_33d() {
4016         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4018
4019         local MDTIDX=1
4020         local remote_dir=$DIR/$tdir/remote_dir
4021
4022         test_mkdir $DIR/$tdir
4023         $LFS mkdir -i $MDTIDX $remote_dir ||
4024                 error "create remote directory failed"
4025
4026         touch $remote_dir/$tfile
4027         chmod 444 $remote_dir/$tfile
4028         chown $RUNAS_ID $remote_dir/$tfile
4029
4030         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4031
4032         chown $RUNAS_ID $remote_dir
4033         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4034                                         error "create" || true
4035         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4036                                     error "open RDWR" || true
4037         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4038 }
4039 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4040
4041 test_33e() {
4042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4043
4044         mkdir $DIR/$tdir
4045
4046         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4047         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4048         mkdir $DIR/$tdir/local_dir
4049
4050         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4051         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4052         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4053
4054         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4055                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4056
4057         rmdir $DIR/$tdir/* || error "rmdir failed"
4058
4059         umask 777
4060         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4061         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4062         mkdir $DIR/$tdir/local_dir
4063
4064         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4065         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4066         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4067
4068         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4069                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4070
4071         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4072
4073         umask 000
4074         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4075         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4076         mkdir $DIR/$tdir/local_dir
4077
4078         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4079         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4080         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4081
4082         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4083                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4084 }
4085 run_test 33e "mkdir and striped directory should have same mode"
4086
4087 cleanup_33f() {
4088         trap 0
4089         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4090 }
4091
4092 test_33f() {
4093         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4094         remote_mds_nodsh && skip "remote MDS with nodsh"
4095
4096         mkdir $DIR/$tdir
4097         chmod go+rwx $DIR/$tdir
4098         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4099         trap cleanup_33f EXIT
4100
4101         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4102                 error "cannot create striped directory"
4103
4104         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4105                 error "cannot create files in striped directory"
4106
4107         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4108                 error "cannot remove files in striped directory"
4109
4110         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4111                 error "cannot remove striped directory"
4112
4113         cleanup_33f
4114 }
4115 run_test 33f "nonroot user can create, access, and remove a striped directory"
4116
4117 test_33g() {
4118         mkdir -p $DIR/$tdir/dir2
4119
4120         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4121         echo $err
4122         [[ $err =~ "exists" ]] || error "Not exists error"
4123 }
4124 run_test 33g "nonroot user create already existing root created file"
4125
4126 test_33h() {
4127         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4128         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4129                 skip "Need MDS version at least 2.13.50"
4130
4131         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4132                 error "mkdir $tdir failed"
4133         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4134
4135         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4136         local index2
4137
4138         for fname in $DIR/$tdir/$tfile.bak \
4139                      $DIR/$tdir/$tfile.SAV \
4140                      $DIR/$tdir/$tfile.orig \
4141                      $DIR/$tdir/$tfile~; do
4142                 touch $fname  || error "touch $fname failed"
4143                 index2=$($LFS getstripe -m $fname)
4144                 [ $index -eq $index2 ] ||
4145                         error "$fname MDT index mismatch $index != $index2"
4146         done
4147
4148         local failed=0
4149         for i in {1..250}; do
4150                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4151                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4152                         touch $fname  || error "touch $fname failed"
4153                         index2=$($LFS getstripe -m $fname)
4154                         if [[ $index != $index2 ]]; then
4155                                 failed=$((failed + 1))
4156                                 echo "$fname MDT index mismatch $index != $index2"
4157                         fi
4158                 done
4159         done
4160         echo "$failed MDT index mismatches"
4161         (( failed < 20 )) || error "MDT index mismatch $failed times"
4162
4163 }
4164 run_test 33h "temp file is located on the same MDT as target"
4165
4166 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4167 test_34a() {
4168         rm -f $DIR/f34
4169         $MCREATE $DIR/f34 || error "mcreate failed"
4170         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4171                 error "getstripe failed"
4172         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4173         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4174                 error "getstripe failed"
4175         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4176                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4177 }
4178 run_test 34a "truncate file that has not been opened ==========="
4179
4180 test_34b() {
4181         [ ! -f $DIR/f34 ] && test_34a
4182         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4183                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4184         $OPENFILE -f O_RDONLY $DIR/f34
4185         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4186                 error "getstripe failed"
4187         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4188                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4189 }
4190 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4191
4192 test_34c() {
4193         [ ! -f $DIR/f34 ] && test_34a
4194         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4195                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4196         $OPENFILE -f O_RDWR $DIR/f34
4197         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4198                 error "$LFS getstripe failed"
4199         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4200                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4201 }
4202 run_test 34c "O_RDWR opening file-with-size works =============="
4203
4204 test_34d() {
4205         [ ! -f $DIR/f34 ] && test_34a
4206         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4207                 error "dd failed"
4208         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4209                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4210         rm $DIR/f34
4211 }
4212 run_test 34d "write to sparse file ============================="
4213
4214 test_34e() {
4215         rm -f $DIR/f34e
4216         $MCREATE $DIR/f34e || error "mcreate failed"
4217         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4218         $CHECKSTAT -s 1000 $DIR/f34e ||
4219                 error "Size of $DIR/f34e not equal to 1000 bytes"
4220         $OPENFILE -f O_RDWR $DIR/f34e
4221         $CHECKSTAT -s 1000 $DIR/f34e ||
4222                 error "Size of $DIR/f34e not equal to 1000 bytes"
4223 }
4224 run_test 34e "create objects, some with size and some without =="
4225
4226 test_34f() { # bug 6242, 6243
4227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4228
4229         SIZE34F=48000
4230         rm -f $DIR/f34f
4231         $MCREATE $DIR/f34f || error "mcreate failed"
4232         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4233         dd if=$DIR/f34f of=$TMP/f34f
4234         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4235         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4236         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4237         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4238         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4239 }
4240 run_test 34f "read from a file with no objects until EOF ======="
4241
4242 test_34g() {
4243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4244
4245         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4246                 error "dd failed"
4247         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4248         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4249                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4250         cancel_lru_locks osc
4251         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4252                 error "wrong size after lock cancel"
4253
4254         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4255         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4256                 error "expanding truncate failed"
4257         cancel_lru_locks osc
4258         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4259                 error "wrong expanded size after lock cancel"
4260 }
4261 run_test 34g "truncate long file ==============================="
4262
4263 test_34h() {
4264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4265
4266         local gid=10
4267         local sz=1000
4268
4269         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4270         sync # Flush the cache so that multiop below does not block on cache
4271              # flush when getting the group lock
4272         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4273         MULTIPID=$!
4274
4275         # Since just timed wait is not good enough, let's do a sync write
4276         # that way we are sure enough time for a roundtrip + processing
4277         # passed + 2 seconds of extra margin.
4278         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4279         rm $DIR/${tfile}-1
4280         sleep 2
4281
4282         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4283                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4284                 kill -9 $MULTIPID
4285         fi
4286         wait $MULTIPID
4287         local nsz=`stat -c %s $DIR/$tfile`
4288         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4289 }
4290 run_test 34h "ftruncate file under grouplock should not block"
4291
4292 test_35a() {
4293         cp /bin/sh $DIR/f35a
4294         chmod 444 $DIR/f35a
4295         chown $RUNAS_ID $DIR/f35a
4296         $RUNAS $DIR/f35a && error || true
4297         rm $DIR/f35a
4298 }
4299 run_test 35a "exec file with mode 444 (should return and not leak)"
4300
4301 test_36a() {
4302         rm -f $DIR/f36
4303         utime $DIR/f36 || error "utime failed for MDS"
4304 }
4305 run_test 36a "MDS utime check (mknod, utime)"
4306
4307 test_36b() {
4308         echo "" > $DIR/f36
4309         utime $DIR/f36 || error "utime failed for OST"
4310 }
4311 run_test 36b "OST utime check (open, utime)"
4312
4313 test_36c() {
4314         rm -f $DIR/d36/f36
4315         test_mkdir $DIR/d36
4316         chown $RUNAS_ID $DIR/d36
4317         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4318 }
4319 run_test 36c "non-root MDS utime check (mknod, utime)"
4320
4321 test_36d() {
4322         [ ! -d $DIR/d36 ] && test_36c
4323         echo "" > $DIR/d36/f36
4324         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4325 }
4326 run_test 36d "non-root OST utime check (open, utime)"
4327
4328 test_36e() {
4329         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4330
4331         test_mkdir $DIR/$tdir
4332         touch $DIR/$tdir/$tfile
4333         $RUNAS utime $DIR/$tdir/$tfile &&
4334                 error "utime worked, expected failure" || true
4335 }
4336 run_test 36e "utime on non-owned file (should return error)"
4337
4338 subr_36fh() {
4339         local fl="$1"
4340         local LANG_SAVE=$LANG
4341         local LC_LANG_SAVE=$LC_LANG
4342         export LANG=C LC_LANG=C # for date language
4343
4344         DATESTR="Dec 20  2000"
4345         test_mkdir $DIR/$tdir
4346         lctl set_param fail_loc=$fl
4347         date; date +%s
4348         cp /etc/hosts $DIR/$tdir/$tfile
4349         sync & # write RPC generated with "current" inode timestamp, but delayed
4350         sleep 1
4351         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4352         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4353         cancel_lru_locks $OSC
4354         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4355         date; date +%s
4356         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4357                 echo "BEFORE: $LS_BEFORE" && \
4358                 echo "AFTER : $LS_AFTER" && \
4359                 echo "WANT  : $DATESTR" && \
4360                 error "$DIR/$tdir/$tfile timestamps changed" || true
4361
4362         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4363 }
4364
4365 test_36f() {
4366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4367
4368         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4369         subr_36fh "0x80000214"
4370 }
4371 run_test 36f "utime on file racing with OST BRW write =========="
4372
4373 test_36g() {
4374         remote_ost_nodsh && skip "remote OST with nodsh"
4375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4376         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4377                 skip "Need MDS version at least 2.12.51"
4378
4379         local fmd_max_age
4380         local fmd
4381         local facet="ost1"
4382         local tgt="obdfilter"
4383
4384         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4385
4386         test_mkdir $DIR/$tdir
4387         fmd_max_age=$(do_facet $facet \
4388                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4389                 head -n 1")
4390
4391         echo "FMD max age: ${fmd_max_age}s"
4392         touch $DIR/$tdir/$tfile
4393         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4394                 gawk '{cnt=cnt+$1}  END{print cnt}')
4395         echo "FMD before: $fmd"
4396         [[ $fmd == 0 ]] &&
4397                 error "FMD wasn't create by touch"
4398         sleep $((fmd_max_age + 12))
4399         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4400                 gawk '{cnt=cnt+$1}  END{print cnt}')
4401         echo "FMD after: $fmd"
4402         [[ $fmd == 0 ]] ||
4403                 error "FMD wasn't expired by ping"
4404 }
4405 run_test 36g "FMD cache expiry ====================="
4406
4407 test_36h() {
4408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4409
4410         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4411         subr_36fh "0x80000227"
4412 }
4413 run_test 36h "utime on file racing with OST BRW write =========="
4414
4415 test_36i() {
4416         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4417
4418         test_mkdir $DIR/$tdir
4419         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4420
4421         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4422         local new_mtime=$((mtime + 200))
4423
4424         #change Modify time of striped dir
4425         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4426                         error "change mtime failed"
4427
4428         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4429
4430         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4431 }
4432 run_test 36i "change mtime on striped directory"
4433
4434 # test_37 - duplicate with tests 32q 32r
4435
4436 test_38() {
4437         local file=$DIR/$tfile
4438         touch $file
4439         openfile -f O_DIRECTORY $file
4440         local RC=$?
4441         local ENOTDIR=20
4442         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4443         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4444 }
4445 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4446
4447 test_39a() { # was test_39
4448         touch $DIR/$tfile
4449         touch $DIR/${tfile}2
4450 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4451 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4452 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4453         sleep 2
4454         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4455         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4456                 echo "mtime"
4457                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4458                 echo "atime"
4459                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4460                 echo "ctime"
4461                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4462                 error "O_TRUNC didn't change timestamps"
4463         fi
4464 }
4465 run_test 39a "mtime changed on create"
4466
4467 test_39b() {
4468         test_mkdir -c1 $DIR/$tdir
4469         cp -p /etc/passwd $DIR/$tdir/fopen
4470         cp -p /etc/passwd $DIR/$tdir/flink
4471         cp -p /etc/passwd $DIR/$tdir/funlink
4472         cp -p /etc/passwd $DIR/$tdir/frename
4473         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4474
4475         sleep 1
4476         echo "aaaaaa" >> $DIR/$tdir/fopen
4477         echo "aaaaaa" >> $DIR/$tdir/flink
4478         echo "aaaaaa" >> $DIR/$tdir/funlink
4479         echo "aaaaaa" >> $DIR/$tdir/frename
4480
4481         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4482         local link_new=`stat -c %Y $DIR/$tdir/flink`
4483         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4484         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4485
4486         cat $DIR/$tdir/fopen > /dev/null
4487         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4488         rm -f $DIR/$tdir/funlink2
4489         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4490
4491         for (( i=0; i < 2; i++ )) ; do
4492                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4493                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4494                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4495                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4496
4497                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4498                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4499                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4500                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4501
4502                 cancel_lru_locks $OSC
4503                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4504         done
4505 }
4506 run_test 39b "mtime change on open, link, unlink, rename  ======"
4507
4508 # this should be set to past
4509 TEST_39_MTIME=`date -d "1 year ago" +%s`
4510
4511 # bug 11063
4512 test_39c() {
4513         touch $DIR1/$tfile
4514         sleep 2
4515         local mtime0=`stat -c %Y $DIR1/$tfile`
4516
4517         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4518         local mtime1=`stat -c %Y $DIR1/$tfile`
4519         [ "$mtime1" = $TEST_39_MTIME ] || \
4520                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4521
4522         local d1=`date +%s`
4523         echo hello >> $DIR1/$tfile
4524         local d2=`date +%s`
4525         local mtime2=`stat -c %Y $DIR1/$tfile`
4526         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4527                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4528
4529         mv $DIR1/$tfile $DIR1/$tfile-1
4530
4531         for (( i=0; i < 2; i++ )) ; do
4532                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4533                 [ "$mtime2" = "$mtime3" ] || \
4534                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4535
4536                 cancel_lru_locks $OSC
4537                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4538         done
4539 }
4540 run_test 39c "mtime change on rename ==========================="
4541
4542 # bug 21114
4543 test_39d() {
4544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4545
4546         touch $DIR1/$tfile
4547         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4548
4549         for (( i=0; i < 2; i++ )) ; do
4550                 local mtime=`stat -c %Y $DIR1/$tfile`
4551                 [ $mtime = $TEST_39_MTIME ] || \
4552                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4553
4554                 cancel_lru_locks $OSC
4555                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4556         done
4557 }
4558 run_test 39d "create, utime, stat =============================="
4559
4560 # bug 21114
4561 test_39e() {
4562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4563
4564         touch $DIR1/$tfile
4565         local mtime1=`stat -c %Y $DIR1/$tfile`
4566
4567         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4568
4569         for (( i=0; i < 2; i++ )) ; do
4570                 local mtime2=`stat -c %Y $DIR1/$tfile`
4571                 [ $mtime2 = $TEST_39_MTIME ] || \
4572                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4573
4574                 cancel_lru_locks $OSC
4575                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4576         done
4577 }
4578 run_test 39e "create, stat, utime, stat ========================"
4579
4580 # bug 21114
4581 test_39f() {
4582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4583
4584         touch $DIR1/$tfile
4585         mtime1=`stat -c %Y $DIR1/$tfile`
4586
4587         sleep 2
4588         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4589
4590         for (( i=0; i < 2; i++ )) ; do
4591                 local mtime2=`stat -c %Y $DIR1/$tfile`
4592                 [ $mtime2 = $TEST_39_MTIME ] || \
4593                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4594
4595                 cancel_lru_locks $OSC
4596                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4597         done
4598 }
4599 run_test 39f "create, stat, sleep, utime, stat ================="
4600
4601 # bug 11063
4602 test_39g() {
4603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4604
4605         echo hello >> $DIR1/$tfile
4606         local mtime1=`stat -c %Y $DIR1/$tfile`
4607
4608         sleep 2
4609         chmod o+r $DIR1/$tfile
4610
4611         for (( i=0; i < 2; i++ )) ; do
4612                 local mtime2=`stat -c %Y $DIR1/$tfile`
4613                 [ "$mtime1" = "$mtime2" ] || \
4614                         error "lost mtime: $mtime2, should be $mtime1"
4615
4616                 cancel_lru_locks $OSC
4617                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4618         done
4619 }
4620 run_test 39g "write, chmod, stat ==============================="
4621
4622 # bug 11063
4623 test_39h() {
4624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4625
4626         touch $DIR1/$tfile
4627         sleep 1
4628
4629         local d1=`date`
4630         echo hello >> $DIR1/$tfile
4631         local mtime1=`stat -c %Y $DIR1/$tfile`
4632
4633         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4634         local d2=`date`
4635         if [ "$d1" != "$d2" ]; then
4636                 echo "write and touch not within one second"
4637         else
4638                 for (( i=0; i < 2; i++ )) ; do
4639                         local mtime2=`stat -c %Y $DIR1/$tfile`
4640                         [ "$mtime2" = $TEST_39_MTIME ] || \
4641                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4642
4643                         cancel_lru_locks $OSC
4644                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4645                 done
4646         fi
4647 }
4648 run_test 39h "write, utime within one second, stat ============="
4649
4650 test_39i() {
4651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4652
4653         touch $DIR1/$tfile
4654         sleep 1
4655
4656         echo hello >> $DIR1/$tfile
4657         local mtime1=`stat -c %Y $DIR1/$tfile`
4658
4659         mv $DIR1/$tfile $DIR1/$tfile-1
4660
4661         for (( i=0; i < 2; i++ )) ; do
4662                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4663
4664                 [ "$mtime1" = "$mtime2" ] || \
4665                         error "lost mtime: $mtime2, should be $mtime1"
4666
4667                 cancel_lru_locks $OSC
4668                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4669         done
4670 }
4671 run_test 39i "write, rename, stat =============================="
4672
4673 test_39j() {
4674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4675
4676         start_full_debug_logging
4677         touch $DIR1/$tfile
4678         sleep 1
4679
4680         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4681         lctl set_param fail_loc=0x80000412
4682         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4683                 error "multiop failed"
4684         local multipid=$!
4685         local mtime1=`stat -c %Y $DIR1/$tfile`
4686
4687         mv $DIR1/$tfile $DIR1/$tfile-1
4688
4689         kill -USR1 $multipid
4690         wait $multipid || error "multiop close failed"
4691
4692         for (( i=0; i < 2; i++ )) ; do
4693                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4694                 [ "$mtime1" = "$mtime2" ] ||
4695                         error "mtime is lost on close: $mtime2, " \
4696                               "should be $mtime1"
4697
4698                 cancel_lru_locks
4699                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4700         done
4701         lctl set_param fail_loc=0
4702         stop_full_debug_logging
4703 }
4704 run_test 39j "write, rename, close, stat ======================="
4705
4706 test_39k() {
4707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4708
4709         touch $DIR1/$tfile
4710         sleep 1
4711
4712         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4713         local multipid=$!
4714         local mtime1=`stat -c %Y $DIR1/$tfile`
4715
4716         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4717
4718         kill -USR1 $multipid
4719         wait $multipid || error "multiop close failed"
4720
4721         for (( i=0; i < 2; i++ )) ; do
4722                 local mtime2=`stat -c %Y $DIR1/$tfile`
4723
4724                 [ "$mtime2" = $TEST_39_MTIME ] || \
4725                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4726
4727                 cancel_lru_locks
4728                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4729         done
4730 }
4731 run_test 39k "write, utime, close, stat ========================"
4732
4733 # this should be set to future
4734 TEST_39_ATIME=`date -d "1 year" +%s`
4735
4736 test_39l() {
4737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4738         remote_mds_nodsh && skip "remote MDS with nodsh"
4739
4740         local atime_diff=$(do_facet $SINGLEMDS \
4741                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4742         rm -rf $DIR/$tdir
4743         mkdir -p $DIR/$tdir
4744
4745         # test setting directory atime to future
4746         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4747         local atime=$(stat -c %X $DIR/$tdir)
4748         [ "$atime" = $TEST_39_ATIME ] ||
4749                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4750
4751         # test setting directory atime from future to now
4752         local now=$(date +%s)
4753         touch -a -d @$now $DIR/$tdir
4754
4755         atime=$(stat -c %X $DIR/$tdir)
4756         [ "$atime" -eq "$now"  ] ||
4757                 error "atime is not updated from future: $atime, $now"
4758
4759         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4760         sleep 3
4761
4762         # test setting directory atime when now > dir atime + atime_diff
4763         local d1=$(date +%s)
4764         ls $DIR/$tdir
4765         local d2=$(date +%s)
4766         cancel_lru_locks mdc
4767         atime=$(stat -c %X $DIR/$tdir)
4768         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4769                 error "atime is not updated  : $atime, should be $d2"
4770
4771         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4772         sleep 3
4773
4774         # test not setting directory atime when now < dir atime + atime_diff
4775         ls $DIR/$tdir
4776         cancel_lru_locks mdc
4777         atime=$(stat -c %X $DIR/$tdir)
4778         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4779                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4780
4781         do_facet $SINGLEMDS \
4782                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4783 }
4784 run_test 39l "directory atime update ==========================="
4785
4786 test_39m() {
4787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4788
4789         touch $DIR1/$tfile
4790         sleep 2
4791         local far_past_mtime=$(date -d "May 29 1953" +%s)
4792         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4793
4794         touch -m -d @$far_past_mtime $DIR1/$tfile
4795         touch -a -d @$far_past_atime $DIR1/$tfile
4796
4797         for (( i=0; i < 2; i++ )) ; do
4798                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4799                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4800                         error "atime or mtime set incorrectly"
4801
4802                 cancel_lru_locks $OSC
4803                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4804         done
4805 }
4806 run_test 39m "test atime and mtime before 1970"
4807
4808 test_39n() { # LU-3832
4809         remote_mds_nodsh && skip "remote MDS with nodsh"
4810
4811         local atime_diff=$(do_facet $SINGLEMDS \
4812                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4813         local atime0
4814         local atime1
4815         local atime2
4816
4817         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4818
4819         rm -rf $DIR/$tfile
4820         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4821         atime0=$(stat -c %X $DIR/$tfile)
4822
4823         sleep 5
4824         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4825         atime1=$(stat -c %X $DIR/$tfile)
4826
4827         sleep 5
4828         cancel_lru_locks mdc
4829         cancel_lru_locks osc
4830         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4831         atime2=$(stat -c %X $DIR/$tfile)
4832
4833         do_facet $SINGLEMDS \
4834                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4835
4836         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4837         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4838 }
4839 run_test 39n "check that O_NOATIME is honored"
4840
4841 test_39o() {
4842         TESTDIR=$DIR/$tdir/$tfile
4843         [ -e $TESTDIR ] && rm -rf $TESTDIR
4844         mkdir -p $TESTDIR
4845         cd $TESTDIR
4846         links1=2
4847         ls
4848         mkdir a b
4849         ls
4850         links2=$(stat -c %h .)
4851         [ $(($links1 + 2)) != $links2 ] &&
4852                 error "wrong links count $(($links1 + 2)) != $links2"
4853         rmdir b
4854         links3=$(stat -c %h .)
4855         [ $(($links1 + 1)) != $links3 ] &&
4856                 error "wrong links count $links1 != $links3"
4857         return 0
4858 }
4859 run_test 39o "directory cached attributes updated after create"
4860
4861 test_39p() {
4862         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4863
4864         local MDTIDX=1
4865         TESTDIR=$DIR/$tdir/$tdir
4866         [ -e $TESTDIR ] && rm -rf $TESTDIR
4867         test_mkdir -p $TESTDIR
4868         cd $TESTDIR
4869         links1=2
4870         ls
4871         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4872         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4873         ls
4874         links2=$(stat -c %h .)
4875         [ $(($links1 + 2)) != $links2 ] &&
4876                 error "wrong links count $(($links1 + 2)) != $links2"
4877         rmdir remote_dir2
4878         links3=$(stat -c %h .)
4879         [ $(($links1 + 1)) != $links3 ] &&
4880                 error "wrong links count $links1 != $links3"
4881         return 0
4882 }
4883 run_test 39p "remote directory cached attributes updated after create ========"
4884
4885 test_39r() {
4886         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4887                 skip "no atime update on old OST"
4888         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4889                 skip_env "ldiskfs only test"
4890         fi
4891
4892         local saved_adiff
4893         saved_adiff=$(do_facet ost1 \
4894                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4895         stack_trap "do_facet ost1 \
4896                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4897
4898         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4899
4900         $LFS setstripe -i 0 $DIR/$tfile
4901         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4902                 error "can't write initial file"
4903         cancel_lru_locks osc
4904
4905         # exceed atime_diff and access file
4906         sleep 6
4907         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4908                 error "can't udpate atime"
4909
4910         local atime_cli=$(stat -c %X $DIR/$tfile)
4911         echo "client atime: $atime_cli"
4912         # allow atime update to be written to device
4913         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4914         sleep 5
4915
4916         local ostdev=$(ostdevname 1)
4917         local fid=($(lfs getstripe -y $DIR/$tfile |
4918                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4919         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4920         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4921
4922         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4923         local atime_ost=$(do_facet ost1 "$cmd" |&
4924                           awk -F'[: ]' '/atime:/ { print $4 }')
4925         (( atime_cli == atime_ost )) ||
4926                 error "atime on client $atime_cli != ost $atime_ost"
4927 }
4928 run_test 39r "lazy atime update on OST"
4929
4930 test_39q() { # LU-8041
4931         local testdir=$DIR/$tdir
4932         mkdir -p $testdir
4933         multiop_bg_pause $testdir D_c || error "multiop failed"
4934         local multipid=$!
4935         cancel_lru_locks mdc
4936         kill -USR1 $multipid
4937         local atime=$(stat -c %X $testdir)
4938         [ "$atime" -ne 0 ] || error "atime is zero"
4939 }
4940 run_test 39q "close won't zero out atime"
4941
4942 test_40() {
4943         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4944         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4945                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4946         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4947                 error "$tfile is not 4096 bytes in size"
4948 }
4949 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4950
4951 test_41() {
4952         # bug 1553
4953         small_write $DIR/f41 18
4954 }
4955 run_test 41 "test small file write + fstat ====================="
4956
4957 count_ost_writes() {
4958         lctl get_param -n ${OSC}.*.stats |
4959                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4960                         END { printf("%0.0f", writes) }'
4961 }
4962
4963 # decent default
4964 WRITEBACK_SAVE=500
4965 DIRTY_RATIO_SAVE=40
4966 MAX_DIRTY_RATIO=50
4967 BG_DIRTY_RATIO_SAVE=10
4968 MAX_BG_DIRTY_RATIO=25
4969
4970 start_writeback() {
4971         trap 0
4972         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4973         # dirty_ratio, dirty_background_ratio
4974         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4975                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4976                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4977                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4978         else
4979                 # if file not here, we are a 2.4 kernel
4980                 kill -CONT `pidof kupdated`
4981         fi
4982 }
4983
4984 stop_writeback() {
4985         # setup the trap first, so someone cannot exit the test at the
4986         # exact wrong time and mess up a machine
4987         trap start_writeback EXIT
4988         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4989         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4990                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4991                 sysctl -w vm.dirty_writeback_centisecs=0
4992                 sysctl -w vm.dirty_writeback_centisecs=0
4993                 # save and increase /proc/sys/vm/dirty_ratio
4994                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4995                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4996                 # save and increase /proc/sys/vm/dirty_background_ratio
4997                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4998                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4999         else
5000                 # if file not here, we are a 2.4 kernel
5001                 kill -STOP `pidof kupdated`
5002         fi
5003 }
5004
5005 # ensure that all stripes have some grant before we test client-side cache
5006 setup_test42() {
5007         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5008                 dd if=/dev/zero of=$i bs=4k count=1
5009                 rm $i
5010         done
5011 }
5012
5013 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5014 # file truncation, and file removal.
5015 test_42a() {
5016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5017
5018         setup_test42
5019         cancel_lru_locks $OSC
5020         stop_writeback
5021         sync; sleep 1; sync # just to be safe
5022         BEFOREWRITES=`count_ost_writes`
5023         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5024         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5025         AFTERWRITES=`count_ost_writes`
5026         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5027                 error "$BEFOREWRITES < $AFTERWRITES"
5028         start_writeback
5029 }
5030 run_test 42a "ensure that we don't flush on close"
5031
5032 test_42b() {
5033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5034
5035         setup_test42
5036         cancel_lru_locks $OSC
5037         stop_writeback
5038         sync
5039         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5040         BEFOREWRITES=$(count_ost_writes)
5041         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5042         AFTERWRITES=$(count_ost_writes)
5043         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5044                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5045         fi
5046         BEFOREWRITES=$(count_ost_writes)
5047         sync || error "sync: $?"
5048         AFTERWRITES=$(count_ost_writes)
5049         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5050                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5051         fi
5052         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5053         start_writeback
5054         return 0
5055 }
5056 run_test 42b "test destroy of file with cached dirty data ======"
5057
5058 # if these tests just want to test the effect of truncation,
5059 # they have to be very careful.  consider:
5060 # - the first open gets a {0,EOF}PR lock
5061 # - the first write conflicts and gets a {0, count-1}PW
5062 # - the rest of the writes are under {count,EOF}PW
5063 # - the open for truncate tries to match a {0,EOF}PR
5064 #   for the filesize and cancels the PWs.
5065 # any number of fixes (don't get {0,EOF} on open, match
5066 # composite locks, do smarter file size management) fix
5067 # this, but for now we want these tests to verify that
5068 # the cancellation with truncate intent works, so we
5069 # start the file with a full-file pw lock to match against
5070 # until the truncate.
5071 trunc_test() {
5072         test=$1
5073         file=$DIR/$test
5074         offset=$2
5075         cancel_lru_locks $OSC
5076         stop_writeback
5077         # prime the file with 0,EOF PW to match
5078         touch $file
5079         $TRUNCATE $file 0
5080         sync; sync
5081         # now the real test..
5082         dd if=/dev/zero of=$file bs=1024 count=100
5083         BEFOREWRITES=`count_ost_writes`
5084         $TRUNCATE $file $offset
5085         cancel_lru_locks $OSC
5086         AFTERWRITES=`count_ost_writes`
5087         start_writeback
5088 }
5089
5090 test_42c() {
5091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5092
5093         trunc_test 42c 1024
5094         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5095                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5096         rm $file
5097 }
5098 run_test 42c "test partial truncate of file with cached dirty data"
5099
5100 test_42d() {
5101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5102
5103         trunc_test 42d 0
5104         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5105                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5106         rm $file
5107 }
5108 run_test 42d "test complete truncate of file with cached dirty data"
5109
5110 test_42e() { # bug22074
5111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5112
5113         local TDIR=$DIR/${tdir}e
5114         local pages=16 # hardcoded 16 pages, don't change it.
5115         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5116         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5117         local max_dirty_mb
5118         local warmup_files
5119
5120         test_mkdir $DIR/${tdir}e
5121         $LFS setstripe -c 1 $TDIR
5122         createmany -o $TDIR/f $files
5123
5124         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5125
5126         # we assume that with $OSTCOUNT files, at least one of them will
5127         # be allocated on OST0.
5128         warmup_files=$((OSTCOUNT * max_dirty_mb))
5129         createmany -o $TDIR/w $warmup_files
5130
5131         # write a large amount of data into one file and sync, to get good
5132         # avail_grant number from OST.
5133         for ((i=0; i<$warmup_files; i++)); do
5134                 idx=$($LFS getstripe -i $TDIR/w$i)
5135                 [ $idx -ne 0 ] && continue
5136                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5137                 break
5138         done
5139         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5140         sync
5141         $LCTL get_param $proc_osc0/cur_dirty_bytes
5142         $LCTL get_param $proc_osc0/cur_grant_bytes
5143
5144         # create as much dirty pages as we can while not to trigger the actual
5145         # RPCs directly. but depends on the env, VFS may trigger flush during this
5146         # period, hopefully we are good.
5147         for ((i=0; i<$warmup_files; i++)); do
5148                 idx=$($LFS getstripe -i $TDIR/w$i)
5149                 [ $idx -ne 0 ] && continue
5150                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5151         done
5152         $LCTL get_param $proc_osc0/cur_dirty_bytes
5153         $LCTL get_param $proc_osc0/cur_grant_bytes
5154
5155         # perform the real test
5156         $LCTL set_param $proc_osc0/rpc_stats 0
5157         for ((;i<$files; i++)); do
5158                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5159                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5160         done
5161         sync
5162         $LCTL get_param $proc_osc0/rpc_stats
5163
5164         local percent=0
5165         local have_ppr=false
5166         $LCTL get_param $proc_osc0/rpc_stats |
5167                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5168                         # skip lines until we are at the RPC histogram data
5169                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5170                         $have_ppr || continue
5171
5172                         # we only want the percent stat for < 16 pages
5173                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5174
5175                         percent=$((percent + WPCT))
5176                         if [[ $percent -gt 15 ]]; then
5177                                 error "less than 16-pages write RPCs" \
5178                                       "$percent% > 15%"
5179                                 break
5180                         fi
5181                 done
5182         rm -rf $TDIR
5183 }
5184 run_test 42e "verify sub-RPC writes are not done synchronously"
5185
5186 test_43A() { # was test_43
5187         test_mkdir $DIR/$tdir
5188         cp -p /bin/ls $DIR/$tdir/$tfile
5189         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5190         pid=$!
5191         # give multiop a chance to open
5192         sleep 1
5193
5194         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5195         kill -USR1 $pid
5196         # Wait for multiop to exit
5197         wait $pid
5198 }
5199 run_test 43A "execution of file opened for write should return -ETXTBSY"
5200
5201 test_43a() {
5202         test_mkdir $DIR/$tdir
5203         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5204         $DIR/$tdir/sleep 60 &
5205         SLEEP_PID=$!
5206         # Make sure exec of $tdir/sleep wins race with truncate
5207         sleep 1
5208         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5209         kill $SLEEP_PID
5210 }
5211 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5212
5213 test_43b() {
5214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5215
5216         test_mkdir $DIR/$tdir
5217         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5218         $DIR/$tdir/sleep 60 &
5219         SLEEP_PID=$!
5220         # Make sure exec of $tdir/sleep wins race with truncate
5221         sleep 1
5222         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5223         kill $SLEEP_PID
5224 }
5225 run_test 43b "truncate of file being executed should return -ETXTBSY"
5226
5227 test_43c() {
5228         local testdir="$DIR/$tdir"
5229         test_mkdir $testdir
5230         cp $SHELL $testdir/
5231         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5232                 ( cd $testdir && md5sum -c )
5233 }
5234 run_test 43c "md5sum of copy into lustre"
5235
5236 test_44A() { # was test_44
5237         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5238
5239         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5240         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5241 }
5242 run_test 44A "zero length read from a sparse stripe"
5243
5244 test_44a() {
5245         local nstripe=$($LFS getstripe -c -d $DIR)
5246         [ -z "$nstripe" ] && skip "can't get stripe info"
5247         [[ $nstripe -gt $OSTCOUNT ]] &&
5248                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5249
5250         local stride=$($LFS getstripe -S -d $DIR)
5251         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5252                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5253         fi
5254
5255         OFFSETS="0 $((stride/2)) $((stride-1))"
5256         for offset in $OFFSETS; do
5257                 for i in $(seq 0 $((nstripe-1))); do
5258                         local GLOBALOFFSETS=""
5259                         # size in Bytes
5260                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5261                         local myfn=$DIR/d44a-$size
5262                         echo "--------writing $myfn at $size"
5263                         ll_sparseness_write $myfn $size ||
5264                                 error "ll_sparseness_write"
5265                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5266                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5267                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5268
5269                         for j in $(seq 0 $((nstripe-1))); do
5270                                 # size in Bytes
5271                                 size=$((((j + $nstripe )*$stride + $offset)))
5272                                 ll_sparseness_write $myfn $size ||
5273                                         error "ll_sparseness_write"
5274                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5275                         done
5276                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5277                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5278                         rm -f $myfn
5279                 done
5280         done
5281 }
5282 run_test 44a "test sparse pwrite ==============================="
5283
5284 dirty_osc_total() {
5285         tot=0
5286         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5287                 tot=$(($tot + $d))
5288         done
5289         echo $tot
5290 }
5291 do_dirty_record() {
5292         before=`dirty_osc_total`
5293         echo executing "\"$*\""
5294         eval $*
5295         after=`dirty_osc_total`
5296         echo before $before, after $after
5297 }
5298 test_45() {
5299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5300
5301         f="$DIR/f45"
5302         # Obtain grants from OST if it supports it
5303         echo blah > ${f}_grant
5304         stop_writeback
5305         sync
5306         do_dirty_record "echo blah > $f"
5307         [[ $before -eq $after ]] && error "write wasn't cached"
5308         do_dirty_record "> $f"
5309         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5310         do_dirty_record "echo blah > $f"
5311         [[ $before -eq $after ]] && error "write wasn't cached"
5312         do_dirty_record "sync"
5313         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5314         do_dirty_record "echo blah > $f"
5315         [[ $before -eq $after ]] && error "write wasn't cached"
5316         do_dirty_record "cancel_lru_locks osc"
5317         [[ $before -gt $after ]] ||
5318                 error "lock cancellation didn't lower dirty count"
5319         start_writeback
5320 }
5321 run_test 45 "osc io page accounting ============================"
5322
5323 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5324 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5325 # objects offset and an assert hit when an rpc was built with 1023's mapped
5326 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5327 test_46() {
5328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5329
5330         f="$DIR/f46"
5331         stop_writeback
5332         sync
5333         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5334         sync
5335         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5336         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5337         sync
5338         start_writeback
5339 }
5340 run_test 46 "dirtying a previously written page ================"
5341
5342 # test_47 is removed "Device nodes check" is moved to test_28
5343
5344 test_48a() { # bug 2399
5345         [ "$mds1_FSTYPE" = "zfs" ] &&
5346         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5347                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5348
5349         test_mkdir $DIR/$tdir
5350         cd $DIR/$tdir
5351         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5352         test_mkdir $DIR/$tdir
5353         touch foo || error "'touch foo' failed after recreating cwd"
5354         test_mkdir bar
5355         touch .foo || error "'touch .foo' failed after recreating cwd"
5356         test_mkdir .bar
5357         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5358         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5359         cd . || error "'cd .' failed after recreating cwd"
5360         mkdir . && error "'mkdir .' worked after recreating cwd"
5361         rmdir . && error "'rmdir .' worked after recreating cwd"
5362         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5363         cd .. || error "'cd ..' failed after recreating cwd"
5364 }
5365 run_test 48a "Access renamed working dir (should return errors)="
5366
5367 test_48b() { # bug 2399
5368         rm -rf $DIR/$tdir
5369         test_mkdir $DIR/$tdir
5370         cd $DIR/$tdir
5371         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5372         touch foo && error "'touch foo' worked after removing cwd"
5373         mkdir foo && error "'mkdir foo' worked after removing cwd"
5374         touch .foo && error "'touch .foo' worked after removing cwd"
5375         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5376         ls . > /dev/null && error "'ls .' worked after removing cwd"
5377         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5378         mkdir . && error "'mkdir .' worked after removing cwd"
5379         rmdir . && error "'rmdir .' worked after removing cwd"
5380         ln -s . foo && error "'ln -s .' worked after removing cwd"
5381         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5382 }
5383 run_test 48b "Access removed working dir (should return errors)="
5384
5385 test_48c() { # bug 2350
5386         #lctl set_param debug=-1
5387         #set -vx
5388         rm -rf $DIR/$tdir
5389         test_mkdir -p $DIR/$tdir/dir
5390         cd $DIR/$tdir/dir
5391         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5392         $TRACE touch foo && error "touch foo worked after removing cwd"
5393         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5394         touch .foo && error "touch .foo worked after removing cwd"
5395         mkdir .foo && error "mkdir .foo worked after removing cwd"
5396         $TRACE ls . && error "'ls .' worked after removing cwd"
5397         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5398         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5399         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5400         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5401         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5402 }
5403 run_test 48c "Access removed working subdir (should return errors)"
5404
5405 test_48d() { # bug 2350
5406         #lctl set_param debug=-1
5407         #set -vx
5408         rm -rf $DIR/$tdir
5409         test_mkdir -p $DIR/$tdir/dir
5410         cd $DIR/$tdir/dir
5411         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5412         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5413         $TRACE touch foo && error "'touch foo' worked after removing parent"
5414         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5415         touch .foo && error "'touch .foo' worked after removing parent"
5416         mkdir .foo && error "mkdir .foo worked after removing parent"
5417         $TRACE ls . && error "'ls .' worked after removing parent"
5418         $TRACE ls .. && error "'ls ..' worked after removing parent"
5419         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5420         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5421         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5422         true
5423 }
5424 run_test 48d "Access removed parent subdir (should return errors)"
5425
5426 test_48e() { # bug 4134
5427         #lctl set_param debug=-1
5428         #set -vx
5429         rm -rf $DIR/$tdir
5430         test_mkdir -p $DIR/$tdir/dir
5431         cd $DIR/$tdir/dir
5432         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5433         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5434         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5435         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5436         # On a buggy kernel addition of "touch foo" after cd .. will
5437         # produce kernel oops in lookup_hash_it
5438         touch ../foo && error "'cd ..' worked after recreate parent"
5439         cd $DIR
5440         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5441 }
5442 run_test 48e "Access to recreated parent subdir (should return errors)"
5443
5444 test_48f() {
5445         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5446                 skip "need MDS >= 2.13.55"
5447         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5448         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5449                 skip "needs different host for mdt1 mdt2"
5450         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5451
5452         $LFS mkdir -i0 $DIR/$tdir
5453         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5454
5455         for d in sub1 sub2 sub3; do
5456                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5457                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5458                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5459         done
5460
5461         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5462 }
5463 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5464
5465 test_49() { # LU-1030
5466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5467         remote_ost_nodsh && skip "remote OST with nodsh"
5468
5469         # get ost1 size - $FSNAME-OST0000
5470         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5471                 awk '{ print $4 }')
5472         # write 800M at maximum
5473         [[ $ost1_size -lt 2 ]] && ost1_size=2
5474         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5475
5476         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5477         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5478         local dd_pid=$!
5479
5480         # change max_pages_per_rpc while writing the file
5481         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5482         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5483         # loop until dd process exits
5484         while ps ax -opid | grep -wq $dd_pid; do
5485                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5486                 sleep $((RANDOM % 5 + 1))
5487         done
5488         # restore original max_pages_per_rpc
5489         $LCTL set_param $osc1_mppc=$orig_mppc
5490         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5491 }
5492 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5493
5494 test_50() {
5495         # bug 1485
5496         test_mkdir $DIR/$tdir
5497         cd $DIR/$tdir
5498         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5499 }
5500 run_test 50 "special situations: /proc symlinks  ==============="
5501
5502 test_51a() {    # was test_51
5503         # bug 1516 - create an empty entry right after ".." then split dir
5504         test_mkdir -c1 $DIR/$tdir
5505         touch $DIR/$tdir/foo
5506         $MCREATE $DIR/$tdir/bar
5507         rm $DIR/$tdir/foo
5508         createmany -m $DIR/$tdir/longfile 201
5509         FNUM=202
5510         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5511                 $MCREATE $DIR/$tdir/longfile$FNUM
5512                 FNUM=$(($FNUM + 1))
5513                 echo -n "+"
5514         done
5515         echo
5516         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5517 }
5518 run_test 51a "special situations: split htree with empty entry =="
5519
5520 cleanup_print_lfs_df () {
5521         trap 0
5522         $LFS df
5523         $LFS df -i
5524 }
5525
5526 test_51b() {
5527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5528
5529         local dir=$DIR/$tdir
5530         local nrdirs=$((65536 + 100))
5531
5532         # cleanup the directory
5533         rm -fr $dir
5534
5535         test_mkdir -c1 $dir
5536
5537         $LFS df
5538         $LFS df -i
5539         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5540         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5541         [[ $numfree -lt $nrdirs ]] &&
5542                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5543
5544         # need to check free space for the directories as well
5545         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5546         numfree=$(( blkfree / $(fs_inode_ksize) ))
5547         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5548
5549         trap cleanup_print_lfs_df EXIT
5550
5551         # create files
5552         createmany -d $dir/d $nrdirs || {
5553                 unlinkmany $dir/d $nrdirs
5554                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5555         }
5556
5557         # really created :
5558         nrdirs=$(ls -U $dir | wc -l)
5559
5560         # unlink all but 100 subdirectories, then check it still works
5561         local left=100
5562         local delete=$((nrdirs - left))
5563
5564         $LFS df
5565         $LFS df -i
5566
5567         # for ldiskfs the nlink count should be 1, but this is OSD specific
5568         # and so this is listed for informational purposes only
5569         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5570         unlinkmany -d $dir/d $delete ||
5571                 error "unlink of first $delete subdirs failed"
5572
5573         echo "nlink between: $(stat -c %h $dir)"
5574         local found=$(ls -U $dir | wc -l)
5575         [ $found -ne $left ] &&
5576                 error "can't find subdirs: found only $found, expected $left"
5577
5578         unlinkmany -d $dir/d $delete $left ||
5579                 error "unlink of second $left subdirs failed"
5580         # regardless of whether the backing filesystem tracks nlink accurately
5581         # or not, the nlink count shouldn't be more than "." and ".." here
5582         local after=$(stat -c %h $dir)
5583         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5584                 echo "nlink after: $after"
5585
5586         cleanup_print_lfs_df
5587 }
5588 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5589
5590 test_51d() {
5591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5592         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5593
5594         test_mkdir $DIR/$tdir
5595         createmany -o $DIR/$tdir/t- 1000
5596         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5597         for N in $(seq 0 $((OSTCOUNT - 1))); do
5598                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5599                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5600                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5601                         '($1 == '$N') { objs += 1 } \
5602                         END { printf("%0.0f", objs) }')
5603                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5604         done
5605         unlinkmany $DIR/$tdir/t- 1000
5606
5607         NLAST=0
5608         for N in $(seq 1 $((OSTCOUNT - 1))); do
5609                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5610                         error "OST $N has less objects vs OST $NLAST" \
5611                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5612                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5613                         error "OST $N has less objects vs OST $NLAST" \
5614                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5615
5616                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5617                         error "OST $N has less #0 objects vs OST $NLAST" \
5618                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5619                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5620                         error "OST $N has less #0 objects vs OST $NLAST" \
5621                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5622                 NLAST=$N
5623         done
5624         rm -f $TMP/$tfile
5625 }
5626 run_test 51d "check object distribution"
5627
5628 test_51e() {
5629         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5630                 skip_env "ldiskfs only test"
5631         fi
5632
5633         test_mkdir -c1 $DIR/$tdir
5634         test_mkdir -c1 $DIR/$tdir/d0
5635
5636         touch $DIR/$tdir/d0/foo
5637         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5638                 error "file exceed 65000 nlink limit!"
5639         unlinkmany $DIR/$tdir/d0/f- 65001
5640         return 0
5641 }
5642 run_test 51e "check file nlink limit"
5643
5644 test_51f() {
5645         test_mkdir $DIR/$tdir
5646
5647         local max=100000
5648         local ulimit_old=$(ulimit -n)
5649         local spare=20 # number of spare fd's for scripts/libraries, etc.
5650         local mdt=$($LFS getstripe -m $DIR/$tdir)
5651         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5652
5653         echo "MDT$mdt numfree=$numfree, max=$max"
5654         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5655         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5656                 while ! ulimit -n $((numfree + spare)); do
5657                         numfree=$((numfree * 3 / 4))
5658                 done
5659                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5660         else
5661                 echo "left ulimit at $ulimit_old"
5662         fi
5663
5664         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5665                 unlinkmany $DIR/$tdir/f $numfree
5666                 error "create+open $numfree files in $DIR/$tdir failed"
5667         }
5668         ulimit -n $ulimit_old
5669
5670         # if createmany exits at 120s there will be fewer than $numfree files
5671         unlinkmany $DIR/$tdir/f $numfree || true
5672 }
5673 run_test 51f "check many open files limit"
5674
5675 test_52a() {
5676         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5677         test_mkdir $DIR/$tdir
5678         touch $DIR/$tdir/foo
5679         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5680         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5681         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5682         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5683         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5684                                         error "link worked"
5685         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5686         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5687         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5688                                                      error "lsattr"
5689         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5690         cp -r $DIR/$tdir $TMP/
5691         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5692 }
5693 run_test 52a "append-only flag test (should return errors)"
5694
5695 test_52b() {
5696         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5697         test_mkdir $DIR/$tdir
5698         touch $DIR/$tdir/foo
5699         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5700         cat test > $DIR/$tdir/foo && error "cat test worked"
5701         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5702         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5703         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5704                                         error "link worked"
5705         echo foo >> $DIR/$tdir/foo && error "echo worked"
5706         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5707         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5708         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5709         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5710                                                         error "lsattr"
5711         chattr -i $DIR/$tdir/foo || error "chattr failed"
5712
5713         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5714 }
5715 run_test 52b "immutable flag test (should return errors) ======="
5716
5717 test_53() {
5718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5719         remote_mds_nodsh && skip "remote MDS with nodsh"
5720         remote_ost_nodsh && skip "remote OST with nodsh"
5721
5722         local param
5723         local param_seq
5724         local ostname
5725         local mds_last
5726         local mds_last_seq
5727         local ost_last
5728         local ost_last_seq
5729         local ost_last_id
5730         local ostnum
5731         local node
5732         local found=false
5733         local support_last_seq=true
5734
5735         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5736                 support_last_seq=false
5737
5738         # only test MDT0000
5739         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5740         local value
5741         for value in $(do_facet $SINGLEMDS \
5742                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5743                 param=$(echo ${value[0]} | cut -d "=" -f1)
5744                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5745
5746                 if $support_last_seq; then
5747                         param_seq=$(echo $param |
5748                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5749                         mds_last_seq=$(do_facet $SINGLEMDS \
5750                                        $LCTL get_param -n $param_seq)
5751                 fi
5752                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5753
5754                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5755                 node=$(facet_active_host ost$((ostnum+1)))
5756                 param="obdfilter.$ostname.last_id"
5757                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5758                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5759                         ost_last_id=$ost_last
5760
5761                         if $support_last_seq; then
5762                                 ost_last_id=$(echo $ost_last |
5763                                               awk -F':' '{print $2}' |
5764                                               sed -e "s/^0x//g")
5765                                 ost_last_seq=$(echo $ost_last |
5766                                                awk -F':' '{print $1}')
5767                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5768                         fi
5769
5770                         if [[ $ost_last_id != $mds_last ]]; then
5771                                 error "$ost_last_id != $mds_last"
5772                         else
5773                                 found=true
5774                                 break
5775                         fi
5776                 done
5777         done
5778         $found || error "can not match last_seq/last_id for $mdtosc"
5779         return 0
5780 }
5781 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5782
5783 test_54a() {
5784         perl -MSocket -e ';' || skip "no Socket perl module installed"
5785
5786         $SOCKETSERVER $DIR/socket ||
5787                 error "$SOCKETSERVER $DIR/socket failed: $?"
5788         $SOCKETCLIENT $DIR/socket ||
5789                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5790         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5791 }
5792 run_test 54a "unix domain socket test =========================="
5793
5794 test_54b() {
5795         f="$DIR/f54b"
5796         mknod $f c 1 3
5797         chmod 0666 $f
5798         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5799 }
5800 run_test 54b "char device works in lustre ======================"
5801
5802 find_loop_dev() {
5803         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5804         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5805         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5806
5807         for i in $(seq 3 7); do
5808                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5809                 LOOPDEV=$LOOPBASE$i
5810                 LOOPNUM=$i
5811                 break
5812         done
5813 }
5814
5815 cleanup_54c() {
5816         local rc=0
5817         loopdev="$DIR/loop54c"
5818
5819         trap 0
5820         $UMOUNT $DIR/$tdir || rc=$?
5821         losetup -d $loopdev || true
5822         losetup -d $LOOPDEV || true
5823         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5824         return $rc
5825 }
5826
5827 test_54c() {
5828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5829
5830         loopdev="$DIR/loop54c"
5831
5832         find_loop_dev
5833         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5834         trap cleanup_54c EXIT
5835         mknod $loopdev b 7 $LOOPNUM
5836         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5837         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5838         losetup $loopdev $DIR/$tfile ||
5839                 error "can't set up $loopdev for $DIR/$tfile"
5840         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5841         test_mkdir $DIR/$tdir
5842         mount -t ext2 $loopdev $DIR/$tdir ||
5843                 error "error mounting $loopdev on $DIR/$tdir"
5844         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5845                 error "dd write"
5846         df $DIR/$tdir
5847         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5848                 error "dd read"
5849         cleanup_54c
5850 }
5851 run_test 54c "block device works in lustre ====================="
5852
5853 test_54d() {
5854         f="$DIR/f54d"
5855         string="aaaaaa"
5856         mknod $f p
5857         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5858 }
5859 run_test 54d "fifo device works in lustre ======================"
5860
5861 test_54e() {
5862         f="$DIR/f54e"
5863         string="aaaaaa"
5864         cp -aL /dev/console $f
5865         echo $string > $f || error "echo $string to $f failed"
5866 }
5867 run_test 54e "console/tty device works in lustre ======================"
5868
5869 test_56a() {
5870         local numfiles=3
5871         local dir=$DIR/$tdir
5872
5873         rm -rf $dir
5874         test_mkdir -p $dir/dir
5875         for i in $(seq $numfiles); do
5876                 touch $dir/file$i
5877                 touch $dir/dir/file$i
5878         done
5879
5880         local numcomp=$($LFS getstripe --component-count $dir)
5881
5882         [[ $numcomp == 0 ]] && numcomp=1
5883
5884         # test lfs getstripe with --recursive
5885         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5886
5887         [[ $filenum -eq $((numfiles * 2)) ]] ||
5888                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5889         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5890         [[ $filenum -eq $numfiles ]] ||
5891                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5892         echo "$LFS getstripe showed obdidx or l_ost_idx"
5893
5894         # test lfs getstripe with file instead of dir
5895         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5896         [[ $filenum -eq 1 ]] ||
5897                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5898         echo "$LFS getstripe file1 passed"
5899
5900         #test lfs getstripe with --verbose
5901         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5902         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5903                 error "$LFS getstripe --verbose $dir: "\
5904                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5905         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5906                 error "$LFS getstripe $dir: showed lmm_magic"
5907
5908         #test lfs getstripe with -v prints lmm_fid
5909         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5910         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5911                 error "$LFS getstripe -v $dir: "\
5912                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5913         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5914                 error "$LFS getstripe $dir: showed lmm_fid by default"
5915         echo "$LFS getstripe --verbose passed"
5916
5917         #check for FID information
5918         local fid1=$($LFS getstripe --fid $dir/file1)
5919         local fid2=$($LFS getstripe --verbose $dir/file1 |
5920                      awk '/lmm_fid: / { print $2; exit; }')
5921         local fid3=$($LFS path2fid $dir/file1)
5922
5923         [ "$fid1" != "$fid2" ] &&
5924                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5925         [ "$fid1" != "$fid3" ] &&
5926                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5927         echo "$LFS getstripe --fid passed"
5928
5929         #test lfs getstripe with --obd
5930         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5931                 error "$LFS getstripe --obd wrong_uuid: should return error"
5932
5933         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5934
5935         local ostidx=1
5936         local obduuid=$(ostuuid_from_index $ostidx)
5937         local found=$($LFS getstripe -r --obd $obduuid $dir |
5938                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5939
5940         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5941         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5942                 ((filenum--))
5943         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5944                 ((filenum--))
5945
5946         [[ $found -eq $filenum ]] ||
5947                 error "$LFS getstripe --obd: found $found expect $filenum"
5948         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5949                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5950                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5951                 error "$LFS getstripe --obd: should not show file on other obd"
5952         echo "$LFS getstripe --obd passed"
5953 }
5954 run_test 56a "check $LFS getstripe"
5955
5956 test_56b() {
5957         local dir=$DIR/$tdir
5958         local numdirs=3
5959
5960         test_mkdir $dir
5961         for i in $(seq $numdirs); do
5962                 test_mkdir $dir/dir$i
5963         done
5964
5965         # test lfs getdirstripe default mode is non-recursion, which is
5966         # different from lfs getstripe
5967         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5968
5969         [[ $dircnt -eq 1 ]] ||
5970                 error "$LFS getdirstripe: found $dircnt, not 1"
5971         dircnt=$($LFS getdirstripe --recursive $dir |
5972                 grep -c lmv_stripe_count)
5973         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5974                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5975 }
5976 run_test 56b "check $LFS getdirstripe"
5977
5978 test_56c() {
5979         remote_ost_nodsh && skip "remote OST with nodsh"
5980
5981         local ost_idx=0
5982         local ost_name=$(ostname_from_index $ost_idx)
5983         local old_status=$(ost_dev_status $ost_idx)
5984         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5985
5986         [[ -z "$old_status" ]] ||
5987                 skip_env "OST $ost_name is in $old_status status"
5988
5989         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5990         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5991                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5992         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5993                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5994                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5995         fi
5996
5997         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5998                 error "$LFS df -v showing inactive devices"
5999         sleep_maxage
6000
6001         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6002
6003         [[ "$new_status" =~ "D" ]] ||
6004                 error "$ost_name status is '$new_status', missing 'D'"
6005         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6006                 [[ "$new_status" =~ "N" ]] ||
6007                         error "$ost_name status is '$new_status', missing 'N'"
6008         fi
6009         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6010                 [[ "$new_status" =~ "f" ]] ||
6011                         error "$ost_name status is '$new_status', missing 'f'"
6012         fi
6013
6014         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6015         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6016                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6017         [[ -z "$p" ]] && restore_lustre_params < $p || true
6018         sleep_maxage
6019
6020         new_status=$(ost_dev_status $ost_idx)
6021         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6022                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6023         # can't check 'f' as devices may actually be on flash
6024 }
6025 run_test 56c "check 'lfs df' showing device status"
6026
6027 test_56d() {
6028         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6029         local osts=$($LFS df -v $MOUNT | grep -c OST)
6030
6031         $LFS df $MOUNT
6032
6033         (( mdts == MDSCOUNT )) ||
6034                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6035         (( osts == OSTCOUNT )) ||
6036                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6037 }
6038 run_test 56d "'lfs df -v' prints only configured devices"
6039
6040 NUMFILES=3
6041 NUMDIRS=3
6042 setup_56() {
6043         local local_tdir="$1"
6044         local local_numfiles="$2"
6045         local local_numdirs="$3"
6046         local dir_params="$4"
6047         local dir_stripe_params="$5"
6048
6049         if [ ! -d "$local_tdir" ] ; then
6050                 test_mkdir -p $dir_stripe_params $local_tdir
6051                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6052                 for i in $(seq $local_numfiles) ; do
6053                         touch $local_tdir/file$i
6054                 done
6055                 for i in $(seq $local_numdirs) ; do
6056                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6057                         for j in $(seq $local_numfiles) ; do
6058                                 touch $local_tdir/dir$i/file$j
6059                         done
6060                 done
6061         fi
6062 }
6063
6064 setup_56_special() {
6065         local local_tdir=$1
6066         local local_numfiles=$2
6067         local local_numdirs=$3
6068
6069         setup_56 $local_tdir $local_numfiles $local_numdirs
6070
6071         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6072                 for i in $(seq $local_numfiles) ; do
6073                         mknod $local_tdir/loop${i}b b 7 $i
6074                         mknod $local_tdir/null${i}c c 1 3
6075                         ln -s $local_tdir/file1 $local_tdir/link${i}
6076                 done
6077                 for i in $(seq $local_numdirs) ; do
6078                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6079                         mknod $local_tdir/dir$i/null${i}c c 1 3
6080                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6081                 done
6082         fi
6083 }
6084
6085 test_56g() {
6086         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6087         local expected=$(($NUMDIRS + 2))
6088
6089         setup_56 $dir $NUMFILES $NUMDIRS
6090
6091         # test lfs find with -name
6092         for i in $(seq $NUMFILES) ; do
6093                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6094
6095                 [ $nums -eq $expected ] ||
6096                         error "lfs find -name '*$i' $dir wrong: "\
6097                               "found $nums, expected $expected"
6098         done
6099 }
6100 run_test 56g "check lfs find -name"
6101
6102 test_56h() {
6103         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6104         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6105
6106         setup_56 $dir $NUMFILES $NUMDIRS
6107
6108         # test lfs find with ! -name
6109         for i in $(seq $NUMFILES) ; do
6110                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6111
6112                 [ $nums -eq $expected ] ||
6113                         error "lfs find ! -name '*$i' $dir wrong: "\
6114                               "found $nums, expected $expected"
6115         done
6116 }
6117 run_test 56h "check lfs find ! -name"
6118
6119 test_56i() {
6120         local dir=$DIR/$tdir
6121
6122         test_mkdir $dir
6123
6124         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6125         local out=$($cmd)
6126
6127         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6128 }
6129 run_test 56i "check 'lfs find -ost UUID' skips directories"
6130
6131 test_56j() {
6132         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6133
6134         setup_56_special $dir $NUMFILES $NUMDIRS
6135
6136         local expected=$((NUMDIRS + 1))
6137         local cmd="$LFS find -type d $dir"
6138         local nums=$($cmd | wc -l)
6139
6140         [ $nums -eq $expected ] ||
6141                 error "'$cmd' wrong: found $nums, expected $expected"
6142 }
6143 run_test 56j "check lfs find -type d"
6144
6145 test_56k() {
6146         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6147
6148         setup_56_special $dir $NUMFILES $NUMDIRS
6149
6150         local expected=$(((NUMDIRS + 1) * NUMFILES))
6151         local cmd="$LFS find -type f $dir"
6152         local nums=$($cmd | wc -l)
6153
6154         [ $nums -eq $expected ] ||
6155                 error "'$cmd' wrong: found $nums, expected $expected"
6156 }
6157 run_test 56k "check lfs find -type f"
6158
6159 test_56l() {
6160         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6161
6162         setup_56_special $dir $NUMFILES $NUMDIRS
6163
6164         local expected=$((NUMDIRS + NUMFILES))
6165         local cmd="$LFS find -type b $dir"
6166         local nums=$($cmd | wc -l)
6167
6168         [ $nums -eq $expected ] ||
6169                 error "'$cmd' wrong: found $nums, expected $expected"
6170 }
6171 run_test 56l "check lfs find -type b"
6172
6173 test_56m() {
6174         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6175
6176         setup_56_special $dir $NUMFILES $NUMDIRS
6177
6178         local expected=$((NUMDIRS + NUMFILES))
6179         local cmd="$LFS find -type c $dir"
6180         local nums=$($cmd | wc -l)
6181         [ $nums -eq $expected ] ||
6182                 error "'$cmd' wrong: found $nums, expected $expected"
6183 }
6184 run_test 56m "check lfs find -type c"
6185
6186 test_56n() {
6187         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6188         setup_56_special $dir $NUMFILES $NUMDIRS
6189
6190         local expected=$((NUMDIRS + NUMFILES))
6191         local cmd="$LFS find -type l $dir"
6192         local nums=$($cmd | wc -l)
6193
6194         [ $nums -eq $expected ] ||
6195                 error "'$cmd' wrong: found $nums, expected $expected"
6196 }
6197 run_test 56n "check lfs find -type l"
6198
6199 test_56o() {
6200         local dir=$DIR/$tdir
6201
6202         setup_56 $dir $NUMFILES $NUMDIRS
6203         utime $dir/file1 > /dev/null || error "utime (1)"
6204         utime $dir/file2 > /dev/null || error "utime (2)"
6205         utime $dir/dir1 > /dev/null || error "utime (3)"
6206         utime $dir/dir2 > /dev/null || error "utime (4)"
6207         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6208         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6209
6210         local expected=4
6211         local nums=$($LFS find -mtime +0 $dir | wc -l)
6212
6213         [ $nums -eq $expected ] ||
6214                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6215
6216         expected=12
6217         cmd="$LFS find -mtime 0 $dir"
6218         nums=$($cmd | wc -l)
6219         [ $nums -eq $expected ] ||
6220                 error "'$cmd' wrong: found $nums, expected $expected"
6221 }
6222 run_test 56o "check lfs find -mtime for old files"
6223
6224 test_56ob() {
6225         local dir=$DIR/$tdir
6226         local expected=1
6227         local count=0
6228
6229         # just to make sure there is something that won't be found
6230         test_mkdir $dir
6231         touch $dir/$tfile.now
6232
6233         for age in year week day hour min; do
6234                 count=$((count + 1))
6235
6236                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6237                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6238                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6239
6240                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6241                 local nums=$($cmd | wc -l)
6242                 [ $nums -eq $expected ] ||
6243                         error "'$cmd' wrong: found $nums, expected $expected"
6244
6245                 cmd="$LFS find $dir -atime $count${age:0:1}"
6246                 nums=$($cmd | wc -l)
6247                 [ $nums -eq $expected ] ||
6248                         error "'$cmd' wrong: found $nums, expected $expected"
6249         done
6250
6251         sleep 2
6252         cmd="$LFS find $dir -ctime +1s -type f"
6253         nums=$($cmd | wc -l)
6254         (( $nums == $count * 2 + 1)) ||
6255                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6256 }
6257 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6258
6259 test_newerXY_base() {
6260         local x=$1
6261         local y=$2
6262         local dir=$DIR/$tdir
6263         local ref
6264         local negref
6265
6266         if [ $y == "t" ]; then
6267                 if [ $x == "b" ]; then
6268                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6269                 else
6270                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6271                 fi
6272         else
6273                 ref=$DIR/$tfile.newer.$x$y
6274                 touch $ref || error "touch $ref failed"
6275         fi
6276
6277         echo "before = $ref"
6278         sleep 2
6279         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6280         sleep 2
6281         if [ $y == "t" ]; then
6282                 if [ $x == "b" ]; then
6283                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6284                 else
6285                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6286                 fi
6287         else
6288                 negref=$DIR/$tfile.negnewer.$x$y
6289                 touch $negref || error "touch $negref failed"
6290         fi
6291
6292         echo "after = $negref"
6293         local cmd="$LFS find $dir -newer$x$y $ref"
6294         local nums=$(eval $cmd | wc -l)
6295         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6296
6297         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6298                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6299
6300         cmd="$LFS find $dir ! -newer$x$y $negref"
6301         nums=$(eval $cmd | wc -l)
6302         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6303                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6304
6305         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6306         nums=$(eval $cmd | wc -l)
6307         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6308                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6309
6310         rm -rf $DIR/*
6311 }
6312
6313 test_56oc() {
6314         test_newerXY_base "a" "a"
6315         test_newerXY_base "a" "m"
6316         test_newerXY_base "a" "c"
6317         test_newerXY_base "m" "a"
6318         test_newerXY_base "m" "m"
6319         test_newerXY_base "m" "c"
6320         test_newerXY_base "c" "a"
6321         test_newerXY_base "c" "m"
6322         test_newerXY_base "c" "c"
6323
6324         [[ -n "$sles_version" ]] &&
6325                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6326
6327         test_newerXY_base "a" "t"
6328         test_newerXY_base "m" "t"
6329         test_newerXY_base "c" "t"
6330
6331         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6332            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6333                 ! btime_supported && echo "btime unsupported" && return 0
6334
6335         test_newerXY_base "b" "b"
6336         test_newerXY_base "b" "t"
6337 }
6338 run_test 56oc "check lfs find -newerXY work"
6339
6340 btime_supported() {
6341         local dir=$DIR/$tdir
6342         local rc
6343
6344         mkdir -p $dir
6345         touch $dir/$tfile
6346         $LFS find $dir -btime -1d -type f
6347         rc=$?
6348         rm -rf $dir
6349         return $rc
6350 }
6351
6352 test_56od() {
6353         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6354                 ! btime_supported && skip "btime unsupported on MDS"
6355
6356         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6357                 ! btime_supported && skip "btime unsupported on clients"
6358
6359         local dir=$DIR/$tdir
6360         local ref=$DIR/$tfile.ref
6361         local negref=$DIR/$tfile.negref
6362
6363         mkdir $dir || error "mkdir $dir failed"
6364         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6365         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6366         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6367         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6368         touch $ref || error "touch $ref failed"
6369         # sleep 3 seconds at least
6370         sleep 3
6371
6372         local before=$(do_facet mds1 date +%s)
6373         local skew=$(($(date +%s) - before + 1))
6374
6375         if (( skew < 0 && skew > -5 )); then
6376                 sleep $((0 - skew + 1))
6377                 skew=0
6378         fi
6379
6380         # Set the dir stripe params to limit files all on MDT0,
6381         # otherwise we need to calc the max clock skew between
6382         # the client and MDTs.
6383         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6384         sleep 2
6385         touch $negref || error "touch $negref failed"
6386
6387         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6388         local nums=$($cmd | wc -l)
6389         local expected=$(((NUMFILES + 1) * NUMDIRS))
6390
6391         [ $nums -eq $expected ] ||
6392                 error "'$cmd' wrong: found $nums, expected $expected"
6393
6394         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6395         nums=$($cmd | wc -l)
6396         expected=$((NUMFILES + 1))
6397         [ $nums -eq $expected ] ||
6398                 error "'$cmd' wrong: found $nums, expected $expected"
6399
6400         [ $skew -lt 0 ] && return
6401
6402         local after=$(do_facet mds1 date +%s)
6403         local age=$((after - before + 1 + skew))
6404
6405         cmd="$LFS find $dir -btime -${age}s -type f"
6406         nums=$($cmd | wc -l)
6407         expected=$(((NUMFILES + 1) * NUMDIRS))
6408
6409         echo "Clock skew between client and server: $skew, age:$age"
6410         [ $nums -eq $expected ] ||
6411                 error "'$cmd' wrong: found $nums, expected $expected"
6412
6413         expected=$(($NUMDIRS + 1))
6414         cmd="$LFS find $dir -btime -${age}s -type d"
6415         nums=$($cmd | wc -l)
6416         [ $nums -eq $expected ] ||
6417                 error "'$cmd' wrong: found $nums, expected $expected"
6418         rm -f $ref $negref || error "Failed to remove $ref $negref"
6419 }
6420 run_test 56od "check lfs find -btime with units"
6421
6422 test_56p() {
6423         [ $RUNAS_ID -eq $UID ] &&
6424                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6425
6426         local dir=$DIR/$tdir
6427
6428         setup_56 $dir $NUMFILES $NUMDIRS
6429         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6430
6431         local expected=$NUMFILES
6432         local cmd="$LFS find -uid $RUNAS_ID $dir"
6433         local nums=$($cmd | wc -l)
6434
6435         [ $nums -eq $expected ] ||
6436                 error "'$cmd' wrong: found $nums, expected $expected"
6437
6438         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6439         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6440         nums=$($cmd | wc -l)
6441         [ $nums -eq $expected ] ||
6442                 error "'$cmd' wrong: found $nums, expected $expected"
6443 }
6444 run_test 56p "check lfs find -uid and ! -uid"
6445
6446 test_56q() {
6447         [ $RUNAS_ID -eq $UID ] &&
6448                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6449
6450         local dir=$DIR/$tdir
6451
6452         setup_56 $dir $NUMFILES $NUMDIRS
6453         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6454
6455         local expected=$NUMFILES
6456         local cmd="$LFS find -gid $RUNAS_GID $dir"
6457         local nums=$($cmd | wc -l)
6458
6459         [ $nums -eq $expected ] ||
6460                 error "'$cmd' wrong: found $nums, expected $expected"
6461
6462         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6463         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6464         nums=$($cmd | wc -l)
6465         [ $nums -eq $expected ] ||
6466                 error "'$cmd' wrong: found $nums, expected $expected"
6467 }
6468 run_test 56q "check lfs find -gid and ! -gid"
6469
6470 test_56r() {
6471         local dir=$DIR/$tdir
6472
6473         setup_56 $dir $NUMFILES $NUMDIRS
6474
6475         local expected=12
6476         local cmd="$LFS find -size 0 -type f -lazy $dir"
6477         local nums=$($cmd | wc -l)
6478
6479         [ $nums -eq $expected ] ||
6480                 error "'$cmd' wrong: found $nums, expected $expected"
6481         cmd="$LFS find -size 0 -type f $dir"
6482         nums=$($cmd | wc -l)
6483         [ $nums -eq $expected ] ||
6484                 error "'$cmd' wrong: found $nums, expected $expected"
6485
6486         expected=0
6487         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6488         nums=$($cmd | wc -l)
6489         [ $nums -eq $expected ] ||
6490                 error "'$cmd' wrong: found $nums, expected $expected"
6491         cmd="$LFS find ! -size 0 -type f $dir"
6492         nums=$($cmd | wc -l)
6493         [ $nums -eq $expected ] ||
6494                 error "'$cmd' wrong: found $nums, expected $expected"
6495
6496         echo "test" > $dir/$tfile
6497         echo "test2" > $dir/$tfile.2 && sync
6498         expected=1
6499         cmd="$LFS find -size 5 -type f -lazy $dir"
6500         nums=$($cmd | wc -l)
6501         [ $nums -eq $expected ] ||
6502                 error "'$cmd' wrong: found $nums, expected $expected"
6503         cmd="$LFS find -size 5 -type f $dir"
6504         nums=$($cmd | wc -l)
6505         [ $nums -eq $expected ] ||
6506                 error "'$cmd' wrong: found $nums, expected $expected"
6507
6508         expected=1
6509         cmd="$LFS find -size +5 -type f -lazy $dir"
6510         nums=$($cmd | wc -l)
6511         [ $nums -eq $expected ] ||
6512                 error "'$cmd' wrong: found $nums, expected $expected"
6513         cmd="$LFS find -size +5 -type f $dir"
6514         nums=$($cmd | wc -l)
6515         [ $nums -eq $expected ] ||
6516                 error "'$cmd' wrong: found $nums, expected $expected"
6517
6518         expected=2
6519         cmd="$LFS find -size +0 -type f -lazy $dir"
6520         nums=$($cmd | wc -l)
6521         [ $nums -eq $expected ] ||
6522                 error "'$cmd' wrong: found $nums, expected $expected"
6523         cmd="$LFS find -size +0 -type f $dir"
6524         nums=$($cmd | wc -l)
6525         [ $nums -eq $expected ] ||
6526                 error "'$cmd' wrong: found $nums, expected $expected"
6527
6528         expected=2
6529         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6530         nums=$($cmd | wc -l)
6531         [ $nums -eq $expected ] ||
6532                 error "'$cmd' wrong: found $nums, expected $expected"
6533         cmd="$LFS find ! -size -5 -type f $dir"
6534         nums=$($cmd | wc -l)
6535         [ $nums -eq $expected ] ||
6536                 error "'$cmd' wrong: found $nums, expected $expected"
6537
6538         expected=12
6539         cmd="$LFS find -size -5 -type f -lazy $dir"
6540         nums=$($cmd | wc -l)
6541         [ $nums -eq $expected ] ||
6542                 error "'$cmd' wrong: found $nums, expected $expected"
6543         cmd="$LFS find -size -5 -type f $dir"
6544         nums=$($cmd | wc -l)
6545         [ $nums -eq $expected ] ||
6546                 error "'$cmd' wrong: found $nums, expected $expected"
6547 }
6548 run_test 56r "check lfs find -size works"
6549
6550 test_56ra_sub() {
6551         local expected=$1
6552         local glimpses=$2
6553         local cmd="$3"
6554
6555         cancel_lru_locks $OSC
6556
6557         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6558         local nums=$($cmd | wc -l)
6559
6560         [ $nums -eq $expected ] ||
6561                 error "'$cmd' wrong: found $nums, expected $expected"
6562
6563         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6564
6565         if (( rpcs_before + glimpses != rpcs_after )); then
6566                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6567                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6568
6569                 if [[ $glimpses == 0 ]]; then
6570                         error "'$cmd' should not send glimpse RPCs to OST"
6571                 else
6572                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6573                 fi
6574         fi
6575 }
6576
6577 test_56ra() {
6578         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6579                 skip "MDS < 2.12.58 doesn't return LSOM data"
6580         local dir=$DIR/$tdir
6581         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6582
6583         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6584
6585         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6586         $LCTL set_param -n llite.*.statahead_agl=0
6587         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6588
6589         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6590         # open and close all files to ensure LSOM is updated
6591         cancel_lru_locks $OSC
6592         find $dir -type f | xargs cat > /dev/null
6593
6594         #   expect_found  glimpse_rpcs  command_to_run
6595         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6596         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6597         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6598         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6599
6600         echo "test" > $dir/$tfile
6601         echo "test2" > $dir/$tfile.2 && sync
6602         cancel_lru_locks $OSC
6603         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6604
6605         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6606         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6607         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6608         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6609
6610         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6611         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6612         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6613         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6614         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6615         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6616 }
6617 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6618
6619 test_56rb() {
6620         local dir=$DIR/$tdir
6621         local tmp=$TMP/$tfile.log
6622         local mdt_idx;
6623
6624         test_mkdir -p $dir || error "failed to mkdir $dir"
6625         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6626                 error "failed to setstripe $dir/$tfile"
6627         mdt_idx=$($LFS getdirstripe -i $dir)
6628         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6629
6630         stack_trap "rm -f $tmp" EXIT
6631         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6632         ! grep -q obd_uuid $tmp ||
6633                 error "failed to find --size +100K --ost 0 $dir"
6634         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6635         ! grep -q obd_uuid $tmp ||
6636                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6637 }
6638 run_test 56rb "check lfs find --size --ost/--mdt works"
6639
6640 test_56s() { # LU-611 #LU-9369
6641         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6642
6643         local dir=$DIR/$tdir
6644         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6645
6646         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6647         for i in $(seq $NUMDIRS); do
6648                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6649         done
6650
6651         local expected=$NUMDIRS
6652         local cmd="$LFS find -c $OSTCOUNT $dir"
6653         local nums=$($cmd | wc -l)
6654
6655         [ $nums -eq $expected ] || {
6656                 $LFS getstripe -R $dir
6657                 error "'$cmd' wrong: found $nums, expected $expected"
6658         }
6659
6660         expected=$((NUMDIRS + onestripe))
6661         cmd="$LFS find -stripe-count +0 -type f $dir"
6662         nums=$($cmd | wc -l)
6663         [ $nums -eq $expected ] || {
6664                 $LFS getstripe -R $dir
6665                 error "'$cmd' wrong: found $nums, expected $expected"
6666         }
6667
6668         expected=$onestripe
6669         cmd="$LFS find -stripe-count 1 -type f $dir"
6670         nums=$($cmd | wc -l)
6671         [ $nums -eq $expected ] || {
6672                 $LFS getstripe -R $dir
6673                 error "'$cmd' wrong: found $nums, expected $expected"
6674         }
6675
6676         cmd="$LFS find -stripe-count -2 -type f $dir"
6677         nums=$($cmd | wc -l)
6678         [ $nums -eq $expected ] || {
6679                 $LFS getstripe -R $dir
6680                 error "'$cmd' wrong: found $nums, expected $expected"
6681         }
6682
6683         expected=0
6684         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6685         nums=$($cmd | wc -l)
6686         [ $nums -eq $expected ] || {
6687                 $LFS getstripe -R $dir
6688                 error "'$cmd' wrong: found $nums, expected $expected"
6689         }
6690 }
6691 run_test 56s "check lfs find -stripe-count works"
6692
6693 test_56t() { # LU-611 #LU-9369
6694         local dir=$DIR/$tdir
6695
6696         setup_56 $dir 0 $NUMDIRS
6697         for i in $(seq $NUMDIRS); do
6698                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6699         done
6700
6701         local expected=$NUMDIRS
6702         local cmd="$LFS find -S 8M $dir"
6703         local nums=$($cmd | wc -l)
6704
6705         [ $nums -eq $expected ] || {
6706                 $LFS getstripe -R $dir
6707                 error "'$cmd' wrong: found $nums, expected $expected"
6708         }
6709         rm -rf $dir
6710
6711         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6712
6713         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6714
6715         expected=$(((NUMDIRS + 1) * NUMFILES))
6716         cmd="$LFS find -stripe-size 512k -type f $dir"
6717         nums=$($cmd | wc -l)
6718         [ $nums -eq $expected ] ||
6719                 error "'$cmd' wrong: found $nums, expected $expected"
6720
6721         cmd="$LFS find -stripe-size +320k -type f $dir"
6722         nums=$($cmd | wc -l)
6723         [ $nums -eq $expected ] ||
6724                 error "'$cmd' wrong: found $nums, expected $expected"
6725
6726         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6727         cmd="$LFS find -stripe-size +200k -type f $dir"
6728         nums=$($cmd | wc -l)
6729         [ $nums -eq $expected ] ||
6730                 error "'$cmd' wrong: found $nums, expected $expected"
6731
6732         cmd="$LFS find -stripe-size -640k -type f $dir"
6733         nums=$($cmd | wc -l)
6734         [ $nums -eq $expected ] ||
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736
6737         expected=4
6738         cmd="$LFS find -stripe-size 256k -type f $dir"
6739         nums=$($cmd | wc -l)
6740         [ $nums -eq $expected ] ||
6741                 error "'$cmd' wrong: found $nums, expected $expected"
6742
6743         cmd="$LFS find -stripe-size -320k -type f $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] ||
6746                 error "'$cmd' wrong: found $nums, expected $expected"
6747
6748         expected=0
6749         cmd="$LFS find -stripe-size 1024k -type f $dir"
6750         nums=$($cmd | wc -l)
6751         [ $nums -eq $expected ] ||
6752                 error "'$cmd' wrong: found $nums, expected $expected"
6753 }
6754 run_test 56t "check lfs find -stripe-size works"
6755
6756 test_56u() { # LU-611
6757         local dir=$DIR/$tdir
6758
6759         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6760
6761         if [[ $OSTCOUNT -gt 1 ]]; then
6762                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6763                 onestripe=4
6764         else
6765                 onestripe=0
6766         fi
6767
6768         local expected=$(((NUMDIRS + 1) * NUMFILES))
6769         local cmd="$LFS find -stripe-index 0 -type f $dir"
6770         local nums=$($cmd | wc -l)
6771
6772         [ $nums -eq $expected ] ||
6773                 error "'$cmd' wrong: found $nums, expected $expected"
6774
6775         expected=$onestripe
6776         cmd="$LFS find -stripe-index 1 -type f $dir"
6777         nums=$($cmd | wc -l)
6778         [ $nums -eq $expected ] ||
6779                 error "'$cmd' wrong: found $nums, expected $expected"
6780
6781         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6782         nums=$($cmd | wc -l)
6783         [ $nums -eq $expected ] ||
6784                 error "'$cmd' wrong: found $nums, expected $expected"
6785
6786         expected=0
6787         # This should produce an error and not return any files
6788         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6789         nums=$($cmd 2>/dev/null | wc -l)
6790         [ $nums -eq $expected ] ||
6791                 error "'$cmd' wrong: found $nums, expected $expected"
6792
6793         if [[ $OSTCOUNT -gt 1 ]]; then
6794                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6795                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6796                 nums=$($cmd | wc -l)
6797                 [ $nums -eq $expected ] ||
6798                         error "'$cmd' wrong: found $nums, expected $expected"
6799         fi
6800 }
6801 run_test 56u "check lfs find -stripe-index works"
6802
6803 test_56v() {
6804         local mdt_idx=0
6805         local dir=$DIR/$tdir
6806
6807         setup_56 $dir $NUMFILES $NUMDIRS
6808
6809         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6810         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6811
6812         for file in $($LFS find -m $UUID $dir); do
6813                 file_midx=$($LFS getstripe -m $file)
6814                 [ $file_midx -eq $mdt_idx ] ||
6815                         error "lfs find -m $UUID != getstripe -m $file_midx"
6816         done
6817 }
6818 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6819
6820 test_56w() {
6821         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6823
6824         local dir=$DIR/$tdir
6825
6826         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6827
6828         local stripe_size=$($LFS getstripe -S -d $dir) ||
6829                 error "$LFS getstripe -S -d $dir failed"
6830         stripe_size=${stripe_size%% *}
6831
6832         local file_size=$((stripe_size * OSTCOUNT))
6833         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6834         local required_space=$((file_num * file_size))
6835         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6836                            head -n1)
6837         [[ $free_space -le $((required_space / 1024)) ]] &&
6838                 skip_env "need $required_space, have $free_space kbytes"
6839
6840         local dd_bs=65536
6841         local dd_count=$((file_size / dd_bs))
6842
6843         # write data into the files
6844         local i
6845         local j
6846         local file
6847
6848         for i in $(seq $NUMFILES); do
6849                 file=$dir/file$i
6850                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6851                         error "write data into $file failed"
6852         done
6853         for i in $(seq $NUMDIRS); do
6854                 for j in $(seq $NUMFILES); do
6855                         file=$dir/dir$i/file$j
6856                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6857                                 error "write data into $file failed"
6858                 done
6859         done
6860
6861         # $LFS_MIGRATE will fail if hard link migration is unsupported
6862         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6863                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6864                         error "creating links to $dir/dir1/file1 failed"
6865         fi
6866
6867         local expected=-1
6868
6869         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6870
6871         # lfs_migrate file
6872         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6873
6874         echo "$cmd"
6875         eval $cmd || error "$cmd failed"
6876
6877         check_stripe_count $dir/file1 $expected
6878
6879         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6880         then
6881                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6882                 # OST 1 if it is on OST 0. This file is small enough to
6883                 # be on only one stripe.
6884                 file=$dir/migr_1_ost
6885                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6886                         error "write data into $file failed"
6887                 local obdidx=$($LFS getstripe -i $file)
6888                 local oldmd5=$(md5sum $file)
6889                 local newobdidx=0
6890
6891                 [[ $obdidx -eq 0 ]] && newobdidx=1
6892                 cmd="$LFS migrate -i $newobdidx $file"
6893                 echo $cmd
6894                 eval $cmd || error "$cmd failed"
6895
6896                 local realobdix=$($LFS getstripe -i $file)
6897                 local newmd5=$(md5sum $file)
6898
6899                 [[ $newobdidx -ne $realobdix ]] &&
6900                         error "new OST is different (was=$obdidx, "\
6901                               "wanted=$newobdidx, got=$realobdix)"
6902                 [[ "$oldmd5" != "$newmd5" ]] &&
6903                         error "md5sum differ: $oldmd5, $newmd5"
6904         fi
6905
6906         # lfs_migrate dir
6907         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6908         echo "$cmd"
6909         eval $cmd || error "$cmd failed"
6910
6911         for j in $(seq $NUMFILES); do
6912                 check_stripe_count $dir/dir1/file$j $expected
6913         done
6914
6915         # lfs_migrate works with lfs find
6916         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6917              $LFS_MIGRATE -y -c $expected"
6918         echo "$cmd"
6919         eval $cmd || error "$cmd failed"
6920
6921         for i in $(seq 2 $NUMFILES); do
6922                 check_stripe_count $dir/file$i $expected
6923         done
6924         for i in $(seq 2 $NUMDIRS); do
6925                 for j in $(seq $NUMFILES); do
6926                 check_stripe_count $dir/dir$i/file$j $expected
6927                 done
6928         done
6929 }
6930 run_test 56w "check lfs_migrate -c stripe_count works"
6931
6932 test_56wb() {
6933         local file1=$DIR/$tdir/file1
6934         local create_pool=false
6935         local initial_pool=$($LFS getstripe -p $DIR)
6936         local pool_list=()
6937         local pool=""
6938
6939         echo -n "Creating test dir..."
6940         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6941         echo "done."
6942
6943         echo -n "Creating test file..."
6944         touch $file1 || error "cannot create file"
6945         echo "done."
6946
6947         echo -n "Detecting existing pools..."
6948         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6949
6950         if [ ${#pool_list[@]} -gt 0 ]; then
6951                 echo "${pool_list[@]}"
6952                 for thispool in "${pool_list[@]}"; do
6953                         if [[ -z "$initial_pool" ||
6954                               "$initial_pool" != "$thispool" ]]; then
6955                                 pool="$thispool"
6956                                 echo "Using existing pool '$pool'"
6957                                 break
6958                         fi
6959                 done
6960         else
6961                 echo "none detected."
6962         fi
6963         if [ -z "$pool" ]; then
6964                 pool=${POOL:-testpool}
6965                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6966                 echo -n "Creating pool '$pool'..."
6967                 create_pool=true
6968                 pool_add $pool &> /dev/null ||
6969                         error "pool_add failed"
6970                 echo "done."
6971
6972                 echo -n "Adding target to pool..."
6973                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6974                         error "pool_add_targets failed"
6975                 echo "done."
6976         fi
6977
6978         echo -n "Setting pool using -p option..."
6979         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6980                 error "migrate failed rc = $?"
6981         echo "done."
6982
6983         echo -n "Verifying test file is in pool after migrating..."
6984         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6985                 error "file was not migrated to pool $pool"
6986         echo "done."
6987
6988         echo -n "Removing test file from pool '$pool'..."
6989         # "lfs migrate $file" won't remove the file from the pool
6990         # until some striping information is changed.
6991         $LFS migrate -c 1 $file1 &> /dev/null ||
6992                 error "cannot remove from pool"
6993         [ "$($LFS getstripe -p $file1)" ] &&
6994                 error "pool still set"
6995         echo "done."
6996
6997         echo -n "Setting pool using --pool option..."
6998         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6999                 error "migrate failed rc = $?"
7000         echo "done."
7001
7002         # Clean up
7003         rm -f $file1
7004         if $create_pool; then
7005                 destroy_test_pools 2> /dev/null ||
7006                         error "destroy test pools failed"
7007         fi
7008 }
7009 run_test 56wb "check lfs_migrate pool support"
7010
7011 test_56wc() {
7012         local file1="$DIR/$tdir/file1"
7013         local parent_ssize
7014         local parent_scount
7015         local cur_ssize
7016         local cur_scount
7017         local orig_ssize
7018
7019         echo -n "Creating test dir..."
7020         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7021         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7022                 error "cannot set stripe by '-S 1M -c 1'"
7023         echo "done"
7024
7025         echo -n "Setting initial stripe for test file..."
7026         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7027                 error "cannot set stripe"
7028         cur_ssize=$($LFS getstripe -S "$file1")
7029         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7030         echo "done."
7031
7032         # File currently set to -S 512K -c 1
7033
7034         # Ensure -c and -S options are rejected when -R is set
7035         echo -n "Verifying incompatible options are detected..."
7036         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7037                 error "incompatible -c and -R options not detected"
7038         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7039                 error "incompatible -S and -R options not detected"
7040         echo "done."
7041
7042         # Ensure unrecognized options are passed through to 'lfs migrate'
7043         echo -n "Verifying -S option is passed through to lfs migrate..."
7044         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7045                 error "migration failed"
7046         cur_ssize=$($LFS getstripe -S "$file1")
7047         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7048         echo "done."
7049
7050         # File currently set to -S 1M -c 1
7051
7052         # Ensure long options are supported
7053         echo -n "Verifying long options supported..."
7054         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7055                 error "long option without argument not supported"
7056         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7057                 error "long option with argument not supported"
7058         cur_ssize=$($LFS getstripe -S "$file1")
7059         [ $cur_ssize -eq 524288 ] ||
7060                 error "migrate --stripe-size $cur_ssize != 524288"
7061         echo "done."
7062
7063         # File currently set to -S 512K -c 1
7064
7065         if [ "$OSTCOUNT" -gt 1 ]; then
7066                 echo -n "Verifying explicit stripe count can be set..."
7067                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7068                         error "migrate failed"
7069                 cur_scount=$($LFS getstripe -c "$file1")
7070                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7071                 echo "done."
7072         fi
7073
7074         # File currently set to -S 512K -c 1 or -S 512K -c 2
7075
7076         # Ensure parent striping is used if -R is set, and no stripe
7077         # count or size is specified
7078         echo -n "Setting stripe for parent directory..."
7079         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7080                 error "cannot set stripe '-S 2M -c 1'"
7081         echo "done."
7082
7083         echo -n "Verifying restripe option uses parent stripe settings..."
7084         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7085         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7086         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7087                 error "migrate failed"
7088         cur_ssize=$($LFS getstripe -S "$file1")
7089         [ $cur_ssize -eq $parent_ssize ] ||
7090                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7091         cur_scount=$($LFS getstripe -c "$file1")
7092         [ $cur_scount -eq $parent_scount ] ||
7093                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7094         echo "done."
7095
7096         # File currently set to -S 1M -c 1
7097
7098         # Ensure striping is preserved if -R is not set, and no stripe
7099         # count or size is specified
7100         echo -n "Verifying striping size preserved when not specified..."
7101         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7102         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7103                 error "cannot set stripe on parent directory"
7104         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7105                 error "migrate failed"
7106         cur_ssize=$($LFS getstripe -S "$file1")
7107         [ $cur_ssize -eq $orig_ssize ] ||
7108                 error "migrate by default $cur_ssize != $orig_ssize"
7109         echo "done."
7110
7111         # Ensure file name properly detected when final option has no argument
7112         echo -n "Verifying file name properly detected..."
7113         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7114                 error "file name interpreted as option argument"
7115         echo "done."
7116
7117         # Clean up
7118         rm -f "$file1"
7119 }
7120 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7121
7122 test_56wd() {
7123         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7124
7125         local file1=$DIR/$tdir/file1
7126
7127         echo -n "Creating test dir..."
7128         test_mkdir $DIR/$tdir || error "cannot create dir"
7129         echo "done."
7130
7131         echo -n "Creating test file..."
7132         touch $file1
7133         echo "done."
7134
7135         # Ensure 'lfs migrate' will fail by using a non-existent option,
7136         # and make sure rsync is not called to recover
7137         echo -n "Make sure --no-rsync option works..."
7138         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7139                 grep -q 'refusing to fall back to rsync' ||
7140                 error "rsync was called with --no-rsync set"
7141         echo "done."
7142
7143         # Ensure rsync is called without trying 'lfs migrate' first
7144         echo -n "Make sure --rsync option works..."
7145         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7146                 grep -q 'falling back to rsync' &&
7147                 error "lfs migrate was called with --rsync set"
7148         echo "done."
7149
7150         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7151         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7152                 grep -q 'at the same time' ||
7153                 error "--rsync and --no-rsync accepted concurrently"
7154         echo "done."
7155
7156         # Clean up
7157         rm -f $file1
7158 }
7159 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7160
7161 test_56we() {
7162         local td=$DIR/$tdir
7163         local tf=$td/$tfile
7164
7165         test_mkdir $td || error "cannot create $td"
7166         touch $tf || error "cannot touch $tf"
7167
7168         echo -n "Make sure --non-direct|-D works..."
7169         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7170                 grep -q "lfs migrate --non-direct" ||
7171                 error "--non-direct option cannot work correctly"
7172         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7173                 grep -q "lfs migrate -D" ||
7174                 error "-D option cannot work correctly"
7175         echo "done."
7176 }
7177 run_test 56we "check lfs_migrate --non-direct|-D support"
7178
7179 test_56x() {
7180         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7181         check_swap_layouts_support
7182
7183         local dir=$DIR/$tdir
7184         local ref1=/etc/passwd
7185         local file1=$dir/file1
7186
7187         test_mkdir $dir || error "creating dir $dir"
7188         $LFS setstripe -c 2 $file1
7189         cp $ref1 $file1
7190         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7191         stripe=$($LFS getstripe -c $file1)
7192         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7193         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7194
7195         # clean up
7196         rm -f $file1
7197 }
7198 run_test 56x "lfs migration support"
7199
7200 test_56xa() {
7201         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7202         check_swap_layouts_support
7203
7204         local dir=$DIR/$tdir/$testnum
7205
7206         test_mkdir -p $dir
7207
7208         local ref1=/etc/passwd
7209         local file1=$dir/file1
7210
7211         $LFS setstripe -c 2 $file1
7212         cp $ref1 $file1
7213         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7214
7215         local stripe=$($LFS getstripe -c $file1)
7216
7217         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7218         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7219
7220         # clean up
7221         rm -f $file1
7222 }
7223 run_test 56xa "lfs migration --block support"
7224
7225 check_migrate_links() {
7226         local dir="$1"
7227         local file1="$dir/file1"
7228         local begin="$2"
7229         local count="$3"
7230         local runas="$4"
7231         local total_count=$(($begin + $count - 1))
7232         local symlink_count=10
7233         local uniq_count=10
7234
7235         if [ ! -f "$file1" ]; then
7236                 echo -n "creating initial file..."
7237                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7238                         error "cannot setstripe initial file"
7239                 echo "done"
7240
7241                 echo -n "creating symlinks..."
7242                 for s in $(seq 1 $symlink_count); do
7243                         ln -s "$file1" "$dir/slink$s" ||
7244                                 error "cannot create symlinks"
7245                 done
7246                 echo "done"
7247
7248                 echo -n "creating nonlinked files..."
7249                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7250                         error "cannot create nonlinked files"
7251                 echo "done"
7252         fi
7253
7254         # create hard links
7255         if [ ! -f "$dir/file$total_count" ]; then
7256                 echo -n "creating hard links $begin:$total_count..."
7257                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7258                         /dev/null || error "cannot create hard links"
7259                 echo "done"
7260         fi
7261
7262         echo -n "checking number of hard links listed in xattrs..."
7263         local fid=$($LFS getstripe -F "$file1")
7264         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7265
7266         echo "${#paths[*]}"
7267         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7268                         skip "hard link list has unexpected size, skipping test"
7269         fi
7270         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7271                         error "link names should exceed xattrs size"
7272         fi
7273
7274         echo -n "migrating files..."
7275         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7276         local rc=$?
7277         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7278         echo "done"
7279
7280         # make sure all links have been properly migrated
7281         echo -n "verifying files..."
7282         fid=$($LFS getstripe -F "$file1") ||
7283                 error "cannot get fid for file $file1"
7284         for i in $(seq 2 $total_count); do
7285                 local fid2=$($LFS getstripe -F $dir/file$i)
7286
7287                 [ "$fid2" == "$fid" ] ||
7288                         error "migrated hard link has mismatched FID"
7289         done
7290
7291         # make sure hard links were properly detected, and migration was
7292         # performed only once for the entire link set; nonlinked files should
7293         # also be migrated
7294         local actual=$(grep -c 'done' <<< "$migrate_out")
7295         local expected=$(($uniq_count + 1))
7296
7297         [ "$actual" -eq  "$expected" ] ||
7298                 error "hard links individually migrated ($actual != $expected)"
7299
7300         # make sure the correct number of hard links are present
7301         local hardlinks=$(stat -c '%h' "$file1")
7302
7303         [ $hardlinks -eq $total_count ] ||
7304                 error "num hard links $hardlinks != $total_count"
7305         echo "done"
7306
7307         return 0
7308 }
7309
7310 test_56xb() {
7311         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7312                 skip "Need MDS version at least 2.10.55"
7313
7314         local dir="$DIR/$tdir"
7315
7316         test_mkdir "$dir" || error "cannot create dir $dir"
7317
7318         echo "testing lfs migrate mode when all links fit within xattrs"
7319         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7320
7321         echo "testing rsync mode when all links fit within xattrs"
7322         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7323
7324         echo "testing lfs migrate mode when all links do not fit within xattrs"
7325         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7326
7327         echo "testing rsync mode when all links do not fit within xattrs"
7328         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7329
7330         chown -R $RUNAS_ID $dir
7331         echo "testing non-root lfs migrate mode when not all links are in xattr"
7332         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7333
7334         # clean up
7335         rm -rf $dir
7336 }
7337 run_test 56xb "lfs migration hard link support"
7338
7339 test_56xc() {
7340         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7341
7342         local dir="$DIR/$tdir"
7343
7344         test_mkdir "$dir" || error "cannot create dir $dir"
7345
7346         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7347         echo -n "Setting initial stripe for 20MB test file..."
7348         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7349                 error "cannot setstripe 20MB file"
7350         echo "done"
7351         echo -n "Sizing 20MB test file..."
7352         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7353         echo "done"
7354         echo -n "Verifying small file autostripe count is 1..."
7355         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7356                 error "cannot migrate 20MB file"
7357         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7358                 error "cannot get stripe for $dir/20mb"
7359         [ $stripe_count -eq 1 ] ||
7360                 error "unexpected stripe count $stripe_count for 20MB file"
7361         rm -f "$dir/20mb"
7362         echo "done"
7363
7364         # Test 2: File is small enough to fit within the available space on
7365         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7366         # have at least an additional 1KB for each desired stripe for test 3
7367         echo -n "Setting stripe for 1GB test file..."
7368         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7369         echo "done"
7370         echo -n "Sizing 1GB test file..."
7371         # File size is 1GB + 3KB
7372         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7373         echo "done"
7374
7375         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7376         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7377         if (( avail > 524288 * OSTCOUNT )); then
7378                 echo -n "Migrating 1GB file..."
7379                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7380                         error "cannot migrate 1GB file"
7381                 echo "done"
7382                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7383                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7384                         error "cannot getstripe for 1GB file"
7385                 [ $stripe_count -eq 2 ] ||
7386                         error "unexpected stripe count $stripe_count != 2"
7387                 echo "done"
7388         fi
7389
7390         # Test 3: File is too large to fit within the available space on
7391         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7392         if [ $OSTCOUNT -ge 3 ]; then
7393                 # The required available space is calculated as
7394                 # file size (1GB + 3KB) / OST count (3).
7395                 local kb_per_ost=349526
7396
7397                 echo -n "Migrating 1GB file with limit..."
7398                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7399                         error "cannot migrate 1GB file with limit"
7400                 echo "done"
7401
7402                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7403                 echo -n "Verifying 1GB autostripe count with limited space..."
7404                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7405                         error "unexpected stripe count $stripe_count (min 3)"
7406                 echo "done"
7407         fi
7408
7409         # clean up
7410         rm -rf $dir
7411 }
7412 run_test 56xc "lfs migration autostripe"
7413
7414 test_56xd() {
7415         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7416
7417         local dir=$DIR/$tdir
7418         local f_mgrt=$dir/$tfile.mgrt
7419         local f_yaml=$dir/$tfile.yaml
7420         local f_copy=$dir/$tfile.copy
7421         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7422         local layout_copy="-c 2 -S 2M -i 1"
7423         local yamlfile=$dir/yamlfile
7424         local layout_before;
7425         local layout_after;
7426
7427         test_mkdir "$dir" || error "cannot create dir $dir"
7428         $LFS setstripe $layout_yaml $f_yaml ||
7429                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7430         $LFS getstripe --yaml $f_yaml > $yamlfile
7431         $LFS setstripe $layout_copy $f_copy ||
7432                 error "cannot setstripe $f_copy with layout $layout_copy"
7433         touch $f_mgrt
7434         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7435
7436         # 1. test option --yaml
7437         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7438                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7439         layout_before=$(get_layout_param $f_yaml)
7440         layout_after=$(get_layout_param $f_mgrt)
7441         [ "$layout_after" == "$layout_before" ] ||
7442                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7443
7444         # 2. test option --copy
7445         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7446                 error "cannot migrate $f_mgrt with --copy $f_copy"
7447         layout_before=$(get_layout_param $f_copy)
7448         layout_after=$(get_layout_param $f_mgrt)
7449         [ "$layout_after" == "$layout_before" ] ||
7450                 error "lfs_migrate --copy: $layout_after != $layout_before"
7451 }
7452 run_test 56xd "check lfs_migrate --yaml and --copy support"
7453
7454 test_56xe() {
7455         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7456
7457         local dir=$DIR/$tdir
7458         local f_comp=$dir/$tfile
7459         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7460         local layout_before=""
7461         local layout_after=""
7462
7463         test_mkdir "$dir" || error "cannot create dir $dir"
7464         $LFS setstripe $layout $f_comp ||
7465                 error "cannot setstripe $f_comp with layout $layout"
7466         layout_before=$(get_layout_param $f_comp)
7467         dd if=/dev/zero of=$f_comp bs=1M count=4
7468
7469         # 1. migrate a comp layout file by lfs_migrate
7470         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7471         layout_after=$(get_layout_param $f_comp)
7472         [ "$layout_before" == "$layout_after" ] ||
7473                 error "lfs_migrate: $layout_before != $layout_after"
7474
7475         # 2. migrate a comp layout file by lfs migrate
7476         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7477         layout_after=$(get_layout_param $f_comp)
7478         [ "$layout_before" == "$layout_after" ] ||
7479                 error "lfs migrate: $layout_before != $layout_after"
7480 }
7481 run_test 56xe "migrate a composite layout file"
7482
7483 test_56xf() {
7484         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7485
7486         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7487                 skip "Need server version at least 2.13.53"
7488
7489         local dir=$DIR/$tdir
7490         local f_comp=$dir/$tfile
7491         local layout="-E 1M -c1 -E -1 -c2"
7492         local fid_before=""
7493         local fid_after=""
7494
7495         test_mkdir "$dir" || error "cannot create dir $dir"
7496         $LFS setstripe $layout $f_comp ||
7497                 error "cannot setstripe $f_comp with layout $layout"
7498         fid_before=$($LFS getstripe --fid $f_comp)
7499         dd if=/dev/zero of=$f_comp bs=1M count=4
7500
7501         # 1. migrate a comp layout file to a comp layout
7502         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7503         fid_after=$($LFS getstripe --fid $f_comp)
7504         [ "$fid_before" == "$fid_after" ] ||
7505                 error "comp-to-comp migrate: $fid_before != $fid_after"
7506
7507         # 2. migrate a comp layout file to a plain layout
7508         $LFS migrate -c2 $f_comp ||
7509                 error "cannot migrate $f_comp by lfs migrate"
7510         fid_after=$($LFS getstripe --fid $f_comp)
7511         [ "$fid_before" == "$fid_after" ] ||
7512                 error "comp-to-plain migrate: $fid_before != $fid_after"
7513
7514         # 3. migrate a plain layout file to a comp layout
7515         $LFS migrate $layout $f_comp ||
7516                 error "cannot migrate $f_comp by lfs migrate"
7517         fid_after=$($LFS getstripe --fid $f_comp)
7518         [ "$fid_before" == "$fid_after" ] ||
7519                 error "plain-to-comp migrate: $fid_before != $fid_after"
7520 }
7521 run_test 56xf "FID is not lost during migration of a composite layout file"
7522
7523 test_56y() {
7524         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7525                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7526
7527         local res=""
7528         local dir=$DIR/$tdir
7529         local f1=$dir/file1
7530         local f2=$dir/file2
7531
7532         test_mkdir -p $dir || error "creating dir $dir"
7533         touch $f1 || error "creating std file $f1"
7534         $MULTIOP $f2 H2c || error "creating released file $f2"
7535
7536         # a directory can be raid0, so ask only for files
7537         res=$($LFS find $dir -L raid0 -type f | wc -l)
7538         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7539
7540         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7541         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7542
7543         # only files can be released, so no need to force file search
7544         res=$($LFS find $dir -L released)
7545         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7546
7547         res=$($LFS find $dir -type f \! -L released)
7548         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7549 }
7550 run_test 56y "lfs find -L raid0|released"
7551
7552 test_56z() { # LU-4824
7553         # This checks to make sure 'lfs find' continues after errors
7554         # There are two classes of errors that should be caught:
7555         # - If multiple paths are provided, all should be searched even if one
7556         #   errors out
7557         # - If errors are encountered during the search, it should not terminate
7558         #   early
7559         local dir=$DIR/$tdir
7560         local i
7561
7562         test_mkdir $dir
7563         for i in d{0..9}; do
7564                 test_mkdir $dir/$i
7565                 touch $dir/$i/$tfile
7566         done
7567         $LFS find $DIR/non_existent_dir $dir &&
7568                 error "$LFS find did not return an error"
7569         # Make a directory unsearchable. This should NOT be the last entry in
7570         # directory order.  Arbitrarily pick the 6th entry
7571         chmod 700 $($LFS find $dir -type d | sed '6!d')
7572
7573         $RUNAS $LFS find $DIR/non_existent $dir
7574         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7575
7576         # The user should be able to see 10 directories and 9 files
7577         (( count == 19 )) ||
7578                 error "$LFS find found $count != 19 entries after error"
7579 }
7580 run_test 56z "lfs find should continue after an error"
7581
7582 test_56aa() { # LU-5937
7583         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7584
7585         local dir=$DIR/$tdir
7586
7587         mkdir $dir
7588         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7589
7590         createmany -o $dir/striped_dir/${tfile}- 1024
7591         local dirs=$($LFS find --size +8k $dir/)
7592
7593         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7594 }
7595 run_test 56aa "lfs find --size under striped dir"
7596
7597 test_56ab() { # LU-10705
7598         test_mkdir $DIR/$tdir
7599         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7600         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7601         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7602         # Flush writes to ensure valid blocks.  Need to be more thorough for
7603         # ZFS, since blocks are not allocated/returned to client immediately.
7604         sync_all_data
7605         wait_zfs_commit ost1 2
7606         cancel_lru_locks osc
7607         ls -ls $DIR/$tdir
7608
7609         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7610
7611         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7612
7613         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7614         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7615
7616         rm -f $DIR/$tdir/$tfile.[123]
7617 }
7618 run_test 56ab "lfs find --blocks"
7619
7620 test_56ba() {
7621         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7622                 skip "Need MDS version at least 2.10.50"
7623
7624         # Create composite files with one component
7625         local dir=$DIR/$tdir
7626
7627         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7628         # Create composite files with three components
7629         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7630         # Create non-composite files
7631         createmany -o $dir/${tfile}- 10
7632
7633         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7634
7635         [[ $nfiles == 10 ]] ||
7636                 error "lfs find -E 1M found $nfiles != 10 files"
7637
7638         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7639         [[ $nfiles == 25 ]] ||
7640                 error "lfs find ! -E 1M found $nfiles != 25 files"
7641
7642         # All files have a component that starts at 0
7643         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7644         [[ $nfiles == 35 ]] ||
7645                 error "lfs find --component-start 0 - $nfiles != 35 files"
7646
7647         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7648         [[ $nfiles == 15 ]] ||
7649                 error "lfs find --component-start 2M - $nfiles != 15 files"
7650
7651         # All files created here have a componenet that does not starts at 2M
7652         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7653         [[ $nfiles == 35 ]] ||
7654                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7655
7656         # Find files with a specified number of components
7657         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7658         [[ $nfiles == 15 ]] ||
7659                 error "lfs find --component-count 3 - $nfiles != 15 files"
7660
7661         # Remember non-composite files have a component count of zero
7662         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7663         [[ $nfiles == 10 ]] ||
7664                 error "lfs find --component-count 0 - $nfiles != 10 files"
7665
7666         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7667         [[ $nfiles == 20 ]] ||
7668                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7669
7670         # All files have a flag called "init"
7671         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7672         [[ $nfiles == 35 ]] ||
7673                 error "lfs find --component-flags init - $nfiles != 35 files"
7674
7675         # Multi-component files will have a component not initialized
7676         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7677         [[ $nfiles == 15 ]] ||
7678                 error "lfs find !--component-flags init - $nfiles != 15 files"
7679
7680         rm -rf $dir
7681
7682 }
7683 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7684
7685 test_56ca() {
7686         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7687                 skip "Need MDS version at least 2.10.57"
7688
7689         local td=$DIR/$tdir
7690         local tf=$td/$tfile
7691         local dir
7692         local nfiles
7693         local cmd
7694         local i
7695         local j
7696
7697         # create mirrored directories and mirrored files
7698         mkdir $td || error "mkdir $td failed"
7699         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7700         createmany -o $tf- 10 || error "create $tf- failed"
7701
7702         for i in $(seq 2); do
7703                 dir=$td/dir$i
7704                 mkdir $dir || error "mkdir $dir failed"
7705                 $LFS mirror create -N$((3 + i)) $dir ||
7706                         error "create mirrored dir $dir failed"
7707                 createmany -o $dir/$tfile- 10 ||
7708                         error "create $dir/$tfile- failed"
7709         done
7710
7711         # change the states of some mirrored files
7712         echo foo > $tf-6
7713         for i in $(seq 2); do
7714                 dir=$td/dir$i
7715                 for j in $(seq 4 9); do
7716                         echo foo > $dir/$tfile-$j
7717                 done
7718         done
7719
7720         # find mirrored files with specific mirror count
7721         cmd="$LFS find --mirror-count 3 --type f $td"
7722         nfiles=$($cmd | wc -l)
7723         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7724
7725         cmd="$LFS find ! --mirror-count 3 --type f $td"
7726         nfiles=$($cmd | wc -l)
7727         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7728
7729         cmd="$LFS find --mirror-count +2 --type f $td"
7730         nfiles=$($cmd | wc -l)
7731         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7732
7733         cmd="$LFS find --mirror-count -6 --type f $td"
7734         nfiles=$($cmd | wc -l)
7735         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7736
7737         # find mirrored files with specific file state
7738         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7739         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7740
7741         cmd="$LFS find --mirror-state=ro --type f $td"
7742         nfiles=$($cmd | wc -l)
7743         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7744
7745         cmd="$LFS find ! --mirror-state=ro --type f $td"
7746         nfiles=$($cmd | wc -l)
7747         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7748
7749         cmd="$LFS find --mirror-state=wp --type f $td"
7750         nfiles=$($cmd | wc -l)
7751         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7752
7753         cmd="$LFS find ! --mirror-state=sp --type f $td"
7754         nfiles=$($cmd | wc -l)
7755         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7756 }
7757 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7758
7759 test_56da() { # LU-14179
7760         local path=$DIR/$tdir
7761
7762         test_mkdir $path
7763         cd $path
7764
7765         local longdir=$(str_repeat 'a' 255)
7766
7767         for i in {1..15}; do
7768                 path=$path/$longdir
7769                 test_mkdir $longdir
7770                 cd $longdir
7771         done
7772
7773         local len=${#path}
7774         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7775
7776         test_mkdir $lastdir
7777         cd $lastdir
7778         # PATH_MAX-1
7779         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7780
7781         # NAME_MAX
7782         touch $(str_repeat 'f' 255)
7783
7784         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7785                 error "lfs find reported an error"
7786
7787         rm -rf $DIR/$tdir
7788 }
7789 run_test 56da "test lfs find with long paths"
7790
7791 test_57a() {
7792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7793         # note test will not do anything if MDS is not local
7794         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7795                 skip_env "ldiskfs only test"
7796         fi
7797         remote_mds_nodsh && skip "remote MDS with nodsh"
7798
7799         local MNTDEV="osd*.*MDT*.mntdev"
7800         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7801         [ -z "$DEV" ] && error "can't access $MNTDEV"
7802         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7803                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7804                         error "can't access $DEV"
7805                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7806                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7807                 rm $TMP/t57a.dump
7808         done
7809 }
7810 run_test 57a "verify MDS filesystem created with large inodes =="
7811
7812 test_57b() {
7813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7814         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7815                 skip_env "ldiskfs only test"
7816         fi
7817         remote_mds_nodsh && skip "remote MDS with nodsh"
7818
7819         local dir=$DIR/$tdir
7820         local filecount=100
7821         local file1=$dir/f1
7822         local fileN=$dir/f$filecount
7823
7824         rm -rf $dir || error "removing $dir"
7825         test_mkdir -c1 $dir
7826         local mdtidx=$($LFS getstripe -m $dir)
7827         local mdtname=MDT$(printf %04x $mdtidx)
7828         local facet=mds$((mdtidx + 1))
7829
7830         echo "mcreating $filecount files"
7831         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7832
7833         # verify that files do not have EAs yet
7834         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7835                 error "$file1 has an EA"
7836         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7837                 error "$fileN has an EA"
7838
7839         sync
7840         sleep 1
7841         df $dir  #make sure we get new statfs data
7842         local mdsfree=$(do_facet $facet \
7843                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7844         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7845         local file
7846
7847         echo "opening files to create objects/EAs"
7848         for file in $(seq -f $dir/f%g 1 $filecount); do
7849                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7850                         error "opening $file"
7851         done
7852
7853         # verify that files have EAs now
7854         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7855         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7856
7857         sleep 1  #make sure we get new statfs data
7858         df $dir
7859         local mdsfree2=$(do_facet $facet \
7860                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7861         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7862
7863         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7864                 if [ "$mdsfree" != "$mdsfree2" ]; then
7865                         error "MDC before $mdcfree != after $mdcfree2"
7866                 else
7867                         echo "MDC before $mdcfree != after $mdcfree2"
7868                         echo "unable to confirm if MDS has large inodes"
7869                 fi
7870         fi
7871         rm -rf $dir
7872 }
7873 run_test 57b "default LOV EAs are stored inside large inodes ==="
7874
7875 test_58() {
7876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7877         [ -z "$(which wiretest 2>/dev/null)" ] &&
7878                         skip_env "could not find wiretest"
7879
7880         wiretest
7881 }
7882 run_test 58 "verify cross-platform wire constants =============="
7883
7884 test_59() {
7885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7886
7887         echo "touch 130 files"
7888         createmany -o $DIR/f59- 130
7889         echo "rm 130 files"
7890         unlinkmany $DIR/f59- 130
7891         sync
7892         # wait for commitment of removal
7893         wait_delete_completed
7894 }
7895 run_test 59 "verify cancellation of llog records async ========="
7896
7897 TEST60_HEAD="test_60 run $RANDOM"
7898 test_60a() {
7899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7900         remote_mgs_nodsh && skip "remote MGS with nodsh"
7901         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7902                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7903                         skip_env "missing subtest run-llog.sh"
7904
7905         log "$TEST60_HEAD - from kernel mode"
7906         do_facet mgs "$LCTL dk > /dev/null"
7907         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7908         do_facet mgs $LCTL dk > $TMP/$tfile
7909
7910         # LU-6388: test llog_reader
7911         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7912         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7913         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7914                         skip_env "missing llog_reader"
7915         local fstype=$(facet_fstype mgs)
7916         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7917                 skip_env "Only for ldiskfs or zfs type mgs"
7918
7919         local mntpt=$(facet_mntpt mgs)
7920         local mgsdev=$(mgsdevname 1)
7921         local fid_list
7922         local fid
7923         local rec_list
7924         local rec
7925         local rec_type
7926         local obj_file
7927         local path
7928         local seq
7929         local oid
7930         local pass=true
7931
7932         #get fid and record list
7933         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7934                 tail -n 4))
7935         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7936                 tail -n 4))
7937         #remount mgs as ldiskfs or zfs type
7938         stop mgs || error "stop mgs failed"
7939         mount_fstype mgs || error "remount mgs failed"
7940         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7941                 fid=${fid_list[i]}
7942                 rec=${rec_list[i]}
7943                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7944                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7945                 oid=$((16#$oid))
7946
7947                 case $fstype in
7948                         ldiskfs )
7949                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7950                         zfs )
7951                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7952                 esac
7953                 echo "obj_file is $obj_file"
7954                 do_facet mgs $llog_reader $obj_file
7955
7956                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7957                         awk '{ print $3 }' | sed -e "s/^type=//g")
7958                 if [ $rec_type != $rec ]; then
7959                         echo "FAILED test_60a wrong record type $rec_type," \
7960                               "should be $rec"
7961                         pass=false
7962                         break
7963                 fi
7964
7965                 #check obj path if record type is LLOG_LOGID_MAGIC
7966                 if [ "$rec" == "1064553b" ]; then
7967                         path=$(do_facet mgs $llog_reader $obj_file |
7968                                 grep "path=" | awk '{ print $NF }' |
7969                                 sed -e "s/^path=//g")
7970                         if [ $obj_file != $mntpt/$path ]; then
7971                                 echo "FAILED test_60a wrong obj path" \
7972                                       "$montpt/$path, should be $obj_file"
7973                                 pass=false
7974                                 break
7975                         fi
7976                 fi
7977         done
7978         rm -f $TMP/$tfile
7979         #restart mgs before "error", otherwise it will block the next test
7980         stop mgs || error "stop mgs failed"
7981         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7982         $pass || error "test failed, see FAILED test_60a messages for specifics"
7983 }
7984 run_test 60a "llog_test run from kernel module and test llog_reader"
7985
7986 test_60b() { # bug 6411
7987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7988
7989         dmesg > $DIR/$tfile
7990         LLOG_COUNT=$(do_facet mgs dmesg |
7991                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7992                           /llog_[a-z]*.c:[0-9]/ {
7993                                 if (marker)
7994                                         from_marker++
7995                                 from_begin++
7996                           }
7997                           END {
7998                                 if (marker)
7999                                         print from_marker
8000                                 else
8001                                         print from_begin
8002                           }")
8003
8004         [[ $LLOG_COUNT -gt 120 ]] &&
8005                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8006 }
8007 run_test 60b "limit repeated messages from CERROR/CWARN"
8008
8009 test_60c() {
8010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8011
8012         echo "create 5000 files"
8013         createmany -o $DIR/f60c- 5000
8014 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8015         lctl set_param fail_loc=0x80000137
8016         unlinkmany $DIR/f60c- 5000
8017         lctl set_param fail_loc=0
8018 }
8019 run_test 60c "unlink file when mds full"
8020
8021 test_60d() {
8022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8023
8024         SAVEPRINTK=$(lctl get_param -n printk)
8025         # verify "lctl mark" is even working"
8026         MESSAGE="test message ID $RANDOM $$"
8027         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8028         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8029
8030         lctl set_param printk=0 || error "set lnet.printk failed"
8031         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8032         MESSAGE="new test message ID $RANDOM $$"
8033         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8034         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8035         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8036
8037         lctl set_param -n printk="$SAVEPRINTK"
8038 }
8039 run_test 60d "test printk console message masking"
8040
8041 test_60e() {
8042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8043         remote_mds_nodsh && skip "remote MDS with nodsh"
8044
8045         touch $DIR/$tfile
8046 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8047         do_facet mds1 lctl set_param fail_loc=0x15b
8048         rm $DIR/$tfile
8049 }
8050 run_test 60e "no space while new llog is being created"
8051
8052 test_60g() {
8053         local pid
8054         local i
8055
8056         test_mkdir -c $MDSCOUNT $DIR/$tdir
8057
8058         (
8059                 local index=0
8060                 while true; do
8061                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8062                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8063                                 2>/dev/null
8064                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8065                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8066                         index=$((index + 1))
8067                 done
8068         ) &
8069
8070         pid=$!
8071
8072         for i in {0..100}; do
8073                 # define OBD_FAIL_OSD_TXN_START    0x19a
8074                 local index=$((i % MDSCOUNT + 1))
8075
8076                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8077                         > /dev/null
8078                 sleep 0.01
8079         done
8080
8081         kill -9 $pid
8082
8083         for i in $(seq $MDSCOUNT); do
8084                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8085         done
8086
8087         mkdir $DIR/$tdir/new || error "mkdir failed"
8088         rmdir $DIR/$tdir/new || error "rmdir failed"
8089
8090         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8091                 -t namespace
8092         for i in $(seq $MDSCOUNT); do
8093                 wait_update_facet mds$i "$LCTL get_param -n \
8094                         mdd.$(facet_svc mds$i).lfsck_namespace |
8095                         awk '/^status/ { print \\\$2 }'" "completed"
8096         done
8097
8098         ls -R $DIR/$tdir || error "ls failed"
8099         rm -rf $DIR/$tdir || error "rmdir failed"
8100 }
8101 run_test 60g "transaction abort won't cause MDT hung"
8102
8103 test_60h() {
8104         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8105                 skip "Need MDS version at least 2.12.52"
8106         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8107
8108         local f
8109
8110         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8111         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8112         for fail_loc in 0x80000188 0x80000189; do
8113                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8114                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8115                         error "mkdir $dir-$fail_loc failed"
8116                 for i in {0..10}; do
8117                         # create may fail on missing stripe
8118                         echo $i > $DIR/$tdir-$fail_loc/$i
8119                 done
8120                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8121                         error "getdirstripe $tdir-$fail_loc failed"
8122                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8123                         error "migrate $tdir-$fail_loc failed"
8124                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8125                         error "getdirstripe $tdir-$fail_loc failed"
8126                 pushd $DIR/$tdir-$fail_loc
8127                 for f in *; do
8128                         echo $f | cmp $f - || error "$f data mismatch"
8129                 done
8130                 popd
8131                 rm -rf $DIR/$tdir-$fail_loc
8132         done
8133 }
8134 run_test 60h "striped directory with missing stripes can be accessed"
8135
8136 test_61a() {
8137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8138
8139         f="$DIR/f61"
8140         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8141         cancel_lru_locks osc
8142         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8143         sync
8144 }
8145 run_test 61a "mmap() writes don't make sync hang ================"
8146
8147 test_61b() {
8148         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8149 }
8150 run_test 61b "mmap() of unstriped file is successful"
8151
8152 # bug 2330 - insufficient obd_match error checking causes LBUG
8153 test_62() {
8154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8155
8156         f="$DIR/f62"
8157         echo foo > $f
8158         cancel_lru_locks osc
8159         lctl set_param fail_loc=0x405
8160         cat $f && error "cat succeeded, expect -EIO"
8161         lctl set_param fail_loc=0
8162 }
8163 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8164 # match every page all of the time.
8165 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8166
8167 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8168 # Though this test is irrelevant anymore, it helped to reveal some
8169 # other grant bugs (LU-4482), let's keep it.
8170 test_63a() {   # was test_63
8171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8172
8173         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8174
8175         for i in `seq 10` ; do
8176                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8177                 sleep 5
8178                 kill $!
8179                 sleep 1
8180         done
8181
8182         rm -f $DIR/f63 || true
8183 }
8184 run_test 63a "Verify oig_wait interruption does not crash ======="
8185
8186 # bug 2248 - async write errors didn't return to application on sync
8187 # bug 3677 - async write errors left page locked
8188 test_63b() {
8189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8190
8191         debugsave
8192         lctl set_param debug=-1
8193
8194         # ensure we have a grant to do async writes
8195         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8196         rm $DIR/$tfile
8197
8198         sync    # sync lest earlier test intercept the fail_loc
8199
8200         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8201         lctl set_param fail_loc=0x80000406
8202         $MULTIOP $DIR/$tfile Owy && \
8203                 error "sync didn't return ENOMEM"
8204         sync; sleep 2; sync     # do a real sync this time to flush page
8205         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8206                 error "locked page left in cache after async error" || true
8207         debugrestore
8208 }
8209 run_test 63b "async write errors should be returned to fsync ==="
8210
8211 test_64a () {
8212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8213
8214         lfs df $DIR
8215         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8216 }
8217 run_test 64a "verify filter grant calculations (in kernel) ====="
8218
8219 test_64b () {
8220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8221
8222         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8223 }
8224 run_test 64b "check out-of-space detection on client"
8225
8226 test_64c() {
8227         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8228 }
8229 run_test 64c "verify grant shrink"
8230
8231 import_param() {
8232         local tgt=$1
8233         local param=$2
8234
8235         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8236 }
8237
8238 # this does exactly what osc_request.c:osc_announce_cached() does in
8239 # order to calculate max amount of grants to ask from server
8240 want_grant() {
8241         local tgt=$1
8242
8243         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8244         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8245
8246         ((rpc_in_flight++));
8247         nrpages=$((nrpages * rpc_in_flight))
8248
8249         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8250
8251         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8252
8253         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8254         local undirty=$((nrpages * PAGE_SIZE))
8255
8256         local max_extent_pages
8257         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8258         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8259         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8260         local grant_extent_tax
8261         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8262
8263         undirty=$((undirty + nrextents * grant_extent_tax))
8264
8265         echo $undirty
8266 }
8267
8268 # this is size of unit for grant allocation. It should be equal to
8269 # what tgt_grant.c:tgt_grant_chunk() calculates
8270 grant_chunk() {
8271         local tgt=$1
8272         local max_brw_size
8273         local grant_extent_tax
8274
8275         max_brw_size=$(import_param $tgt max_brw_size)
8276
8277         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8278
8279         echo $(((max_brw_size + grant_extent_tax) * 2))
8280 }
8281
8282 test_64d() {
8283         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8284                 skip "OST < 2.10.55 doesn't limit grants enough"
8285
8286         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8287
8288         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8289                 skip "no grant_param connect flag"
8290
8291         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8292
8293         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8294         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8295
8296
8297         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8298         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8299
8300         $LFS setstripe $DIR/$tfile -i 0 -c 1
8301         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8302         ddpid=$!
8303
8304         while kill -0 $ddpid; do
8305                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8306
8307                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8308                         kill $ddpid
8309                         error "cur_grant $cur_grant > $max_cur_granted"
8310                 fi
8311
8312                 sleep 1
8313         done
8314 }
8315 run_test 64d "check grant limit exceed"
8316
8317 check_grants() {
8318         local tgt=$1
8319         local expected=$2
8320         local msg=$3
8321         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8322
8323         ((cur_grants == expected)) ||
8324                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8325 }
8326
8327 round_up_p2() {
8328         echo $((($1 + $2 - 1) & ~($2 - 1)))
8329 }
8330
8331 test_64e() {
8332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8333         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8334                 skip "Need OSS version at least 2.11.56"
8335
8336         # Remount client to reset grant
8337         remount_client $MOUNT || error "failed to remount client"
8338         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8339
8340         local init_grants=$(import_param $osc_tgt initial_grant)
8341
8342         check_grants $osc_tgt $init_grants "init grants"
8343
8344         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8345         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8346         local gbs=$(import_param $osc_tgt grant_block_size)
8347
8348         # write random number of bytes from max_brw_size / 4 to max_brw_size
8349         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8350         # align for direct io
8351         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8352         # round to grant consumption unit
8353         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8354
8355         local grants=$((wb_round_up + extent_tax))
8356
8357         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8358
8359         # define OBD_FAIL_TGT_NO_GRANT 0x725
8360         # make the server not grant more back
8361         do_facet ost1 $LCTL set_param fail_loc=0x725
8362         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8363
8364         do_facet ost1 $LCTL set_param fail_loc=0
8365
8366         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8367
8368         rm -f $DIR/$tfile || error "rm failed"
8369
8370         # Remount client to reset grant
8371         remount_client $MOUNT || error "failed to remount client"
8372         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8373
8374         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8375
8376         # define OBD_FAIL_TGT_NO_GRANT 0x725
8377         # make the server not grant more back
8378         do_facet ost1 $LCTL set_param fail_loc=0x725
8379         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8380         do_facet ost1 $LCTL set_param fail_loc=0
8381
8382         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8383 }
8384 run_test 64e "check grant consumption (no grant allocation)"
8385
8386 test_64f() {
8387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8388
8389         # Remount client to reset grant
8390         remount_client $MOUNT || error "failed to remount client"
8391         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8392
8393         local init_grants=$(import_param $osc_tgt initial_grant)
8394         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8395         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8396         local gbs=$(import_param $osc_tgt grant_block_size)
8397         local chunk=$(grant_chunk $osc_tgt)
8398
8399         # write random number of bytes from max_brw_size / 4 to max_brw_size
8400         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8401         # align for direct io
8402         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8403         # round to grant consumption unit
8404         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8405
8406         local grants=$((wb_round_up + extent_tax))
8407
8408         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8409         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8410                 error "error writing to $DIR/$tfile"
8411
8412         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8413                 "direct io with grant allocation"
8414
8415         rm -f $DIR/$tfile || error "rm failed"
8416
8417         # Remount client to reset grant
8418         remount_client $MOUNT || error "failed to remount client"
8419         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8420
8421         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8422
8423         local cmd="oO_WRONLY:w${write_bytes}_yc"
8424
8425         $MULTIOP $DIR/$tfile $cmd &
8426         MULTIPID=$!
8427         sleep 1
8428
8429         check_grants $osc_tgt $((init_grants - grants)) \
8430                 "buffered io, not write rpc"
8431
8432         kill -USR1 $MULTIPID
8433         wait
8434
8435         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8436                 "buffered io, one RPC"
8437 }
8438 run_test 64f "check grant consumption (with grant allocation)"
8439
8440 # bug 1414 - set/get directories' stripe info
8441 test_65a() {
8442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8443
8444         test_mkdir $DIR/$tdir
8445         touch $DIR/$tdir/f1
8446         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8447 }
8448 run_test 65a "directory with no stripe info"
8449
8450 test_65b() {
8451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8452
8453         test_mkdir $DIR/$tdir
8454         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8455
8456         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8457                                                 error "setstripe"
8458         touch $DIR/$tdir/f2
8459         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8460 }
8461 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8462
8463 test_65c() {
8464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8465         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8466
8467         test_mkdir $DIR/$tdir
8468         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8469
8470         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8471                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8472         touch $DIR/$tdir/f3
8473         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8474 }
8475 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8476
8477 test_65d() {
8478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8479
8480         test_mkdir $DIR/$tdir
8481         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8482         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8483
8484         if [[ $STRIPECOUNT -le 0 ]]; then
8485                 sc=1
8486         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8487                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8488                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8489         else
8490                 sc=$(($STRIPECOUNT - 1))
8491         fi
8492         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8493         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8494         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8495                 error "lverify failed"
8496 }
8497 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8498
8499 test_65e() {
8500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8501
8502         test_mkdir $DIR/$tdir
8503
8504         $LFS setstripe $DIR/$tdir || error "setstripe"
8505         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8506                                         error "no stripe info failed"
8507         touch $DIR/$tdir/f6
8508         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8509 }
8510 run_test 65e "directory setstripe defaults"
8511
8512 test_65f() {
8513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8514
8515         test_mkdir $DIR/${tdir}f
8516         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8517                 error "setstripe succeeded" || true
8518 }
8519 run_test 65f "dir setstripe permission (should return error) ==="
8520
8521 test_65g() {
8522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8523
8524         test_mkdir $DIR/$tdir
8525         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8526
8527         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8528                 error "setstripe -S failed"
8529         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8530         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8531                 error "delete default stripe failed"
8532 }
8533 run_test 65g "directory setstripe -d"
8534
8535 test_65h() {
8536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8537
8538         test_mkdir $DIR/$tdir
8539         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8540
8541         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8542                 error "setstripe -S failed"
8543         test_mkdir $DIR/$tdir/dd1
8544         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8545                 error "stripe info inherit failed"
8546 }
8547 run_test 65h "directory stripe info inherit ===================="
8548
8549 test_65i() {
8550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8551
8552         save_layout_restore_at_exit $MOUNT
8553
8554         # bug6367: set non-default striping on root directory
8555         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8556
8557         # bug12836: getstripe on -1 default directory striping
8558         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8559
8560         # bug12836: getstripe -v on -1 default directory striping
8561         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8562
8563         # bug12836: new find on -1 default directory striping
8564         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8565 }
8566 run_test 65i "various tests to set root directory striping"
8567
8568 test_65j() { # bug6367
8569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8570
8571         sync; sleep 1
8572
8573         # if we aren't already remounting for each test, do so for this test
8574         if [ "$I_MOUNTED" = "yes" ]; then
8575                 cleanup || error "failed to unmount"
8576                 setup
8577         fi
8578
8579         save_layout_restore_at_exit $MOUNT
8580
8581         $LFS setstripe -d $MOUNT || error "setstripe failed"
8582 }
8583 run_test 65j "set default striping on root directory (bug 6367)="
8584
8585 cleanup_65k() {
8586         rm -rf $DIR/$tdir
8587         wait_delete_completed
8588         do_facet $SINGLEMDS "lctl set_param -n \
8589                 osp.$ost*MDT0000.max_create_count=$max_count"
8590         do_facet $SINGLEMDS "lctl set_param -n \
8591                 osp.$ost*MDT0000.create_count=$count"
8592         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8593         echo $INACTIVE_OSC "is Activate"
8594
8595         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8596 }
8597
8598 test_65k() { # bug11679
8599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8600         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8601         remote_mds_nodsh && skip "remote MDS with nodsh"
8602
8603         local disable_precreate=true
8604         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8605                 disable_precreate=false
8606
8607         echo "Check OST status: "
8608         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8609                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8610
8611         for OSC in $MDS_OSCS; do
8612                 echo $OSC "is active"
8613                 do_facet $SINGLEMDS lctl --device %$OSC activate
8614         done
8615
8616         for INACTIVE_OSC in $MDS_OSCS; do
8617                 local ost=$(osc_to_ost $INACTIVE_OSC)
8618                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8619                                lov.*md*.target_obd |
8620                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8621
8622                 mkdir -p $DIR/$tdir
8623                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8624                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8625
8626                 echo "Deactivate: " $INACTIVE_OSC
8627                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8628
8629                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8630                               osp.$ost*MDT0000.create_count")
8631                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8632                                   osp.$ost*MDT0000.max_create_count")
8633                 $disable_precreate &&
8634                         do_facet $SINGLEMDS "lctl set_param -n \
8635                                 osp.$ost*MDT0000.max_create_count=0"
8636
8637                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8638                         [ -f $DIR/$tdir/$idx ] && continue
8639                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8640                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8641                                 { cleanup_65k;
8642                                   error "setstripe $idx should succeed"; }
8643                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8644                 done
8645                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8646                 rmdir $DIR/$tdir
8647
8648                 do_facet $SINGLEMDS "lctl set_param -n \
8649                         osp.$ost*MDT0000.max_create_count=$max_count"
8650                 do_facet $SINGLEMDS "lctl set_param -n \
8651                         osp.$ost*MDT0000.create_count=$count"
8652                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8653                 echo $INACTIVE_OSC "is Activate"
8654
8655                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8656         done
8657 }
8658 run_test 65k "validate manual striping works properly with deactivated OSCs"
8659
8660 test_65l() { # bug 12836
8661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8662
8663         test_mkdir -p $DIR/$tdir/test_dir
8664         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8665         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8666 }
8667 run_test 65l "lfs find on -1 stripe dir ========================"
8668
8669 test_65m() {
8670         local layout=$(save_layout $MOUNT)
8671         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8672                 restore_layout $MOUNT $layout
8673                 error "setstripe should fail by non-root users"
8674         }
8675         true
8676 }
8677 run_test 65m "normal user can't set filesystem default stripe"
8678
8679 test_65n() {
8680         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8681         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8682                 skip "Need MDS version at least 2.12.50"
8683         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8684
8685         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8686         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8687         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8688
8689         local root_layout=$(save_layout $MOUNT)
8690         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8691
8692         # new subdirectory under root directory should not inherit
8693         # the default layout from root
8694         local dir1=$MOUNT/$tdir-1
8695         mkdir $dir1 || error "mkdir $dir1 failed"
8696         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8697                 error "$dir1 shouldn't have LOV EA"
8698
8699         # delete the default layout on root directory
8700         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8701
8702         local dir2=$MOUNT/$tdir-2
8703         mkdir $dir2 || error "mkdir $dir2 failed"
8704         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8705                 error "$dir2 shouldn't have LOV EA"
8706
8707         # set a new striping pattern on root directory
8708         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8709         local new_def_stripe_size=$((def_stripe_size * 2))
8710         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8711                 error "set stripe size on $MOUNT failed"
8712
8713         # new file created in $dir2 should inherit the new stripe size from
8714         # the filesystem default
8715         local file2=$dir2/$tfile-2
8716         touch $file2 || error "touch $file2 failed"
8717
8718         local file2_stripe_size=$($LFS getstripe -S $file2)
8719         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8720         {
8721                 echo "file2_stripe_size: '$file2_stripe_size'"
8722                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8723                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8724         }
8725
8726         local dir3=$MOUNT/$tdir-3
8727         mkdir $dir3 || error "mkdir $dir3 failed"
8728         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8729         # the root layout, which is the actual default layout that will be used
8730         # when new files are created in $dir3.
8731         local dir3_layout=$(get_layout_param $dir3)
8732         local root_dir_layout=$(get_layout_param $MOUNT)
8733         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8734         {
8735                 echo "dir3_layout: '$dir3_layout'"
8736                 echo "root_dir_layout: '$root_dir_layout'"
8737                 error "$dir3 should show the default layout from $MOUNT"
8738         }
8739
8740         # set OST pool on root directory
8741         local pool=$TESTNAME
8742         pool_add $pool || error "add $pool failed"
8743         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8744                 error "add targets to $pool failed"
8745
8746         $LFS setstripe -p $pool $MOUNT ||
8747                 error "set OST pool on $MOUNT failed"
8748
8749         # new file created in $dir3 should inherit the pool from
8750         # the filesystem default
8751         local file3=$dir3/$tfile-3
8752         touch $file3 || error "touch $file3 failed"
8753
8754         local file3_pool=$($LFS getstripe -p $file3)
8755         [[ "$file3_pool" = "$pool" ]] ||
8756                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8757
8758         local dir4=$MOUNT/$tdir-4
8759         mkdir $dir4 || error "mkdir $dir4 failed"
8760         local dir4_layout=$(get_layout_param $dir4)
8761         root_dir_layout=$(get_layout_param $MOUNT)
8762         echo "$LFS getstripe -d $dir4"
8763         $LFS getstripe -d $dir4
8764         echo "$LFS getstripe -d $MOUNT"
8765         $LFS getstripe -d $MOUNT
8766         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8767         {
8768                 echo "dir4_layout: '$dir4_layout'"
8769                 echo "root_dir_layout: '$root_dir_layout'"
8770                 error "$dir4 should show the default layout from $MOUNT"
8771         }
8772
8773         # new file created in $dir4 should inherit the pool from
8774         # the filesystem default
8775         local file4=$dir4/$tfile-4
8776         touch $file4 || error "touch $file4 failed"
8777
8778         local file4_pool=$($LFS getstripe -p $file4)
8779         [[ "$file4_pool" = "$pool" ]] ||
8780                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8781
8782         # new subdirectory under non-root directory should inherit
8783         # the default layout from its parent directory
8784         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8785                 error "set directory layout on $dir4 failed"
8786
8787         local dir5=$dir4/$tdir-5
8788         mkdir $dir5 || error "mkdir $dir5 failed"
8789
8790         dir4_layout=$(get_layout_param $dir4)
8791         local dir5_layout=$(get_layout_param $dir5)
8792         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8793         {
8794                 echo "dir4_layout: '$dir4_layout'"
8795                 echo "dir5_layout: '$dir5_layout'"
8796                 error "$dir5 should inherit the default layout from $dir4"
8797         }
8798
8799         # though subdir under ROOT doesn't inherit default layout, but
8800         # its sub dir/file should be created with default layout.
8801         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8802         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8803                 skip "Need MDS version at least 2.12.59"
8804
8805         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8806         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8807         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8808
8809         if [ $default_lmv_hash == "none" ]; then
8810                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8811         else
8812                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8813                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8814         fi
8815
8816         $LFS setdirstripe -D -c 2 $MOUNT ||
8817                 error "setdirstripe -D -c 2 failed"
8818         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8819         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8820         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8821 }
8822 run_test 65n "don't inherit default layout from root for new subdirectories"
8823
8824 # bug 2543 - update blocks count on client
8825 test_66() {
8826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8827
8828         COUNT=${COUNT:-8}
8829         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8830         sync; sync_all_data; sync; sync_all_data
8831         cancel_lru_locks osc
8832         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8833         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8834 }
8835 run_test 66 "update inode blocks count on client ==============="
8836
8837 meminfo() {
8838         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8839 }
8840
8841 swap_used() {
8842         swapon -s | awk '($1 == "'$1'") { print $4 }'
8843 }
8844
8845 # bug5265, obdfilter oa2dentry return -ENOENT
8846 # #define OBD_FAIL_SRV_ENOENT 0x217
8847 test_69() {
8848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8849         remote_ost_nodsh && skip "remote OST with nodsh"
8850
8851         f="$DIR/$tfile"
8852         $LFS setstripe -c 1 -i 0 $f
8853
8854         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8855
8856         do_facet ost1 lctl set_param fail_loc=0x217
8857         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8858         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8859
8860         do_facet ost1 lctl set_param fail_loc=0
8861         $DIRECTIO write $f 0 2 || error "write error"
8862
8863         cancel_lru_locks osc
8864         $DIRECTIO read $f 0 1 || error "read error"
8865
8866         do_facet ost1 lctl set_param fail_loc=0x217
8867         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8868
8869         do_facet ost1 lctl set_param fail_loc=0
8870         rm -f $f
8871 }
8872 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8873
8874 test_71() {
8875         test_mkdir $DIR/$tdir
8876         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8877         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8878 }
8879 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8880
8881 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8883         [ "$RUNAS_ID" = "$UID" ] &&
8884                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8885         # Check that testing environment is properly set up. Skip if not
8886         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8887                 skip_env "User $RUNAS_ID does not exist - skipping"
8888
8889         touch $DIR/$tfile
8890         chmod 777 $DIR/$tfile
8891         chmod ug+s $DIR/$tfile
8892         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8893                 error "$RUNAS dd $DIR/$tfile failed"
8894         # See if we are still setuid/sgid
8895         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8896                 error "S/gid is not dropped on write"
8897         # Now test that MDS is updated too
8898         cancel_lru_locks mdc
8899         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8900                 error "S/gid is not dropped on MDS"
8901         rm -f $DIR/$tfile
8902 }
8903 run_test 72a "Test that remove suid works properly (bug5695) ===="
8904
8905 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8906         local perm
8907
8908         [ "$RUNAS_ID" = "$UID" ] &&
8909                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8910         [ "$RUNAS_ID" -eq 0 ] &&
8911                 skip_env "RUNAS_ID = 0 -- skipping"
8912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8913         # Check that testing environment is properly set up. Skip if not
8914         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8915                 skip_env "User $RUNAS_ID does not exist - skipping"
8916
8917         touch $DIR/${tfile}-f{g,u}
8918         test_mkdir $DIR/${tfile}-dg
8919         test_mkdir $DIR/${tfile}-du
8920         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8921         chmod g+s $DIR/${tfile}-{f,d}g
8922         chmod u+s $DIR/${tfile}-{f,d}u
8923         for perm in 777 2777 4777; do
8924                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8925                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8926                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8927                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8928         done
8929         true
8930 }
8931 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8932
8933 # bug 3462 - multiple simultaneous MDC requests
8934 test_73() {
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936
8937         test_mkdir $DIR/d73-1
8938         test_mkdir $DIR/d73-2
8939         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8940         pid1=$!
8941
8942         lctl set_param fail_loc=0x80000129
8943         $MULTIOP $DIR/d73-1/f73-2 Oc &
8944         sleep 1
8945         lctl set_param fail_loc=0
8946
8947         $MULTIOP $DIR/d73-2/f73-3 Oc &
8948         pid3=$!
8949
8950         kill -USR1 $pid1
8951         wait $pid1 || return 1
8952
8953         sleep 25
8954
8955         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8956         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8957         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8958
8959         rm -rf $DIR/d73-*
8960 }
8961 run_test 73 "multiple MDC requests (should not deadlock)"
8962
8963 test_74a() { # bug 6149, 6184
8964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8965
8966         touch $DIR/f74a
8967         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8968         #
8969         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8970         # will spin in a tight reconnection loop
8971         $LCTL set_param fail_loc=0x8000030e
8972         # get any lock that won't be difficult - lookup works.
8973         ls $DIR/f74a
8974         $LCTL set_param fail_loc=0
8975         rm -f $DIR/f74a
8976         true
8977 }
8978 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8979
8980 test_74b() { # bug 13310
8981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8982
8983         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8984         #
8985         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8986         # will spin in a tight reconnection loop
8987         $LCTL set_param fail_loc=0x8000030e
8988         # get a "difficult" lock
8989         touch $DIR/f74b
8990         $LCTL set_param fail_loc=0
8991         rm -f $DIR/f74b
8992         true
8993 }
8994 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8995
8996 test_74c() {
8997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8998
8999         #define OBD_FAIL_LDLM_NEW_LOCK
9000         $LCTL set_param fail_loc=0x319
9001         touch $DIR/$tfile && error "touch successful"
9002         $LCTL set_param fail_loc=0
9003         true
9004 }
9005 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9006
9007 slab_lic=/sys/kernel/slab/lustre_inode_cache
9008 num_objects() {
9009         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9010         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9011                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9012 }
9013
9014 test_76a() { # Now for b=20433, added originally in b=1443
9015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9016
9017         cancel_lru_locks osc
9018         # there may be some slab objects cached per core
9019         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9020         local before=$(num_objects)
9021         local count=$((512 * cpus))
9022         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9023         local margin=$((count / 10))
9024         if [[ -f $slab_lic/aliases ]]; then
9025                 local aliases=$(cat $slab_lic/aliases)
9026                 (( aliases > 0 )) && margin=$((margin * aliases))
9027         fi
9028
9029         echo "before slab objects: $before"
9030         for i in $(seq $count); do
9031                 touch $DIR/$tfile
9032                 rm -f $DIR/$tfile
9033         done
9034         cancel_lru_locks osc
9035         local after=$(num_objects)
9036         echo "created: $count, after slab objects: $after"
9037         # shared slab counts are not very accurate, allow significant margin
9038         # the main goal is that the cache growth is not permanently > $count
9039         while (( after > before + margin )); do
9040                 sleep 1
9041                 after=$(num_objects)
9042                 wait=$((wait + 1))
9043                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9044                 if (( wait > 60 )); then
9045                         error "inode slab grew from $before+$margin to $after"
9046                 fi
9047         done
9048 }
9049 run_test 76a "confirm clients recycle inodes properly ===="
9050
9051 test_76b() {
9052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9053         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9054
9055         local count=512
9056         local before=$(num_objects)
9057
9058         for i in $(seq $count); do
9059                 mkdir $DIR/$tdir
9060                 rmdir $DIR/$tdir
9061         done
9062
9063         local after=$(num_objects)
9064         local wait=0
9065
9066         while (( after > before )); do
9067                 sleep 1
9068                 after=$(num_objects)
9069                 wait=$((wait + 1))
9070                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9071                 if (( wait > 60 )); then
9072                         error "inode slab grew from $before to $after"
9073                 fi
9074         done
9075
9076         echo "slab objects before: $before, after: $after"
9077 }
9078 run_test 76b "confirm clients recycle directory inodes properly ===="
9079
9080 export ORIG_CSUM=""
9081 set_checksums()
9082 {
9083         # Note: in sptlrpc modes which enable its own bulk checksum, the
9084         # original crc32_le bulk checksum will be automatically disabled,
9085         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9086         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9087         # In this case set_checksums() will not be no-op, because sptlrpc
9088         # bulk checksum will be enabled all through the test.
9089
9090         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9091         lctl set_param -n osc.*.checksums $1
9092         return 0
9093 }
9094
9095 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9096                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9097 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9098                              tr -d [] | head -n1)}
9099 set_checksum_type()
9100 {
9101         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9102         rc=$?
9103         log "set checksum type to $1, rc = $rc"
9104         return $rc
9105 }
9106
9107 get_osc_checksum_type()
9108 {
9109         # arugment 1: OST name, like OST0000
9110         ost=$1
9111         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9112                         sed 's/.*\[\(.*\)\].*/\1/g')
9113         rc=$?
9114         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9115         echo $checksum_type
9116 }
9117
9118 F77_TMP=$TMP/f77-temp
9119 F77SZ=8
9120 setup_f77() {
9121         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9122                 error "error writing to $F77_TMP"
9123 }
9124
9125 test_77a() { # bug 10889
9126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9127         $GSS && skip_env "could not run with gss"
9128
9129         [ ! -f $F77_TMP ] && setup_f77
9130         set_checksums 1
9131         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9132         set_checksums 0
9133         rm -f $DIR/$tfile
9134 }
9135 run_test 77a "normal checksum read/write operation"
9136
9137 test_77b() { # bug 10889
9138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9139         $GSS && skip_env "could not run with gss"
9140
9141         [ ! -f $F77_TMP ] && setup_f77
9142         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9143         $LCTL set_param fail_loc=0x80000409
9144         set_checksums 1
9145
9146         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9147                 error "dd error: $?"
9148         $LCTL set_param fail_loc=0
9149
9150         for algo in $CKSUM_TYPES; do
9151                 cancel_lru_locks osc
9152                 set_checksum_type $algo
9153                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9154                 $LCTL set_param fail_loc=0x80000408
9155                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9156                 $LCTL set_param fail_loc=0
9157         done
9158         set_checksums 0
9159         set_checksum_type $ORIG_CSUM_TYPE
9160         rm -f $DIR/$tfile
9161 }
9162 run_test 77b "checksum error on client write, read"
9163
9164 cleanup_77c() {
9165         trap 0
9166         set_checksums 0
9167         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9168         $check_ost &&
9169                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9170         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9171         $check_ost && [ -n "$ost_file_prefix" ] &&
9172                 do_facet ost1 rm -f ${ost_file_prefix}\*
9173 }
9174
9175 test_77c() {
9176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9177         $GSS && skip_env "could not run with gss"
9178         remote_ost_nodsh && skip "remote OST with nodsh"
9179
9180         local bad1
9181         local osc_file_prefix
9182         local osc_file
9183         local check_ost=false
9184         local ost_file_prefix
9185         local ost_file
9186         local orig_cksum
9187         local dump_cksum
9188         local fid
9189
9190         # ensure corruption will occur on first OSS/OST
9191         $LFS setstripe -i 0 $DIR/$tfile
9192
9193         [ ! -f $F77_TMP ] && setup_f77
9194         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9195                 error "dd write error: $?"
9196         fid=$($LFS path2fid $DIR/$tfile)
9197
9198         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9199         then
9200                 check_ost=true
9201                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9202                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9203         else
9204                 echo "OSS do not support bulk pages dump upon error"
9205         fi
9206
9207         osc_file_prefix=$($LCTL get_param -n debug_path)
9208         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9209
9210         trap cleanup_77c EXIT
9211
9212         set_checksums 1
9213         # enable bulk pages dump upon error on Client
9214         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9215         # enable bulk pages dump upon error on OSS
9216         $check_ost &&
9217                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9218
9219         # flush Client cache to allow next read to reach OSS
9220         cancel_lru_locks osc
9221
9222         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9223         $LCTL set_param fail_loc=0x80000408
9224         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9225         $LCTL set_param fail_loc=0
9226
9227         rm -f $DIR/$tfile
9228
9229         # check cksum dump on Client
9230         osc_file=$(ls ${osc_file_prefix}*)
9231         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9232         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9233         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9234         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9235         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9236                      cksum)
9237         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9238         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9239                 error "dump content does not match on Client"
9240
9241         $check_ost || skip "No need to check cksum dump on OSS"
9242
9243         # check cksum dump on OSS
9244         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9245         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9246         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9247         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9248         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9249                 error "dump content does not match on OSS"
9250
9251         cleanup_77c
9252 }
9253 run_test 77c "checksum error on client read with debug"
9254
9255 test_77d() { # bug 10889
9256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9257         $GSS && skip_env "could not run with gss"
9258
9259         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9260         $LCTL set_param fail_loc=0x80000409
9261         set_checksums 1
9262         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9263                 error "direct write: rc=$?"
9264         $LCTL set_param fail_loc=0
9265         set_checksums 0
9266
9267         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9268         $LCTL set_param fail_loc=0x80000408
9269         set_checksums 1
9270         cancel_lru_locks osc
9271         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9272                 error "direct read: rc=$?"
9273         $LCTL set_param fail_loc=0
9274         set_checksums 0
9275 }
9276 run_test 77d "checksum error on OST direct write, read"
9277
9278 test_77f() { # bug 10889
9279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9280         $GSS && skip_env "could not run with gss"
9281
9282         set_checksums 1
9283         for algo in $CKSUM_TYPES; do
9284                 cancel_lru_locks osc
9285                 set_checksum_type $algo
9286                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9287                 $LCTL set_param fail_loc=0x409
9288                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9289                         error "direct write succeeded"
9290                 $LCTL set_param fail_loc=0
9291         done
9292         set_checksum_type $ORIG_CSUM_TYPE
9293         set_checksums 0
9294 }
9295 run_test 77f "repeat checksum error on write (expect error)"
9296
9297 test_77g() { # bug 10889
9298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9299         $GSS && skip_env "could not run with gss"
9300         remote_ost_nodsh && skip "remote OST with nodsh"
9301
9302         [ ! -f $F77_TMP ] && setup_f77
9303
9304         local file=$DIR/$tfile
9305         stack_trap "rm -f $file" EXIT
9306
9307         $LFS setstripe -c 1 -i 0 $file
9308         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9309         do_facet ost1 lctl set_param fail_loc=0x8000021a
9310         set_checksums 1
9311         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9312                 error "write error: rc=$?"
9313         do_facet ost1 lctl set_param fail_loc=0
9314         set_checksums 0
9315
9316         cancel_lru_locks osc
9317         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9318         do_facet ost1 lctl set_param fail_loc=0x8000021b
9319         set_checksums 1
9320         cmp $F77_TMP $file || error "file compare failed"
9321         do_facet ost1 lctl set_param fail_loc=0
9322         set_checksums 0
9323 }
9324 run_test 77g "checksum error on OST write, read"
9325
9326 test_77k() { # LU-10906
9327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9328         $GSS && skip_env "could not run with gss"
9329
9330         local cksum_param="osc.$FSNAME*.checksums"
9331         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9332         local checksum
9333         local i
9334
9335         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9336         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9337         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9338
9339         for i in 0 1; do
9340                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9341                         error "failed to set checksum=$i on MGS"
9342                 wait_update $HOSTNAME "$get_checksum" $i
9343                 #remount
9344                 echo "remount client, checksum should be $i"
9345                 remount_client $MOUNT || error "failed to remount client"
9346                 checksum=$(eval $get_checksum)
9347                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9348         done
9349         # remove persistent param to avoid races with checksum mountopt below
9350         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9351                 error "failed to delete checksum on MGS"
9352
9353         for opt in "checksum" "nochecksum"; do
9354                 #remount with mount option
9355                 echo "remount client with option $opt, checksum should be $i"
9356                 umount_client $MOUNT || error "failed to umount client"
9357                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9358                         error "failed to mount client with option '$opt'"
9359                 checksum=$(eval $get_checksum)
9360                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9361                 i=$((i - 1))
9362         done
9363
9364         remount_client $MOUNT || error "failed to remount client"
9365 }
9366 run_test 77k "enable/disable checksum correctly"
9367
9368 test_77l() {
9369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9370         $GSS && skip_env "could not run with gss"
9371
9372         set_checksums 1
9373         stack_trap "set_checksums $ORIG_CSUM" EXIT
9374         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9375
9376         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9377
9378         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9379         for algo in $CKSUM_TYPES; do
9380                 set_checksum_type $algo || error "fail to set checksum type $algo"
9381                 osc_algo=$(get_osc_checksum_type OST0000)
9382                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9383
9384                 # no locks, no reqs to let the connection idle
9385                 cancel_lru_locks osc
9386                 lru_resize_disable osc
9387                 wait_osc_import_state client ost1 IDLE
9388
9389                 # ensure ost1 is connected
9390                 stat $DIR/$tfile >/dev/null || error "can't stat"
9391                 wait_osc_import_state client ost1 FULL
9392
9393                 osc_algo=$(get_osc_checksum_type OST0000)
9394                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9395         done
9396         return 0
9397 }
9398 run_test 77l "preferred checksum type is remembered after reconnected"
9399
9400 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9401 rm -f $F77_TMP
9402 unset F77_TMP
9403
9404 cleanup_test_78() {
9405         trap 0
9406         rm -f $DIR/$tfile
9407 }
9408
9409 test_78() { # bug 10901
9410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9411         remote_ost || skip_env "local OST"
9412
9413         NSEQ=5
9414         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9415         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9416         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9417         echo "MemTotal: $MEMTOTAL"
9418
9419         # reserve 256MB of memory for the kernel and other running processes,
9420         # and then take 1/2 of the remaining memory for the read/write buffers.
9421         if [ $MEMTOTAL -gt 512 ] ;then
9422                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9423         else
9424                 # for those poor memory-starved high-end clusters...
9425                 MEMTOTAL=$((MEMTOTAL / 2))
9426         fi
9427         echo "Mem to use for directio: $MEMTOTAL"
9428
9429         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9430         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9431         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9432         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9433                 head -n1)
9434         echo "Smallest OST: $SMALLESTOST"
9435         [[ $SMALLESTOST -lt 10240 ]] &&
9436                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9437
9438         trap cleanup_test_78 EXIT
9439
9440         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9441                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9442
9443         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9444         echo "File size: $F78SIZE"
9445         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9446         for i in $(seq 1 $NSEQ); do
9447                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9448                 echo directIO rdwr round $i of $NSEQ
9449                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9450         done
9451
9452         cleanup_test_78
9453 }
9454 run_test 78 "handle large O_DIRECT writes correctly ============"
9455
9456 test_79() { # bug 12743
9457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9458
9459         wait_delete_completed
9460
9461         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9462         BKFREE=$(calc_osc_kbytes kbytesfree)
9463         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9464
9465         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9466         DFTOTAL=`echo $STRING | cut -d, -f1`
9467         DFUSED=`echo $STRING  | cut -d, -f2`
9468         DFAVAIL=`echo $STRING | cut -d, -f3`
9469         DFFREE=$(($DFTOTAL - $DFUSED))
9470
9471         ALLOWANCE=$((64 * $OSTCOUNT))
9472
9473         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9474            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9475                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9476         fi
9477         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9478            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9479                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9480         fi
9481         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9482            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9483                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9484         fi
9485 }
9486 run_test 79 "df report consistency check ======================="
9487
9488 test_80() { # bug 10718
9489         remote_ost_nodsh && skip "remote OST with nodsh"
9490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9491
9492         # relax strong synchronous semantics for slow backends like ZFS
9493         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9494                 local soc="obdfilter.*.sync_lock_cancel"
9495                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9496
9497                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9498                 if [ -z "$save" ]; then
9499                         soc="obdfilter.*.sync_on_lock_cancel"
9500                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9501                 fi
9502
9503                 if [ "$save" != "never" ]; then
9504                         local hosts=$(comma_list $(osts_nodes))
9505
9506                         do_nodes $hosts $LCTL set_param $soc=never
9507                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9508                 fi
9509         fi
9510
9511         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9512         sync; sleep 1; sync
9513         local before=$(date +%s)
9514         cancel_lru_locks osc
9515         local after=$(date +%s)
9516         local diff=$((after - before))
9517         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9518
9519         rm -f $DIR/$tfile
9520 }
9521 run_test 80 "Page eviction is equally fast at high offsets too"
9522
9523 test_81a() { # LU-456
9524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9525         remote_ost_nodsh && skip "remote OST with nodsh"
9526
9527         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9528         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9529         do_facet ost1 lctl set_param fail_loc=0x80000228
9530
9531         # write should trigger a retry and success
9532         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9533         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9534         RC=$?
9535         if [ $RC -ne 0 ] ; then
9536                 error "write should success, but failed for $RC"
9537         fi
9538 }
9539 run_test 81a "OST should retry write when get -ENOSPC ==============="
9540
9541 test_81b() { # LU-456
9542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9543         remote_ost_nodsh && skip "remote OST with nodsh"
9544
9545         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9546         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9547         do_facet ost1 lctl set_param fail_loc=0x228
9548
9549         # write should retry several times and return -ENOSPC finally
9550         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9551         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9552         RC=$?
9553         ENOSPC=28
9554         if [ $RC -ne $ENOSPC ] ; then
9555                 error "dd should fail for -ENOSPC, but succeed."
9556         fi
9557 }
9558 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9559
9560 test_99() {
9561         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9562
9563         test_mkdir $DIR/$tdir.cvsroot
9564         chown $RUNAS_ID $DIR/$tdir.cvsroot
9565
9566         cd $TMP
9567         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9568
9569         cd /etc/init.d
9570         # some versions of cvs import exit(1) when asked to import links or
9571         # files they can't read.  ignore those files.
9572         local toignore=$(find . -type l -printf '-I %f\n' -o \
9573                          ! -perm /4 -printf '-I %f\n')
9574         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9575                 $tdir.reposname vtag rtag
9576
9577         cd $DIR
9578         test_mkdir $DIR/$tdir.reposname
9579         chown $RUNAS_ID $DIR/$tdir.reposname
9580         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9581
9582         cd $DIR/$tdir.reposname
9583         $RUNAS touch foo99
9584         $RUNAS cvs add -m 'addmsg' foo99
9585         $RUNAS cvs update
9586         $RUNAS cvs commit -m 'nomsg' foo99
9587         rm -fr $DIR/$tdir.cvsroot
9588 }
9589 run_test 99 "cvs strange file/directory operations"
9590
9591 test_100() {
9592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9593         [[ "$NETTYPE" =~ tcp ]] ||
9594                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9595         remote_ost_nodsh && skip "remote OST with nodsh"
9596         remote_mds_nodsh && skip "remote MDS with nodsh"
9597         remote_servers ||
9598                 skip "useless for local single node setup"
9599
9600         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9601                 [ "$PROT" != "tcp" ] && continue
9602                 RPORT=$(echo $REMOTE | cut -d: -f2)
9603                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9604
9605                 rc=0
9606                 LPORT=`echo $LOCAL | cut -d: -f2`
9607                 if [ $LPORT -ge 1024 ]; then
9608                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9609                         netstat -tna
9610                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9611                 fi
9612         done
9613         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9614 }
9615 run_test 100 "check local port using privileged port ==========="
9616
9617 function get_named_value()
9618 {
9619     local tag
9620
9621     tag=$1
9622     while read ;do
9623         line=$REPLY
9624         case $line in
9625         $tag*)
9626             echo $line | sed "s/^$tag[ ]*//"
9627             break
9628             ;;
9629         esac
9630     done
9631 }
9632
9633 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9634                    awk '/^max_cached_mb/ { print $2 }')
9635
9636 cleanup_101a() {
9637         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9638         trap 0
9639 }
9640
9641 test_101a() {
9642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9643
9644         local s
9645         local discard
9646         local nreads=10000
9647         local cache_limit=32
9648
9649         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9650         trap cleanup_101a EXIT
9651         $LCTL set_param -n llite.*.read_ahead_stats 0
9652         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9653
9654         #
9655         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9656         #
9657         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9658         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9659
9660         discard=0
9661         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9662                 get_named_value 'read but discarded' | cut -d" " -f1); do
9663                         discard=$(($discard + $s))
9664         done
9665         cleanup_101a
9666
9667         $LCTL get_param osc.*-osc*.rpc_stats
9668         $LCTL get_param llite.*.read_ahead_stats
9669
9670         # Discard is generally zero, but sometimes a few random reads line up
9671         # and trigger larger readahead, which is wasted & leads to discards.
9672         if [[ $(($discard)) -gt $nreads ]]; then
9673                 error "too many ($discard) discarded pages"
9674         fi
9675         rm -f $DIR/$tfile || true
9676 }
9677 run_test 101a "check read-ahead for random reads"
9678
9679 setup_test101bc() {
9680         test_mkdir $DIR/$tdir
9681         local ssize=$1
9682         local FILE_LENGTH=$2
9683         STRIPE_OFFSET=0
9684
9685         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9686
9687         local list=$(comma_list $(osts_nodes))
9688         set_osd_param $list '' read_cache_enable 0
9689         set_osd_param $list '' writethrough_cache_enable 0
9690
9691         trap cleanup_test101bc EXIT
9692         # prepare the read-ahead file
9693         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9694
9695         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9696                                 count=$FILE_SIZE_MB 2> /dev/null
9697
9698 }
9699
9700 cleanup_test101bc() {
9701         trap 0
9702         rm -rf $DIR/$tdir
9703         rm -f $DIR/$tfile
9704
9705         local list=$(comma_list $(osts_nodes))
9706         set_osd_param $list '' read_cache_enable 1
9707         set_osd_param $list '' writethrough_cache_enable 1
9708 }
9709
9710 calc_total() {
9711         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9712 }
9713
9714 ra_check_101() {
9715         local READ_SIZE=$1
9716         local STRIPE_SIZE=$2
9717         local FILE_LENGTH=$3
9718         local RA_INC=1048576
9719         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9720         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9721                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9722         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9723                         get_named_value 'read but discarded' |
9724                         cut -d" " -f1 | calc_total)
9725         if [[ $DISCARD -gt $discard_limit ]]; then
9726                 $LCTL get_param llite.*.read_ahead_stats
9727                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9728         else
9729                 echo "Read-ahead success for size ${READ_SIZE}"
9730         fi
9731 }
9732
9733 test_101b() {
9734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9735         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9736
9737         local STRIPE_SIZE=1048576
9738         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9739
9740         if [ $SLOW == "yes" ]; then
9741                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9742         else
9743                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9744         fi
9745
9746         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9747
9748         # prepare the read-ahead file
9749         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9750         cancel_lru_locks osc
9751         for BIDX in 2 4 8 16 32 64 128 256
9752         do
9753                 local BSIZE=$((BIDX*4096))
9754                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9755                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9756                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9757                 $LCTL set_param -n llite.*.read_ahead_stats 0
9758                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9759                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9760                 cancel_lru_locks osc
9761                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9762         done
9763         cleanup_test101bc
9764         true
9765 }
9766 run_test 101b "check stride-io mode read-ahead ================="
9767
9768 test_101c() {
9769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9770
9771         local STRIPE_SIZE=1048576
9772         local FILE_LENGTH=$((STRIPE_SIZE*100))
9773         local nreads=10000
9774         local rsize=65536
9775         local osc_rpc_stats
9776
9777         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9778
9779         cancel_lru_locks osc
9780         $LCTL set_param osc.*.rpc_stats 0
9781         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9782         $LCTL get_param osc.*.rpc_stats
9783         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9784                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9785                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9786                 local size
9787
9788                 if [ $lines -le 20 ]; then
9789                         echo "continue debug"
9790                         continue
9791                 fi
9792                 for size in 1 2 4 8; do
9793                         local rpc=$(echo "$stats" |
9794                                     awk '($1 == "'$size':") {print $2; exit; }')
9795                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9796                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9797                 done
9798                 echo "$osc_rpc_stats check passed!"
9799         done
9800         cleanup_test101bc
9801         true
9802 }
9803 run_test 101c "check stripe_size aligned read-ahead ================="
9804
9805 test_101d() {
9806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9807
9808         local file=$DIR/$tfile
9809         local sz_MB=${FILESIZE_101d:-80}
9810         local ra_MB=${READAHEAD_MB:-40}
9811
9812         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9813         [ $free_MB -lt $sz_MB ] &&
9814                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9815
9816         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9817         $LFS setstripe -c -1 $file || error "setstripe failed"
9818
9819         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9820         echo Cancel LRU locks on lustre client to flush the client cache
9821         cancel_lru_locks osc
9822
9823         echo Disable read-ahead
9824         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9825         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9826         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9827         $LCTL get_param -n llite.*.max_read_ahead_mb
9828
9829         echo "Reading the test file $file with read-ahead disabled"
9830         local sz_KB=$((sz_MB * 1024 / 4))
9831         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9832         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9833         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9834                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9835
9836         echo "Cancel LRU locks on lustre client to flush the client cache"
9837         cancel_lru_locks osc
9838         echo Enable read-ahead with ${ra_MB}MB
9839         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9840
9841         echo "Reading the test file $file with read-ahead enabled"
9842         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9843                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9844
9845         echo "read-ahead disabled time read $raOFF"
9846         echo "read-ahead enabled time read $raON"
9847
9848         rm -f $file
9849         wait_delete_completed
9850
9851         # use awk for this check instead of bash because it handles decimals
9852         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9853                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9854 }
9855 run_test 101d "file read with and without read-ahead enabled"
9856
9857 test_101e() {
9858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9859
9860         local file=$DIR/$tfile
9861         local size_KB=500  #KB
9862         local count=100
9863         local bsize=1024
9864
9865         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9866         local need_KB=$((count * size_KB))
9867         [[ $free_KB -le $need_KB ]] &&
9868                 skip_env "Need free space $need_KB, have $free_KB"
9869
9870         echo "Creating $count ${size_KB}K test files"
9871         for ((i = 0; i < $count; i++)); do
9872                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9873         done
9874
9875         echo "Cancel LRU locks on lustre client to flush the client cache"
9876         cancel_lru_locks $OSC
9877
9878         echo "Reset readahead stats"
9879         $LCTL set_param -n llite.*.read_ahead_stats 0
9880
9881         for ((i = 0; i < $count; i++)); do
9882                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9883         done
9884
9885         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9886                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9887
9888         for ((i = 0; i < $count; i++)); do
9889                 rm -rf $file.$i 2>/dev/null
9890         done
9891
9892         #10000 means 20% reads are missing in readahead
9893         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9894 }
9895 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9896
9897 test_101f() {
9898         which iozone || skip_env "no iozone installed"
9899
9900         local old_debug=$($LCTL get_param debug)
9901         old_debug=${old_debug#*=}
9902         $LCTL set_param debug="reada mmap"
9903
9904         # create a test file
9905         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9906
9907         echo Cancel LRU locks on lustre client to flush the client cache
9908         cancel_lru_locks osc
9909
9910         echo Reset readahead stats
9911         $LCTL set_param -n llite.*.read_ahead_stats 0
9912
9913         echo mmap read the file with small block size
9914         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9915                 > /dev/null 2>&1
9916
9917         echo checking missing pages
9918         $LCTL get_param llite.*.read_ahead_stats
9919         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9920                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9921
9922         $LCTL set_param debug="$old_debug"
9923         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9924         rm -f $DIR/$tfile
9925 }
9926 run_test 101f "check mmap read performance"
9927
9928 test_101g_brw_size_test() {
9929         local mb=$1
9930         local pages=$((mb * 1048576 / PAGE_SIZE))
9931         local file=$DIR/$tfile
9932
9933         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9934                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9935         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9936                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9937                         return 2
9938         done
9939
9940         stack_trap "rm -f $file" EXIT
9941         $LCTL set_param -n osc.*.rpc_stats=0
9942
9943         # 10 RPCs should be enough for the test
9944         local count=10
9945         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9946                 { error "dd write ${mb} MB blocks failed"; return 3; }
9947         cancel_lru_locks osc
9948         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9949                 { error "dd write ${mb} MB blocks failed"; return 4; }
9950
9951         # calculate number of full-sized read and write RPCs
9952         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9953                 sed -n '/pages per rpc/,/^$/p' |
9954                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9955                 END { print reads,writes }'))
9956         # allow one extra full-sized read RPC for async readahead
9957         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9958                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9959         [[ ${rpcs[1]} == $count ]] ||
9960                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9961 }
9962
9963 test_101g() {
9964         remote_ost_nodsh && skip "remote OST with nodsh"
9965
9966         local rpcs
9967         local osts=$(get_facets OST)
9968         local list=$(comma_list $(osts_nodes))
9969         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9970         local brw_size="obdfilter.*.brw_size"
9971
9972         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9973
9974         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9975
9976         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9977                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9978                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9979            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9980                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9981                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9982
9983                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9984                         suffix="M"
9985
9986                 if [[ $orig_mb -lt 16 ]]; then
9987                         save_lustre_params $osts "$brw_size" > $p
9988                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9989                                 error "set 16MB RPC size failed"
9990
9991                         echo "remount client to enable new RPC size"
9992                         remount_client $MOUNT || error "remount_client failed"
9993                 fi
9994
9995                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9996                 # should be able to set brw_size=12, but no rpc_stats for that
9997                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9998         fi
9999
10000         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10001
10002         if [[ $orig_mb -lt 16 ]]; then
10003                 restore_lustre_params < $p
10004                 remount_client $MOUNT || error "remount_client restore failed"
10005         fi
10006
10007         rm -f $p $DIR/$tfile
10008 }
10009 run_test 101g "Big bulk(4/16 MiB) readahead"
10010
10011 test_101h() {
10012         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10013
10014         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10015                 error "dd 70M file failed"
10016         echo Cancel LRU locks on lustre client to flush the client cache
10017         cancel_lru_locks osc
10018
10019         echo "Reset readahead stats"
10020         $LCTL set_param -n llite.*.read_ahead_stats 0
10021
10022         echo "Read 10M of data but cross 64M bundary"
10023         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10024         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10025                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
10026         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10027         rm -f $p $DIR/$tfile
10028 }
10029 run_test 101h "Readahead should cover current read window"
10030
10031 test_101i() {
10032         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10033                 error "dd 10M file failed"
10034
10035         local max_per_file_mb=$($LCTL get_param -n \
10036                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10037         cancel_lru_locks osc
10038         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10039         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10040                 error "set max_read_ahead_per_file_mb to 1 failed"
10041
10042         echo "Reset readahead stats"
10043         $LCTL set_param llite.*.read_ahead_stats=0
10044
10045         dd if=$DIR/$tfile of=/dev/null bs=2M
10046
10047         $LCTL get_param llite.*.read_ahead_stats
10048         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10049                      awk '/misses/ { print $2 }')
10050         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10051         rm -f $DIR/$tfile
10052 }
10053 run_test 101i "allow current readahead to exceed reservation"
10054
10055 test_101j() {
10056         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10057                 error "setstripe $DIR/$tfile failed"
10058         local file_size=$((1048576 * 16))
10059         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10060         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10061
10062         echo Disable read-ahead
10063         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10064
10065         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10066         for blk in $PAGE_SIZE 1048576 $file_size; do
10067                 cancel_lru_locks osc
10068                 echo "Reset readahead stats"
10069                 $LCTL set_param -n llite.*.read_ahead_stats=0
10070                 local count=$(($file_size / $blk))
10071                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10072                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10073                              get_named_value 'failed to fast read' |
10074                              cut -d" " -f1 | calc_total)
10075                 $LCTL get_param -n llite.*.read_ahead_stats
10076                 [ $miss -eq $count ] || error "expected $count got $miss"
10077         done
10078
10079         rm -f $p $DIR/$tfile
10080 }
10081 run_test 101j "A complete read block should be submitted when no RA"
10082
10083 setup_test102() {
10084         test_mkdir $DIR/$tdir
10085         chown $RUNAS_ID $DIR/$tdir
10086         STRIPE_SIZE=65536
10087         STRIPE_OFFSET=1
10088         STRIPE_COUNT=$OSTCOUNT
10089         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10090
10091         trap cleanup_test102 EXIT
10092         cd $DIR
10093         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10094         cd $DIR/$tdir
10095         for num in 1 2 3 4; do
10096                 for count in $(seq 1 $STRIPE_COUNT); do
10097                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10098                                 local size=`expr $STRIPE_SIZE \* $num`
10099                                 local file=file"$num-$idx-$count"
10100                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10101                         done
10102                 done
10103         done
10104
10105         cd $DIR
10106         $1 tar cf $TMP/f102.tar $tdir --xattrs
10107 }
10108
10109 cleanup_test102() {
10110         trap 0
10111         rm -f $TMP/f102.tar
10112         rm -rf $DIR/d0.sanity/d102
10113 }
10114
10115 test_102a() {
10116         [ "$UID" != 0 ] && skip "must run as root"
10117         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10118                 skip_env "must have user_xattr"
10119
10120         [ -z "$(which setfattr 2>/dev/null)" ] &&
10121                 skip_env "could not find setfattr"
10122
10123         local testfile=$DIR/$tfile
10124
10125         touch $testfile
10126         echo "set/get xattr..."
10127         setfattr -n trusted.name1 -v value1 $testfile ||
10128                 error "setfattr -n trusted.name1=value1 $testfile failed"
10129         getfattr -n trusted.name1 $testfile 2> /dev/null |
10130           grep "trusted.name1=.value1" ||
10131                 error "$testfile missing trusted.name1=value1"
10132
10133         setfattr -n user.author1 -v author1 $testfile ||
10134                 error "setfattr -n user.author1=author1 $testfile failed"
10135         getfattr -n user.author1 $testfile 2> /dev/null |
10136           grep "user.author1=.author1" ||
10137                 error "$testfile missing trusted.author1=author1"
10138
10139         echo "listxattr..."
10140         setfattr -n trusted.name2 -v value2 $testfile ||
10141                 error "$testfile unable to set trusted.name2"
10142         setfattr -n trusted.name3 -v value3 $testfile ||
10143                 error "$testfile unable to set trusted.name3"
10144         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10145             grep "trusted.name" | wc -l) -eq 3 ] ||
10146                 error "$testfile missing 3 trusted.name xattrs"
10147
10148         setfattr -n user.author2 -v author2 $testfile ||
10149                 error "$testfile unable to set user.author2"
10150         setfattr -n user.author3 -v author3 $testfile ||
10151                 error "$testfile unable to set user.author3"
10152         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10153             grep "user.author" | wc -l) -eq 3 ] ||
10154                 error "$testfile missing 3 user.author xattrs"
10155
10156         echo "remove xattr..."
10157         setfattr -x trusted.name1 $testfile ||
10158                 error "$testfile error deleting trusted.name1"
10159         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10160                 error "$testfile did not delete trusted.name1 xattr"
10161
10162         setfattr -x user.author1 $testfile ||
10163                 error "$testfile error deleting user.author1"
10164         echo "set lustre special xattr ..."
10165         $LFS setstripe -c1 $testfile
10166         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10167                 awk -F "=" '/trusted.lov/ { print $2 }' )
10168         setfattr -n "trusted.lov" -v $lovea $testfile ||
10169                 error "$testfile doesn't ignore setting trusted.lov again"
10170         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10171                 error "$testfile allow setting invalid trusted.lov"
10172         rm -f $testfile
10173 }
10174 run_test 102a "user xattr test =================================="
10175
10176 check_102b_layout() {
10177         local layout="$*"
10178         local testfile=$DIR/$tfile
10179
10180         echo "test layout '$layout'"
10181         $LFS setstripe $layout $testfile || error "setstripe failed"
10182         $LFS getstripe -y $testfile
10183
10184         echo "get/set/list trusted.lov xattr ..." # b=10930
10185         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10186         [[ "$value" =~ "trusted.lov" ]] ||
10187                 error "can't get trusted.lov from $testfile"
10188         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10189                 error "getstripe failed"
10190
10191         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10192
10193         value=$(cut -d= -f2 <<<$value)
10194         # LU-13168: truncated xattr should fail if short lov_user_md header
10195         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10196                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10197         for len in $lens; do
10198                 echo "setfattr $len $testfile.2"
10199                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10200                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10201         done
10202         local stripe_size=$($LFS getstripe -S $testfile.2)
10203         local stripe_count=$($LFS getstripe -c $testfile.2)
10204         [[ $stripe_size -eq 65536 ]] ||
10205                 error "stripe size $stripe_size != 65536"
10206         [[ $stripe_count -eq $stripe_count_orig ]] ||
10207                 error "stripe count $stripe_count != $stripe_count_orig"
10208         rm $testfile $testfile.2
10209 }
10210
10211 test_102b() {
10212         [ -z "$(which setfattr 2>/dev/null)" ] &&
10213                 skip_env "could not find setfattr"
10214         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10215
10216         # check plain layout
10217         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10218
10219         # and also check composite layout
10220         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10221
10222 }
10223 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10224
10225 test_102c() {
10226         [ -z "$(which setfattr 2>/dev/null)" ] &&
10227                 skip_env "could not find setfattr"
10228         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10229
10230         # b10930: get/set/list lustre.lov xattr
10231         echo "get/set/list lustre.lov xattr ..."
10232         test_mkdir $DIR/$tdir
10233         chown $RUNAS_ID $DIR/$tdir
10234         local testfile=$DIR/$tdir/$tfile
10235         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10236                 error "setstripe failed"
10237         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10238                 error "getstripe failed"
10239         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10240         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10241
10242         local testfile2=${testfile}2
10243         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10244                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10245
10246         $RUNAS $MCREATE $testfile2
10247         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10248         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10249         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10250         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10251         [ $stripe_count -eq $STRIPECOUNT ] ||
10252                 error "stripe count $stripe_count != $STRIPECOUNT"
10253 }
10254 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10255
10256 compare_stripe_info1() {
10257         local stripe_index_all_zero=true
10258
10259         for num in 1 2 3 4; do
10260                 for count in $(seq 1 $STRIPE_COUNT); do
10261                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10262                                 local size=$((STRIPE_SIZE * num))
10263                                 local file=file"$num-$offset-$count"
10264                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10265                                 [[ $stripe_size -ne $size ]] &&
10266                                     error "$file: size $stripe_size != $size"
10267                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10268                                 # allow fewer stripes to be created, ORI-601
10269                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10270                                     error "$file: count $stripe_count != $count"
10271                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10272                                 [[ $stripe_index -ne 0 ]] &&
10273                                         stripe_index_all_zero=false
10274                         done
10275                 done
10276         done
10277         $stripe_index_all_zero &&
10278                 error "all files are being extracted starting from OST index 0"
10279         return 0
10280 }
10281
10282 have_xattrs_include() {
10283         tar --help | grep -q xattrs-include &&
10284                 echo --xattrs-include="lustre.*"
10285 }
10286
10287 test_102d() {
10288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10289         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10290
10291         XINC=$(have_xattrs_include)
10292         setup_test102
10293         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10294         cd $DIR/$tdir/$tdir
10295         compare_stripe_info1
10296 }
10297 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10298
10299 test_102f() {
10300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10301         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10302
10303         XINC=$(have_xattrs_include)
10304         setup_test102
10305         test_mkdir $DIR/$tdir.restore
10306         cd $DIR
10307         tar cf - --xattrs $tdir | tar xf - \
10308                 -C $DIR/$tdir.restore --xattrs $XINC
10309         cd $DIR/$tdir.restore/$tdir
10310         compare_stripe_info1
10311 }
10312 run_test 102f "tar copy files, not keep osts"
10313
10314 grow_xattr() {
10315         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10316                 skip "must have user_xattr"
10317         [ -z "$(which setfattr 2>/dev/null)" ] &&
10318                 skip_env "could not find setfattr"
10319         [ -z "$(which getfattr 2>/dev/null)" ] &&
10320                 skip_env "could not find getfattr"
10321
10322         local xsize=${1:-1024}  # in bytes
10323         local file=$DIR/$tfile
10324         local value="$(generate_string $xsize)"
10325         local xbig=trusted.big
10326         local toobig=$2
10327
10328         touch $file
10329         log "save $xbig on $file"
10330         if [ -z "$toobig" ]
10331         then
10332                 setfattr -n $xbig -v $value $file ||
10333                         error "saving $xbig on $file failed"
10334         else
10335                 setfattr -n $xbig -v $value $file &&
10336                         error "saving $xbig on $file succeeded"
10337                 return 0
10338         fi
10339
10340         local orig=$(get_xattr_value $xbig $file)
10341         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10342
10343         local xsml=trusted.sml
10344         log "save $xsml on $file"
10345         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10346
10347         local new=$(get_xattr_value $xbig $file)
10348         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10349
10350         log "grow $xsml on $file"
10351         setfattr -n $xsml -v "$value" $file ||
10352                 error "growing $xsml on $file failed"
10353
10354         new=$(get_xattr_value $xbig $file)
10355         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10356         log "$xbig still valid after growing $xsml"
10357
10358         rm -f $file
10359 }
10360
10361 test_102h() { # bug 15777
10362         grow_xattr 1024
10363 }
10364 run_test 102h "grow xattr from inside inode to external block"
10365
10366 test_102ha() {
10367         large_xattr_enabled || skip_env "ea_inode feature disabled"
10368
10369         echo "setting xattr of max xattr size: $(max_xattr_size)"
10370         grow_xattr $(max_xattr_size)
10371
10372         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10373         echo "This should fail:"
10374         grow_xattr $(($(max_xattr_size) + 10)) 1
10375 }
10376 run_test 102ha "grow xattr from inside inode to external inode"
10377
10378 test_102i() { # bug 17038
10379         [ -z "$(which getfattr 2>/dev/null)" ] &&
10380                 skip "could not find getfattr"
10381
10382         touch $DIR/$tfile
10383         ln -s $DIR/$tfile $DIR/${tfile}link
10384         getfattr -n trusted.lov $DIR/$tfile ||
10385                 error "lgetxattr on $DIR/$tfile failed"
10386         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10387                 grep -i "no such attr" ||
10388                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10389         rm -f $DIR/$tfile $DIR/${tfile}link
10390 }
10391 run_test 102i "lgetxattr test on symbolic link ============"
10392
10393 test_102j() {
10394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10395         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10396
10397         XINC=$(have_xattrs_include)
10398         setup_test102 "$RUNAS"
10399         chown $RUNAS_ID $DIR/$tdir
10400         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10401         cd $DIR/$tdir/$tdir
10402         compare_stripe_info1 "$RUNAS"
10403 }
10404 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10405
10406 test_102k() {
10407         [ -z "$(which setfattr 2>/dev/null)" ] &&
10408                 skip "could not find setfattr"
10409
10410         touch $DIR/$tfile
10411         # b22187 just check that does not crash for regular file.
10412         setfattr -n trusted.lov $DIR/$tfile
10413         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10414         local test_kdir=$DIR/$tdir
10415         test_mkdir $test_kdir
10416         local default_size=$($LFS getstripe -S $test_kdir)
10417         local default_count=$($LFS getstripe -c $test_kdir)
10418         local default_offset=$($LFS getstripe -i $test_kdir)
10419         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10420                 error 'dir setstripe failed'
10421         setfattr -n trusted.lov $test_kdir
10422         local stripe_size=$($LFS getstripe -S $test_kdir)
10423         local stripe_count=$($LFS getstripe -c $test_kdir)
10424         local stripe_offset=$($LFS getstripe -i $test_kdir)
10425         [ $stripe_size -eq $default_size ] ||
10426                 error "stripe size $stripe_size != $default_size"
10427         [ $stripe_count -eq $default_count ] ||
10428                 error "stripe count $stripe_count != $default_count"
10429         [ $stripe_offset -eq $default_offset ] ||
10430                 error "stripe offset $stripe_offset != $default_offset"
10431         rm -rf $DIR/$tfile $test_kdir
10432 }
10433 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10434
10435 test_102l() {
10436         [ -z "$(which getfattr 2>/dev/null)" ] &&
10437                 skip "could not find getfattr"
10438
10439         # LU-532 trusted. xattr is invisible to non-root
10440         local testfile=$DIR/$tfile
10441
10442         touch $testfile
10443
10444         echo "listxattr as user..."
10445         chown $RUNAS_ID $testfile
10446         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10447             grep -q "trusted" &&
10448                 error "$testfile trusted xattrs are user visible"
10449
10450         return 0;
10451 }
10452 run_test 102l "listxattr size test =================================="
10453
10454 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10455         local path=$DIR/$tfile
10456         touch $path
10457
10458         listxattr_size_check $path || error "listattr_size_check $path failed"
10459 }
10460 run_test 102m "Ensure listxattr fails on small bufffer ========"
10461
10462 cleanup_test102
10463
10464 getxattr() { # getxattr path name
10465         # Return the base64 encoding of the value of xattr name on path.
10466         local path=$1
10467         local name=$2
10468
10469         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10470         # file: $path
10471         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10472         #
10473         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10474
10475         getfattr --absolute-names --encoding=base64 --name=$name $path |
10476                 awk -F= -v name=$name '$1 == name {
10477                         print substr($0, index($0, "=") + 1);
10478         }'
10479 }
10480
10481 test_102n() { # LU-4101 mdt: protect internal xattrs
10482         [ -z "$(which setfattr 2>/dev/null)" ] &&
10483                 skip "could not find setfattr"
10484         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10485         then
10486                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10487         fi
10488
10489         local file0=$DIR/$tfile.0
10490         local file1=$DIR/$tfile.1
10491         local xattr0=$TMP/$tfile.0
10492         local xattr1=$TMP/$tfile.1
10493         local namelist="lov lma lmv link fid version som hsm"
10494         local name
10495         local value
10496
10497         rm -rf $file0 $file1 $xattr0 $xattr1
10498         touch $file0 $file1
10499
10500         # Get 'before' xattrs of $file1.
10501         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10502
10503         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10504                 namelist+=" lfsck_namespace"
10505         for name in $namelist; do
10506                 # Try to copy xattr from $file0 to $file1.
10507                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10508
10509                 setfattr --name=trusted.$name --value="$value" $file1 ||
10510                         error "setxattr 'trusted.$name' failed"
10511
10512                 # Try to set a garbage xattr.
10513                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10514
10515                 if [[ x$name == "xlov" ]]; then
10516                         setfattr --name=trusted.lov --value="$value" $file1 &&
10517                         error "setxattr invalid 'trusted.lov' success"
10518                 else
10519                         setfattr --name=trusted.$name --value="$value" $file1 ||
10520                                 error "setxattr invalid 'trusted.$name' failed"
10521                 fi
10522
10523                 # Try to remove the xattr from $file1. We don't care if this
10524                 # appears to succeed or fail, we just don't want there to be
10525                 # any changes or crashes.
10526                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10527         done
10528
10529         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10530         then
10531                 name="lfsck_ns"
10532                 # Try to copy xattr from $file0 to $file1.
10533                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10534
10535                 setfattr --name=trusted.$name --value="$value" $file1 ||
10536                         error "setxattr 'trusted.$name' failed"
10537
10538                 # Try to set a garbage xattr.
10539                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10540
10541                 setfattr --name=trusted.$name --value="$value" $file1 ||
10542                         error "setxattr 'trusted.$name' failed"
10543
10544                 # Try to remove the xattr from $file1. We don't care if this
10545                 # appears to succeed or fail, we just don't want there to be
10546                 # any changes or crashes.
10547                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10548         fi
10549
10550         # Get 'after' xattrs of file1.
10551         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10552
10553         if ! diff $xattr0 $xattr1; then
10554                 error "before and after xattrs of '$file1' differ"
10555         fi
10556
10557         rm -rf $file0 $file1 $xattr0 $xattr1
10558
10559         return 0
10560 }
10561 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10562
10563 test_102p() { # LU-4703 setxattr did not check ownership
10564         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10565                 skip "MDS needs to be at least 2.5.56"
10566
10567         local testfile=$DIR/$tfile
10568
10569         touch $testfile
10570
10571         echo "setfacl as user..."
10572         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10573         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10574
10575         echo "setfattr as user..."
10576         setfacl -m "u:$RUNAS_ID:---" $testfile
10577         $RUNAS setfattr -x system.posix_acl_access $testfile
10578         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10579 }
10580 run_test 102p "check setxattr(2) correctly fails without permission"
10581
10582 test_102q() {
10583         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10584                 skip "MDS needs to be at least 2.6.92"
10585
10586         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10587 }
10588 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10589
10590 test_102r() {
10591         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10592                 skip "MDS needs to be at least 2.6.93"
10593
10594         touch $DIR/$tfile || error "touch"
10595         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10596         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10597         rm $DIR/$tfile || error "rm"
10598
10599         #normal directory
10600         mkdir -p $DIR/$tdir || error "mkdir"
10601         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10602         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10603         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10604                 error "$testfile error deleting user.author1"
10605         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10606                 grep "user.$(basename $tdir)" &&
10607                 error "$tdir did not delete user.$(basename $tdir)"
10608         rmdir $DIR/$tdir || error "rmdir"
10609
10610         #striped directory
10611         test_mkdir $DIR/$tdir
10612         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10613         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10614         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10615                 error "$testfile error deleting user.author1"
10616         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10617                 grep "user.$(basename $tdir)" &&
10618                 error "$tdir did not delete user.$(basename $tdir)"
10619         rmdir $DIR/$tdir || error "rm striped dir"
10620 }
10621 run_test 102r "set EAs with empty values"
10622
10623 test_102s() {
10624         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10625                 skip "MDS needs to be at least 2.11.52"
10626
10627         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10628
10629         save_lustre_params client "llite.*.xattr_cache" > $save
10630
10631         for cache in 0 1; do
10632                 lctl set_param llite.*.xattr_cache=$cache
10633
10634                 rm -f $DIR/$tfile
10635                 touch $DIR/$tfile || error "touch"
10636                 for prefix in lustre security system trusted user; do
10637                         # Note getxattr() may fail with 'Operation not
10638                         # supported' or 'No such attribute' depending
10639                         # on prefix and cache.
10640                         getfattr -n $prefix.n102s $DIR/$tfile &&
10641                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10642                 done
10643         done
10644
10645         restore_lustre_params < $save
10646 }
10647 run_test 102s "getting nonexistent xattrs should fail"
10648
10649 test_102t() {
10650         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10651                 skip "MDS needs to be at least 2.11.52"
10652
10653         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10654
10655         save_lustre_params client "llite.*.xattr_cache" > $save
10656
10657         for cache in 0 1; do
10658                 lctl set_param llite.*.xattr_cache=$cache
10659
10660                 for buf_size in 0 256; do
10661                         rm -f $DIR/$tfile
10662                         touch $DIR/$tfile || error "touch"
10663                         setfattr -n user.multiop $DIR/$tfile
10664                         $MULTIOP $DIR/$tfile oa$buf_size ||
10665                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10666                 done
10667         done
10668
10669         restore_lustre_params < $save
10670 }
10671 run_test 102t "zero length xattr values handled correctly"
10672
10673 run_acl_subtest()
10674 {
10675     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10676     return $?
10677 }
10678
10679 test_103a() {
10680         [ "$UID" != 0 ] && skip "must run as root"
10681         $GSS && skip_env "could not run under gss"
10682         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10683                 skip_env "must have acl enabled"
10684         [ -z "$(which setfacl 2>/dev/null)" ] &&
10685                 skip_env "could not find setfacl"
10686         remote_mds_nodsh && skip "remote MDS with nodsh"
10687
10688         gpasswd -a daemon bin                           # LU-5641
10689         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10690
10691         declare -a identity_old
10692
10693         for num in $(seq $MDSCOUNT); do
10694                 switch_identity $num true || identity_old[$num]=$?
10695         done
10696
10697         SAVE_UMASK=$(umask)
10698         umask 0022
10699         mkdir -p $DIR/$tdir
10700         cd $DIR/$tdir
10701
10702         echo "performing cp ..."
10703         run_acl_subtest cp || error "run_acl_subtest cp failed"
10704         echo "performing getfacl-noacl..."
10705         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10706         echo "performing misc..."
10707         run_acl_subtest misc || error  "misc test failed"
10708         echo "performing permissions..."
10709         run_acl_subtest permissions || error "permissions failed"
10710         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10711         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10712                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10713                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10714         then
10715                 echo "performing permissions xattr..."
10716                 run_acl_subtest permissions_xattr ||
10717                         error "permissions_xattr failed"
10718         fi
10719         echo "performing setfacl..."
10720         run_acl_subtest setfacl || error  "setfacl test failed"
10721
10722         # inheritance test got from HP
10723         echo "performing inheritance..."
10724         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10725         chmod +x make-tree || error "chmod +x failed"
10726         run_acl_subtest inheritance || error "inheritance test failed"
10727         rm -f make-tree
10728
10729         echo "LU-974 ignore umask when acl is enabled..."
10730         run_acl_subtest 974 || error "LU-974 umask test failed"
10731         if [ $MDSCOUNT -ge 2 ]; then
10732                 run_acl_subtest 974_remote ||
10733                         error "LU-974 umask test failed under remote dir"
10734         fi
10735
10736         echo "LU-2561 newly created file is same size as directory..."
10737         if [ "$mds1_FSTYPE" != "zfs" ]; then
10738                 run_acl_subtest 2561 || error "LU-2561 test failed"
10739         else
10740                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10741         fi
10742
10743         run_acl_subtest 4924 || error "LU-4924 test failed"
10744
10745         cd $SAVE_PWD
10746         umask $SAVE_UMASK
10747
10748         for num in $(seq $MDSCOUNT); do
10749                 if [ "${identity_old[$num]}" = 1 ]; then
10750                         switch_identity $num false || identity_old[$num]=$?
10751                 fi
10752         done
10753 }
10754 run_test 103a "acl test"
10755
10756 test_103b() {
10757         declare -a pids
10758         local U
10759
10760         for U in {0..511}; do
10761                 {
10762                 local O=$(printf "%04o" $U)
10763
10764                 umask $(printf "%04o" $((511 ^ $O)))
10765                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10766                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10767
10768                 (( $S == ($O & 0666) )) ||
10769                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10770
10771                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10772                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10773                 (( $S == ($O & 0666) )) ||
10774                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10775
10776                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10777                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10778                 (( $S == ($O & 0666) )) ||
10779                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10780                 rm -f $DIR/$tfile.[smp]$0
10781                 } &
10782                 local pid=$!
10783
10784                 # limit the concurrently running threads to 64. LU-11878
10785                 local idx=$((U % 64))
10786                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10787                 pids[idx]=$pid
10788         done
10789         wait
10790 }
10791 run_test 103b "umask lfs setstripe"
10792
10793 test_103c() {
10794         mkdir -p $DIR/$tdir
10795         cp -rp $DIR/$tdir $DIR/$tdir.bak
10796
10797         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10798                 error "$DIR/$tdir shouldn't contain default ACL"
10799         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10800                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10801         true
10802 }
10803 run_test 103c "'cp -rp' won't set empty acl"
10804
10805 test_103e() {
10806         (( $MDS1_VERSION >= $(version_code 2.13.59) )) ||
10807                 skip "MDS needs to be at least 2.13.59"
10808
10809         mkdir -p $DIR/$tdir
10810         # one default ACL will be created for the file owner
10811         for U in {2..256}; do
10812                 setfacl -m default:user:$U:rwx $DIR/$tdir
10813                 numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10814                 touch $DIR/$tdir/$tfile.$U ||
10815                         error "failed to create $tfile.$U with $numacl ACLs"
10816         done
10817 }
10818 run_test 103e "inheritance of big amount of default ACLs"
10819
10820 test_104a() {
10821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10822
10823         touch $DIR/$tfile
10824         lfs df || error "lfs df failed"
10825         lfs df -ih || error "lfs df -ih failed"
10826         lfs df -h $DIR || error "lfs df -h $DIR failed"
10827         lfs df -i $DIR || error "lfs df -i $DIR failed"
10828         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10829         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10830
10831         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10832         lctl --device %$OSC deactivate
10833         lfs df || error "lfs df with deactivated OSC failed"
10834         lctl --device %$OSC activate
10835         # wait the osc back to normal
10836         wait_osc_import_ready client ost
10837
10838         lfs df || error "lfs df with reactivated OSC failed"
10839         rm -f $DIR/$tfile
10840 }
10841 run_test 104a "lfs df [-ih] [path] test ========================="
10842
10843 test_104b() {
10844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10845         [ $RUNAS_ID -eq $UID ] &&
10846                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10847
10848         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10849                         grep "Permission denied" | wc -l)))
10850         if [ $denied_cnt -ne 0 ]; then
10851                 error "lfs check servers test failed"
10852         fi
10853 }
10854 run_test 104b "$RUNAS lfs check servers test ===================="
10855
10856 test_105a() {
10857         # doesn't work on 2.4 kernels
10858         touch $DIR/$tfile
10859         if $(flock_is_enabled); then
10860                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10861         else
10862                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10863         fi
10864         rm -f $DIR/$tfile
10865 }
10866 run_test 105a "flock when mounted without -o flock test ========"
10867
10868 test_105b() {
10869         touch $DIR/$tfile
10870         if $(flock_is_enabled); then
10871                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10872         else
10873                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10874         fi
10875         rm -f $DIR/$tfile
10876 }
10877 run_test 105b "fcntl when mounted without -o flock test ========"
10878
10879 test_105c() {
10880         touch $DIR/$tfile
10881         if $(flock_is_enabled); then
10882                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10883         else
10884                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10885         fi
10886         rm -f $DIR/$tfile
10887 }
10888 run_test 105c "lockf when mounted without -o flock test"
10889
10890 test_105d() { # bug 15924
10891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10892
10893         test_mkdir $DIR/$tdir
10894         flock_is_enabled || skip_env "mount w/o flock enabled"
10895         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10896         $LCTL set_param fail_loc=0x80000315
10897         flocks_test 2 $DIR/$tdir
10898 }
10899 run_test 105d "flock race (should not freeze) ========"
10900
10901 test_105e() { # bug 22660 && 22040
10902         flock_is_enabled || skip_env "mount w/o flock enabled"
10903
10904         touch $DIR/$tfile
10905         flocks_test 3 $DIR/$tfile
10906 }
10907 run_test 105e "Two conflicting flocks from same process"
10908
10909 test_106() { #bug 10921
10910         test_mkdir $DIR/$tdir
10911         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10912         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10913 }
10914 run_test 106 "attempt exec of dir followed by chown of that dir"
10915
10916 test_107() {
10917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10918
10919         CDIR=`pwd`
10920         local file=core
10921
10922         cd $DIR
10923         rm -f $file
10924
10925         local save_pattern=$(sysctl -n kernel.core_pattern)
10926         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10927         sysctl -w kernel.core_pattern=$file
10928         sysctl -w kernel.core_uses_pid=0
10929
10930         ulimit -c unlimited
10931         sleep 60 &
10932         SLEEPPID=$!
10933
10934         sleep 1
10935
10936         kill -s 11 $SLEEPPID
10937         wait $SLEEPPID
10938         if [ -e $file ]; then
10939                 size=`stat -c%s $file`
10940                 [ $size -eq 0 ] && error "Fail to create core file $file"
10941         else
10942                 error "Fail to create core file $file"
10943         fi
10944         rm -f $file
10945         sysctl -w kernel.core_pattern=$save_pattern
10946         sysctl -w kernel.core_uses_pid=$save_uses_pid
10947         cd $CDIR
10948 }
10949 run_test 107 "Coredump on SIG"
10950
10951 test_110() {
10952         test_mkdir $DIR/$tdir
10953         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10954         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10955                 error "mkdir with 256 char should fail, but did not"
10956         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10957                 error "create with 255 char failed"
10958         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10959                 error "create with 256 char should fail, but did not"
10960
10961         ls -l $DIR/$tdir
10962         rm -rf $DIR/$tdir
10963 }
10964 run_test 110 "filename length checking"
10965
10966 #
10967 # Purpose: To verify dynamic thread (OSS) creation.
10968 #
10969 test_115() {
10970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10971         remote_ost_nodsh && skip "remote OST with nodsh"
10972
10973         # Lustre does not stop service threads once they are started.
10974         # Reset number of running threads to default.
10975         stopall
10976         setupall
10977
10978         local OSTIO_pre
10979         local save_params="$TMP/sanity-$TESTNAME.parameters"
10980
10981         # Get ll_ost_io count before I/O
10982         OSTIO_pre=$(do_facet ost1 \
10983                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10984         # Exit if lustre is not running (ll_ost_io not running).
10985         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10986
10987         echo "Starting with $OSTIO_pre threads"
10988         local thread_max=$((OSTIO_pre * 2))
10989         local rpc_in_flight=$((thread_max * 2))
10990         # Number of I/O Process proposed to be started.
10991         local nfiles
10992         local facets=$(get_facets OST)
10993
10994         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10995         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10996
10997         # Set in_flight to $rpc_in_flight
10998         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10999                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11000         nfiles=${rpc_in_flight}
11001         # Set ost thread_max to $thread_max
11002         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11003
11004         # 5 Minutes should be sufficient for max number of OSS
11005         # threads(thread_max) to be created.
11006         local timeout=300
11007
11008         # Start I/O.
11009         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11010         test_mkdir $DIR/$tdir
11011         for i in $(seq $nfiles); do
11012                 local file=$DIR/$tdir/${tfile}-$i
11013                 $LFS setstripe -c -1 -i 0 $file
11014                 ($WTL $file $timeout)&
11015         done
11016
11017         # I/O Started - Wait for thread_started to reach thread_max or report
11018         # error if thread_started is more than thread_max.
11019         echo "Waiting for thread_started to reach thread_max"
11020         local thread_started=0
11021         local end_time=$((SECONDS + timeout))
11022
11023         while [ $SECONDS -le $end_time ] ; do
11024                 echo -n "."
11025                 # Get ost i/o thread_started count.
11026                 thread_started=$(do_facet ost1 \
11027                         "$LCTL get_param \
11028                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11029                 # Break out if thread_started is equal/greater than thread_max
11030                 if [[ $thread_started -ge $thread_max ]]; then
11031                         echo ll_ost_io thread_started $thread_started, \
11032                                 equal/greater than thread_max $thread_max
11033                         break
11034                 fi
11035                 sleep 1
11036         done
11037
11038         # Cleanup - We have the numbers, Kill i/o jobs if running.
11039         jobcount=($(jobs -p))
11040         for i in $(seq 0 $((${#jobcount[@]}-1)))
11041         do
11042                 kill -9 ${jobcount[$i]}
11043                 if [ $? -ne 0 ] ; then
11044                         echo Warning: \
11045                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11046                 fi
11047         done
11048
11049         # Cleanup files left by WTL binary.
11050         for i in $(seq $nfiles); do
11051                 local file=$DIR/$tdir/${tfile}-$i
11052                 rm -rf $file
11053                 if [ $? -ne 0 ] ; then
11054                         echo "Warning: Failed to delete file $file"
11055                 fi
11056         done
11057
11058         restore_lustre_params <$save_params
11059         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11060
11061         # Error out if no new thread has started or Thread started is greater
11062         # than thread max.
11063         if [[ $thread_started -le $OSTIO_pre ||
11064                         $thread_started -gt $thread_max ]]; then
11065                 error "ll_ost_io: thread_started $thread_started" \
11066                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11067                       "No new thread started or thread started greater " \
11068                       "than thread_max."
11069         fi
11070 }
11071 run_test 115 "verify dynamic thread creation===================="
11072
11073 free_min_max () {
11074         wait_delete_completed
11075         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11076         echo "OST kbytes available: ${AVAIL[@]}"
11077         MAXV=${AVAIL[0]}
11078         MAXI=0
11079         MINV=${AVAIL[0]}
11080         MINI=0
11081         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11082                 #echo OST $i: ${AVAIL[i]}kb
11083                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11084                         MAXV=${AVAIL[i]}
11085                         MAXI=$i
11086                 fi
11087                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11088                         MINV=${AVAIL[i]}
11089                         MINI=$i
11090                 fi
11091         done
11092         echo "Min free space: OST $MINI: $MINV"
11093         echo "Max free space: OST $MAXI: $MAXV"
11094 }
11095
11096 test_116a() { # was previously test_116()
11097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11098         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11099         remote_mds_nodsh && skip "remote MDS with nodsh"
11100
11101         echo -n "Free space priority "
11102         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11103                 head -n1
11104         declare -a AVAIL
11105         free_min_max
11106
11107         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11108         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11109         trap simple_cleanup_common EXIT
11110
11111         # Check if we need to generate uneven OSTs
11112         test_mkdir -p $DIR/$tdir/OST${MINI}
11113         local FILL=$((MINV / 4))
11114         local DIFF=$((MAXV - MINV))
11115         local DIFF2=$((DIFF * 100 / MINV))
11116
11117         local threshold=$(do_facet $SINGLEMDS \
11118                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11119         threshold=${threshold%%%}
11120         echo -n "Check for uneven OSTs: "
11121         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11122
11123         if [[ $DIFF2 -gt $threshold ]]; then
11124                 echo "ok"
11125                 echo "Don't need to fill OST$MINI"
11126         else
11127                 # generate uneven OSTs. Write 2% over the QOS threshold value
11128                 echo "no"
11129                 DIFF=$((threshold - DIFF2 + 2))
11130                 DIFF2=$((MINV * DIFF / 100))
11131                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11132                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11133                         error "setstripe failed"
11134                 DIFF=$((DIFF2 / 2048))
11135                 i=0
11136                 while [ $i -lt $DIFF ]; do
11137                         i=$((i + 1))
11138                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11139                                 bs=2M count=1 2>/dev/null
11140                         echo -n .
11141                 done
11142                 echo .
11143                 sync
11144                 sleep_maxage
11145                 free_min_max
11146         fi
11147
11148         DIFF=$((MAXV - MINV))
11149         DIFF2=$((DIFF * 100 / MINV))
11150         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11151         if [ $DIFF2 -gt $threshold ]; then
11152                 echo "ok"
11153         else
11154                 echo "failed - QOS mode won't be used"
11155                 simple_cleanup_common
11156                 skip "QOS imbalance criteria not met"
11157         fi
11158
11159         MINI1=$MINI
11160         MINV1=$MINV
11161         MAXI1=$MAXI
11162         MAXV1=$MAXV
11163
11164         # now fill using QOS
11165         $LFS setstripe -c 1 $DIR/$tdir
11166         FILL=$((FILL / 200))
11167         if [ $FILL -gt 600 ]; then
11168                 FILL=600
11169         fi
11170         echo "writing $FILL files to QOS-assigned OSTs"
11171         i=0
11172         while [ $i -lt $FILL ]; do
11173                 i=$((i + 1))
11174                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11175                         count=1 2>/dev/null
11176                 echo -n .
11177         done
11178         echo "wrote $i 200k files"
11179         sync
11180         sleep_maxage
11181
11182         echo "Note: free space may not be updated, so measurements might be off"
11183         free_min_max
11184         DIFF2=$((MAXV - MINV))
11185         echo "free space delta: orig $DIFF final $DIFF2"
11186         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11187         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11188         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11189         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11190         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11191         if [[ $DIFF -gt 0 ]]; then
11192                 FILL=$((DIFF2 * 100 / DIFF - 100))
11193                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11194         fi
11195
11196         # Figure out which files were written where
11197         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11198                awk '/'$MINI1': / {print $2; exit}')
11199         echo $UUID
11200         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11201         echo "$MINC files created on smaller OST $MINI1"
11202         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11203                awk '/'$MAXI1': / {print $2; exit}')
11204         echo $UUID
11205         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11206         echo "$MAXC files created on larger OST $MAXI1"
11207         if [[ $MINC -gt 0 ]]; then
11208                 FILL=$((MAXC * 100 / MINC - 100))
11209                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11210         fi
11211         [[ $MAXC -gt $MINC ]] ||
11212                 error_ignore LU-9 "stripe QOS didn't balance free space"
11213         simple_cleanup_common
11214 }
11215 run_test 116a "stripe QOS: free space balance ==================="
11216
11217 test_116b() { # LU-2093
11218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11219         remote_mds_nodsh && skip "remote MDS with nodsh"
11220
11221 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11222         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11223                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11224         [ -z "$old_rr" ] && skip "no QOS"
11225         do_facet $SINGLEMDS lctl set_param \
11226                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11227         mkdir -p $DIR/$tdir
11228         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11229         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11230         do_facet $SINGLEMDS lctl set_param fail_loc=0
11231         rm -rf $DIR/$tdir
11232         do_facet $SINGLEMDS lctl set_param \
11233                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11234 }
11235 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11236
11237 test_117() # bug 10891
11238 {
11239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11240
11241         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11242         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11243         lctl set_param fail_loc=0x21e
11244         > $DIR/$tfile || error "truncate failed"
11245         lctl set_param fail_loc=0
11246         echo "Truncate succeeded."
11247         rm -f $DIR/$tfile
11248 }
11249 run_test 117 "verify osd extend =========="
11250
11251 NO_SLOW_RESENDCOUNT=4
11252 export OLD_RESENDCOUNT=""
11253 set_resend_count () {
11254         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11255         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11256         lctl set_param -n $PROC_RESENDCOUNT $1
11257         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11258 }
11259
11260 # for reduce test_118* time (b=14842)
11261 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11262
11263 # Reset async IO behavior after error case
11264 reset_async() {
11265         FILE=$DIR/reset_async
11266
11267         # Ensure all OSCs are cleared
11268         $LFS setstripe -c -1 $FILE
11269         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11270         sync
11271         rm $FILE
11272 }
11273
11274 test_118a() #bug 11710
11275 {
11276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11277
11278         reset_async
11279
11280         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11281         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11282         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11283
11284         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11285                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11286                 return 1;
11287         fi
11288         rm -f $DIR/$tfile
11289 }
11290 run_test 118a "verify O_SYNC works =========="
11291
11292 test_118b()
11293 {
11294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11295         remote_ost_nodsh && skip "remote OST with nodsh"
11296
11297         reset_async
11298
11299         #define OBD_FAIL_SRV_ENOENT 0x217
11300         set_nodes_failloc "$(osts_nodes)" 0x217
11301         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11302         RC=$?
11303         set_nodes_failloc "$(osts_nodes)" 0
11304         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11305         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11306                     grep -c writeback)
11307
11308         if [[ $RC -eq 0 ]]; then
11309                 error "Must return error due to dropped pages, rc=$RC"
11310                 return 1;
11311         fi
11312
11313         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11314                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11315                 return 1;
11316         fi
11317
11318         echo "Dirty pages not leaked on ENOENT"
11319
11320         # Due to the above error the OSC will issue all RPCs syncronously
11321         # until a subsequent RPC completes successfully without error.
11322         $MULTIOP $DIR/$tfile Ow4096yc
11323         rm -f $DIR/$tfile
11324
11325         return 0
11326 }
11327 run_test 118b "Reclaim dirty pages on fatal error =========="
11328
11329 test_118c()
11330 {
11331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11332
11333         # for 118c, restore the original resend count, LU-1940
11334         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11335                                 set_resend_count $OLD_RESENDCOUNT
11336         remote_ost_nodsh && skip "remote OST with nodsh"
11337
11338         reset_async
11339
11340         #define OBD_FAIL_OST_EROFS               0x216
11341         set_nodes_failloc "$(osts_nodes)" 0x216
11342
11343         # multiop should block due to fsync until pages are written
11344         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11345         MULTIPID=$!
11346         sleep 1
11347
11348         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11349                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11350         fi
11351
11352         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11353                     grep -c writeback)
11354         if [[ $WRITEBACK -eq 0 ]]; then
11355                 error "No page in writeback, writeback=$WRITEBACK"
11356         fi
11357
11358         set_nodes_failloc "$(osts_nodes)" 0
11359         wait $MULTIPID
11360         RC=$?
11361         if [[ $RC -ne 0 ]]; then
11362                 error "Multiop fsync failed, rc=$RC"
11363         fi
11364
11365         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11366         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11367                     grep -c writeback)
11368         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11369                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11370         fi
11371
11372         rm -f $DIR/$tfile
11373         echo "Dirty pages flushed via fsync on EROFS"
11374         return 0
11375 }
11376 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11377
11378 # continue to use small resend count to reduce test_118* time (b=14842)
11379 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11380
11381 test_118d()
11382 {
11383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11384         remote_ost_nodsh && skip "remote OST with nodsh"
11385
11386         reset_async
11387
11388         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11389         set_nodes_failloc "$(osts_nodes)" 0x214
11390         # multiop should block due to fsync until pages are written
11391         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11392         MULTIPID=$!
11393         sleep 1
11394
11395         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11396                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11397         fi
11398
11399         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11400                     grep -c writeback)
11401         if [[ $WRITEBACK -eq 0 ]]; then
11402                 error "No page in writeback, writeback=$WRITEBACK"
11403         fi
11404
11405         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11406         set_nodes_failloc "$(osts_nodes)" 0
11407
11408         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11409         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11410                     grep -c writeback)
11411         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11412                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11413         fi
11414
11415         rm -f $DIR/$tfile
11416         echo "Dirty pages gaurenteed flushed via fsync"
11417         return 0
11418 }
11419 run_test 118d "Fsync validation inject a delay of the bulk =========="
11420
11421 test_118f() {
11422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11423
11424         reset_async
11425
11426         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11427         lctl set_param fail_loc=0x8000040a
11428
11429         # Should simulate EINVAL error which is fatal
11430         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11431         RC=$?
11432         if [[ $RC -eq 0 ]]; then
11433                 error "Must return error due to dropped pages, rc=$RC"
11434         fi
11435
11436         lctl set_param fail_loc=0x0
11437
11438         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11439         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11440         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11441                     grep -c writeback)
11442         if [[ $LOCKED -ne 0 ]]; then
11443                 error "Locked pages remain in cache, locked=$LOCKED"
11444         fi
11445
11446         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11447                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11448         fi
11449
11450         rm -f $DIR/$tfile
11451         echo "No pages locked after fsync"
11452
11453         reset_async
11454         return 0
11455 }
11456 run_test 118f "Simulate unrecoverable OSC side error =========="
11457
11458 test_118g() {
11459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11460
11461         reset_async
11462
11463         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11464         lctl set_param fail_loc=0x406
11465
11466         # simulate local -ENOMEM
11467         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11468         RC=$?
11469
11470         lctl set_param fail_loc=0
11471         if [[ $RC -eq 0 ]]; then
11472                 error "Must return error due to dropped pages, rc=$RC"
11473         fi
11474
11475         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11476         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11477         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11478                         grep -c writeback)
11479         if [[ $LOCKED -ne 0 ]]; then
11480                 error "Locked pages remain in cache, locked=$LOCKED"
11481         fi
11482
11483         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11484                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11485         fi
11486
11487         rm -f $DIR/$tfile
11488         echo "No pages locked after fsync"
11489
11490         reset_async
11491         return 0
11492 }
11493 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11494
11495 test_118h() {
11496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11497         remote_ost_nodsh && skip "remote OST with nodsh"
11498
11499         reset_async
11500
11501         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11502         set_nodes_failloc "$(osts_nodes)" 0x20e
11503         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11504         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11505         RC=$?
11506
11507         set_nodes_failloc "$(osts_nodes)" 0
11508         if [[ $RC -eq 0 ]]; then
11509                 error "Must return error due to dropped pages, rc=$RC"
11510         fi
11511
11512         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11513         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11514         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11515                     grep -c writeback)
11516         if [[ $LOCKED -ne 0 ]]; then
11517                 error "Locked pages remain in cache, locked=$LOCKED"
11518         fi
11519
11520         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11521                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11522         fi
11523
11524         rm -f $DIR/$tfile
11525         echo "No pages locked after fsync"
11526
11527         return 0
11528 }
11529 run_test 118h "Verify timeout in handling recoverables errors  =========="
11530
11531 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11532
11533 test_118i() {
11534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11535         remote_ost_nodsh && skip "remote OST with nodsh"
11536
11537         reset_async
11538
11539         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11540         set_nodes_failloc "$(osts_nodes)" 0x20e
11541
11542         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11543         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11544         PID=$!
11545         sleep 5
11546         set_nodes_failloc "$(osts_nodes)" 0
11547
11548         wait $PID
11549         RC=$?
11550         if [[ $RC -ne 0 ]]; then
11551                 error "got error, but should be not, rc=$RC"
11552         fi
11553
11554         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11555         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11556         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11557         if [[ $LOCKED -ne 0 ]]; then
11558                 error "Locked pages remain in cache, locked=$LOCKED"
11559         fi
11560
11561         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11562                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11563         fi
11564
11565         rm -f $DIR/$tfile
11566         echo "No pages locked after fsync"
11567
11568         return 0
11569 }
11570 run_test 118i "Fix error before timeout in recoverable error  =========="
11571
11572 [ "$SLOW" = "no" ] && set_resend_count 4
11573
11574 test_118j() {
11575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11576         remote_ost_nodsh && skip "remote OST with nodsh"
11577
11578         reset_async
11579
11580         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11581         set_nodes_failloc "$(osts_nodes)" 0x220
11582
11583         # return -EIO from OST
11584         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11585         RC=$?
11586         set_nodes_failloc "$(osts_nodes)" 0x0
11587         if [[ $RC -eq 0 ]]; then
11588                 error "Must return error due to dropped pages, rc=$RC"
11589         fi
11590
11591         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11592         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11593         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11594         if [[ $LOCKED -ne 0 ]]; then
11595                 error "Locked pages remain in cache, locked=$LOCKED"
11596         fi
11597
11598         # in recoverable error on OST we want resend and stay until it finished
11599         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11600                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11601         fi
11602
11603         rm -f $DIR/$tfile
11604         echo "No pages locked after fsync"
11605
11606         return 0
11607 }
11608 run_test 118j "Simulate unrecoverable OST side error =========="
11609
11610 test_118k()
11611 {
11612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11613         remote_ost_nodsh && skip "remote OSTs with nodsh"
11614
11615         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11616         set_nodes_failloc "$(osts_nodes)" 0x20e
11617         test_mkdir $DIR/$tdir
11618
11619         for ((i=0;i<10;i++)); do
11620                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11621                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11622                 SLEEPPID=$!
11623                 sleep 0.500s
11624                 kill $SLEEPPID
11625                 wait $SLEEPPID
11626         done
11627
11628         set_nodes_failloc "$(osts_nodes)" 0
11629         rm -rf $DIR/$tdir
11630 }
11631 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11632
11633 test_118l() # LU-646
11634 {
11635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11636
11637         test_mkdir $DIR/$tdir
11638         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11639         rm -rf $DIR/$tdir
11640 }
11641 run_test 118l "fsync dir"
11642
11643 test_118m() # LU-3066
11644 {
11645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11646
11647         test_mkdir $DIR/$tdir
11648         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11649         rm -rf $DIR/$tdir
11650 }
11651 run_test 118m "fdatasync dir ========="
11652
11653 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11654
11655 test_118n()
11656 {
11657         local begin
11658         local end
11659
11660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11661         remote_ost_nodsh && skip "remote OSTs with nodsh"
11662
11663         # Sleep to avoid a cached response.
11664         #define OBD_STATFS_CACHE_SECONDS 1
11665         sleep 2
11666
11667         # Inject a 10 second delay in the OST_STATFS handler.
11668         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11669         set_nodes_failloc "$(osts_nodes)" 0x242
11670
11671         begin=$SECONDS
11672         stat --file-system $MOUNT > /dev/null
11673         end=$SECONDS
11674
11675         set_nodes_failloc "$(osts_nodes)" 0
11676
11677         if ((end - begin > 20)); then
11678             error "statfs took $((end - begin)) seconds, expected 10"
11679         fi
11680 }
11681 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11682
11683 test_119a() # bug 11737
11684 {
11685         BSIZE=$((512 * 1024))
11686         directio write $DIR/$tfile 0 1 $BSIZE
11687         # We ask to read two blocks, which is more than a file size.
11688         # directio will indicate an error when requested and actual
11689         # sizes aren't equeal (a normal situation in this case) and
11690         # print actual read amount.
11691         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11692         if [ "$NOB" != "$BSIZE" ]; then
11693                 error "read $NOB bytes instead of $BSIZE"
11694         fi
11695         rm -f $DIR/$tfile
11696 }
11697 run_test 119a "Short directIO read must return actual read amount"
11698
11699 test_119b() # bug 11737
11700 {
11701         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11702
11703         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11704         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11705         sync
11706         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11707                 error "direct read failed"
11708         rm -f $DIR/$tfile
11709 }
11710 run_test 119b "Sparse directIO read must return actual read amount"
11711
11712 test_119c() # bug 13099
11713 {
11714         BSIZE=1048576
11715         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11716         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11717         rm -f $DIR/$tfile
11718 }
11719 run_test 119c "Testing for direct read hitting hole"
11720
11721 test_119d() # bug 15950
11722 {
11723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11724
11725         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11726         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11727         BSIZE=1048576
11728         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11729         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11730         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11731         lctl set_param fail_loc=0x40d
11732         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11733         pid_dio=$!
11734         sleep 1
11735         cat $DIR/$tfile > /dev/null &
11736         lctl set_param fail_loc=0
11737         pid_reads=$!
11738         wait $pid_dio
11739         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11740         sleep 2
11741         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11742         error "the read rpcs have not completed in 2s"
11743         rm -f $DIR/$tfile
11744         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11745 }
11746 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11747
11748 test_120a() {
11749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11750         remote_mds_nodsh && skip "remote MDS with nodsh"
11751         test_mkdir -i0 -c1 $DIR/$tdir
11752         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11753                 skip_env "no early lock cancel on server"
11754
11755         lru_resize_disable mdc
11756         lru_resize_disable osc
11757         cancel_lru_locks mdc
11758         # asynchronous object destroy at MDT could cause bl ast to client
11759         cancel_lru_locks osc
11760
11761         stat $DIR/$tdir > /dev/null
11762         can1=$(do_facet mds1 \
11763                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11764                awk '/ldlm_cancel/ {print $2}')
11765         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11766                awk '/ldlm_bl_callback/ {print $2}')
11767         test_mkdir -i0 -c1 $DIR/$tdir/d1
11768         can2=$(do_facet mds1 \
11769                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11770                awk '/ldlm_cancel/ {print $2}')
11771         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11772                awk '/ldlm_bl_callback/ {print $2}')
11773         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11774         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11775         lru_resize_enable mdc
11776         lru_resize_enable osc
11777 }
11778 run_test 120a "Early Lock Cancel: mkdir test"
11779
11780 test_120b() {
11781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11782         remote_mds_nodsh && skip "remote MDS with nodsh"
11783         test_mkdir $DIR/$tdir
11784         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11785                 skip_env "no early lock cancel on server"
11786
11787         lru_resize_disable mdc
11788         lru_resize_disable osc
11789         cancel_lru_locks mdc
11790         stat $DIR/$tdir > /dev/null
11791         can1=$(do_facet $SINGLEMDS \
11792                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11793                awk '/ldlm_cancel/ {print $2}')
11794         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11795                awk '/ldlm_bl_callback/ {print $2}')
11796         touch $DIR/$tdir/f1
11797         can2=$(do_facet $SINGLEMDS \
11798                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11799                awk '/ldlm_cancel/ {print $2}')
11800         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11801                awk '/ldlm_bl_callback/ {print $2}')
11802         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11803         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11804         lru_resize_enable mdc
11805         lru_resize_enable osc
11806 }
11807 run_test 120b "Early Lock Cancel: create test"
11808
11809 test_120c() {
11810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11811         remote_mds_nodsh && skip "remote MDS with nodsh"
11812         test_mkdir -i0 -c1 $DIR/$tdir
11813         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11814                 skip "no early lock cancel on server"
11815
11816         lru_resize_disable mdc
11817         lru_resize_disable osc
11818         test_mkdir -i0 -c1 $DIR/$tdir/d1
11819         test_mkdir -i0 -c1 $DIR/$tdir/d2
11820         touch $DIR/$tdir/d1/f1
11821         cancel_lru_locks mdc
11822         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11823         can1=$(do_facet mds1 \
11824                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11825                awk '/ldlm_cancel/ {print $2}')
11826         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11827                awk '/ldlm_bl_callback/ {print $2}')
11828         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11829         can2=$(do_facet mds1 \
11830                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11831                awk '/ldlm_cancel/ {print $2}')
11832         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11833                awk '/ldlm_bl_callback/ {print $2}')
11834         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11835         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11836         lru_resize_enable mdc
11837         lru_resize_enable osc
11838 }
11839 run_test 120c "Early Lock Cancel: link test"
11840
11841 test_120d() {
11842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11843         remote_mds_nodsh && skip "remote MDS with nodsh"
11844         test_mkdir -i0 -c1 $DIR/$tdir
11845         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11846                 skip_env "no early lock cancel on server"
11847
11848         lru_resize_disable mdc
11849         lru_resize_disable osc
11850         touch $DIR/$tdir
11851         cancel_lru_locks mdc
11852         stat $DIR/$tdir > /dev/null
11853         can1=$(do_facet mds1 \
11854                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11855                awk '/ldlm_cancel/ {print $2}')
11856         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11857                awk '/ldlm_bl_callback/ {print $2}')
11858         chmod a+x $DIR/$tdir
11859         can2=$(do_facet mds1 \
11860                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11861                awk '/ldlm_cancel/ {print $2}')
11862         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11863                awk '/ldlm_bl_callback/ {print $2}')
11864         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11865         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11866         lru_resize_enable mdc
11867         lru_resize_enable osc
11868 }
11869 run_test 120d "Early Lock Cancel: setattr test"
11870
11871 test_120e() {
11872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11873         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11874                 skip_env "no early lock cancel on server"
11875         remote_mds_nodsh && skip "remote MDS with nodsh"
11876
11877         local dlmtrace_set=false
11878
11879         test_mkdir -i0 -c1 $DIR/$tdir
11880         lru_resize_disable mdc
11881         lru_resize_disable osc
11882         ! $LCTL get_param debug | grep -q dlmtrace &&
11883                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11884         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11885         cancel_lru_locks mdc
11886         cancel_lru_locks osc
11887         dd if=$DIR/$tdir/f1 of=/dev/null
11888         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11889         # XXX client can not do early lock cancel of OST lock
11890         # during unlink (LU-4206), so cancel osc lock now.
11891         sleep 2
11892         cancel_lru_locks osc
11893         can1=$(do_facet mds1 \
11894                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11895                awk '/ldlm_cancel/ {print $2}')
11896         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11897                awk '/ldlm_bl_callback/ {print $2}')
11898         unlink $DIR/$tdir/f1
11899         sleep 5
11900         can2=$(do_facet mds1 \
11901                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11902                awk '/ldlm_cancel/ {print $2}')
11903         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11904                awk '/ldlm_bl_callback/ {print $2}')
11905         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11906                 $LCTL dk $TMP/cancel.debug.txt
11907         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11908                 $LCTL dk $TMP/blocking.debug.txt
11909         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11910         lru_resize_enable mdc
11911         lru_resize_enable osc
11912 }
11913 run_test 120e "Early Lock Cancel: unlink test"
11914
11915 test_120f() {
11916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11917         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11918                 skip_env "no early lock cancel on server"
11919         remote_mds_nodsh && skip "remote MDS with nodsh"
11920
11921         test_mkdir -i0 -c1 $DIR/$tdir
11922         lru_resize_disable mdc
11923         lru_resize_disable osc
11924         test_mkdir -i0 -c1 $DIR/$tdir/d1
11925         test_mkdir -i0 -c1 $DIR/$tdir/d2
11926         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11927         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11928         cancel_lru_locks mdc
11929         cancel_lru_locks osc
11930         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11931         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11932         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11933         # XXX client can not do early lock cancel of OST lock
11934         # during rename (LU-4206), so cancel osc lock now.
11935         sleep 2
11936         cancel_lru_locks osc
11937         can1=$(do_facet mds1 \
11938                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11939                awk '/ldlm_cancel/ {print $2}')
11940         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11941                awk '/ldlm_bl_callback/ {print $2}')
11942         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11943         sleep 5
11944         can2=$(do_facet mds1 \
11945                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11946                awk '/ldlm_cancel/ {print $2}')
11947         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11948                awk '/ldlm_bl_callback/ {print $2}')
11949         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11950         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11951         lru_resize_enable mdc
11952         lru_resize_enable osc
11953 }
11954 run_test 120f "Early Lock Cancel: rename test"
11955
11956 test_120g() {
11957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11958         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11959                 skip_env "no early lock cancel on server"
11960         remote_mds_nodsh && skip "remote MDS with nodsh"
11961
11962         lru_resize_disable mdc
11963         lru_resize_disable osc
11964         count=10000
11965         echo create $count files
11966         test_mkdir $DIR/$tdir
11967         cancel_lru_locks mdc
11968         cancel_lru_locks osc
11969         t0=$(date +%s)
11970
11971         can0=$(do_facet $SINGLEMDS \
11972                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11973                awk '/ldlm_cancel/ {print $2}')
11974         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11975                awk '/ldlm_bl_callback/ {print $2}')
11976         createmany -o $DIR/$tdir/f $count
11977         sync
11978         can1=$(do_facet $SINGLEMDS \
11979                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11980                awk '/ldlm_cancel/ {print $2}')
11981         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11982                awk '/ldlm_bl_callback/ {print $2}')
11983         t1=$(date +%s)
11984         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11985         echo rm $count files
11986         rm -r $DIR/$tdir
11987         sync
11988         can2=$(do_facet $SINGLEMDS \
11989                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11990                awk '/ldlm_cancel/ {print $2}')
11991         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11992                awk '/ldlm_bl_callback/ {print $2}')
11993         t2=$(date +%s)
11994         echo total: $count removes in $((t2-t1))
11995         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11996         sleep 2
11997         # wait for commitment of removal
11998         lru_resize_enable mdc
11999         lru_resize_enable osc
12000 }
12001 run_test 120g "Early Lock Cancel: performance test"
12002
12003 test_121() { #bug #10589
12004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12005
12006         rm -rf $DIR/$tfile
12007         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12008 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12009         lctl set_param fail_loc=0x310
12010         cancel_lru_locks osc > /dev/null
12011         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12012         lctl set_param fail_loc=0
12013         [[ $reads -eq $writes ]] ||
12014                 error "read $reads blocks, must be $writes blocks"
12015 }
12016 run_test 121 "read cancel race ========="
12017
12018 test_123a_base() { # was test 123, statahead(bug 11401)
12019         local lsx="$1"
12020
12021         SLOWOK=0
12022         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12023                 log "testing UP system. Performance may be lower than expected."
12024                 SLOWOK=1
12025         fi
12026
12027         rm -rf $DIR/$tdir
12028         test_mkdir $DIR/$tdir
12029         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12030         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12031         MULT=10
12032         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12033                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12034
12035                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12036                 lctl set_param -n llite.*.statahead_max 0
12037                 lctl get_param llite.*.statahead_max
12038                 cancel_lru_locks mdc
12039                 cancel_lru_locks osc
12040                 stime=$(date +%s)
12041                 time $lsx $DIR/$tdir | wc -l
12042                 etime=$(date +%s)
12043                 delta=$((etime - stime))
12044                 log "$lsx $i files without statahead: $delta sec"
12045                 lctl set_param llite.*.statahead_max=$max
12046
12047                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12048                         grep "statahead wrong:" | awk '{print $3}')
12049                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12050                 cancel_lru_locks mdc
12051                 cancel_lru_locks osc
12052                 stime=$(date +%s)
12053                 time $lsx $DIR/$tdir | wc -l
12054                 etime=$(date +%s)
12055                 delta_sa=$((etime - stime))
12056                 log "$lsx $i files with statahead: $delta_sa sec"
12057                 lctl get_param -n llite.*.statahead_stats
12058                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12059                         grep "statahead wrong:" | awk '{print $3}')
12060
12061                 [[ $swrong -lt $ewrong ]] &&
12062                         log "statahead was stopped, maybe too many locks held!"
12063                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12064
12065                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12066                         max=$(lctl get_param -n llite.*.statahead_max |
12067                                 head -n 1)
12068                         lctl set_param -n llite.*.statahead_max 0
12069                         lctl get_param llite.*.statahead_max
12070                         cancel_lru_locks mdc
12071                         cancel_lru_locks osc
12072                         stime=$(date +%s)
12073                         time $lsx $DIR/$tdir | wc -l
12074                         etime=$(date +%s)
12075                         delta=$((etime - stime))
12076                         log "$lsx $i files again without statahead: $delta sec"
12077                         lctl set_param llite.*.statahead_max=$max
12078                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12079                                 if [  $SLOWOK -eq 0 ]; then
12080                                         error "$lsx $i files is slower with statahead!"
12081                                 else
12082                                         log "$lsx $i files is slower with statahead!"
12083                                 fi
12084                                 break
12085                         fi
12086                 fi
12087
12088                 [ $delta -gt 20 ] && break
12089                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12090                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12091         done
12092         log "$lsx done"
12093
12094         stime=$(date +%s)
12095         rm -r $DIR/$tdir
12096         sync
12097         etime=$(date +%s)
12098         delta=$((etime - stime))
12099         log "rm -r $DIR/$tdir/: $delta seconds"
12100         log "rm done"
12101         lctl get_param -n llite.*.statahead_stats
12102 }
12103
12104 test_123aa() {
12105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12106
12107         test_123a_base "ls -l"
12108 }
12109 run_test 123aa "verify statahead work"
12110
12111 test_123ab() {
12112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12113
12114         statx_supported || skip_env "Test must be statx() syscall supported"
12115
12116         test_123a_base "$STATX -l"
12117 }
12118 run_test 123ab "verify statahead work by using statx"
12119
12120 test_123ac() {
12121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12122
12123         statx_supported || skip_env "Test must be statx() syscall supported"
12124
12125         local rpcs_before
12126         local rpcs_after
12127         local agl_before
12128         local agl_after
12129
12130         cancel_lru_locks $OSC
12131         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12132         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12133                 awk '/agl.total:/ {print $3}')
12134         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12135         test_123a_base "$STATX --cached=always -D"
12136         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12137                 awk '/agl.total:/ {print $3}')
12138         [ $agl_before -eq $agl_after ] ||
12139                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12140         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12141         [ $rpcs_after -eq $rpcs_before ] ||
12142                 error "$STATX should not send glimpse RPCs to $OSC"
12143 }
12144 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12145
12146 test_123b () { # statahead(bug 15027)
12147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12148
12149         test_mkdir $DIR/$tdir
12150         createmany -o $DIR/$tdir/$tfile-%d 1000
12151
12152         cancel_lru_locks mdc
12153         cancel_lru_locks osc
12154
12155 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12156         lctl set_param fail_loc=0x80000803
12157         ls -lR $DIR/$tdir > /dev/null
12158         log "ls done"
12159         lctl set_param fail_loc=0x0
12160         lctl get_param -n llite.*.statahead_stats
12161         rm -r $DIR/$tdir
12162         sync
12163
12164 }
12165 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12166
12167 test_123c() {
12168         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12169
12170         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12171         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12172         touch $DIR/$tdir.1/{1..3}
12173         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12174
12175         remount_client $MOUNT
12176
12177         $MULTIOP $DIR/$tdir.0 Q
12178
12179         # let statahead to complete
12180         ls -l $DIR/$tdir.0 > /dev/null
12181
12182         testid=$(echo $TESTNAME | tr '_' ' ')
12183         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12184                 error "statahead warning" || true
12185 }
12186 run_test 123c "Can not initialize inode warning on DNE statahead"
12187
12188 test_124a() {
12189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12190         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12191                 skip_env "no lru resize on server"
12192
12193         local NR=2000
12194
12195         test_mkdir $DIR/$tdir
12196
12197         log "create $NR files at $DIR/$tdir"
12198         createmany -o $DIR/$tdir/f $NR ||
12199                 error "failed to create $NR files in $DIR/$tdir"
12200
12201         cancel_lru_locks mdc
12202         ls -l $DIR/$tdir > /dev/null
12203
12204         local NSDIR=""
12205         local LRU_SIZE=0
12206         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12207                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12208                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12209                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12210                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12211                         log "NSDIR=$NSDIR"
12212                         log "NS=$(basename $NSDIR)"
12213                         break
12214                 fi
12215         done
12216
12217         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12218                 skip "Not enough cached locks created!"
12219         fi
12220         log "LRU=$LRU_SIZE"
12221
12222         local SLEEP=30
12223
12224         # We know that lru resize allows one client to hold $LIMIT locks
12225         # for 10h. After that locks begin to be killed by client.
12226         local MAX_HRS=10
12227         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12228         log "LIMIT=$LIMIT"
12229         if [ $LIMIT -lt $LRU_SIZE ]; then
12230                 skip "Limit is too small $LIMIT"
12231         fi
12232
12233         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12234         # killing locks. Some time was spent for creating locks. This means
12235         # that up to the moment of sleep finish we must have killed some of
12236         # them (10-100 locks). This depends on how fast ther were created.
12237         # Many of them were touched in almost the same moment and thus will
12238         # be killed in groups.
12239         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12240
12241         # Use $LRU_SIZE_B here to take into account real number of locks
12242         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12243         local LRU_SIZE_B=$LRU_SIZE
12244         log "LVF=$LVF"
12245         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12246         log "OLD_LVF=$OLD_LVF"
12247         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12248
12249         # Let's make sure that we really have some margin. Client checks
12250         # cached locks every 10 sec.
12251         SLEEP=$((SLEEP+20))
12252         log "Sleep ${SLEEP} sec"
12253         local SEC=0
12254         while ((SEC<$SLEEP)); do
12255                 echo -n "..."
12256                 sleep 5
12257                 SEC=$((SEC+5))
12258                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12259                 echo -n "$LRU_SIZE"
12260         done
12261         echo ""
12262         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12263         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12264
12265         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12266                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12267                 unlinkmany $DIR/$tdir/f $NR
12268                 return
12269         }
12270
12271         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12272         log "unlink $NR files at $DIR/$tdir"
12273         unlinkmany $DIR/$tdir/f $NR
12274 }
12275 run_test 124a "lru resize ======================================="
12276
12277 get_max_pool_limit()
12278 {
12279         local limit=$($LCTL get_param \
12280                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12281         local max=0
12282         for l in $limit; do
12283                 if [[ $l -gt $max ]]; then
12284                         max=$l
12285                 fi
12286         done
12287         echo $max
12288 }
12289
12290 test_124b() {
12291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12292         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12293                 skip_env "no lru resize on server"
12294
12295         LIMIT=$(get_max_pool_limit)
12296
12297         NR=$(($(default_lru_size)*20))
12298         if [[ $NR -gt $LIMIT ]]; then
12299                 log "Limit lock number by $LIMIT locks"
12300                 NR=$LIMIT
12301         fi
12302
12303         IFree=$(mdsrate_inodes_available)
12304         if [ $IFree -lt $NR ]; then
12305                 log "Limit lock number by $IFree inodes"
12306                 NR=$IFree
12307         fi
12308
12309         lru_resize_disable mdc
12310         test_mkdir -p $DIR/$tdir/disable_lru_resize
12311
12312         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12313         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12314         cancel_lru_locks mdc
12315         stime=`date +%s`
12316         PID=""
12317         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12318         PID="$PID $!"
12319         sleep 2
12320         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12321         PID="$PID $!"
12322         sleep 2
12323         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12324         PID="$PID $!"
12325         wait $PID
12326         etime=`date +%s`
12327         nolruresize_delta=$((etime-stime))
12328         log "ls -la time: $nolruresize_delta seconds"
12329         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12330         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12331
12332         lru_resize_enable mdc
12333         test_mkdir -p $DIR/$tdir/enable_lru_resize
12334
12335         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12336         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12337         cancel_lru_locks mdc
12338         stime=`date +%s`
12339         PID=""
12340         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12341         PID="$PID $!"
12342         sleep 2
12343         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12344         PID="$PID $!"
12345         sleep 2
12346         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12347         PID="$PID $!"
12348         wait $PID
12349         etime=`date +%s`
12350         lruresize_delta=$((etime-stime))
12351         log "ls -la time: $lruresize_delta seconds"
12352         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12353
12354         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12355                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12356         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12357                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12358         else
12359                 log "lru resize performs the same with no lru resize"
12360         fi
12361         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12362 }
12363 run_test 124b "lru resize (performance test) ======================="
12364
12365 test_124c() {
12366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12367         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12368                 skip_env "no lru resize on server"
12369
12370         # cache ununsed locks on client
12371         local nr=100
12372         cancel_lru_locks mdc
12373         test_mkdir $DIR/$tdir
12374         createmany -o $DIR/$tdir/f $nr ||
12375                 error "failed to create $nr files in $DIR/$tdir"
12376         ls -l $DIR/$tdir > /dev/null
12377
12378         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12379         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12380         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12381         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12382         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12383
12384         # set lru_max_age to 1 sec
12385         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12386         echo "sleep $((recalc_p * 2)) seconds..."
12387         sleep $((recalc_p * 2))
12388
12389         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12390         # restore lru_max_age
12391         $LCTL set_param -n $nsdir.lru_max_age $max_age
12392         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12393         unlinkmany $DIR/$tdir/f $nr
12394 }
12395 run_test 124c "LRUR cancel very aged locks"
12396
12397 test_124d() {
12398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12399         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12400                 skip_env "no lru resize on server"
12401
12402         # cache ununsed locks on client
12403         local nr=100
12404
12405         lru_resize_disable mdc
12406         stack_trap "lru_resize_enable mdc" EXIT
12407
12408         cancel_lru_locks mdc
12409
12410         # asynchronous object destroy at MDT could cause bl ast to client
12411         test_mkdir $DIR/$tdir
12412         createmany -o $DIR/$tdir/f $nr ||
12413                 error "failed to create $nr files in $DIR/$tdir"
12414         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12415
12416         ls -l $DIR/$tdir > /dev/null
12417
12418         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12419         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12420         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12421         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12422
12423         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12424
12425         # set lru_max_age to 1 sec
12426         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12427         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12428
12429         echo "sleep $((recalc_p * 2)) seconds..."
12430         sleep $((recalc_p * 2))
12431
12432         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12433
12434         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12435 }
12436 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12437
12438 test_125() { # 13358
12439         $LCTL get_param -n llite.*.client_type | grep -q local ||
12440                 skip "must run as local client"
12441         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12442                 skip_env "must have acl enabled"
12443         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12444
12445         test_mkdir $DIR/$tdir
12446         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12447         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12448         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12449 }
12450 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12451
12452 test_126() { # bug 12829/13455
12453         $GSS && skip_env "must run as gss disabled"
12454         $LCTL get_param -n llite.*.client_type | grep -q local ||
12455                 skip "must run as local client"
12456         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12457
12458         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12459         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12460         rm -f $DIR/$tfile
12461         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12462 }
12463 run_test 126 "check that the fsgid provided by the client is taken into account"
12464
12465 test_127a() { # bug 15521
12466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12467         local name count samp unit min max sum sumsq
12468
12469         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12470         echo "stats before reset"
12471         $LCTL get_param osc.*.stats
12472         $LCTL set_param osc.*.stats=0
12473         local fsize=$((2048 * 1024))
12474
12475         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12476         cancel_lru_locks osc
12477         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12478
12479         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12480         stack_trap "rm -f $TMP/$tfile.tmp"
12481         while read name count samp unit min max sum sumsq; do
12482                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12483                 [ ! $min ] && error "Missing min value for $name proc entry"
12484                 eval $name=$count || error "Wrong proc format"
12485
12486                 case $name in
12487                 read_bytes|write_bytes)
12488                         [[ "$unit" =~ "bytes" ]] ||
12489                                 error "unit is not 'bytes': $unit"
12490                         (( $min >= 4096 )) || error "min is too small: $min"
12491                         (( $min <= $fsize )) || error "min is too big: $min"
12492                         (( $max >= 4096 )) || error "max is too small: $max"
12493                         (( $max <= $fsize )) || error "max is too big: $max"
12494                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12495                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12496                                 error "sumsquare is too small: $sumsq"
12497                         (( $sumsq <= $fsize * $fsize )) ||
12498                                 error "sumsquare is too big: $sumsq"
12499                         ;;
12500                 ost_read|ost_write)
12501                         [[ "$unit" =~ "usec" ]] ||
12502                                 error "unit is not 'usec': $unit"
12503                         ;;
12504                 *)      ;;
12505                 esac
12506         done < $DIR/$tfile.tmp
12507
12508         #check that we actually got some stats
12509         [ "$read_bytes" ] || error "Missing read_bytes stats"
12510         [ "$write_bytes" ] || error "Missing write_bytes stats"
12511         [ "$read_bytes" != 0 ] || error "no read done"
12512         [ "$write_bytes" != 0 ] || error "no write done"
12513 }
12514 run_test 127a "verify the client stats are sane"
12515
12516 test_127b() { # bug LU-333
12517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12518         local name count samp unit min max sum sumsq
12519
12520         echo "stats before reset"
12521         $LCTL get_param llite.*.stats
12522         $LCTL set_param llite.*.stats=0
12523
12524         # perform 2 reads and writes so MAX is different from SUM.
12525         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12526         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12527         cancel_lru_locks osc
12528         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12529         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12530
12531         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12532         stack_trap "rm -f $TMP/$tfile.tmp"
12533         while read name count samp unit min max sum sumsq; do
12534                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12535                 eval $name=$count || error "Wrong proc format"
12536
12537                 case $name in
12538                 read_bytes|write_bytes)
12539                         [[ "$unit" =~ "bytes" ]] ||
12540                                 error "unit is not 'bytes': $unit"
12541                         (( $count == 2 )) || error "count is not 2: $count"
12542                         (( $min == $PAGE_SIZE )) ||
12543                                 error "min is not $PAGE_SIZE: $min"
12544                         (( $max == $PAGE_SIZE )) ||
12545                                 error "max is not $PAGE_SIZE: $max"
12546                         (( $sum == $PAGE_SIZE * 2 )) ||
12547                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12548                         ;;
12549                 read|write)
12550                         [[ "$unit" =~ "usec" ]] ||
12551                                 error "unit is not 'usec': $unit"
12552                         ;;
12553                 *)      ;;
12554                 esac
12555         done < $TMP/$tfile.tmp
12556
12557         #check that we actually got some stats
12558         [ "$read_bytes" ] || error "Missing read_bytes stats"
12559         [ "$write_bytes" ] || error "Missing write_bytes stats"
12560         [ "$read_bytes" != 0 ] || error "no read done"
12561         [ "$write_bytes" != 0 ] || error "no write done"
12562 }
12563 run_test 127b "verify the llite client stats are sane"
12564
12565 test_127c() { # LU-12394
12566         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12567         local size
12568         local bsize
12569         local reads
12570         local writes
12571         local count
12572
12573         $LCTL set_param llite.*.extents_stats=1
12574         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12575
12576         # Use two stripes so there is enough space in default config
12577         $LFS setstripe -c 2 $DIR/$tfile
12578
12579         # Extent stats start at 0-4K and go in power of two buckets
12580         # LL_HIST_START = 12 --> 2^12 = 4K
12581         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12582         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12583         # small configs
12584         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12585                 do
12586                 # Write and read, 2x each, second time at a non-zero offset
12587                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12588                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12589                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12590                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12591                 rm -f $DIR/$tfile
12592         done
12593
12594         $LCTL get_param llite.*.extents_stats
12595
12596         count=2
12597         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12598                 do
12599                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12600                                 grep -m 1 $bsize)
12601                 reads=$(echo $bucket | awk '{print $5}')
12602                 writes=$(echo $bucket | awk '{print $9}')
12603                 [ "$reads" -eq $count ] ||
12604                         error "$reads reads in < $bsize bucket, expect $count"
12605                 [ "$writes" -eq $count ] ||
12606                         error "$writes writes in < $bsize bucket, expect $count"
12607         done
12608
12609         # Test mmap write and read
12610         $LCTL set_param llite.*.extents_stats=c
12611         size=512
12612         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12613         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12614         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12615
12616         $LCTL get_param llite.*.extents_stats
12617
12618         count=$(((size*1024) / PAGE_SIZE))
12619
12620         bsize=$((2 * PAGE_SIZE / 1024))K
12621
12622         bucket=$($LCTL get_param -n llite.*.extents_stats |
12623                         grep -m 1 $bsize)
12624         reads=$(echo $bucket | awk '{print $5}')
12625         writes=$(echo $bucket | awk '{print $9}')
12626         # mmap writes fault in the page first, creating an additonal read
12627         [ "$reads" -eq $((2 * count)) ] ||
12628                 error "$reads reads in < $bsize bucket, expect $count"
12629         [ "$writes" -eq $count ] ||
12630                 error "$writes writes in < $bsize bucket, expect $count"
12631 }
12632 run_test 127c "test llite extent stats with regular & mmap i/o"
12633
12634 test_128() { # bug 15212
12635         touch $DIR/$tfile
12636         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12637                 find $DIR/$tfile
12638                 find $DIR/$tfile
12639         EOF
12640
12641         result=$(grep error $TMP/$tfile.log)
12642         rm -f $DIR/$tfile $TMP/$tfile.log
12643         [ -z "$result" ] ||
12644                 error "consecutive find's under interactive lfs failed"
12645 }
12646 run_test 128 "interactive lfs for 2 consecutive find's"
12647
12648 set_dir_limits () {
12649         local mntdev
12650         local canondev
12651         local node
12652
12653         local ldproc=/proc/fs/ldiskfs
12654         local facets=$(get_facets MDS)
12655
12656         for facet in ${facets//,/ }; do
12657                 canondev=$(ldiskfs_canon \
12658                            *.$(convert_facet2label $facet).mntdev $facet)
12659                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12660                         ldproc=/sys/fs/ldiskfs
12661                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12662                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12663         done
12664 }
12665
12666 check_mds_dmesg() {
12667         local facets=$(get_facets MDS)
12668         for facet in ${facets//,/ }; do
12669                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12670         done
12671         return 1
12672 }
12673
12674 test_129() {
12675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12676         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12677                 skip "Need MDS version with at least 2.5.56"
12678         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12679                 skip_env "ldiskfs only test"
12680         fi
12681         remote_mds_nodsh && skip "remote MDS with nodsh"
12682
12683         local ENOSPC=28
12684         local has_warning=false
12685
12686         rm -rf $DIR/$tdir
12687         mkdir -p $DIR/$tdir
12688
12689         # block size of mds1
12690         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12691         set_dir_limits $maxsize $((maxsize * 6 / 8))
12692         stack_trap "set_dir_limits 0 0"
12693         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12694         local dirsize=$(stat -c%s "$DIR/$tdir")
12695         local nfiles=0
12696         while (( $dirsize <= $maxsize )); do
12697                 $MCREATE $DIR/$tdir/file_base_$nfiles
12698                 rc=$?
12699                 # check two errors:
12700                 # ENOSPC for ext4 max_dir_size, which has been used since
12701                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12702                 if (( rc == ENOSPC )); then
12703                         set_dir_limits 0 0
12704                         echo "rc=$rc returned as expected after $nfiles files"
12705
12706                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12707                                 error "create failed w/o dir size limit"
12708
12709                         # messages may be rate limited if test is run repeatedly
12710                         check_mds_dmesg '"is approaching max"' ||
12711                                 echo "warning message should be output"
12712                         check_mds_dmesg '"has reached max"' ||
12713                                 echo "reached message should be output"
12714
12715                         dirsize=$(stat -c%s "$DIR/$tdir")
12716
12717                         [[ $dirsize -ge $maxsize ]] && return 0
12718                         error "dirsize $dirsize < $maxsize after $nfiles files"
12719                 elif (( rc != 0 )); then
12720                         break
12721                 fi
12722                 nfiles=$((nfiles + 1))
12723                 dirsize=$(stat -c%s "$DIR/$tdir")
12724         done
12725
12726         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12727 }
12728 run_test 129 "test directory size limit ========================"
12729
12730 OLDIFS="$IFS"
12731 cleanup_130() {
12732         trap 0
12733         IFS="$OLDIFS"
12734 }
12735
12736 test_130a() {
12737         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12738         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12739
12740         trap cleanup_130 EXIT RETURN
12741
12742         local fm_file=$DIR/$tfile
12743         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12744         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12745                 error "dd failed for $fm_file"
12746
12747         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12748         filefrag -ves $fm_file
12749         RC=$?
12750         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12751                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12752         [ $RC != 0 ] && error "filefrag $fm_file failed"
12753
12754         filefrag_op=$(filefrag -ve -k $fm_file |
12755                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12756         lun=$($LFS getstripe -i $fm_file)
12757
12758         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12759         IFS=$'\n'
12760         tot_len=0
12761         for line in $filefrag_op
12762         do
12763                 frag_lun=`echo $line | cut -d: -f5`
12764                 ext_len=`echo $line | cut -d: -f4`
12765                 if (( $frag_lun != $lun )); then
12766                         cleanup_130
12767                         error "FIEMAP on 1-stripe file($fm_file) failed"
12768                         return
12769                 fi
12770                 (( tot_len += ext_len ))
12771         done
12772
12773         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12774                 cleanup_130
12775                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12776                 return
12777         fi
12778
12779         cleanup_130
12780
12781         echo "FIEMAP on single striped file succeeded"
12782 }
12783 run_test 130a "FIEMAP (1-stripe file)"
12784
12785 test_130b() {
12786         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12787
12788         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12789         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12790
12791         trap cleanup_130 EXIT RETURN
12792
12793         local fm_file=$DIR/$tfile
12794         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12795                         error "setstripe on $fm_file"
12796         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12797                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12798
12799         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12800                 error "dd failed on $fm_file"
12801
12802         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12803         filefrag_op=$(filefrag -ve -k $fm_file |
12804                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12805
12806         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12807                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12808
12809         IFS=$'\n'
12810         tot_len=0
12811         num_luns=1
12812         for line in $filefrag_op
12813         do
12814                 frag_lun=$(echo $line | cut -d: -f5 |
12815                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12816                 ext_len=$(echo $line | cut -d: -f4)
12817                 if (( $frag_lun != $last_lun )); then
12818                         if (( tot_len != 1024 )); then
12819                                 cleanup_130
12820                                 error "FIEMAP on $fm_file failed; returned " \
12821                                 "len $tot_len for OST $last_lun instead of 1024"
12822                                 return
12823                         else
12824                                 (( num_luns += 1 ))
12825                                 tot_len=0
12826                         fi
12827                 fi
12828                 (( tot_len += ext_len ))
12829                 last_lun=$frag_lun
12830         done
12831         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12832                 cleanup_130
12833                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12834                         "luns or wrong len for OST $last_lun"
12835                 return
12836         fi
12837
12838         cleanup_130
12839
12840         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12841 }
12842 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12843
12844 test_130c() {
12845         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12846
12847         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12848         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12849
12850         trap cleanup_130 EXIT RETURN
12851
12852         local fm_file=$DIR/$tfile
12853         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12854         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12855                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12856
12857         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12858                         error "dd failed on $fm_file"
12859
12860         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12861         filefrag_op=$(filefrag -ve -k $fm_file |
12862                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12863
12864         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12865                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12866
12867         IFS=$'\n'
12868         tot_len=0
12869         num_luns=1
12870         for line in $filefrag_op
12871         do
12872                 frag_lun=$(echo $line | cut -d: -f5 |
12873                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12874                 ext_len=$(echo $line | cut -d: -f4)
12875                 if (( $frag_lun != $last_lun )); then
12876                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12877                         if (( logical != 512 )); then
12878                                 cleanup_130
12879                                 error "FIEMAP on $fm_file failed; returned " \
12880                                 "logical start for lun $logical instead of 512"
12881                                 return
12882                         fi
12883                         if (( tot_len != 512 )); then
12884                                 cleanup_130
12885                                 error "FIEMAP on $fm_file failed; returned " \
12886                                 "len $tot_len for OST $last_lun instead of 1024"
12887                                 return
12888                         else
12889                                 (( num_luns += 1 ))
12890                                 tot_len=0
12891                         fi
12892                 fi
12893                 (( tot_len += ext_len ))
12894                 last_lun=$frag_lun
12895         done
12896         if (( num_luns != 2 || tot_len != 512 )); then
12897                 cleanup_130
12898                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12899                         "luns or wrong len for OST $last_lun"
12900                 return
12901         fi
12902
12903         cleanup_130
12904
12905         echo "FIEMAP on 2-stripe file with hole succeeded"
12906 }
12907 run_test 130c "FIEMAP (2-stripe file with hole)"
12908
12909 test_130d() {
12910         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12911
12912         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12913         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12914
12915         trap cleanup_130 EXIT RETURN
12916
12917         local fm_file=$DIR/$tfile
12918         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12919                         error "setstripe on $fm_file"
12920         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12921                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12922
12923         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12924         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12925                 error "dd failed on $fm_file"
12926
12927         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12928         filefrag_op=$(filefrag -ve -k $fm_file |
12929                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12930
12931         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12932                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12933
12934         IFS=$'\n'
12935         tot_len=0
12936         num_luns=1
12937         for line in $filefrag_op
12938         do
12939                 frag_lun=$(echo $line | cut -d: -f5 |
12940                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12941                 ext_len=$(echo $line | cut -d: -f4)
12942                 if (( $frag_lun != $last_lun )); then
12943                         if (( tot_len != 1024 )); then
12944                                 cleanup_130
12945                                 error "FIEMAP on $fm_file failed; returned " \
12946                                 "len $tot_len for OST $last_lun instead of 1024"
12947                                 return
12948                         else
12949                                 (( num_luns += 1 ))
12950                                 tot_len=0
12951                         fi
12952                 fi
12953                 (( tot_len += ext_len ))
12954                 last_lun=$frag_lun
12955         done
12956         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12957                 cleanup_130
12958                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12959                         "luns or wrong len for OST $last_lun"
12960                 return
12961         fi
12962
12963         cleanup_130
12964
12965         echo "FIEMAP on N-stripe file succeeded"
12966 }
12967 run_test 130d "FIEMAP (N-stripe file)"
12968
12969 test_130e() {
12970         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12971
12972         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12973         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12974
12975         trap cleanup_130 EXIT RETURN
12976
12977         local fm_file=$DIR/$tfile
12978         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12979
12980         NUM_BLKS=512
12981         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12982         for ((i = 0; i < $NUM_BLKS; i++)); do
12983                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
12984                         conv=notrunc > /dev/null 2>&1
12985         done
12986
12987         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12988         filefrag_op=$(filefrag -ve -k $fm_file |
12989                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12990
12991         last_lun=$(echo $filefrag_op | cut -d: -f5)
12992
12993         IFS=$'\n'
12994         tot_len=0
12995         num_luns=1
12996         for line in $filefrag_op; do
12997                 frag_lun=$(echo $line | cut -d: -f5)
12998                 ext_len=$(echo $line | cut -d: -f4)
12999                 if [[ "$frag_lun" != "$last_lun" ]]; then
13000                         if (( tot_len != $EXPECTED_LEN )); then
13001                                 cleanup_130
13002                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13003                         else
13004                                 (( num_luns += 1 ))
13005                                 tot_len=0
13006                         fi
13007                 fi
13008                 (( tot_len += ext_len ))
13009                 last_lun=$frag_lun
13010         done
13011         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13012                 cleanup_130
13013                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13014         fi
13015
13016         echo "FIEMAP with continuation calls succeeded"
13017 }
13018 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13019
13020 test_130f() {
13021         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13022         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13023
13024         local fm_file=$DIR/$tfile
13025         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13026                 error "multiop create with lov_delay_create on $fm_file"
13027
13028         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13029         filefrag_extents=$(filefrag -vek $fm_file |
13030                            awk '/extents? found/ { print $2 }')
13031         if [[ "$filefrag_extents" != "0" ]]; then
13032                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13033         fi
13034
13035         rm -f $fm_file
13036 }
13037 run_test 130f "FIEMAP (unstriped file)"
13038
13039 test_130g() {
13040         local file=$DIR/$tfile
13041         local nr=$((OSTCOUNT * 100))
13042
13043         $LFS setstripe -C $nr $file ||
13044                 error "failed to setstripe -C $nr $file"
13045
13046         dd if=/dev/zero of=$file count=$nr bs=1M
13047         sync
13048         nr=$($LFS getstripe -c $file)
13049
13050         local extents=$(filefrag -v $file |
13051                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13052
13053         echo "filefrag list $extents extents in file with stripecount $nr"
13054         if (( extents < nr )); then
13055                 $LFS getstripe $file
13056                 filefrag -v $file
13057                 error "filefrag printed $extents < $nr extents"
13058         fi
13059
13060         rm -f $file
13061 }
13062 run_test 130g "FIEMAP (overstripe file)"
13063
13064 # Test for writev/readv
13065 test_131a() {
13066         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13067                 error "writev test failed"
13068         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13069                 error "readv failed"
13070         rm -f $DIR/$tfile
13071 }
13072 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13073
13074 test_131b() {
13075         local fsize=$((524288 + 1048576 + 1572864))
13076         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13077                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13078                         error "append writev test failed"
13079
13080         ((fsize += 1572864 + 1048576))
13081         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13082                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13083                         error "append writev test failed"
13084         rm -f $DIR/$tfile
13085 }
13086 run_test 131b "test append writev"
13087
13088 test_131c() {
13089         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13090         error "NOT PASS"
13091 }
13092 run_test 131c "test read/write on file w/o objects"
13093
13094 test_131d() {
13095         rwv -f $DIR/$tfile -w -n 1 1572864
13096         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13097         if [ "$NOB" != 1572864 ]; then
13098                 error "Short read filed: read $NOB bytes instead of 1572864"
13099         fi
13100         rm -f $DIR/$tfile
13101 }
13102 run_test 131d "test short read"
13103
13104 test_131e() {
13105         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13106         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13107         error "read hitting hole failed"
13108         rm -f $DIR/$tfile
13109 }
13110 run_test 131e "test read hitting hole"
13111
13112 check_stats() {
13113         local facet=$1
13114         local op=$2
13115         local want=${3:-0}
13116         local res
13117
13118         case $facet in
13119         mds*) res=$(do_facet $facet \
13120                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13121                  ;;
13122         ost*) res=$(do_facet $facet \
13123                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13124                  ;;
13125         *) error "Wrong facet '$facet'" ;;
13126         esac
13127         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13128         # if the argument $3 is zero, it means any stat increment is ok.
13129         if [[ $want -gt 0 ]]; then
13130                 local count=$(echo $res | awk '{ print $2 }')
13131                 [[ $count -ne $want ]] &&
13132                         error "The $op counter on $facet is $count, not $want"
13133         fi
13134 }
13135
13136 test_133a() {
13137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13138         remote_ost_nodsh && skip "remote OST with nodsh"
13139         remote_mds_nodsh && skip "remote MDS with nodsh"
13140         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13141                 skip_env "MDS doesn't support rename stats"
13142
13143         local testdir=$DIR/${tdir}/stats_testdir
13144
13145         mkdir -p $DIR/${tdir}
13146
13147         # clear stats.
13148         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13149         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13150
13151         # verify mdt stats first.
13152         mkdir ${testdir} || error "mkdir failed"
13153         check_stats $SINGLEMDS "mkdir" 1
13154         touch ${testdir}/${tfile} || error "touch failed"
13155         check_stats $SINGLEMDS "open" 1
13156         check_stats $SINGLEMDS "close" 1
13157         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13158                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13159                 check_stats $SINGLEMDS "mknod" 2
13160         }
13161         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13162         check_stats $SINGLEMDS "unlink" 1
13163         rm -f ${testdir}/${tfile} || error "file remove failed"
13164         check_stats $SINGLEMDS "unlink" 2
13165
13166         # remove working dir and check mdt stats again.
13167         rmdir ${testdir} || error "rmdir failed"
13168         check_stats $SINGLEMDS "rmdir" 1
13169
13170         local testdir1=$DIR/${tdir}/stats_testdir1
13171         mkdir -p ${testdir}
13172         mkdir -p ${testdir1}
13173         touch ${testdir1}/test1
13174         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13175         check_stats $SINGLEMDS "crossdir_rename" 1
13176
13177         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13178         check_stats $SINGLEMDS "samedir_rename" 1
13179
13180         rm -rf $DIR/${tdir}
13181 }
13182 run_test 133a "Verifying MDT stats ========================================"
13183
13184 test_133b() {
13185         local res
13186
13187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13188         remote_ost_nodsh && skip "remote OST with nodsh"
13189         remote_mds_nodsh && skip "remote MDS with nodsh"
13190
13191         local testdir=$DIR/${tdir}/stats_testdir
13192
13193         mkdir -p ${testdir} || error "mkdir failed"
13194         touch ${testdir}/${tfile} || error "touch failed"
13195         cancel_lru_locks mdc
13196
13197         # clear stats.
13198         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13199         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13200
13201         # extra mdt stats verification.
13202         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13203         check_stats $SINGLEMDS "setattr" 1
13204         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13205         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13206         then            # LU-1740
13207                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13208                 check_stats $SINGLEMDS "getattr" 1
13209         fi
13210         rm -rf $DIR/${tdir}
13211
13212         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13213         # so the check below is not reliable
13214         [ $MDSCOUNT -eq 1 ] || return 0
13215
13216         # Sleep to avoid a cached response.
13217         #define OBD_STATFS_CACHE_SECONDS 1
13218         sleep 2
13219         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13220         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13221         $LFS df || error "lfs failed"
13222         check_stats $SINGLEMDS "statfs" 1
13223
13224         # check aggregated statfs (LU-10018)
13225         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13226                 return 0
13227         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13228                 return 0
13229         sleep 2
13230         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13231         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13232         df $DIR
13233         check_stats $SINGLEMDS "statfs" 1
13234
13235         # We want to check that the client didn't send OST_STATFS to
13236         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13237         # extra care is needed here.
13238         if remote_mds; then
13239                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13240                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13241
13242                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13243                 [ "$res" ] && error "OST got STATFS"
13244         fi
13245
13246         return 0
13247 }
13248 run_test 133b "Verifying extra MDT stats =================================="
13249
13250 test_133c() {
13251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13252         remote_ost_nodsh && skip "remote OST with nodsh"
13253         remote_mds_nodsh && skip "remote MDS with nodsh"
13254
13255         local testdir=$DIR/$tdir/stats_testdir
13256
13257         test_mkdir -p $testdir
13258
13259         # verify obdfilter stats.
13260         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13261         sync
13262         cancel_lru_locks osc
13263         wait_delete_completed
13264
13265         # clear stats.
13266         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13267         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13268
13269         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13270                 error "dd failed"
13271         sync
13272         cancel_lru_locks osc
13273         check_stats ost1 "write" 1
13274
13275         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13276         check_stats ost1 "read" 1
13277
13278         > $testdir/$tfile || error "truncate failed"
13279         check_stats ost1 "punch" 1
13280
13281         rm -f $testdir/$tfile || error "file remove failed"
13282         wait_delete_completed
13283         check_stats ost1 "destroy" 1
13284
13285         rm -rf $DIR/$tdir
13286 }
13287 run_test 133c "Verifying OST stats ========================================"
13288
13289 order_2() {
13290         local value=$1
13291         local orig=$value
13292         local order=1
13293
13294         while [ $value -ge 2 ]; do
13295                 order=$((order*2))
13296                 value=$((value/2))
13297         done
13298
13299         if [ $orig -gt $order ]; then
13300                 order=$((order*2))
13301         fi
13302         echo $order
13303 }
13304
13305 size_in_KMGT() {
13306     local value=$1
13307     local size=('K' 'M' 'G' 'T');
13308     local i=0
13309     local size_string=$value
13310
13311     while [ $value -ge 1024 ]; do
13312         if [ $i -gt 3 ]; then
13313             #T is the biggest unit we get here, if that is bigger,
13314             #just return XXXT
13315             size_string=${value}T
13316             break
13317         fi
13318         value=$((value >> 10))
13319         if [ $value -lt 1024 ]; then
13320             size_string=${value}${size[$i]}
13321             break
13322         fi
13323         i=$((i + 1))
13324     done
13325
13326     echo $size_string
13327 }
13328
13329 get_rename_size() {
13330         local size=$1
13331         local context=${2:-.}
13332         local sample=$(do_facet $SINGLEMDS $LCTL \
13333                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13334                 grep -A1 $context |
13335                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13336         echo $sample
13337 }
13338
13339 test_133d() {
13340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13341         remote_ost_nodsh && skip "remote OST with nodsh"
13342         remote_mds_nodsh && skip "remote MDS with nodsh"
13343         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13344                 skip_env "MDS doesn't support rename stats"
13345
13346         local testdir1=$DIR/${tdir}/stats_testdir1
13347         local testdir2=$DIR/${tdir}/stats_testdir2
13348         mkdir -p $DIR/${tdir}
13349
13350         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13351
13352         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13353         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13354
13355         createmany -o $testdir1/test 512 || error "createmany failed"
13356
13357         # check samedir rename size
13358         mv ${testdir1}/test0 ${testdir1}/test_0
13359
13360         local testdir1_size=$(ls -l $DIR/${tdir} |
13361                 awk '/stats_testdir1/ {print $5}')
13362         local testdir2_size=$(ls -l $DIR/${tdir} |
13363                 awk '/stats_testdir2/ {print $5}')
13364
13365         testdir1_size=$(order_2 $testdir1_size)
13366         testdir2_size=$(order_2 $testdir2_size)
13367
13368         testdir1_size=$(size_in_KMGT $testdir1_size)
13369         testdir2_size=$(size_in_KMGT $testdir2_size)
13370
13371         echo "source rename dir size: ${testdir1_size}"
13372         echo "target rename dir size: ${testdir2_size}"
13373
13374         local cmd="do_facet $SINGLEMDS $LCTL "
13375         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13376
13377         eval $cmd || error "$cmd failed"
13378         local samedir=$($cmd | grep 'same_dir')
13379         local same_sample=$(get_rename_size $testdir1_size)
13380         [ -z "$samedir" ] && error "samedir_rename_size count error"
13381         [[ $same_sample -eq 1 ]] ||
13382                 error "samedir_rename_size error $same_sample"
13383         echo "Check same dir rename stats success"
13384
13385         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13386
13387         # check crossdir rename size
13388         mv ${testdir1}/test_0 ${testdir2}/test_0
13389
13390         testdir1_size=$(ls -l $DIR/${tdir} |
13391                 awk '/stats_testdir1/ {print $5}')
13392         testdir2_size=$(ls -l $DIR/${tdir} |
13393                 awk '/stats_testdir2/ {print $5}')
13394
13395         testdir1_size=$(order_2 $testdir1_size)
13396         testdir2_size=$(order_2 $testdir2_size)
13397
13398         testdir1_size=$(size_in_KMGT $testdir1_size)
13399         testdir2_size=$(size_in_KMGT $testdir2_size)
13400
13401         echo "source rename dir size: ${testdir1_size}"
13402         echo "target rename dir size: ${testdir2_size}"
13403
13404         eval $cmd || error "$cmd failed"
13405         local crossdir=$($cmd | grep 'crossdir')
13406         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13407         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13408         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13409         [[ $src_sample -eq 1 ]] ||
13410                 error "crossdir_rename_size error $src_sample"
13411         [[ $tgt_sample -eq 1 ]] ||
13412                 error "crossdir_rename_size error $tgt_sample"
13413         echo "Check cross dir rename stats success"
13414         rm -rf $DIR/${tdir}
13415 }
13416 run_test 133d "Verifying rename_stats ========================================"
13417
13418 test_133e() {
13419         remote_mds_nodsh && skip "remote MDS with nodsh"
13420         remote_ost_nodsh && skip "remote OST with nodsh"
13421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13422
13423         local testdir=$DIR/${tdir}/stats_testdir
13424         local ctr f0 f1 bs=32768 count=42 sum
13425
13426         mkdir -p ${testdir} || error "mkdir failed"
13427
13428         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13429
13430         for ctr in {write,read}_bytes; do
13431                 sync
13432                 cancel_lru_locks osc
13433
13434                 do_facet ost1 $LCTL set_param -n \
13435                         "obdfilter.*.exports.clear=clear"
13436
13437                 if [ $ctr = write_bytes ]; then
13438                         f0=/dev/zero
13439                         f1=${testdir}/${tfile}
13440                 else
13441                         f0=${testdir}/${tfile}
13442                         f1=/dev/null
13443                 fi
13444
13445                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13446                         error "dd failed"
13447                 sync
13448                 cancel_lru_locks osc
13449
13450                 sum=$(do_facet ost1 $LCTL get_param \
13451                         "obdfilter.*.exports.*.stats" |
13452                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13453                                 $1 == ctr { sum += $7 }
13454                                 END { printf("%0.0f", sum) }')
13455
13456                 if ((sum != bs * count)); then
13457                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13458                 fi
13459         done
13460
13461         rm -rf $DIR/${tdir}
13462 }
13463 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13464
13465 test_133f() {
13466         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13467                 skip "too old lustre for get_param -R ($facet_ver)"
13468
13469         # verifying readability.
13470         $LCTL get_param -R '*' &> /dev/null
13471
13472         # Verifing writability with badarea_io.
13473         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13474                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13475                 error "client badarea_io failed"
13476
13477         # remount the FS in case writes/reads /proc break the FS
13478         cleanup || error "failed to unmount"
13479         setup || error "failed to setup"
13480 }
13481 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13482
13483 test_133g() {
13484         remote_mds_nodsh && skip "remote MDS with nodsh"
13485         remote_ost_nodsh && skip "remote OST with nodsh"
13486
13487         local facet
13488         for facet in mds1 ost1; do
13489                 local facet_ver=$(lustre_version_code $facet)
13490                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13491                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13492                 else
13493                         log "$facet: too old lustre for get_param -R"
13494                 fi
13495                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13496                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13497                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13498                                 xargs badarea_io" ||
13499                                         error "$facet badarea_io failed"
13500                 else
13501                         skip_noexit "$facet: too old lustre for get_param -R"
13502                 fi
13503         done
13504
13505         # remount the FS in case writes/reads /proc break the FS
13506         cleanup || error "failed to unmount"
13507         setup || error "failed to setup"
13508 }
13509 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13510
13511 test_133h() {
13512         remote_mds_nodsh && skip "remote MDS with nodsh"
13513         remote_ost_nodsh && skip "remote OST with nodsh"
13514         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13515                 skip "Need MDS version at least 2.9.54"
13516
13517         local facet
13518         for facet in client mds1 ost1; do
13519                 # Get the list of files that are missing the terminating newline
13520                 local plist=$(do_facet $facet
13521                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13522                 local ent
13523                 for ent in $plist; do
13524                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13525                                 awk -v FS='\v' -v RS='\v\v' \
13526                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13527                                         print FILENAME}'" 2>/dev/null)
13528                         [ -z $missing ] || {
13529                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13530                                 error "file does not end with newline: $facet-$ent"
13531                         }
13532                 done
13533         done
13534 }
13535 run_test 133h "Proc files should end with newlines"
13536
13537 test_134a() {
13538         remote_mds_nodsh && skip "remote MDS with nodsh"
13539         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13540                 skip "Need MDS version at least 2.7.54"
13541
13542         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13543         cancel_lru_locks mdc
13544
13545         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13546         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13547         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13548
13549         local nr=1000
13550         createmany -o $DIR/$tdir/f $nr ||
13551                 error "failed to create $nr files in $DIR/$tdir"
13552         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13553
13554         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13555         do_facet mds1 $LCTL set_param fail_loc=0x327
13556         do_facet mds1 $LCTL set_param fail_val=500
13557         touch $DIR/$tdir/m
13558
13559         echo "sleep 10 seconds ..."
13560         sleep 10
13561         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13562
13563         do_facet mds1 $LCTL set_param fail_loc=0
13564         do_facet mds1 $LCTL set_param fail_val=0
13565         [ $lck_cnt -lt $unused ] ||
13566                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13567
13568         rm $DIR/$tdir/m
13569         unlinkmany $DIR/$tdir/f $nr
13570 }
13571 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13572
13573 test_134b() {
13574         remote_mds_nodsh && skip "remote MDS with nodsh"
13575         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13576                 skip "Need MDS version at least 2.7.54"
13577
13578         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13579         cancel_lru_locks mdc
13580
13581         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13582                         ldlm.lock_reclaim_threshold_mb)
13583         # disable reclaim temporarily
13584         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13585
13586         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13587         do_facet mds1 $LCTL set_param fail_loc=0x328
13588         do_facet mds1 $LCTL set_param fail_val=500
13589
13590         $LCTL set_param debug=+trace
13591
13592         local nr=600
13593         createmany -o $DIR/$tdir/f $nr &
13594         local create_pid=$!
13595
13596         echo "Sleep $TIMEOUT seconds ..."
13597         sleep $TIMEOUT
13598         if ! ps -p $create_pid  > /dev/null 2>&1; then
13599                 do_facet mds1 $LCTL set_param fail_loc=0
13600                 do_facet mds1 $LCTL set_param fail_val=0
13601                 do_facet mds1 $LCTL set_param \
13602                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13603                 error "createmany finished incorrectly!"
13604         fi
13605         do_facet mds1 $LCTL set_param fail_loc=0
13606         do_facet mds1 $LCTL set_param fail_val=0
13607         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13608         wait $create_pid || return 1
13609
13610         unlinkmany $DIR/$tdir/f $nr
13611 }
13612 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13613
13614 test_135() {
13615         remote_mds_nodsh && skip "remote MDS with nodsh"
13616         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13617                 skip "Need MDS version at least 2.13.50"
13618         local fname
13619
13620         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13621
13622 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13623         #set only one record at plain llog
13624         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13625
13626         #fill already existed plain llog each 64767
13627         #wrapping whole catalog
13628         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13629
13630         createmany -o $DIR/$tdir/$tfile_ 64700
13631         for (( i = 0; i < 64700; i = i + 2 ))
13632         do
13633                 rm $DIR/$tdir/$tfile_$i &
13634                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13635                 local pid=$!
13636                 wait $pid
13637         done
13638
13639         #waiting osp synchronization
13640         wait_delete_completed
13641 }
13642 run_test 135 "Race catalog processing"
13643
13644 test_136() {
13645         remote_mds_nodsh && skip "remote MDS with nodsh"
13646         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13647                 skip "Need MDS version at least 2.13.50"
13648         local fname
13649
13650         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13651         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13652         #set only one record at plain llog
13653 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13654         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13655
13656         #fill already existed 2 plain llogs each 64767
13657         #wrapping whole catalog
13658         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13659         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13660         wait_delete_completed
13661
13662         createmany -o $DIR/$tdir/$tfile_ 10
13663         sleep 25
13664
13665         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13666         for (( i = 0; i < 10; i = i + 3 ))
13667         do
13668                 rm $DIR/$tdir/$tfile_$i &
13669                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13670                 local pid=$!
13671                 wait $pid
13672                 sleep 7
13673                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13674         done
13675
13676         #waiting osp synchronization
13677         wait_delete_completed
13678 }
13679 run_test 136 "Race catalog processing 2"
13680
13681 test_140() { #bug-17379
13682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13683
13684         test_mkdir $DIR/$tdir
13685         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13686         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13687
13688         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13689         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13690         local i=0
13691         while i=$((i + 1)); do
13692                 test_mkdir $i
13693                 cd $i || error "Changing to $i"
13694                 ln -s ../stat stat || error "Creating stat symlink"
13695                 # Read the symlink until ELOOP present,
13696                 # not LBUGing the system is considered success,
13697                 # we didn't overrun the stack.
13698                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13699                 if [ $ret -ne 0 ]; then
13700                         if [ $ret -eq 40 ]; then
13701                                 break  # -ELOOP
13702                         else
13703                                 error "Open stat symlink"
13704                                         return
13705                         fi
13706                 fi
13707         done
13708         i=$((i - 1))
13709         echo "The symlink depth = $i"
13710         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13711                 error "Invalid symlink depth"
13712
13713         # Test recursive symlink
13714         ln -s symlink_self symlink_self
13715         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13716         echo "open symlink_self returns $ret"
13717         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13718 }
13719 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13720
13721 test_150a() {
13722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13723
13724         local TF="$TMP/$tfile"
13725
13726         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13727         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13728         cp $TF $DIR/$tfile
13729         cancel_lru_locks $OSC
13730         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13731         remount_client $MOUNT
13732         df -P $MOUNT
13733         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13734
13735         $TRUNCATE $TF 6000
13736         $TRUNCATE $DIR/$tfile 6000
13737         cancel_lru_locks $OSC
13738         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13739
13740         echo "12345" >>$TF
13741         echo "12345" >>$DIR/$tfile
13742         cancel_lru_locks $OSC
13743         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13744
13745         echo "12345" >>$TF
13746         echo "12345" >>$DIR/$tfile
13747         cancel_lru_locks $OSC
13748         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13749 }
13750 run_test 150a "truncate/append tests"
13751
13752 test_150b() {
13753         check_set_fallocate_or_skip
13754
13755         touch $DIR/$tfile
13756         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13757         check_fallocate $DIR/$tfile || error "fallocate failed"
13758 }
13759 run_test 150b "Verify fallocate (prealloc) functionality"
13760
13761 test_150bb() {
13762         check_set_fallocate_or_skip
13763
13764         touch $DIR/$tfile
13765         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13766         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13767         > $DIR/$tfile
13768         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13769         # precomputed md5sum for 20MB of zeroes
13770         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13771         local sum=($(md5sum $DIR/$tfile))
13772
13773         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13774
13775         check_set_fallocate 1
13776
13777         > $DIR/$tfile
13778         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13779         sum=($(md5sum $DIR/$tfile))
13780
13781         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13782 }
13783 run_test 150bb "Verify fallocate modes both zero space"
13784
13785 test_150c() {
13786         check_set_fallocate_or_skip
13787
13788         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13789         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13790         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13791         sync; sync_all_data
13792         cancel_lru_locks $OSC
13793         sleep 5
13794         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13795         want=$((OSTCOUNT * 1048576))
13796
13797         # Must allocate all requested space, not more than 5% extra
13798         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13799                 error "bytes $bytes is not $want"
13800
13801         rm -f $DIR/$tfile
13802         # verify fallocate on PFL file
13803         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13804                 error "Create $DIR/$tfile failed"
13805         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13806                         error "fallocate failed"
13807         sync; sync_all_data
13808         cancel_lru_locks $OSC
13809         sleep 5
13810         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13811         local want=$((1024 * 1048576))
13812
13813         # Must allocate all requested space, not more than 5% extra
13814         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13815                 error "bytes $bytes is not $want"
13816 }
13817 run_test 150c "Verify fallocate Size and Blocks"
13818
13819 test_150d() {
13820         check_set_fallocate_or_skip
13821
13822         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13823         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13824         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13825         sync; sync_all_data
13826         cancel_lru_locks $OSC
13827         sleep 5
13828         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13829         local want=$((OSTCOUNT * 1048576))
13830
13831         # Must allocate all requested space, not more than 5% extra
13832         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13833                 error "bytes $bytes is not $want"
13834 }
13835 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13836
13837 test_150e() {
13838         check_set_fallocate_or_skip
13839
13840         echo "df before:"
13841         $LFS df
13842         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13843         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13844                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13845
13846         # Find OST with Minimum Size
13847         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13848                        sort -un | head -1)
13849
13850         # Get 100MB per OST of the available space to reduce run time
13851         # else 60% of the available space if we are running SLOW tests
13852         if [ $SLOW == "no" ]; then
13853                 local space=$((1024 * 100 * OSTCOUNT))
13854         else
13855                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
13856         fi
13857
13858         fallocate -l${space}k $DIR/$tfile ||
13859                 error "fallocate ${space}k $DIR/$tfile failed"
13860         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13861
13862         # get size immediately after fallocate. This should be correctly
13863         # updated
13864         local size=$(stat -c '%s' $DIR/$tfile)
13865         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13866
13867         # Sleep for a while for statfs to get updated. And not pull from cache.
13868         sleep 2
13869
13870         echo "df after fallocate:"
13871         $LFS df
13872
13873         (( size / 1024 == space )) || error "size $size != requested $space"
13874         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13875                 error "used $used < space $space"
13876
13877         rm $DIR/$tfile || error "rm failed"
13878         sync
13879         wait_delete_completed
13880
13881         echo "df after unlink:"
13882         $LFS df
13883 }
13884 run_test 150e "Verify 60% of available OST space consumed by fallocate"
13885
13886 #LU-2902 roc_hit was not able to read all values from lproc
13887 function roc_hit_init() {
13888         local list=$(comma_list $(osts_nodes))
13889         local dir=$DIR/$tdir-check
13890         local file=$dir/$tfile
13891         local BEFORE
13892         local AFTER
13893         local idx
13894
13895         test_mkdir $dir
13896         #use setstripe to do a write to every ost
13897         for i in $(seq 0 $((OSTCOUNT-1))); do
13898                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13899                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13900                 idx=$(printf %04x $i)
13901                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13902                         awk '$1 == "cache_access" {sum += $7}
13903                                 END { printf("%0.0f", sum) }')
13904
13905                 cancel_lru_locks osc
13906                 cat $file >/dev/null
13907
13908                 AFTER=$(get_osd_param $list *OST*$idx stats |
13909                         awk '$1 == "cache_access" {sum += $7}
13910                                 END { printf("%0.0f", sum) }')
13911
13912                 echo BEFORE:$BEFORE AFTER:$AFTER
13913                 if ! let "AFTER - BEFORE == 4"; then
13914                         rm -rf $dir
13915                         error "roc_hit is not safe to use"
13916                 fi
13917                 rm $file
13918         done
13919
13920         rm -rf $dir
13921 }
13922
13923 function roc_hit() {
13924         local list=$(comma_list $(osts_nodes))
13925         echo $(get_osd_param $list '' stats |
13926                 awk '$1 == "cache_hit" {sum += $7}
13927                         END { printf("%0.0f", sum) }')
13928 }
13929
13930 function set_cache() {
13931         local on=1
13932
13933         if [ "$2" == "off" ]; then
13934                 on=0;
13935         fi
13936         local list=$(comma_list $(osts_nodes))
13937         set_osd_param $list '' $1_cache_enable $on
13938
13939         cancel_lru_locks osc
13940 }
13941
13942 test_151() {
13943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13944         remote_ost_nodsh && skip "remote OST with nodsh"
13945
13946         local CPAGES=3
13947         local list=$(comma_list $(osts_nodes))
13948
13949         # check whether obdfilter is cache capable at all
13950         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13951                 skip "not cache-capable obdfilter"
13952         fi
13953
13954         # check cache is enabled on all obdfilters
13955         if get_osd_param $list '' read_cache_enable | grep 0; then
13956                 skip "oss cache is disabled"
13957         fi
13958
13959         set_osd_param $list '' writethrough_cache_enable 1
13960
13961         # check write cache is enabled on all obdfilters
13962         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13963                 skip "oss write cache is NOT enabled"
13964         fi
13965
13966         roc_hit_init
13967
13968         #define OBD_FAIL_OBD_NO_LRU  0x609
13969         do_nodes $list $LCTL set_param fail_loc=0x609
13970
13971         # pages should be in the case right after write
13972         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13973                 error "dd failed"
13974
13975         local BEFORE=$(roc_hit)
13976         cancel_lru_locks osc
13977         cat $DIR/$tfile >/dev/null
13978         local AFTER=$(roc_hit)
13979
13980         do_nodes $list $LCTL set_param fail_loc=0
13981
13982         if ! let "AFTER - BEFORE == CPAGES"; then
13983                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13984         fi
13985
13986         cancel_lru_locks osc
13987         # invalidates OST cache
13988         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13989         set_osd_param $list '' read_cache_enable 0
13990         cat $DIR/$tfile >/dev/null
13991
13992         # now data shouldn't be found in the cache
13993         BEFORE=$(roc_hit)
13994         cancel_lru_locks osc
13995         cat $DIR/$tfile >/dev/null
13996         AFTER=$(roc_hit)
13997         if let "AFTER - BEFORE != 0"; then
13998                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13999         fi
14000
14001         set_osd_param $list '' read_cache_enable 1
14002         rm -f $DIR/$tfile
14003 }
14004 run_test 151 "test cache on oss and controls ==============================="
14005
14006 test_152() {
14007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14008
14009         local TF="$TMP/$tfile"
14010
14011         # simulate ENOMEM during write
14012 #define OBD_FAIL_OST_NOMEM      0x226
14013         lctl set_param fail_loc=0x80000226
14014         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14015         cp $TF $DIR/$tfile
14016         sync || error "sync failed"
14017         lctl set_param fail_loc=0
14018
14019         # discard client's cache
14020         cancel_lru_locks osc
14021
14022         # simulate ENOMEM during read
14023         lctl set_param fail_loc=0x80000226
14024         cmp $TF $DIR/$tfile || error "cmp failed"
14025         lctl set_param fail_loc=0
14026
14027         rm -f $TF
14028 }
14029 run_test 152 "test read/write with enomem ============================"
14030
14031 test_153() {
14032         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14033 }
14034 run_test 153 "test if fdatasync does not crash ======================="
14035
14036 dot_lustre_fid_permission_check() {
14037         local fid=$1
14038         local ffid=$MOUNT/.lustre/fid/$fid
14039         local test_dir=$2
14040
14041         echo "stat fid $fid"
14042         stat $ffid > /dev/null || error "stat $ffid failed."
14043         echo "touch fid $fid"
14044         touch $ffid || error "touch $ffid failed."
14045         echo "write to fid $fid"
14046         cat /etc/hosts > $ffid || error "write $ffid failed."
14047         echo "read fid $fid"
14048         diff /etc/hosts $ffid || error "read $ffid failed."
14049         echo "append write to fid $fid"
14050         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14051         echo "rename fid $fid"
14052         mv $ffid $test_dir/$tfile.1 &&
14053                 error "rename $ffid to $tfile.1 should fail."
14054         touch $test_dir/$tfile.1
14055         mv $test_dir/$tfile.1 $ffid &&
14056                 error "rename $tfile.1 to $ffid should fail."
14057         rm -f $test_dir/$tfile.1
14058         echo "truncate fid $fid"
14059         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14060         echo "link fid $fid"
14061         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14062         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14063                 echo "setfacl fid $fid"
14064                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14065                 echo "getfacl fid $fid"
14066                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14067         fi
14068         echo "unlink fid $fid"
14069         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14070         echo "mknod fid $fid"
14071         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14072
14073         fid=[0xf00000400:0x1:0x0]
14074         ffid=$MOUNT/.lustre/fid/$fid
14075
14076         echo "stat non-exist fid $fid"
14077         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14078         echo "write to non-exist fid $fid"
14079         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14080         echo "link new fid $fid"
14081         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14082
14083         mkdir -p $test_dir/$tdir
14084         touch $test_dir/$tdir/$tfile
14085         fid=$($LFS path2fid $test_dir/$tdir)
14086         rc=$?
14087         [ $rc -ne 0 ] &&
14088                 error "error: could not get fid for $test_dir/$dir/$tfile."
14089
14090         ffid=$MOUNT/.lustre/fid/$fid
14091
14092         echo "ls $fid"
14093         ls $ffid > /dev/null || error "ls $ffid failed."
14094         echo "touch $fid/$tfile.1"
14095         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14096
14097         echo "touch $MOUNT/.lustre/fid/$tfile"
14098         touch $MOUNT/.lustre/fid/$tfile && \
14099                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14100
14101         echo "setxattr to $MOUNT/.lustre/fid"
14102         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14103
14104         echo "listxattr for $MOUNT/.lustre/fid"
14105         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14106
14107         echo "delxattr from $MOUNT/.lustre/fid"
14108         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14109
14110         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14111         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14112                 error "touch invalid fid should fail."
14113
14114         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14115         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14116                 error "touch non-normal fid should fail."
14117
14118         echo "rename $tdir to $MOUNT/.lustre/fid"
14119         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14120                 error "rename to $MOUNT/.lustre/fid should fail."
14121
14122         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14123         then            # LU-3547
14124                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14125                 local new_obf_mode=777
14126
14127                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14128                 chmod $new_obf_mode $DIR/.lustre/fid ||
14129                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14130
14131                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14132                 [ $obf_mode -eq $new_obf_mode ] ||
14133                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14134
14135                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14136                 chmod $old_obf_mode $DIR/.lustre/fid ||
14137                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14138         fi
14139
14140         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14141         fid=$($LFS path2fid $test_dir/$tfile-2)
14142
14143         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14144         then # LU-5424
14145                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14146                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14147                         error "create lov data thru .lustre failed"
14148         fi
14149         echo "cp /etc/passwd $test_dir/$tfile-2"
14150         cp /etc/passwd $test_dir/$tfile-2 ||
14151                 error "copy to $test_dir/$tfile-2 failed."
14152         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14153         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14154                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14155
14156         rm -rf $test_dir/tfile.lnk
14157         rm -rf $test_dir/$tfile-2
14158 }
14159
14160 test_154A() {
14161         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14162                 skip "Need MDS version at least 2.4.1"
14163
14164         local tf=$DIR/$tfile
14165         touch $tf
14166
14167         local fid=$($LFS path2fid $tf)
14168         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14169
14170         # check that we get the same pathname back
14171         local rootpath
14172         local found
14173         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14174                 echo "$rootpath $fid"
14175                 found=$($LFS fid2path $rootpath "$fid")
14176                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14177                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14178         done
14179
14180         # check wrong root path format
14181         rootpath=$MOUNT"_wrong"
14182         found=$($LFS fid2path $rootpath "$fid")
14183         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14184 }
14185 run_test 154A "lfs path2fid and fid2path basic checks"
14186
14187 test_154B() {
14188         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14189                 skip "Need MDS version at least 2.4.1"
14190
14191         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14192         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14193         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14194         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14195
14196         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14197         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14198
14199         # check that we get the same pathname
14200         echo "PFID: $PFID, name: $name"
14201         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14202         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14203         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14204                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14205
14206         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14207 }
14208 run_test 154B "verify the ll_decode_linkea tool"
14209
14210 test_154a() {
14211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14212         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14213         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14214                 skip "Need MDS version at least 2.2.51"
14215         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14216
14217         cp /etc/hosts $DIR/$tfile
14218
14219         fid=$($LFS path2fid $DIR/$tfile)
14220         rc=$?
14221         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14222
14223         dot_lustre_fid_permission_check "$fid" $DIR ||
14224                 error "dot lustre permission check $fid failed"
14225
14226         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14227
14228         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14229
14230         touch $MOUNT/.lustre/file &&
14231                 error "creation is not allowed under .lustre"
14232
14233         mkdir $MOUNT/.lustre/dir &&
14234                 error "mkdir is not allowed under .lustre"
14235
14236         rm -rf $DIR/$tfile
14237 }
14238 run_test 154a "Open-by-FID"
14239
14240 test_154b() {
14241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14242         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14243         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14244         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14245                 skip "Need MDS version at least 2.2.51"
14246
14247         local remote_dir=$DIR/$tdir/remote_dir
14248         local MDTIDX=1
14249         local rc=0
14250
14251         mkdir -p $DIR/$tdir
14252         $LFS mkdir -i $MDTIDX $remote_dir ||
14253                 error "create remote directory failed"
14254
14255         cp /etc/hosts $remote_dir/$tfile
14256
14257         fid=$($LFS path2fid $remote_dir/$tfile)
14258         rc=$?
14259         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14260
14261         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14262                 error "dot lustre permission check $fid failed"
14263         rm -rf $DIR/$tdir
14264 }
14265 run_test 154b "Open-by-FID for remote directory"
14266
14267 test_154c() {
14268         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14269                 skip "Need MDS version at least 2.4.1"
14270
14271         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14272         local FID1=$($LFS path2fid $DIR/$tfile.1)
14273         local FID2=$($LFS path2fid $DIR/$tfile.2)
14274         local FID3=$($LFS path2fid $DIR/$tfile.3)
14275
14276         local N=1
14277         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14278                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14279                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14280                 local want=FID$N
14281                 [ "$FID" = "${!want}" ] ||
14282                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14283                 N=$((N + 1))
14284         done
14285
14286         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14287         do
14288                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14289                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14290                 N=$((N + 1))
14291         done
14292 }
14293 run_test 154c "lfs path2fid and fid2path multiple arguments"
14294
14295 test_154d() {
14296         remote_mds_nodsh && skip "remote MDS with nodsh"
14297         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14298                 skip "Need MDS version at least 2.5.53"
14299
14300         if remote_mds; then
14301                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14302         else
14303                 nid="0@lo"
14304         fi
14305         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14306         local fd
14307         local cmd
14308
14309         rm -f $DIR/$tfile
14310         touch $DIR/$tfile
14311
14312         local fid=$($LFS path2fid $DIR/$tfile)
14313         # Open the file
14314         fd=$(free_fd)
14315         cmd="exec $fd<$DIR/$tfile"
14316         eval $cmd
14317         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14318         echo "$fid_list" | grep "$fid"
14319         rc=$?
14320
14321         cmd="exec $fd>/dev/null"
14322         eval $cmd
14323         if [ $rc -ne 0 ]; then
14324                 error "FID $fid not found in open files list $fid_list"
14325         fi
14326 }
14327 run_test 154d "Verify open file fid"
14328
14329 test_154e()
14330 {
14331         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14332                 skip "Need MDS version at least 2.6.50"
14333
14334         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14335                 error ".lustre returned by readdir"
14336         fi
14337 }
14338 run_test 154e ".lustre is not returned by readdir"
14339
14340 test_154f() {
14341         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14342
14343         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14344         test_mkdir -p -c1 $DIR/$tdir/d
14345         # test dirs inherit from its stripe
14346         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14347         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14348         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14349         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14350         touch $DIR/f
14351
14352         # get fid of parents
14353         local FID0=$($LFS path2fid $DIR/$tdir/d)
14354         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14355         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14356         local FID3=$($LFS path2fid $DIR)
14357
14358         # check that path2fid --parents returns expected <parent_fid>/name
14359         # 1) test for a directory (single parent)
14360         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14361         [ "$parent" == "$FID0/foo1" ] ||
14362                 error "expected parent: $FID0/foo1, got: $parent"
14363
14364         # 2) test for a file with nlink > 1 (multiple parents)
14365         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14366         echo "$parent" | grep -F "$FID1/$tfile" ||
14367                 error "$FID1/$tfile not returned in parent list"
14368         echo "$parent" | grep -F "$FID2/link" ||
14369                 error "$FID2/link not returned in parent list"
14370
14371         # 3) get parent by fid
14372         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14373         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14374         echo "$parent" | grep -F "$FID1/$tfile" ||
14375                 error "$FID1/$tfile not returned in parent list (by fid)"
14376         echo "$parent" | grep -F "$FID2/link" ||
14377                 error "$FID2/link not returned in parent list (by fid)"
14378
14379         # 4) test for entry in root directory
14380         parent=$($LFS path2fid --parents $DIR/f)
14381         echo "$parent" | grep -F "$FID3/f" ||
14382                 error "$FID3/f not returned in parent list"
14383
14384         # 5) test it on root directory
14385         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14386                 error "$MOUNT should not have parents"
14387
14388         # enable xattr caching and check that linkea is correctly updated
14389         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14390         save_lustre_params client "llite.*.xattr_cache" > $save
14391         lctl set_param llite.*.xattr_cache 1
14392
14393         # 6.1) linkea update on rename
14394         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14395
14396         # get parents by fid
14397         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14398         # foo1 should no longer be returned in parent list
14399         echo "$parent" | grep -F "$FID1" &&
14400                 error "$FID1 should no longer be in parent list"
14401         # the new path should appear
14402         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14403                 error "$FID2/$tfile.moved is not in parent list"
14404
14405         # 6.2) linkea update on unlink
14406         rm -f $DIR/$tdir/d/foo2/link
14407         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14408         # foo2/link should no longer be returned in parent list
14409         echo "$parent" | grep -F "$FID2/link" &&
14410                 error "$FID2/link should no longer be in parent list"
14411         true
14412
14413         rm -f $DIR/f
14414         restore_lustre_params < $save
14415         rm -f $save
14416 }
14417 run_test 154f "get parent fids by reading link ea"
14418
14419 test_154g()
14420 {
14421         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14422         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14423            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14424                 skip "Need MDS version at least 2.6.92"
14425
14426         mkdir -p $DIR/$tdir
14427         llapi_fid_test -d $DIR/$tdir
14428 }
14429 run_test 154g "various llapi FID tests"
14430
14431 test_155_small_load() {
14432     local temp=$TMP/$tfile
14433     local file=$DIR/$tfile
14434
14435     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14436         error "dd of=$temp bs=6096 count=1 failed"
14437     cp $temp $file
14438     cancel_lru_locks $OSC
14439     cmp $temp $file || error "$temp $file differ"
14440
14441     $TRUNCATE $temp 6000
14442     $TRUNCATE $file 6000
14443     cmp $temp $file || error "$temp $file differ (truncate1)"
14444
14445     echo "12345" >>$temp
14446     echo "12345" >>$file
14447     cmp $temp $file || error "$temp $file differ (append1)"
14448
14449     echo "12345" >>$temp
14450     echo "12345" >>$file
14451     cmp $temp $file || error "$temp $file differ (append2)"
14452
14453     rm -f $temp $file
14454     true
14455 }
14456
14457 test_155_big_load() {
14458         remote_ost_nodsh && skip "remote OST with nodsh"
14459
14460         local temp=$TMP/$tfile
14461         local file=$DIR/$tfile
14462
14463         free_min_max
14464         local cache_size=$(do_facet ost$((MAXI+1)) \
14465                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14466         local large_file_size=$((cache_size * 2))
14467
14468         echo "OSS cache size: $cache_size KB"
14469         echo "Large file size: $large_file_size KB"
14470
14471         [ $MAXV -le $large_file_size ] &&
14472                 skip_env "max available OST size needs > $large_file_size KB"
14473
14474         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14475
14476         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14477                 error "dd of=$temp bs=$large_file_size count=1k failed"
14478         cp $temp $file
14479         ls -lh $temp $file
14480         cancel_lru_locks osc
14481         cmp $temp $file || error "$temp $file differ"
14482
14483         rm -f $temp $file
14484         true
14485 }
14486
14487 save_writethrough() {
14488         local facets=$(get_facets OST)
14489
14490         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14491 }
14492
14493 test_155a() {
14494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14495
14496         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14497
14498         save_writethrough $p
14499
14500         set_cache read on
14501         set_cache writethrough on
14502         test_155_small_load
14503         restore_lustre_params < $p
14504         rm -f $p
14505 }
14506 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14507
14508 test_155b() {
14509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14510
14511         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14512
14513         save_writethrough $p
14514
14515         set_cache read on
14516         set_cache writethrough off
14517         test_155_small_load
14518         restore_lustre_params < $p
14519         rm -f $p
14520 }
14521 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14522
14523 test_155c() {
14524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14525
14526         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14527
14528         save_writethrough $p
14529
14530         set_cache read off
14531         set_cache writethrough on
14532         test_155_small_load
14533         restore_lustre_params < $p
14534         rm -f $p
14535 }
14536 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14537
14538 test_155d() {
14539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14540
14541         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14542
14543         save_writethrough $p
14544
14545         set_cache read off
14546         set_cache writethrough off
14547         test_155_small_load
14548         restore_lustre_params < $p
14549         rm -f $p
14550 }
14551 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14552
14553 test_155e() {
14554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14555
14556         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14557
14558         save_writethrough $p
14559
14560         set_cache read on
14561         set_cache writethrough on
14562         test_155_big_load
14563         restore_lustre_params < $p
14564         rm -f $p
14565 }
14566 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14567
14568 test_155f() {
14569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14570
14571         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14572
14573         save_writethrough $p
14574
14575         set_cache read on
14576         set_cache writethrough off
14577         test_155_big_load
14578         restore_lustre_params < $p
14579         rm -f $p
14580 }
14581 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14582
14583 test_155g() {
14584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14585
14586         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14587
14588         save_writethrough $p
14589
14590         set_cache read off
14591         set_cache writethrough on
14592         test_155_big_load
14593         restore_lustre_params < $p
14594         rm -f $p
14595 }
14596 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14597
14598 test_155h() {
14599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14600
14601         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14602
14603         save_writethrough $p
14604
14605         set_cache read off
14606         set_cache writethrough off
14607         test_155_big_load
14608         restore_lustre_params < $p
14609         rm -f $p
14610 }
14611 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14612
14613 test_156() {
14614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14615         remote_ost_nodsh && skip "remote OST with nodsh"
14616         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14617                 skip "stats not implemented on old servers"
14618         [ "$ost1_FSTYPE" = "zfs" ] &&
14619                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14620
14621         local CPAGES=3
14622         local BEFORE
14623         local AFTER
14624         local file="$DIR/$tfile"
14625         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14626
14627         save_writethrough $p
14628         roc_hit_init
14629
14630         log "Turn on read and write cache"
14631         set_cache read on
14632         set_cache writethrough on
14633
14634         log "Write data and read it back."
14635         log "Read should be satisfied from the cache."
14636         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14637         BEFORE=$(roc_hit)
14638         cancel_lru_locks osc
14639         cat $file >/dev/null
14640         AFTER=$(roc_hit)
14641         if ! let "AFTER - BEFORE == CPAGES"; then
14642                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14643         else
14644                 log "cache hits: before: $BEFORE, after: $AFTER"
14645         fi
14646
14647         log "Read again; it should be satisfied from the cache."
14648         BEFORE=$AFTER
14649         cancel_lru_locks osc
14650         cat $file >/dev/null
14651         AFTER=$(roc_hit)
14652         if ! let "AFTER - BEFORE == CPAGES"; then
14653                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14654         else
14655                 log "cache hits:: before: $BEFORE, after: $AFTER"
14656         fi
14657
14658         log "Turn off the read cache and turn on the write cache"
14659         set_cache read off
14660         set_cache writethrough on
14661
14662         log "Read again; it should be satisfied from the cache."
14663         BEFORE=$(roc_hit)
14664         cancel_lru_locks osc
14665         cat $file >/dev/null
14666         AFTER=$(roc_hit)
14667         if ! let "AFTER - BEFORE == CPAGES"; then
14668                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14669         else
14670                 log "cache hits:: before: $BEFORE, after: $AFTER"
14671         fi
14672
14673         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14674                 # > 2.12.56 uses pagecache if cached
14675                 log "Read again; it should not be satisfied from the cache."
14676                 BEFORE=$AFTER
14677                 cancel_lru_locks osc
14678                 cat $file >/dev/null
14679                 AFTER=$(roc_hit)
14680                 if ! let "AFTER - BEFORE == 0"; then
14681                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14682                 else
14683                         log "cache hits:: before: $BEFORE, after: $AFTER"
14684                 fi
14685         fi
14686
14687         log "Write data and read it back."
14688         log "Read should be satisfied from the cache."
14689         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14690         BEFORE=$(roc_hit)
14691         cancel_lru_locks osc
14692         cat $file >/dev/null
14693         AFTER=$(roc_hit)
14694         if ! let "AFTER - BEFORE == CPAGES"; then
14695                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14696         else
14697                 log "cache hits:: before: $BEFORE, after: $AFTER"
14698         fi
14699
14700         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14701                 # > 2.12.56 uses pagecache if cached
14702                 log "Read again; it should not be satisfied from the cache."
14703                 BEFORE=$AFTER
14704                 cancel_lru_locks osc
14705                 cat $file >/dev/null
14706                 AFTER=$(roc_hit)
14707                 if ! let "AFTER - BEFORE == 0"; then
14708                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14709                 else
14710                         log "cache hits:: before: $BEFORE, after: $AFTER"
14711                 fi
14712         fi
14713
14714         log "Turn off read and write cache"
14715         set_cache read off
14716         set_cache writethrough off
14717
14718         log "Write data and read it back"
14719         log "It should not be satisfied from the cache."
14720         rm -f $file
14721         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14722         cancel_lru_locks osc
14723         BEFORE=$(roc_hit)
14724         cat $file >/dev/null
14725         AFTER=$(roc_hit)
14726         if ! let "AFTER - BEFORE == 0"; then
14727                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14728         else
14729                 log "cache hits:: before: $BEFORE, after: $AFTER"
14730         fi
14731
14732         log "Turn on the read cache and turn off the write cache"
14733         set_cache read on
14734         set_cache writethrough off
14735
14736         log "Write data and read it back"
14737         log "It should not be satisfied from the cache."
14738         rm -f $file
14739         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14740         BEFORE=$(roc_hit)
14741         cancel_lru_locks osc
14742         cat $file >/dev/null
14743         AFTER=$(roc_hit)
14744         if ! let "AFTER - BEFORE == 0"; then
14745                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14746         else
14747                 log "cache hits:: before: $BEFORE, after: $AFTER"
14748         fi
14749
14750         log "Read again; it should be satisfied from the cache."
14751         BEFORE=$(roc_hit)
14752         cancel_lru_locks osc
14753         cat $file >/dev/null
14754         AFTER=$(roc_hit)
14755         if ! let "AFTER - BEFORE == CPAGES"; then
14756                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14757         else
14758                 log "cache hits:: before: $BEFORE, after: $AFTER"
14759         fi
14760
14761         restore_lustre_params < $p
14762         rm -f $p $file
14763 }
14764 run_test 156 "Verification of tunables"
14765
14766 test_160a() {
14767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14768         remote_mds_nodsh && skip "remote MDS with nodsh"
14769         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14770                 skip "Need MDS version at least 2.2.0"
14771
14772         changelog_register || error "changelog_register failed"
14773         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14774         changelog_users $SINGLEMDS | grep -q $cl_user ||
14775                 error "User $cl_user not found in changelog_users"
14776
14777         # change something
14778         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14779         changelog_clear 0 || error "changelog_clear failed"
14780         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14781         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14782         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14783         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14784         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14785         rm $DIR/$tdir/pics/desktop.jpg
14786
14787         changelog_dump | tail -10
14788
14789         echo "verifying changelog mask"
14790         changelog_chmask "-MKDIR"
14791         changelog_chmask "-CLOSE"
14792
14793         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14794         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14795
14796         changelog_chmask "+MKDIR"
14797         changelog_chmask "+CLOSE"
14798
14799         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14800         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14801
14802         changelog_dump | tail -10
14803         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14804         CLOSES=$(changelog_dump | grep -c "CLOSE")
14805         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14806         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14807
14808         # verify contents
14809         echo "verifying target fid"
14810         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14811         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14812         [ "$fidc" == "$fidf" ] ||
14813                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14814         echo "verifying parent fid"
14815         # The FID returned from the Changelog may be the directory shard on
14816         # a different MDT, and not the FID returned by path2fid on the parent.
14817         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14818         # since this is what will matter when recreating this file in the tree.
14819         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14820         local pathp=$($LFS fid2path $MOUNT "$fidp")
14821         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14822                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14823
14824         echo "getting records for $cl_user"
14825         changelog_users $SINGLEMDS
14826         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14827         local nclr=3
14828         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14829                 error "changelog_clear failed"
14830         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14831         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14832         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14833                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14834
14835         local min0_rec=$(changelog_users $SINGLEMDS |
14836                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14837         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14838                           awk '{ print $1; exit; }')
14839
14840         changelog_dump | tail -n 5
14841         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14842         [ $first_rec == $((min0_rec + 1)) ] ||
14843                 error "first index should be $min0_rec + 1 not $first_rec"
14844
14845         # LU-3446 changelog index reset on MDT restart
14846         local cur_rec1=$(changelog_users $SINGLEMDS |
14847                          awk '/^current.index:/ { print $NF }')
14848         changelog_clear 0 ||
14849                 error "clear all changelog records for $cl_user failed"
14850         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14851         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14852                 error "Fail to start $SINGLEMDS"
14853         local cur_rec2=$(changelog_users $SINGLEMDS |
14854                          awk '/^current.index:/ { print $NF }')
14855         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14856         [ $cur_rec1 == $cur_rec2 ] ||
14857                 error "current index should be $cur_rec1 not $cur_rec2"
14858
14859         echo "verifying users from this test are deregistered"
14860         changelog_deregister || error "changelog_deregister failed"
14861         changelog_users $SINGLEMDS | grep -q $cl_user &&
14862                 error "User '$cl_user' still in changelog_users"
14863
14864         # lctl get_param -n mdd.*.changelog_users
14865         # current index: 144
14866         # ID    index (idle seconds)
14867         # cl3   144 (2)
14868         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14869                 # this is the normal case where all users were deregistered
14870                 # make sure no new records are added when no users are present
14871                 local last_rec1=$(changelog_users $SINGLEMDS |
14872                                   awk '/^current.index:/ { print $NF }')
14873                 touch $DIR/$tdir/chloe
14874                 local last_rec2=$(changelog_users $SINGLEMDS |
14875                                   awk '/^current.index:/ { print $NF }')
14876                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14877                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14878         else
14879                 # any changelog users must be leftovers from a previous test
14880                 changelog_users $SINGLEMDS
14881                 echo "other changelog users; can't verify off"
14882         fi
14883 }
14884 run_test 160a "changelog sanity"
14885
14886 test_160b() { # LU-3587
14887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14888         remote_mds_nodsh && skip "remote MDS with nodsh"
14889         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14890                 skip "Need MDS version at least 2.2.0"
14891
14892         changelog_register || error "changelog_register failed"
14893         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14894         changelog_users $SINGLEMDS | grep -q $cl_user ||
14895                 error "User '$cl_user' not found in changelog_users"
14896
14897         local longname1=$(str_repeat a 255)
14898         local longname2=$(str_repeat b 255)
14899
14900         cd $DIR
14901         echo "creating very long named file"
14902         touch $longname1 || error "create of '$longname1' failed"
14903         echo "renaming very long named file"
14904         mv $longname1 $longname2
14905
14906         changelog_dump | grep RENME | tail -n 5
14907         rm -f $longname2
14908 }
14909 run_test 160b "Verify that very long rename doesn't crash in changelog"
14910
14911 test_160c() {
14912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14913         remote_mds_nodsh && skip "remote MDS with nodsh"
14914
14915         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14916                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14917                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14918                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14919
14920         local rc=0
14921
14922         # Registration step
14923         changelog_register || error "changelog_register failed"
14924
14925         rm -rf $DIR/$tdir
14926         mkdir -p $DIR/$tdir
14927         $MCREATE $DIR/$tdir/foo_160c
14928         changelog_chmask "-TRUNC"
14929         $TRUNCATE $DIR/$tdir/foo_160c 200
14930         changelog_chmask "+TRUNC"
14931         $TRUNCATE $DIR/$tdir/foo_160c 199
14932         changelog_dump | tail -n 5
14933         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14934         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14935 }
14936 run_test 160c "verify that changelog log catch the truncate event"
14937
14938 test_160d() {
14939         remote_mds_nodsh && skip "remote MDS with nodsh"
14940         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14942         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14943                 skip "Need MDS version at least 2.7.60"
14944
14945         # Registration step
14946         changelog_register || error "changelog_register failed"
14947
14948         mkdir -p $DIR/$tdir/migrate_dir
14949         changelog_clear 0 || error "changelog_clear failed"
14950
14951         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14952         changelog_dump | tail -n 5
14953         local migrates=$(changelog_dump | grep -c "MIGRT")
14954         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14955 }
14956 run_test 160d "verify that changelog log catch the migrate event"
14957
14958 test_160e() {
14959         remote_mds_nodsh && skip "remote MDS with nodsh"
14960
14961         # Create a user
14962         changelog_register || error "changelog_register failed"
14963
14964         # Delete a future user (expect fail)
14965         local MDT0=$(facet_svc $SINGLEMDS)
14966         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14967         local rc=$?
14968
14969         if [ $rc -eq 0 ]; then
14970                 error "Deleted non-existant user cl77"
14971         elif [ $rc -ne 2 ]; then
14972                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14973         fi
14974
14975         # Clear to a bad index (1 billion should be safe)
14976         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14977         rc=$?
14978
14979         if [ $rc -eq 0 ]; then
14980                 error "Successfully cleared to invalid CL index"
14981         elif [ $rc -ne 22 ]; then
14982                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14983         fi
14984 }
14985 run_test 160e "changelog negative testing (should return errors)"
14986
14987 test_160f() {
14988         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14989         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14990                 skip "Need MDS version at least 2.10.56"
14991
14992         local mdts=$(comma_list $(mdts_nodes))
14993
14994         # Create a user
14995         changelog_register || error "first changelog_register failed"
14996         changelog_register || error "second changelog_register failed"
14997         local cl_users
14998         declare -A cl_user1
14999         declare -A cl_user2
15000         local user_rec1
15001         local user_rec2
15002         local i
15003
15004         # generate some changelog records to accumulate on each MDT
15005         # use all_char because created files should be evenly distributed
15006         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15007                 error "test_mkdir $tdir failed"
15008         log "$(date +%s): creating first files"
15009         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15010                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15011                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15012         done
15013
15014         # check changelogs have been generated
15015         local start=$SECONDS
15016         local idle_time=$((MDSCOUNT * 5 + 5))
15017         local nbcl=$(changelog_dump | wc -l)
15018         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15019
15020         for param in "changelog_max_idle_time=$idle_time" \
15021                      "changelog_gc=1" \
15022                      "changelog_min_gc_interval=2" \
15023                      "changelog_min_free_cat_entries=3"; do
15024                 local MDT0=$(facet_svc $SINGLEMDS)
15025                 local var="${param%=*}"
15026                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15027
15028                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15029                 do_nodes $mdts $LCTL set_param mdd.*.$param
15030         done
15031
15032         # force cl_user2 to be idle (1st part), but also cancel the
15033         # cl_user1 records so that it is not evicted later in the test.
15034         local sleep1=$((idle_time / 2))
15035         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15036         sleep $sleep1
15037
15038         # simulate changelog catalog almost full
15039         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15040         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15041
15042         for i in $(seq $MDSCOUNT); do
15043                 cl_users=(${CL_USERS[mds$i]})
15044                 cl_user1[mds$i]="${cl_users[0]}"
15045                 cl_user2[mds$i]="${cl_users[1]}"
15046
15047                 [ -n "${cl_user1[mds$i]}" ] ||
15048                         error "mds$i: no user registered"
15049                 [ -n "${cl_user2[mds$i]}" ] ||
15050                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15051
15052                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15053                 [ -n "$user_rec1" ] ||
15054                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15055                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15056                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15057                 [ -n "$user_rec2" ] ||
15058                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15059                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15060                      "$user_rec1 + 2 == $user_rec2"
15061                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15062                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15063                               "$user_rec1 + 2, but is $user_rec2"
15064                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15065                 [ -n "$user_rec2" ] ||
15066                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15067                 [ $user_rec1 == $user_rec2 ] ||
15068                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15069                               "$user_rec1, but is $user_rec2"
15070         done
15071
15072         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15073         local sleep2=$((idle_time - (SECONDS - start) + 1))
15074         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15075         sleep $sleep2
15076
15077         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15078         # cl_user1 should be OK because it recently processed records.
15079         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15080         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15081                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15082                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15083         done
15084
15085         # ensure gc thread is done
15086         for i in $(mdts_nodes); do
15087                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15088                         error "$i: GC-thread not done"
15089         done
15090
15091         local first_rec
15092         for (( i = 1; i <= MDSCOUNT; i++ )); do
15093                 # check cl_user1 still registered
15094                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15095                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15096                 # check cl_user2 unregistered
15097                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15098                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15099
15100                 # check changelogs are present and starting at $user_rec1 + 1
15101                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15102                 [ -n "$user_rec1" ] ||
15103                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15104                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15105                             awk '{ print $1; exit; }')
15106
15107                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15108                 [ $((user_rec1 + 1)) == $first_rec ] ||
15109                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15110         done
15111 }
15112 run_test 160f "changelog garbage collect (timestamped users)"
15113
15114 test_160g() {
15115         remote_mds_nodsh && skip "remote MDS with nodsh"
15116         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15117                 skip "Need MDS version at least 2.10.56"
15118
15119         local mdts=$(comma_list $(mdts_nodes))
15120
15121         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15122         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15123
15124         # Create a user
15125         changelog_register || error "first changelog_register failed"
15126         changelog_register || error "second changelog_register failed"
15127         local cl_users
15128         declare -A cl_user1
15129         declare -A cl_user2
15130         local user_rec1
15131         local user_rec2
15132         local i
15133
15134         # generate some changelog records to accumulate on each MDT
15135         # use all_char because created files should be evenly distributed
15136         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15137                 error "test_mkdir $tdir failed"
15138         for ((i = 0; i < MDSCOUNT; i++)); do
15139                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15140                         error "create $DIR/$tdir/d$i.1 failed"
15141         done
15142
15143         # check changelogs have been generated
15144         local nbcl=$(changelog_dump | wc -l)
15145         (( $nbcl > 0 )) || error "no changelogs found"
15146
15147         # reduce the max_idle_indexes value to make sure we exceed it
15148         for param in "changelog_max_idle_indexes=1" \
15149                      "changelog_gc=1" \
15150                      "changelog_min_gc_interval=2" \
15151                      "changelog_min_free_cat_entries=3"; do
15152                 local MDT0=$(facet_svc $SINGLEMDS)
15153                 local var="${param%=*}"
15154                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15155
15156                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15157                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15158                         error "unable to set mdd.*.$param"
15159         done
15160
15161         # simulate changelog catalog almost full
15162         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15163         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15164
15165         local start=$SECONDS
15166         for i in $(seq $MDSCOUNT); do
15167                 cl_users=(${CL_USERS[mds$i]})
15168                 cl_user1[mds$i]="${cl_users[0]}"
15169                 cl_user2[mds$i]="${cl_users[1]}"
15170
15171                 [ -n "${cl_user1[mds$i]}" ] ||
15172                         error "mds$i: no user registered"
15173                 [ -n "${cl_user2[mds$i]}" ] ||
15174                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15175
15176                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15177                 [ -n "$user_rec1" ] ||
15178                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15179                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15180                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15181                 [ -n "$user_rec2" ] ||
15182                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15183                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15184                      "$user_rec1 + 2 == $user_rec2"
15185                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15186                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15187                               "$user_rec1 + 2, but is $user_rec2"
15188                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15189                 [ -n "$user_rec2" ] ||
15190                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15191                 [ $user_rec1 == $user_rec2 ] ||
15192                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15193                               "$user_rec1, but is $user_rec2"
15194         done
15195
15196         # ensure we are past the previous changelog_min_gc_interval set above
15197         local sleep2=$((start + 2 - SECONDS))
15198         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15199
15200         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15201         # cl_user1 should be OK because it recently processed records.
15202         for ((i = 0; i < MDSCOUNT; i++)); do
15203                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15204                         error "create $DIR/$tdir/d$i.3 failed"
15205         done
15206
15207         # ensure gc thread is done
15208         for i in $(mdts_nodes); do
15209                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15210                         error "$i: GC-thread not done"
15211         done
15212
15213         local first_rec
15214         for (( i = 1; i <= MDSCOUNT; i++ )); do
15215                 # check cl_user1 still registered
15216                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15217                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15218                 # check cl_user2 unregistered
15219                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15220                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15221
15222                 # check changelogs are present and starting at $user_rec1 + 1
15223                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15224                 [ -n "$user_rec1" ] ||
15225                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15226                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15227                             awk '{ print $1; exit; }')
15228
15229                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15230                 [ $((user_rec1 + 1)) == $first_rec ] ||
15231                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15232         done
15233 }
15234 run_test 160g "changelog garbage collect (old users)"
15235
15236 test_160h() {
15237         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15238         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15239                 skip "Need MDS version at least 2.10.56"
15240
15241         local mdts=$(comma_list $(mdts_nodes))
15242
15243         # Create a user
15244         changelog_register || error "first changelog_register failed"
15245         changelog_register || error "second changelog_register failed"
15246         local cl_users
15247         declare -A cl_user1
15248         declare -A cl_user2
15249         local user_rec1
15250         local user_rec2
15251         local i
15252
15253         # generate some changelog records to accumulate on each MDT
15254         # use all_char because created files should be evenly distributed
15255         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15256                 error "test_mkdir $tdir failed"
15257         for ((i = 0; i < MDSCOUNT; i++)); do
15258                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15259                         error "create $DIR/$tdir/d$i.1 failed"
15260         done
15261
15262         # check changelogs have been generated
15263         local nbcl=$(changelog_dump | wc -l)
15264         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15265
15266         for param in "changelog_max_idle_time=10" \
15267                      "changelog_gc=1" \
15268                      "changelog_min_gc_interval=2"; do
15269                 local MDT0=$(facet_svc $SINGLEMDS)
15270                 local var="${param%=*}"
15271                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15272
15273                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15274                 do_nodes $mdts $LCTL set_param mdd.*.$param
15275         done
15276
15277         # force cl_user2 to be idle (1st part)
15278         sleep 9
15279
15280         for i in $(seq $MDSCOUNT); do
15281                 cl_users=(${CL_USERS[mds$i]})
15282                 cl_user1[mds$i]="${cl_users[0]}"
15283                 cl_user2[mds$i]="${cl_users[1]}"
15284
15285                 [ -n "${cl_user1[mds$i]}" ] ||
15286                         error "mds$i: no user registered"
15287                 [ -n "${cl_user2[mds$i]}" ] ||
15288                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15289
15290                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15291                 [ -n "$user_rec1" ] ||
15292                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15293                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15294                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15295                 [ -n "$user_rec2" ] ||
15296                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15297                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15298                      "$user_rec1 + 2 == $user_rec2"
15299                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15300                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15301                               "$user_rec1 + 2, but is $user_rec2"
15302                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15303                 [ -n "$user_rec2" ] ||
15304                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15305                 [ $user_rec1 == $user_rec2 ] ||
15306                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15307                               "$user_rec1, but is $user_rec2"
15308         done
15309
15310         # force cl_user2 to be idle (2nd part) and to reach
15311         # changelog_max_idle_time
15312         sleep 2
15313
15314         # force each GC-thread start and block then
15315         # one per MDT/MDD, set fail_val accordingly
15316         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15317         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15318
15319         # generate more changelogs to trigger fail_loc
15320         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15321                 error "create $DIR/$tdir/${tfile}bis failed"
15322
15323         # stop MDT to stop GC-thread, should be done in back-ground as it will
15324         # block waiting for the thread to be released and exit
15325         declare -A stop_pids
15326         for i in $(seq $MDSCOUNT); do
15327                 stop mds$i &
15328                 stop_pids[mds$i]=$!
15329         done
15330
15331         for i in $(mdts_nodes); do
15332                 local facet
15333                 local nb=0
15334                 local facets=$(facets_up_on_host $i)
15335
15336                 for facet in ${facets//,/ }; do
15337                         if [[ $facet == mds* ]]; then
15338                                 nb=$((nb + 1))
15339                         fi
15340                 done
15341                 # ensure each MDS's gc threads are still present and all in "R"
15342                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15343                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15344                         error "$i: expected $nb GC-thread"
15345                 wait_update $i \
15346                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15347                         "R" 20 ||
15348                         error "$i: GC-thread not found in R-state"
15349                 # check umounts of each MDT on MDS have reached kthread_stop()
15350                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15351                         error "$i: expected $nb umount"
15352                 wait_update $i \
15353                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15354                         error "$i: umount not found in D-state"
15355         done
15356
15357         # release all GC-threads
15358         do_nodes $mdts $LCTL set_param fail_loc=0
15359
15360         # wait for MDT stop to complete
15361         for i in $(seq $MDSCOUNT); do
15362                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15363         done
15364
15365         # XXX
15366         # may try to check if any orphan changelog records are present
15367         # via ldiskfs/zfs and llog_reader...
15368
15369         # re-start/mount MDTs
15370         for i in $(seq $MDSCOUNT); do
15371                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15372                         error "Fail to start mds$i"
15373         done
15374
15375         local first_rec
15376         for i in $(seq $MDSCOUNT); do
15377                 # check cl_user1 still registered
15378                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15379                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15380                 # check cl_user2 unregistered
15381                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15382                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15383
15384                 # check changelogs are present and starting at $user_rec1 + 1
15385                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15386                 [ -n "$user_rec1" ] ||
15387                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15388                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15389                             awk '{ print $1; exit; }')
15390
15391                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15392                 [ $((user_rec1 + 1)) == $first_rec ] ||
15393                         error "mds$i: first index should be $user_rec1 + 1, " \
15394                               "but is $first_rec"
15395         done
15396 }
15397 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15398               "during mount"
15399
15400 test_160i() {
15401
15402         local mdts=$(comma_list $(mdts_nodes))
15403
15404         changelog_register || error "first changelog_register failed"
15405
15406         # generate some changelog records to accumulate on each MDT
15407         # use all_char because created files should be evenly distributed
15408         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15409                 error "test_mkdir $tdir failed"
15410         for ((i = 0; i < MDSCOUNT; i++)); do
15411                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15412                         error "create $DIR/$tdir/d$i.1 failed"
15413         done
15414
15415         # check changelogs have been generated
15416         local nbcl=$(changelog_dump | wc -l)
15417         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15418
15419         # simulate race between register and unregister
15420         # XXX as fail_loc is set per-MDS, with DNE configs the race
15421         # simulation will only occur for one MDT per MDS and for the
15422         # others the normal race scenario will take place
15423         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15424         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15425         do_nodes $mdts $LCTL set_param fail_val=1
15426
15427         # unregister 1st user
15428         changelog_deregister &
15429         local pid1=$!
15430         # wait some time for deregister work to reach race rdv
15431         sleep 2
15432         # register 2nd user
15433         changelog_register || error "2nd user register failed"
15434
15435         wait $pid1 || error "1st user deregister failed"
15436
15437         local i
15438         local last_rec
15439         declare -A LAST_REC
15440         for i in $(seq $MDSCOUNT); do
15441                 if changelog_users mds$i | grep "^cl"; then
15442                         # make sure new records are added with one user present
15443                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15444                                           awk '/^current.index:/ { print $NF }')
15445                 else
15446                         error "mds$i has no user registered"
15447                 fi
15448         done
15449
15450         # generate more changelog records to accumulate on each MDT
15451         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15452                 error "create $DIR/$tdir/${tfile}bis failed"
15453
15454         for i in $(seq $MDSCOUNT); do
15455                 last_rec=$(changelog_users $SINGLEMDS |
15456                            awk '/^current.index:/ { print $NF }')
15457                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15458                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15459                         error "changelogs are off on mds$i"
15460         done
15461 }
15462 run_test 160i "changelog user register/unregister race"
15463
15464 test_160j() {
15465         remote_mds_nodsh && skip "remote MDS with nodsh"
15466         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15467                 skip "Need MDS version at least 2.12.56"
15468
15469         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15470         stack_trap "umount $MOUNT2" EXIT
15471
15472         changelog_register || error "first changelog_register failed"
15473         stack_trap "changelog_deregister" EXIT
15474
15475         # generate some changelog
15476         # use all_char because created files should be evenly distributed
15477         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15478                 error "mkdir $tdir failed"
15479         for ((i = 0; i < MDSCOUNT; i++)); do
15480                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15481                         error "create $DIR/$tdir/d$i.1 failed"
15482         done
15483
15484         # open the changelog device
15485         exec 3>/dev/changelog-$FSNAME-MDT0000
15486         stack_trap "exec 3>&-" EXIT
15487         exec 4</dev/changelog-$FSNAME-MDT0000
15488         stack_trap "exec 4<&-" EXIT
15489
15490         # umount the first lustre mount
15491         umount $MOUNT
15492         stack_trap "mount_client $MOUNT" EXIT
15493
15494         # read changelog, which may or may not fail, but should not crash
15495         cat <&4 >/dev/null
15496
15497         # clear changelog
15498         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15499         changelog_users $SINGLEMDS | grep -q $cl_user ||
15500                 error "User $cl_user not found in changelog_users"
15501
15502         printf 'clear:'$cl_user':0' >&3
15503 }
15504 run_test 160j "client can be umounted while its chanangelog is being used"
15505
15506 test_160k() {
15507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15508         remote_mds_nodsh && skip "remote MDS with nodsh"
15509
15510         mkdir -p $DIR/$tdir/1/1
15511
15512         changelog_register || error "changelog_register failed"
15513         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15514
15515         changelog_users $SINGLEMDS | grep -q $cl_user ||
15516                 error "User '$cl_user' not found in changelog_users"
15517 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15518         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15519         rmdir $DIR/$tdir/1/1 & sleep 1
15520         mkdir $DIR/$tdir/2
15521         touch $DIR/$tdir/2/2
15522         rm -rf $DIR/$tdir/2
15523
15524         wait
15525         sleep 4
15526
15527         changelog_dump | grep rmdir || error "rmdir not recorded"
15528 }
15529 run_test 160k "Verify that changelog records are not lost"
15530
15531 # Verifies that a file passed as a parameter has recently had an operation
15532 # performed on it that has generated an MTIME changelog which contains the
15533 # correct parent FID. As files might reside on a different MDT from the
15534 # parent directory in DNE configurations, the FIDs are translated to paths
15535 # before being compared, which should be identical
15536 compare_mtime_changelog() {
15537         local file="${1}"
15538         local mdtidx
15539         local mtime
15540         local cl_fid
15541         local pdir
15542         local dir
15543
15544         mdtidx=$($LFS getstripe --mdt-index $file)
15545         mdtidx=$(printf "%04x" $mdtidx)
15546
15547         # Obtain the parent FID from the MTIME changelog
15548         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15549         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15550
15551         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15552         [ -z "$cl_fid" ] && error "parent FID not present"
15553
15554         # Verify that the path for the parent FID is the same as the path for
15555         # the test directory
15556         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15557
15558         dir=$(dirname $1)
15559
15560         [[ "${pdir%/}" == "$dir" ]] ||
15561                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15562 }
15563
15564 test_160l() {
15565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15566
15567         remote_mds_nodsh && skip "remote MDS with nodsh"
15568         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15569                 skip "Need MDS version at least 2.13.55"
15570
15571         local cl_user
15572
15573         changelog_register || error "changelog_register failed"
15574         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15575
15576         changelog_users $SINGLEMDS | grep -q $cl_user ||
15577                 error "User '$cl_user' not found in changelog_users"
15578
15579         # Clear some types so that MTIME changelogs are generated
15580         changelog_chmask "-CREAT"
15581         changelog_chmask "-CLOSE"
15582
15583         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15584
15585         # Test CL_MTIME during setattr
15586         touch $DIR/$tdir/$tfile
15587         compare_mtime_changelog $DIR/$tdir/$tfile
15588
15589         # Test CL_MTIME during close
15590         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15591         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15592 }
15593 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15594
15595 test_161a() {
15596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15597
15598         test_mkdir -c1 $DIR/$tdir
15599         cp /etc/hosts $DIR/$tdir/$tfile
15600         test_mkdir -c1 $DIR/$tdir/foo1
15601         test_mkdir -c1 $DIR/$tdir/foo2
15602         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15603         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15604         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15605         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15606         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15607         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15608                 $LFS fid2path $DIR $FID
15609                 error "bad link ea"
15610         fi
15611         # middle
15612         rm $DIR/$tdir/foo2/zachary
15613         # last
15614         rm $DIR/$tdir/foo2/thor
15615         # first
15616         rm $DIR/$tdir/$tfile
15617         # rename
15618         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15619         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15620                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15621         rm $DIR/$tdir/foo2/maggie
15622
15623         # overflow the EA
15624         local longname=$tfile.avg_len_is_thirty_two_
15625         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15626                 error_noexit 'failed to unlink many hardlinks'" EXIT
15627         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15628                 error "failed to hardlink many files"
15629         links=$($LFS fid2path $DIR $FID | wc -l)
15630         echo -n "${links}/1000 links in link EA"
15631         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15632 }
15633 run_test 161a "link ea sanity"
15634
15635 test_161b() {
15636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15637         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15638
15639         local MDTIDX=1
15640         local remote_dir=$DIR/$tdir/remote_dir
15641
15642         mkdir -p $DIR/$tdir
15643         $LFS mkdir -i $MDTIDX $remote_dir ||
15644                 error "create remote directory failed"
15645
15646         cp /etc/hosts $remote_dir/$tfile
15647         mkdir -p $remote_dir/foo1
15648         mkdir -p $remote_dir/foo2
15649         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15650         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15651         ln $remote_dir/$tfile $remote_dir/foo1/luna
15652         ln $remote_dir/$tfile $remote_dir/foo2/thor
15653
15654         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15655                      tr -d ']')
15656         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15657                 $LFS fid2path $DIR $FID
15658                 error "bad link ea"
15659         fi
15660         # middle
15661         rm $remote_dir/foo2/zachary
15662         # last
15663         rm $remote_dir/foo2/thor
15664         # first
15665         rm $remote_dir/$tfile
15666         # rename
15667         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15668         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15669         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15670                 $LFS fid2path $DIR $FID
15671                 error "bad link rename"
15672         fi
15673         rm $remote_dir/foo2/maggie
15674
15675         # overflow the EA
15676         local longname=filename_avg_len_is_thirty_two_
15677         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15678                 error "failed to hardlink many files"
15679         links=$($LFS fid2path $DIR $FID | wc -l)
15680         echo -n "${links}/1000 links in link EA"
15681         [[ ${links} -gt 60 ]] ||
15682                 error "expected at least 60 links in link EA"
15683         unlinkmany $remote_dir/foo2/$longname 1000 ||
15684         error "failed to unlink many hardlinks"
15685 }
15686 run_test 161b "link ea sanity under remote directory"
15687
15688 test_161c() {
15689         remote_mds_nodsh && skip "remote MDS with nodsh"
15690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15691         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15692                 skip "Need MDS version at least 2.1.5"
15693
15694         # define CLF_RENAME_LAST 0x0001
15695         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15696         changelog_register || error "changelog_register failed"
15697
15698         rm -rf $DIR/$tdir
15699         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15700         touch $DIR/$tdir/foo_161c
15701         touch $DIR/$tdir/bar_161c
15702         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15703         changelog_dump | grep RENME | tail -n 5
15704         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15705         changelog_clear 0 || error "changelog_clear failed"
15706         if [ x$flags != "x0x1" ]; then
15707                 error "flag $flags is not 0x1"
15708         fi
15709
15710         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15711         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15712         touch $DIR/$tdir/foo_161c
15713         touch $DIR/$tdir/bar_161c
15714         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15715         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15716         changelog_dump | grep RENME | tail -n 5
15717         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15718         changelog_clear 0 || error "changelog_clear failed"
15719         if [ x$flags != "x0x0" ]; then
15720                 error "flag $flags is not 0x0"
15721         fi
15722         echo "rename overwrite a target having nlink > 1," \
15723                 "changelog record has flags of $flags"
15724
15725         # rename doesn't overwrite a target (changelog flag 0x0)
15726         touch $DIR/$tdir/foo_161c
15727         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15728         changelog_dump | grep RENME | tail -n 5
15729         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15730         changelog_clear 0 || error "changelog_clear failed"
15731         if [ x$flags != "x0x0" ]; then
15732                 error "flag $flags is not 0x0"
15733         fi
15734         echo "rename doesn't overwrite a target," \
15735                 "changelog record has flags of $flags"
15736
15737         # define CLF_UNLINK_LAST 0x0001
15738         # unlink a file having nlink = 1 (changelog flag 0x1)
15739         rm -f $DIR/$tdir/foo2_161c
15740         changelog_dump | grep UNLNK | tail -n 5
15741         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15742         changelog_clear 0 || error "changelog_clear failed"
15743         if [ x$flags != "x0x1" ]; then
15744                 error "flag $flags is not 0x1"
15745         fi
15746         echo "unlink a file having nlink = 1," \
15747                 "changelog record has flags of $flags"
15748
15749         # unlink a file having nlink > 1 (changelog flag 0x0)
15750         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15751         rm -f $DIR/$tdir/foobar_161c
15752         changelog_dump | grep UNLNK | tail -n 5
15753         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15754         changelog_clear 0 || error "changelog_clear failed"
15755         if [ x$flags != "x0x0" ]; then
15756                 error "flag $flags is not 0x0"
15757         fi
15758         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15759 }
15760 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15761
15762 test_161d() {
15763         remote_mds_nodsh && skip "remote MDS with nodsh"
15764         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15765
15766         local pid
15767         local fid
15768
15769         changelog_register || error "changelog_register failed"
15770
15771         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15772         # interfer with $MOUNT/.lustre/fid/ access
15773         mkdir $DIR/$tdir
15774         [[ $? -eq 0 ]] || error "mkdir failed"
15775
15776         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15777         $LCTL set_param fail_loc=0x8000140c
15778         # 5s pause
15779         $LCTL set_param fail_val=5
15780
15781         # create file
15782         echo foofoo > $DIR/$tdir/$tfile &
15783         pid=$!
15784
15785         # wait for create to be delayed
15786         sleep 2
15787
15788         ps -p $pid
15789         [[ $? -eq 0 ]] || error "create should be blocked"
15790
15791         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15792         stack_trap "rm -f $tempfile"
15793         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15794         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15795         # some delay may occur during ChangeLog publishing and file read just
15796         # above, that could allow file write to happen finally
15797         [[ -s $tempfile ]] && echo "file should be empty"
15798
15799         $LCTL set_param fail_loc=0
15800
15801         wait $pid
15802         [[ $? -eq 0 ]] || error "create failed"
15803 }
15804 run_test 161d "create with concurrent .lustre/fid access"
15805
15806 check_path() {
15807         local expected="$1"
15808         shift
15809         local fid="$2"
15810
15811         local path
15812         path=$($LFS fid2path "$@")
15813         local rc=$?
15814
15815         if [ $rc -ne 0 ]; then
15816                 error "path looked up of '$expected' failed: rc=$rc"
15817         elif [ "$path" != "$expected" ]; then
15818                 error "path looked up '$path' instead of '$expected'"
15819         else
15820                 echo "FID '$fid' resolves to path '$path' as expected"
15821         fi
15822 }
15823
15824 test_162a() { # was test_162
15825         test_mkdir -p -c1 $DIR/$tdir/d2
15826         touch $DIR/$tdir/d2/$tfile
15827         touch $DIR/$tdir/d2/x1
15828         touch $DIR/$tdir/d2/x2
15829         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15830         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15831         # regular file
15832         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15833         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15834
15835         # softlink
15836         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15837         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15838         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15839
15840         # softlink to wrong file
15841         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15842         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15843         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15844
15845         # hardlink
15846         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15847         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15848         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15849         # fid2path dir/fsname should both work
15850         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15851         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15852
15853         # hardlink count: check that there are 2 links
15854         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15855         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15856
15857         # hardlink indexing: remove the first link
15858         rm $DIR/$tdir/d2/p/q/r/hlink
15859         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15860 }
15861 run_test 162a "path lookup sanity"
15862
15863 test_162b() {
15864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15865         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15866
15867         mkdir $DIR/$tdir
15868         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15869                                 error "create striped dir failed"
15870
15871         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15872                                         tail -n 1 | awk '{print $2}')
15873         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15874
15875         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15876         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15877
15878         # regular file
15879         for ((i=0;i<5;i++)); do
15880                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15881                         error "get fid for f$i failed"
15882                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15883
15884                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15885                         error "get fid for d$i failed"
15886                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15887         done
15888
15889         return 0
15890 }
15891 run_test 162b "striped directory path lookup sanity"
15892
15893 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15894 test_162c() {
15895         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15896                 skip "Need MDS version at least 2.7.51"
15897
15898         local lpath=$tdir.local
15899         local rpath=$tdir.remote
15900
15901         test_mkdir $DIR/$lpath
15902         test_mkdir $DIR/$rpath
15903
15904         for ((i = 0; i <= 101; i++)); do
15905                 lpath="$lpath/$i"
15906                 mkdir $DIR/$lpath
15907                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15908                         error "get fid for local directory $DIR/$lpath failed"
15909                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15910
15911                 rpath="$rpath/$i"
15912                 test_mkdir $DIR/$rpath
15913                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15914                         error "get fid for remote directory $DIR/$rpath failed"
15915                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15916         done
15917
15918         return 0
15919 }
15920 run_test 162c "fid2path works with paths 100 or more directories deep"
15921
15922 oalr_event_count() {
15923         local event="${1}"
15924         local trace="${2}"
15925
15926         awk -v name="${FSNAME}-OST0000" \
15927             -v event="${event}" \
15928             '$1 == "TRACE" && $2 == event && $3 == name' \
15929             "${trace}" |
15930         wc -l
15931 }
15932
15933 oalr_expect_event_count() {
15934         local event="${1}"
15935         local trace="${2}"
15936         local expect="${3}"
15937         local count
15938
15939         count=$(oalr_event_count "${event}" "${trace}")
15940         if ((count == expect)); then
15941                 return 0
15942         fi
15943
15944         error_noexit "${event} event count was '${count}', expected ${expect}"
15945         cat "${trace}" >&2
15946         exit 1
15947 }
15948
15949 cleanup_165() {
15950         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15951         stop ost1
15952         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15953 }
15954
15955 setup_165() {
15956         sync # Flush previous IOs so we can count log entries.
15957         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15958         stack_trap cleanup_165 EXIT
15959 }
15960
15961 test_165a() {
15962         local trace="/tmp/${tfile}.trace"
15963         local rc
15964         local count
15965
15966         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15967                 skip "OFD access log unsupported"
15968
15969         setup_165
15970         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15971         sleep 5
15972
15973         do_facet ost1 ofd_access_log_reader --list
15974         stop ost1
15975
15976         do_facet ost1 killall -TERM ofd_access_log_reader
15977         wait
15978         rc=$?
15979
15980         if ((rc != 0)); then
15981                 error "ofd_access_log_reader exited with rc = '${rc}'"
15982         fi
15983
15984         # Parse trace file for discovery events:
15985         oalr_expect_event_count alr_log_add "${trace}" 1
15986         oalr_expect_event_count alr_log_eof "${trace}" 1
15987         oalr_expect_event_count alr_log_free "${trace}" 1
15988 }
15989 run_test 165a "ofd access log discovery"
15990
15991 test_165b() {
15992         local trace="/tmp/${tfile}.trace"
15993         local file="${DIR}/${tfile}"
15994         local pfid1
15995         local pfid2
15996         local -a entry
15997         local rc
15998         local count
15999         local size
16000         local flags
16001
16002         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16003                 skip "OFD access log unsupported"
16004
16005         setup_165
16006         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16007         sleep 5
16008
16009         do_facet ost1 ofd_access_log_reader --list
16010
16011         lfs setstripe -c 1 -i 0 "${file}"
16012         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16013                 error "cannot create '${file}'"
16014
16015         sleep 5
16016         do_facet ost1 killall -TERM ofd_access_log_reader
16017         wait
16018         rc=$?
16019
16020         if ((rc != 0)); then
16021                 error "ofd_access_log_reader exited with rc = '${rc}'"
16022         fi
16023
16024         oalr_expect_event_count alr_log_entry "${trace}" 1
16025
16026         pfid1=$($LFS path2fid "${file}")
16027
16028         # 1     2             3   4    5     6   7    8    9     10
16029         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16030         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16031
16032         echo "entry = '${entry[*]}'" >&2
16033
16034         pfid2=${entry[4]}
16035         if [[ "${pfid1}" != "${pfid2}" ]]; then
16036                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16037         fi
16038
16039         size=${entry[8]}
16040         if ((size != 1048576)); then
16041                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16042         fi
16043
16044         flags=${entry[10]}
16045         if [[ "${flags}" != "w" ]]; then
16046                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16047         fi
16048
16049         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16050         sleep 5
16051
16052         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16053                 error "cannot read '${file}'"
16054         sleep 5
16055
16056         do_facet ost1 killall -TERM ofd_access_log_reader
16057         wait
16058         rc=$?
16059
16060         if ((rc != 0)); then
16061                 error "ofd_access_log_reader exited with rc = '${rc}'"
16062         fi
16063
16064         oalr_expect_event_count alr_log_entry "${trace}" 1
16065
16066         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16067         echo "entry = '${entry[*]}'" >&2
16068
16069         pfid2=${entry[4]}
16070         if [[ "${pfid1}" != "${pfid2}" ]]; then
16071                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16072         fi
16073
16074         size=${entry[8]}
16075         if ((size != 524288)); then
16076                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16077         fi
16078
16079         flags=${entry[10]}
16080         if [[ "${flags}" != "r" ]]; then
16081                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16082         fi
16083 }
16084 run_test 165b "ofd access log entries are produced and consumed"
16085
16086 test_165c() {
16087         local trace="/tmp/${tfile}.trace"
16088         local file="${DIR}/${tdir}/${tfile}"
16089
16090         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16091                 skip "OFD access log unsupported"
16092
16093         test_mkdir "${DIR}/${tdir}"
16094
16095         setup_165
16096         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16097         sleep 5
16098
16099         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16100
16101         # 4096 / 64 = 64. Create twice as many entries.
16102         for ((i = 0; i < 128; i++)); do
16103                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16104                         error "cannot create file"
16105         done
16106
16107         sync
16108
16109         do_facet ost1 killall -TERM ofd_access_log_reader
16110         wait
16111         rc=$?
16112         if ((rc != 0)); then
16113                 error "ofd_access_log_reader exited with rc = '${rc}'"
16114         fi
16115
16116         unlinkmany  "${file}-%d" 128
16117 }
16118 run_test 165c "full ofd access logs do not block IOs"
16119
16120 oal_get_read_count() {
16121         local stats="$1"
16122
16123         # STATS lustre-OST0001 alr_read_count 1
16124
16125         do_facet ost1 cat "${stats}" |
16126         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16127              END { print count; }'
16128 }
16129
16130 oal_expect_read_count() {
16131         local stats="$1"
16132         local count
16133         local expect="$2"
16134
16135         # Ask ofd_access_log_reader to write stats.
16136         do_facet ost1 killall -USR1 ofd_access_log_reader
16137
16138         # Allow some time for things to happen.
16139         sleep 1
16140
16141         count=$(oal_get_read_count "${stats}")
16142         if ((count == expect)); then
16143                 return 0
16144         fi
16145
16146         error_noexit "bad read count, got ${count}, expected ${expect}"
16147         do_facet ost1 cat "${stats}" >&2
16148         exit 1
16149 }
16150
16151 test_165d() {
16152         local stats="/tmp/${tfile}.stats"
16153         local file="${DIR}/${tdir}/${tfile}"
16154         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16155
16156         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16157                 skip "OFD access log unsupported"
16158
16159         test_mkdir "${DIR}/${tdir}"
16160
16161         setup_165
16162         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16163         sleep 5
16164
16165         lfs setstripe -c 1 -i 0 "${file}"
16166
16167         do_facet ost1 lctl set_param "${param}=rw"
16168         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16169                 error "cannot create '${file}'"
16170         oal_expect_read_count "${stats}" 1
16171
16172         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16173                 error "cannot read '${file}'"
16174         oal_expect_read_count "${stats}" 2
16175
16176         do_facet ost1 lctl set_param "${param}=r"
16177         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16178                 error "cannot create '${file}'"
16179         oal_expect_read_count "${stats}" 2
16180
16181         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16182                 error "cannot read '${file}'"
16183         oal_expect_read_count "${stats}" 3
16184
16185         do_facet ost1 lctl set_param "${param}=w"
16186         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16187                 error "cannot create '${file}'"
16188         oal_expect_read_count "${stats}" 4
16189
16190         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16191                 error "cannot read '${file}'"
16192         oal_expect_read_count "${stats}" 4
16193
16194         do_facet ost1 lctl set_param "${param}=0"
16195         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16196                 error "cannot create '${file}'"
16197         oal_expect_read_count "${stats}" 4
16198
16199         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16200                 error "cannot read '${file}'"
16201         oal_expect_read_count "${stats}" 4
16202
16203         do_facet ost1 killall -TERM ofd_access_log_reader
16204         wait
16205         rc=$?
16206         if ((rc != 0)); then
16207                 error "ofd_access_log_reader exited with rc = '${rc}'"
16208         fi
16209 }
16210 run_test 165d "ofd_access_log mask works"
16211
16212 test_165e() {
16213         local stats="/tmp/${tfile}.stats"
16214         local file0="${DIR}/${tdir}-0/${tfile}"
16215         local file1="${DIR}/${tdir}-1/${tfile}"
16216
16217         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16218                 skip "OFD access log unsupported"
16219
16220         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16221
16222         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16223         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16224
16225         lfs setstripe -c 1 -i 0 "${file0}"
16226         lfs setstripe -c 1 -i 0 "${file1}"
16227
16228         setup_165
16229         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16230         sleep 5
16231
16232         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16233                 error "cannot create '${file0}'"
16234         sync
16235         oal_expect_read_count "${stats}" 0
16236
16237         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16238                 error "cannot create '${file1}'"
16239         sync
16240         oal_expect_read_count "${stats}" 1
16241
16242         do_facet ost1 killall -TERM ofd_access_log_reader
16243         wait
16244         rc=$?
16245         if ((rc != 0)); then
16246                 error "ofd_access_log_reader exited with rc = '${rc}'"
16247         fi
16248 }
16249 run_test 165e "ofd_access_log MDT index filter works"
16250
16251 test_165f() {
16252         local trace="/tmp/${tfile}.trace"
16253         local rc
16254         local count
16255
16256         setup_165
16257         do_facet ost1 timeout 60 ofd_access_log_reader \
16258                 --exit-on-close --debug=- --trace=- > "${trace}" &
16259         sleep 5
16260         stop ost1
16261
16262         wait
16263         rc=$?
16264
16265         if ((rc != 0)); then
16266                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16267                 cat "${trace}"
16268                 exit 1
16269         fi
16270 }
16271 run_test 165f "ofd_access_log_reader --exit-on-close works"
16272
16273 test_169() {
16274         # do directio so as not to populate the page cache
16275         log "creating a 10 Mb file"
16276         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16277                 error "multiop failed while creating a file"
16278         log "starting reads"
16279         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16280         log "truncating the file"
16281         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16282                 error "multiop failed while truncating the file"
16283         log "killing dd"
16284         kill %+ || true # reads might have finished
16285         echo "wait until dd is finished"
16286         wait
16287         log "removing the temporary file"
16288         rm -rf $DIR/$tfile || error "tmp file removal failed"
16289 }
16290 run_test 169 "parallel read and truncate should not deadlock"
16291
16292 test_170() {
16293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16294
16295         $LCTL clear     # bug 18514
16296         $LCTL debug_daemon start $TMP/${tfile}_log_good
16297         touch $DIR/$tfile
16298         $LCTL debug_daemon stop
16299         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16300                 error "sed failed to read log_good"
16301
16302         $LCTL debug_daemon start $TMP/${tfile}_log_good
16303         rm -rf $DIR/$tfile
16304         $LCTL debug_daemon stop
16305
16306         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16307                error "lctl df log_bad failed"
16308
16309         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16310         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16311
16312         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16313         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16314
16315         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16316                 error "bad_line good_line1 good_line2 are empty"
16317
16318         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16319         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16320         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16321
16322         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16323         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16324         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16325
16326         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16327                 error "bad_line_new good_line_new are empty"
16328
16329         local expected_good=$((good_line1 + good_line2*2))
16330
16331         rm -f $TMP/${tfile}*
16332         # LU-231, short malformed line may not be counted into bad lines
16333         if [ $bad_line -ne $bad_line_new ] &&
16334                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16335                 error "expected $bad_line bad lines, but got $bad_line_new"
16336                 return 1
16337         fi
16338
16339         if [ $expected_good -ne $good_line_new ]; then
16340                 error "expected $expected_good good lines, but got $good_line_new"
16341                 return 2
16342         fi
16343         true
16344 }
16345 run_test 170 "test lctl df to handle corrupted log ====================="
16346
16347 test_171() { # bug20592
16348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16349
16350         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16351         $LCTL set_param fail_loc=0x50e
16352         $LCTL set_param fail_val=3000
16353         multiop_bg_pause $DIR/$tfile O_s || true
16354         local MULTIPID=$!
16355         kill -USR1 $MULTIPID
16356         # cause log dump
16357         sleep 3
16358         wait $MULTIPID
16359         if dmesg | grep "recursive fault"; then
16360                 error "caught a recursive fault"
16361         fi
16362         $LCTL set_param fail_loc=0
16363         true
16364 }
16365 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16366
16367 # it would be good to share it with obdfilter-survey/iokit-libecho code
16368 setup_obdecho_osc () {
16369         local rc=0
16370         local ost_nid=$1
16371         local obdfilter_name=$2
16372         echo "Creating new osc for $obdfilter_name on $ost_nid"
16373         # make sure we can find loopback nid
16374         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16375
16376         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16377                            ${obdfilter_name}_osc_UUID || rc=2; }
16378         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16379                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16380         return $rc
16381 }
16382
16383 cleanup_obdecho_osc () {
16384         local obdfilter_name=$1
16385         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16386         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16387         return 0
16388 }
16389
16390 obdecho_test() {
16391         local OBD=$1
16392         local node=$2
16393         local pages=${3:-64}
16394         local rc=0
16395         local id
16396
16397         local count=10
16398         local obd_size=$(get_obd_size $node $OBD)
16399         local page_size=$(get_page_size $node)
16400         if [[ -n "$obd_size" ]]; then
16401                 local new_count=$((obd_size / (pages * page_size / 1024)))
16402                 [[ $new_count -ge $count ]] || count=$new_count
16403         fi
16404
16405         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16406         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16407                            rc=2; }
16408         if [ $rc -eq 0 ]; then
16409             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16410             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16411         fi
16412         echo "New object id is $id"
16413         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16414                            rc=4; }
16415         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16416                            "test_brw $count w v $pages $id" || rc=4; }
16417         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16418                            rc=4; }
16419         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16420                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16421         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16422                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16423         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16424         return $rc
16425 }
16426
16427 test_180a() {
16428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16429
16430         if ! [ -d /sys/fs/lustre/echo_client ] &&
16431            ! module_loaded obdecho; then
16432                 load_module obdecho/obdecho &&
16433                         stack_trap "rmmod obdecho" EXIT ||
16434                         error "unable to load obdecho on client"
16435         fi
16436
16437         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16438         local host=$($LCTL get_param -n osc.$osc.import |
16439                      awk '/current_connection:/ { print $2 }' )
16440         local target=$($LCTL get_param -n osc.$osc.import |
16441                        awk '/target:/ { print $2 }' )
16442         target=${target%_UUID}
16443
16444         if [ -n "$target" ]; then
16445                 setup_obdecho_osc $host $target &&
16446                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16447                         { error "obdecho setup failed with $?"; return; }
16448
16449                 obdecho_test ${target}_osc client ||
16450                         error "obdecho_test failed on ${target}_osc"
16451         else
16452                 $LCTL get_param osc.$osc.import
16453                 error "there is no osc.$osc.import target"
16454         fi
16455 }
16456 run_test 180a "test obdecho on osc"
16457
16458 test_180b() {
16459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16460         remote_ost_nodsh && skip "remote OST with nodsh"
16461
16462         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16463                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16464                 error "failed to load module obdecho"
16465
16466         local target=$(do_facet ost1 $LCTL dl |
16467                        awk '/obdfilter/ { print $4; exit; }')
16468
16469         if [ -n "$target" ]; then
16470                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16471         else
16472                 do_facet ost1 $LCTL dl
16473                 error "there is no obdfilter target on ost1"
16474         fi
16475 }
16476 run_test 180b "test obdecho directly on obdfilter"
16477
16478 test_180c() { # LU-2598
16479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16480         remote_ost_nodsh && skip "remote OST with nodsh"
16481         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16482                 skip "Need MDS version at least 2.4.0"
16483
16484         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16485                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16486                 error "failed to load module obdecho"
16487
16488         local target=$(do_facet ost1 $LCTL dl |
16489                        awk '/obdfilter/ { print $4; exit; }')
16490
16491         if [ -n "$target" ]; then
16492                 local pages=16384 # 64MB bulk I/O RPC size
16493
16494                 obdecho_test "$target" ost1 "$pages" ||
16495                         error "obdecho_test with pages=$pages failed with $?"
16496         else
16497                 do_facet ost1 $LCTL dl
16498                 error "there is no obdfilter target on ost1"
16499         fi
16500 }
16501 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16502
16503 test_181() { # bug 22177
16504         test_mkdir $DIR/$tdir
16505         # create enough files to index the directory
16506         createmany -o $DIR/$tdir/foobar 4000
16507         # print attributes for debug purpose
16508         lsattr -d .
16509         # open dir
16510         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16511         MULTIPID=$!
16512         # remove the files & current working dir
16513         unlinkmany $DIR/$tdir/foobar 4000
16514         rmdir $DIR/$tdir
16515         kill -USR1 $MULTIPID
16516         wait $MULTIPID
16517         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16518         return 0
16519 }
16520 run_test 181 "Test open-unlinked dir ========================"
16521
16522 test_182() {
16523         local fcount=1000
16524         local tcount=10
16525
16526         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16527
16528         $LCTL set_param mdc.*.rpc_stats=clear
16529
16530         for (( i = 0; i < $tcount; i++ )) ; do
16531                 mkdir $DIR/$tdir/$i
16532         done
16533
16534         for (( i = 0; i < $tcount; i++ )) ; do
16535                 createmany -o $DIR/$tdir/$i/f- $fcount &
16536         done
16537         wait
16538
16539         for (( i = 0; i < $tcount; i++ )) ; do
16540                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16541         done
16542         wait
16543
16544         $LCTL get_param mdc.*.rpc_stats
16545
16546         rm -rf $DIR/$tdir
16547 }
16548 run_test 182 "Test parallel modify metadata operations ================"
16549
16550 test_183() { # LU-2275
16551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16552         remote_mds_nodsh && skip "remote MDS with nodsh"
16553         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16554                 skip "Need MDS version at least 2.3.56"
16555
16556         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16557         echo aaa > $DIR/$tdir/$tfile
16558
16559 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16560         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16561
16562         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16563         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16564
16565         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16566
16567         # Flush negative dentry cache
16568         touch $DIR/$tdir/$tfile
16569
16570         # We are not checking for any leaked references here, they'll
16571         # become evident next time we do cleanup with module unload.
16572         rm -rf $DIR/$tdir
16573 }
16574 run_test 183 "No crash or request leak in case of strange dispositions ========"
16575
16576 # test suite 184 is for LU-2016, LU-2017
16577 test_184a() {
16578         check_swap_layouts_support
16579
16580         dir0=$DIR/$tdir/$testnum
16581         test_mkdir -p -c1 $dir0
16582         ref1=/etc/passwd
16583         ref2=/etc/group
16584         file1=$dir0/f1
16585         file2=$dir0/f2
16586         $LFS setstripe -c1 $file1
16587         cp $ref1 $file1
16588         $LFS setstripe -c2 $file2
16589         cp $ref2 $file2
16590         gen1=$($LFS getstripe -g $file1)
16591         gen2=$($LFS getstripe -g $file2)
16592
16593         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16594         gen=$($LFS getstripe -g $file1)
16595         [[ $gen1 != $gen ]] ||
16596                 "Layout generation on $file1 does not change"
16597         gen=$($LFS getstripe -g $file2)
16598         [[ $gen2 != $gen ]] ||
16599                 "Layout generation on $file2 does not change"
16600
16601         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16602         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16603
16604         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16605 }
16606 run_test 184a "Basic layout swap"
16607
16608 test_184b() {
16609         check_swap_layouts_support
16610
16611         dir0=$DIR/$tdir/$testnum
16612         mkdir -p $dir0 || error "creating dir $dir0"
16613         file1=$dir0/f1
16614         file2=$dir0/f2
16615         file3=$dir0/f3
16616         dir1=$dir0/d1
16617         dir2=$dir0/d2
16618         mkdir $dir1 $dir2
16619         $LFS setstripe -c1 $file1
16620         $LFS setstripe -c2 $file2
16621         $LFS setstripe -c1 $file3
16622         chown $RUNAS_ID $file3
16623         gen1=$($LFS getstripe -g $file1)
16624         gen2=$($LFS getstripe -g $file2)
16625
16626         $LFS swap_layouts $dir1 $dir2 &&
16627                 error "swap of directories layouts should fail"
16628         $LFS swap_layouts $dir1 $file1 &&
16629                 error "swap of directory and file layouts should fail"
16630         $RUNAS $LFS swap_layouts $file1 $file2 &&
16631                 error "swap of file we cannot write should fail"
16632         $LFS swap_layouts $file1 $file3 &&
16633                 error "swap of file with different owner should fail"
16634         /bin/true # to clear error code
16635 }
16636 run_test 184b "Forbidden layout swap (will generate errors)"
16637
16638 test_184c() {
16639         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16640         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16641         check_swap_layouts_support
16642         check_swap_layout_no_dom $DIR
16643
16644         local dir0=$DIR/$tdir/$testnum
16645         mkdir -p $dir0 || error "creating dir $dir0"
16646
16647         local ref1=$dir0/ref1
16648         local ref2=$dir0/ref2
16649         local file1=$dir0/file1
16650         local file2=$dir0/file2
16651         # create a file large enough for the concurrent test
16652         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16653         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16654         echo "ref file size: ref1($(stat -c %s $ref1))," \
16655              "ref2($(stat -c %s $ref2))"
16656
16657         cp $ref2 $file2
16658         dd if=$ref1 of=$file1 bs=16k &
16659         local DD_PID=$!
16660
16661         # Make sure dd starts to copy file, but wait at most 5 seconds
16662         local loops=0
16663         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16664
16665         $LFS swap_layouts $file1 $file2
16666         local rc=$?
16667         wait $DD_PID
16668         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16669         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16670
16671         # how many bytes copied before swapping layout
16672         local copied=$(stat -c %s $file2)
16673         local remaining=$(stat -c %s $ref1)
16674         remaining=$((remaining - copied))
16675         echo "Copied $copied bytes before swapping layout..."
16676
16677         cmp -n $copied $file1 $ref2 | grep differ &&
16678                 error "Content mismatch [0, $copied) of ref2 and file1"
16679         cmp -n $copied $file2 $ref1 ||
16680                 error "Content mismatch [0, $copied) of ref1 and file2"
16681         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16682                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16683
16684         # clean up
16685         rm -f $ref1 $ref2 $file1 $file2
16686 }
16687 run_test 184c "Concurrent write and layout swap"
16688
16689 test_184d() {
16690         check_swap_layouts_support
16691         check_swap_layout_no_dom $DIR
16692         [ -z "$(which getfattr 2>/dev/null)" ] &&
16693                 skip_env "no getfattr command"
16694
16695         local file1=$DIR/$tdir/$tfile-1
16696         local file2=$DIR/$tdir/$tfile-2
16697         local file3=$DIR/$tdir/$tfile-3
16698         local lovea1
16699         local lovea2
16700
16701         mkdir -p $DIR/$tdir
16702         touch $file1 || error "create $file1 failed"
16703         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16704                 error "create $file2 failed"
16705         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16706                 error "create $file3 failed"
16707         lovea1=$(get_layout_param $file1)
16708
16709         $LFS swap_layouts $file2 $file3 ||
16710                 error "swap $file2 $file3 layouts failed"
16711         $LFS swap_layouts $file1 $file2 ||
16712                 error "swap $file1 $file2 layouts failed"
16713
16714         lovea2=$(get_layout_param $file2)
16715         echo "$lovea1"
16716         echo "$lovea2"
16717         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16718
16719         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16720         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16721 }
16722 run_test 184d "allow stripeless layouts swap"
16723
16724 test_184e() {
16725         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16726                 skip "Need MDS version at least 2.6.94"
16727         check_swap_layouts_support
16728         check_swap_layout_no_dom $DIR
16729         [ -z "$(which getfattr 2>/dev/null)" ] &&
16730                 skip_env "no getfattr command"
16731
16732         local file1=$DIR/$tdir/$tfile-1
16733         local file2=$DIR/$tdir/$tfile-2
16734         local file3=$DIR/$tdir/$tfile-3
16735         local lovea
16736
16737         mkdir -p $DIR/$tdir
16738         touch $file1 || error "create $file1 failed"
16739         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16740                 error "create $file2 failed"
16741         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16742                 error "create $file3 failed"
16743
16744         $LFS swap_layouts $file1 $file2 ||
16745                 error "swap $file1 $file2 layouts failed"
16746
16747         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16748         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16749
16750         echo 123 > $file1 || error "Should be able to write into $file1"
16751
16752         $LFS swap_layouts $file1 $file3 ||
16753                 error "swap $file1 $file3 layouts failed"
16754
16755         echo 123 > $file1 || error "Should be able to write into $file1"
16756
16757         rm -rf $file1 $file2 $file3
16758 }
16759 run_test 184e "Recreate layout after stripeless layout swaps"
16760
16761 test_184f() {
16762         # Create a file with name longer than sizeof(struct stat) ==
16763         # 144 to see if we can get chars from the file name to appear
16764         # in the returned striping. Note that 'f' == 0x66.
16765         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16766
16767         mkdir -p $DIR/$tdir
16768         mcreate $DIR/$tdir/$file
16769         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16770                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16771         fi
16772 }
16773 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16774
16775 test_185() { # LU-2441
16776         # LU-3553 - no volatile file support in old servers
16777         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16778                 skip "Need MDS version at least 2.3.60"
16779
16780         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16781         touch $DIR/$tdir/spoo
16782         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16783         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16784                 error "cannot create/write a volatile file"
16785         [ "$FILESET" == "" ] &&
16786         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16787                 error "FID is still valid after close"
16788
16789         multiop_bg_pause $DIR/$tdir vVw4096_c
16790         local multi_pid=$!
16791
16792         local OLD_IFS=$IFS
16793         IFS=":"
16794         local fidv=($fid)
16795         IFS=$OLD_IFS
16796         # assume that the next FID for this client is sequential, since stdout
16797         # is unfortunately eaten by multiop_bg_pause
16798         local n=$((${fidv[1]} + 1))
16799         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16800         if [ "$FILESET" == "" ]; then
16801                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16802                         error "FID is missing before close"
16803         fi
16804         kill -USR1 $multi_pid
16805         # 1 second delay, so if mtime change we will see it
16806         sleep 1
16807         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16808         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16809 }
16810 run_test 185 "Volatile file support"
16811
16812 function create_check_volatile() {
16813         local idx=$1
16814         local tgt
16815
16816         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16817         local PID=$!
16818         sleep 1
16819         local FID=$(cat /tmp/${tfile}.fid)
16820         [ "$FID" == "" ] && error "can't get FID for volatile"
16821         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16822         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16823         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16824         kill -USR1 $PID
16825         wait
16826         sleep 1
16827         cancel_lru_locks mdc # flush opencache
16828         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16829         return 0
16830 }
16831
16832 test_185a(){
16833         # LU-12516 - volatile creation via .lustre
16834         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16835                 skip "Need MDS version at least 2.3.55"
16836
16837         create_check_volatile 0
16838         [ $MDSCOUNT -lt 2 ] && return 0
16839
16840         # DNE case
16841         create_check_volatile 1
16842
16843         return 0
16844 }
16845 run_test 185a "Volatile file creation in .lustre/fid/"
16846
16847 test_187a() {
16848         remote_mds_nodsh && skip "remote MDS with nodsh"
16849         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16850                 skip "Need MDS version at least 2.3.0"
16851
16852         local dir0=$DIR/$tdir/$testnum
16853         mkdir -p $dir0 || error "creating dir $dir0"
16854
16855         local file=$dir0/file1
16856         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16857         local dv1=$($LFS data_version $file)
16858         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16859         local dv2=$($LFS data_version $file)
16860         [[ $dv1 != $dv2 ]] ||
16861                 error "data version did not change on write $dv1 == $dv2"
16862
16863         # clean up
16864         rm -f $file1
16865 }
16866 run_test 187a "Test data version change"
16867
16868 test_187b() {
16869         remote_mds_nodsh && skip "remote MDS with nodsh"
16870         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16871                 skip "Need MDS version at least 2.3.0"
16872
16873         local dir0=$DIR/$tdir/$testnum
16874         mkdir -p $dir0 || error "creating dir $dir0"
16875
16876         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16877         [[ ${DV[0]} != ${DV[1]} ]] ||
16878                 error "data version did not change on write"\
16879                       " ${DV[0]} == ${DV[1]}"
16880
16881         # clean up
16882         rm -f $file1
16883 }
16884 run_test 187b "Test data version change on volatile file"
16885
16886 test_200() {
16887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16888         remote_mgs_nodsh && skip "remote MGS with nodsh"
16889         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16890
16891         local POOL=${POOL:-cea1}
16892         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16893         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16894         # Pool OST targets
16895         local first_ost=0
16896         local last_ost=$(($OSTCOUNT - 1))
16897         local ost_step=2
16898         local ost_list=$(seq $first_ost $ost_step $last_ost)
16899         local ost_range="$first_ost $last_ost $ost_step"
16900         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16901         local file_dir=$POOL_ROOT/file_tst
16902         local subdir=$test_path/subdir
16903         local rc=0
16904
16905         while : ; do
16906                 # former test_200a test_200b
16907                 pool_add $POOL                          || { rc=$? ; break; }
16908                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16909                 # former test_200c test_200d
16910                 mkdir -p $test_path
16911                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16912                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16913                 mkdir -p $subdir
16914                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16915                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16916                                                         || { rc=$? ; break; }
16917                 # former test_200e test_200f
16918                 local files=$((OSTCOUNT*3))
16919                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16920                                                         || { rc=$? ; break; }
16921                 pool_create_files $POOL $file_dir $files "$ost_list" \
16922                                                         || { rc=$? ; break; }
16923                 # former test_200g test_200h
16924                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16925                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16926
16927                 # former test_201a test_201b test_201c
16928                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16929
16930                 local f=$test_path/$tfile
16931                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16932                 pool_remove $POOL $f                    || { rc=$? ; break; }
16933                 break
16934         done
16935
16936         destroy_test_pools
16937
16938         return $rc
16939 }
16940 run_test 200 "OST pools"
16941
16942 # usage: default_attr <count | size | offset>
16943 default_attr() {
16944         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16945 }
16946
16947 # usage: check_default_stripe_attr
16948 check_default_stripe_attr() {
16949         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16950         case $1 in
16951         --stripe-count|-c)
16952                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16953         --stripe-size|-S)
16954                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16955         --stripe-index|-i)
16956                 EXPECTED=-1;;
16957         *)
16958                 error "unknown getstripe attr '$1'"
16959         esac
16960
16961         [ $ACTUAL == $EXPECTED ] ||
16962                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16963 }
16964
16965 test_204a() {
16966         test_mkdir $DIR/$tdir
16967         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16968
16969         check_default_stripe_attr --stripe-count
16970         check_default_stripe_attr --stripe-size
16971         check_default_stripe_attr --stripe-index
16972 }
16973 run_test 204a "Print default stripe attributes"
16974
16975 test_204b() {
16976         test_mkdir $DIR/$tdir
16977         $LFS setstripe --stripe-count 1 $DIR/$tdir
16978
16979         check_default_stripe_attr --stripe-size
16980         check_default_stripe_attr --stripe-index
16981 }
16982 run_test 204b "Print default stripe size and offset"
16983
16984 test_204c() {
16985         test_mkdir $DIR/$tdir
16986         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16987
16988         check_default_stripe_attr --stripe-count
16989         check_default_stripe_attr --stripe-index
16990 }
16991 run_test 204c "Print default stripe count and offset"
16992
16993 test_204d() {
16994         test_mkdir $DIR/$tdir
16995         $LFS setstripe --stripe-index 0 $DIR/$tdir
16996
16997         check_default_stripe_attr --stripe-count
16998         check_default_stripe_attr --stripe-size
16999 }
17000 run_test 204d "Print default stripe count and size"
17001
17002 test_204e() {
17003         test_mkdir $DIR/$tdir
17004         $LFS setstripe -d $DIR/$tdir
17005
17006         check_default_stripe_attr --stripe-count --raw
17007         check_default_stripe_attr --stripe-size --raw
17008         check_default_stripe_attr --stripe-index --raw
17009 }
17010 run_test 204e "Print raw stripe attributes"
17011
17012 test_204f() {
17013         test_mkdir $DIR/$tdir
17014         $LFS setstripe --stripe-count 1 $DIR/$tdir
17015
17016         check_default_stripe_attr --stripe-size --raw
17017         check_default_stripe_attr --stripe-index --raw
17018 }
17019 run_test 204f "Print raw stripe size and offset"
17020
17021 test_204g() {
17022         test_mkdir $DIR/$tdir
17023         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17024
17025         check_default_stripe_attr --stripe-count --raw
17026         check_default_stripe_attr --stripe-index --raw
17027 }
17028 run_test 204g "Print raw stripe count and offset"
17029
17030 test_204h() {
17031         test_mkdir $DIR/$tdir
17032         $LFS setstripe --stripe-index 0 $DIR/$tdir
17033
17034         check_default_stripe_attr --stripe-count --raw
17035         check_default_stripe_attr --stripe-size --raw
17036 }
17037 run_test 204h "Print raw stripe count and size"
17038
17039 # Figure out which job scheduler is being used, if any,
17040 # or use a fake one
17041 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17042         JOBENV=SLURM_JOB_ID
17043 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17044         JOBENV=LSB_JOBID
17045 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17046         JOBENV=PBS_JOBID
17047 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17048         JOBENV=LOADL_STEP_ID
17049 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17050         JOBENV=JOB_ID
17051 else
17052         $LCTL list_param jobid_name > /dev/null 2>&1
17053         if [ $? -eq 0 ]; then
17054                 JOBENV=nodelocal
17055         else
17056                 JOBENV=FAKE_JOBID
17057         fi
17058 fi
17059 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17060
17061 verify_jobstats() {
17062         local cmd=($1)
17063         shift
17064         local facets="$@"
17065
17066 # we don't really need to clear the stats for this test to work, since each
17067 # command has a unique jobid, but it makes debugging easier if needed.
17068 #       for facet in $facets; do
17069 #               local dev=$(convert_facet2label $facet)
17070 #               # clear old jobstats
17071 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17072 #       done
17073
17074         # use a new JobID for each test, or we might see an old one
17075         [ "$JOBENV" = "FAKE_JOBID" ] &&
17076                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17077
17078         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17079
17080         [ "$JOBENV" = "nodelocal" ] && {
17081                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17082                 $LCTL set_param jobid_name=$FAKE_JOBID
17083                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17084         }
17085
17086         log "Test: ${cmd[*]}"
17087         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17088
17089         if [ $JOBENV = "FAKE_JOBID" ]; then
17090                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17091         else
17092                 ${cmd[*]}
17093         fi
17094
17095         # all files are created on OST0000
17096         for facet in $facets; do
17097                 local stats="*.$(convert_facet2label $facet).job_stats"
17098
17099                 # strip out libtool wrappers for in-tree executables
17100                 if [ $(do_facet $facet lctl get_param $stats |
17101                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17102                         do_facet $facet lctl get_param $stats
17103                         error "No jobstats for $JOBVAL found on $facet::$stats"
17104                 fi
17105         done
17106 }
17107
17108 jobstats_set() {
17109         local new_jobenv=$1
17110
17111         set_persistent_param_and_check client "jobid_var" \
17112                 "$FSNAME.sys.jobid_var" $new_jobenv
17113 }
17114
17115 test_205a() { # Job stats
17116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17117         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17118                 skip "Need MDS version with at least 2.7.1"
17119         remote_mgs_nodsh && skip "remote MGS with nodsh"
17120         remote_mds_nodsh && skip "remote MDS with nodsh"
17121         remote_ost_nodsh && skip "remote OST with nodsh"
17122         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17123                 skip "Server doesn't support jobstats"
17124         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17125
17126         local old_jobenv=$($LCTL get_param -n jobid_var)
17127         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17128
17129         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17130                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17131         else
17132                 stack_trap "do_facet mgs $PERM_CMD \
17133                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17134         fi
17135         changelog_register
17136
17137         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17138                                 mdt.*.job_cleanup_interval | head -n 1)
17139         local new_interval=5
17140         do_facet $SINGLEMDS \
17141                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17142         stack_trap "do_facet $SINGLEMDS \
17143                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17144         local start=$SECONDS
17145
17146         local cmd
17147         # mkdir
17148         cmd="mkdir $DIR/$tdir"
17149         verify_jobstats "$cmd" "$SINGLEMDS"
17150         # rmdir
17151         cmd="rmdir $DIR/$tdir"
17152         verify_jobstats "$cmd" "$SINGLEMDS"
17153         # mkdir on secondary MDT
17154         if [ $MDSCOUNT -gt 1 ]; then
17155                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17156                 verify_jobstats "$cmd" "mds2"
17157         fi
17158         # mknod
17159         cmd="mknod $DIR/$tfile c 1 3"
17160         verify_jobstats "$cmd" "$SINGLEMDS"
17161         # unlink
17162         cmd="rm -f $DIR/$tfile"
17163         verify_jobstats "$cmd" "$SINGLEMDS"
17164         # create all files on OST0000 so verify_jobstats can find OST stats
17165         # open & close
17166         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17167         verify_jobstats "$cmd" "$SINGLEMDS"
17168         # setattr
17169         cmd="touch $DIR/$tfile"
17170         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17171         # write
17172         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17173         verify_jobstats "$cmd" "ost1"
17174         # read
17175         cancel_lru_locks osc
17176         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17177         verify_jobstats "$cmd" "ost1"
17178         # truncate
17179         cmd="$TRUNCATE $DIR/$tfile 0"
17180         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17181         # rename
17182         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17183         verify_jobstats "$cmd" "$SINGLEMDS"
17184         # jobstats expiry - sleep until old stats should be expired
17185         local left=$((new_interval + 5 - (SECONDS - start)))
17186         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17187                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17188                         "0" $left
17189         cmd="mkdir $DIR/$tdir.expire"
17190         verify_jobstats "$cmd" "$SINGLEMDS"
17191         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17192             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17193
17194         # Ensure that jobid are present in changelog (if supported by MDS)
17195         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17196                 changelog_dump | tail -10
17197                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17198                 [ $jobids -eq 9 ] ||
17199                         error "Wrong changelog jobid count $jobids != 9"
17200
17201                 # LU-5862
17202                 JOBENV="disable"
17203                 jobstats_set $JOBENV
17204                 touch $DIR/$tfile
17205                 changelog_dump | grep $tfile
17206                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17207                 [ $jobids -eq 0 ] ||
17208                         error "Unexpected jobids when jobid_var=$JOBENV"
17209         fi
17210
17211         # test '%j' access to environment variable - if supported
17212         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17213                 JOBENV="JOBCOMPLEX"
17214                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17215
17216                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17217         fi
17218
17219         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17220                 JOBENV="JOBCOMPLEX"
17221                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17222
17223                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17224         fi
17225
17226         # test '%j' access to per-session jobid - if supported
17227         if lctl list_param jobid_this_session > /dev/null 2>&1
17228         then
17229                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17230                 lctl set_param jobid_this_session=$USER
17231
17232                 JOBENV="JOBCOMPLEX"
17233                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17234
17235                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17236         fi
17237 }
17238 run_test 205a "Verify job stats"
17239
17240 # LU-13117, LU-13597
17241 test_205b() {
17242         job_stats="mdt.*.job_stats"
17243         $LCTL set_param $job_stats=clear
17244         # Setting jobid_var to USER might not be supported
17245         $LCTL set_param jobid_var=USER || true
17246         $LCTL set_param jobid_name="%e.%u"
17247         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17248         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17249                 grep "job_id:.*foolish" &&
17250                         error "Unexpected jobid found"
17251         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17252                 grep "open:.*min.*max.*sum" ||
17253                         error "wrong job_stats format found"
17254 }
17255 run_test 205b "Verify job stats jobid and output format"
17256
17257 # LU-13733
17258 test_205c() {
17259         $LCTL set_param llite.*.stats=0
17260         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17261         $LCTL get_param llite.*.stats
17262         $LCTL get_param llite.*.stats | grep \
17263                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17264                         error "wrong client stats format found"
17265 }
17266 run_test 205c "Verify client stats format"
17267
17268 # LU-1480, LU-1773 and LU-1657
17269 test_206() {
17270         mkdir -p $DIR/$tdir
17271         $LFS setstripe -c -1 $DIR/$tdir
17272 #define OBD_FAIL_LOV_INIT 0x1403
17273         $LCTL set_param fail_loc=0xa0001403
17274         $LCTL set_param fail_val=1
17275         touch $DIR/$tdir/$tfile || true
17276 }
17277 run_test 206 "fail lov_init_raid0() doesn't lbug"
17278
17279 test_207a() {
17280         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17281         local fsz=`stat -c %s $DIR/$tfile`
17282         cancel_lru_locks mdc
17283
17284         # do not return layout in getattr intent
17285 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17286         $LCTL set_param fail_loc=0x170
17287         local sz=`stat -c %s $DIR/$tfile`
17288
17289         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17290
17291         rm -rf $DIR/$tfile
17292 }
17293 run_test 207a "can refresh layout at glimpse"
17294
17295 test_207b() {
17296         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17297         local cksum=`md5sum $DIR/$tfile`
17298         local fsz=`stat -c %s $DIR/$tfile`
17299         cancel_lru_locks mdc
17300         cancel_lru_locks osc
17301
17302         # do not return layout in getattr intent
17303 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17304         $LCTL set_param fail_loc=0x171
17305
17306         # it will refresh layout after the file is opened but before read issues
17307         echo checksum is "$cksum"
17308         echo "$cksum" |md5sum -c --quiet || error "file differs"
17309
17310         rm -rf $DIR/$tfile
17311 }
17312 run_test 207b "can refresh layout at open"
17313
17314 test_208() {
17315         # FIXME: in this test suite, only RD lease is used. This is okay
17316         # for now as only exclusive open is supported. After generic lease
17317         # is done, this test suite should be revised. - Jinshan
17318
17319         remote_mds_nodsh && skip "remote MDS with nodsh"
17320         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17321                 skip "Need MDS version at least 2.4.52"
17322
17323         echo "==== test 1: verify get lease work"
17324         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17325
17326         echo "==== test 2: verify lease can be broken by upcoming open"
17327         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17328         local PID=$!
17329         sleep 1
17330
17331         $MULTIOP $DIR/$tfile oO_RDONLY:c
17332         kill -USR1 $PID && wait $PID || error "break lease error"
17333
17334         echo "==== test 3: verify lease can't be granted if an open already exists"
17335         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17336         local PID=$!
17337         sleep 1
17338
17339         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17340         kill -USR1 $PID && wait $PID || error "open file error"
17341
17342         echo "==== test 4: lease can sustain over recovery"
17343         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17344         PID=$!
17345         sleep 1
17346
17347         fail mds1
17348
17349         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17350
17351         echo "==== test 5: lease broken can't be regained by replay"
17352         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17353         PID=$!
17354         sleep 1
17355
17356         # open file to break lease and then recovery
17357         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17358         fail mds1
17359
17360         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17361
17362         rm -f $DIR/$tfile
17363 }
17364 run_test 208 "Exclusive open"
17365
17366 test_209() {
17367         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17368                 skip_env "must have disp_stripe"
17369
17370         touch $DIR/$tfile
17371         sync; sleep 5; sync;
17372
17373         echo 3 > /proc/sys/vm/drop_caches
17374         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17375                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17376         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17377
17378         # open/close 500 times
17379         for i in $(seq 500); do
17380                 cat $DIR/$tfile
17381         done
17382
17383         echo 3 > /proc/sys/vm/drop_caches
17384         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17385                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17386         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17387
17388         echo "before: $req_before, after: $req_after"
17389         [ $((req_after - req_before)) -ge 300 ] &&
17390                 error "open/close requests are not freed"
17391         return 0
17392 }
17393 run_test 209 "read-only open/close requests should be freed promptly"
17394
17395 test_210() {
17396         local pid
17397
17398         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17399         pid=$!
17400         sleep 1
17401
17402         $LFS getstripe $DIR/$tfile
17403         kill -USR1 $pid
17404         wait $pid || error "multiop failed"
17405
17406         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17407         pid=$!
17408         sleep 1
17409
17410         $LFS getstripe $DIR/$tfile
17411         kill -USR1 $pid
17412         wait $pid || error "multiop failed"
17413 }
17414 run_test 210 "lfs getstripe does not break leases"
17415
17416 test_212() {
17417         size=`date +%s`
17418         size=$((size % 8192 + 1))
17419         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17420         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17421         rm -f $DIR/f212 $DIR/f212.xyz
17422 }
17423 run_test 212 "Sendfile test ============================================"
17424
17425 test_213() {
17426         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17427         cancel_lru_locks osc
17428         lctl set_param fail_loc=0x8000040f
17429         # generate a read lock
17430         cat $DIR/$tfile > /dev/null
17431         # write to the file, it will try to cancel the above read lock.
17432         cat /etc/hosts >> $DIR/$tfile
17433 }
17434 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17435
17436 test_214() { # for bug 20133
17437         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17438         for (( i=0; i < 340; i++ )) ; do
17439                 touch $DIR/$tdir/d214c/a$i
17440         done
17441
17442         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17443         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17444         ls $DIR/d214c || error "ls $DIR/d214c failed"
17445         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17446         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17447 }
17448 run_test 214 "hash-indexed directory test - bug 20133"
17449
17450 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17451 create_lnet_proc_files() {
17452         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17453 }
17454
17455 # counterpart of create_lnet_proc_files
17456 remove_lnet_proc_files() {
17457         rm -f $TMP/lnet_$1.sys
17458 }
17459
17460 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17461 # 3rd arg as regexp for body
17462 check_lnet_proc_stats() {
17463         local l=$(cat "$TMP/lnet_$1" |wc -l)
17464         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17465
17466         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17467 }
17468
17469 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17470 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17471 # optional and can be regexp for 2nd line (lnet.routes case)
17472 check_lnet_proc_entry() {
17473         local blp=2          # blp stands for 'position of 1st line of body'
17474         [ -z "$5" ] || blp=3 # lnet.routes case
17475
17476         local l=$(cat "$TMP/lnet_$1" |wc -l)
17477         # subtracting one from $blp because the body can be empty
17478         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17479
17480         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17481                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17482
17483         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17484                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17485
17486         # bail out if any unexpected line happened
17487         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17488         [ "$?" != 0 ] || error "$2 misformatted"
17489 }
17490
17491 test_215() { # for bugs 18102, 21079, 21517
17492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17493
17494         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17495         local P='[1-9][0-9]*'           # positive numeric
17496         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17497         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17498         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17499         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17500
17501         local L1 # regexp for 1st line
17502         local L2 # regexp for 2nd line (optional)
17503         local BR # regexp for the rest (body)
17504
17505         # lnet.stats should look as 11 space-separated non-negative numerics
17506         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17507         create_lnet_proc_files "stats"
17508         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17509         remove_lnet_proc_files "stats"
17510
17511         # lnet.routes should look like this:
17512         # Routing disabled/enabled
17513         # net hops priority state router
17514         # where net is a string like tcp0, hops > 0, priority >= 0,
17515         # state is up/down,
17516         # router is a string like 192.168.1.1@tcp2
17517         L1="^Routing (disabled|enabled)$"
17518         L2="^net +hops +priority +state +router$"
17519         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17520         create_lnet_proc_files "routes"
17521         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17522         remove_lnet_proc_files "routes"
17523
17524         # lnet.routers should look like this:
17525         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17526         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17527         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17528         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17529         L1="^ref +rtr_ref +alive +router$"
17530         BR="^$P +$P +(up|down) +$NID$"
17531         create_lnet_proc_files "routers"
17532         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17533         remove_lnet_proc_files "routers"
17534
17535         # lnet.peers should look like this:
17536         # nid refs state last max rtr min tx min queue
17537         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17538         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17539         # numeric (0 or >0 or <0), queue >= 0.
17540         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17541         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17542         create_lnet_proc_files "peers"
17543         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17544         remove_lnet_proc_files "peers"
17545
17546         # lnet.buffers  should look like this:
17547         # pages count credits min
17548         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17549         L1="^pages +count +credits +min$"
17550         BR="^ +$N +$N +$I +$I$"
17551         create_lnet_proc_files "buffers"
17552         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17553         remove_lnet_proc_files "buffers"
17554
17555         # lnet.nis should look like this:
17556         # nid status alive refs peer rtr max tx min
17557         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17558         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17559         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17560         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17561         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17562         create_lnet_proc_files "nis"
17563         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17564         remove_lnet_proc_files "nis"
17565
17566         # can we successfully write to lnet.stats?
17567         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17568 }
17569 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17570
17571 test_216() { # bug 20317
17572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17573         remote_ost_nodsh && skip "remote OST with nodsh"
17574
17575         local node
17576         local facets=$(get_facets OST)
17577         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17578
17579         save_lustre_params client "osc.*.contention_seconds" > $p
17580         save_lustre_params $facets \
17581                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17582         save_lustre_params $facets \
17583                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17584         save_lustre_params $facets \
17585                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17586         clear_stats osc.*.osc_stats
17587
17588         # agressive lockless i/o settings
17589         do_nodes $(comma_list $(osts_nodes)) \
17590                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17591                         ldlm.namespaces.filter-*.contended_locks=0 \
17592                         ldlm.namespaces.filter-*.contention_seconds=60"
17593         lctl set_param -n osc.*.contention_seconds=60
17594
17595         $DIRECTIO write $DIR/$tfile 0 10 4096
17596         $CHECKSTAT -s 40960 $DIR/$tfile
17597
17598         # disable lockless i/o
17599         do_nodes $(comma_list $(osts_nodes)) \
17600                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17601                         ldlm.namespaces.filter-*.contended_locks=32 \
17602                         ldlm.namespaces.filter-*.contention_seconds=0"
17603         lctl set_param -n osc.*.contention_seconds=0
17604         clear_stats osc.*.osc_stats
17605
17606         dd if=/dev/zero of=$DIR/$tfile count=0
17607         $CHECKSTAT -s 0 $DIR/$tfile
17608
17609         restore_lustre_params <$p
17610         rm -f $p
17611         rm $DIR/$tfile
17612 }
17613 run_test 216 "check lockless direct write updates file size and kms correctly"
17614
17615 test_217() { # bug 22430
17616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17617
17618         local node
17619         local nid
17620
17621         for node in $(nodes_list); do
17622                 nid=$(host_nids_address $node $NETTYPE)
17623                 if [[ $nid = *-* ]] ; then
17624                         echo "lctl ping $(h2nettype $nid)"
17625                         lctl ping $(h2nettype $nid)
17626                 else
17627                         echo "skipping $node (no hyphen detected)"
17628                 fi
17629         done
17630 }
17631 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17632
17633 test_218() {
17634        # do directio so as not to populate the page cache
17635        log "creating a 10 Mb file"
17636        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17637        log "starting reads"
17638        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17639        log "truncating the file"
17640        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17641        log "killing dd"
17642        kill %+ || true # reads might have finished
17643        echo "wait until dd is finished"
17644        wait
17645        log "removing the temporary file"
17646        rm -rf $DIR/$tfile || error "tmp file removal failed"
17647 }
17648 run_test 218 "parallel read and truncate should not deadlock"
17649
17650 test_219() {
17651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17652
17653         # write one partial page
17654         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17655         # set no grant so vvp_io_commit_write will do sync write
17656         $LCTL set_param fail_loc=0x411
17657         # write a full page at the end of file
17658         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17659
17660         $LCTL set_param fail_loc=0
17661         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17662         $LCTL set_param fail_loc=0x411
17663         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17664
17665         # LU-4201
17666         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17667         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17668 }
17669 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17670
17671 test_220() { #LU-325
17672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17673         remote_ost_nodsh && skip "remote OST with nodsh"
17674         remote_mds_nodsh && skip "remote MDS with nodsh"
17675         remote_mgs_nodsh && skip "remote MGS with nodsh"
17676
17677         local OSTIDX=0
17678
17679         # create on MDT0000 so the last_id and next_id are correct
17680         mkdir $DIR/$tdir
17681         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17682         OST=${OST%_UUID}
17683
17684         # on the mdt's osc
17685         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17686         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17687                         osp.$mdtosc_proc1.prealloc_last_id)
17688         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17689                         osp.$mdtosc_proc1.prealloc_next_id)
17690
17691         $LFS df -i
17692
17693         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17694         #define OBD_FAIL_OST_ENOINO              0x229
17695         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17696         create_pool $FSNAME.$TESTNAME || return 1
17697         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17698
17699         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17700
17701         MDSOBJS=$((last_id - next_id))
17702         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17703
17704         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17705         echo "OST still has $count kbytes free"
17706
17707         echo "create $MDSOBJS files @next_id..."
17708         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17709
17710         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17711                         osp.$mdtosc_proc1.prealloc_last_id)
17712         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17713                         osp.$mdtosc_proc1.prealloc_next_id)
17714
17715         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17716         $LFS df -i
17717
17718         echo "cleanup..."
17719
17720         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17721         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17722
17723         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17724                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17725         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17726                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17727         echo "unlink $MDSOBJS files @$next_id..."
17728         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17729 }
17730 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17731
17732 test_221() {
17733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17734
17735         dd if=`which date` of=$MOUNT/date oflag=sync
17736         chmod +x $MOUNT/date
17737
17738         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17739         $LCTL set_param fail_loc=0x80001401
17740
17741         $MOUNT/date > /dev/null
17742         rm -f $MOUNT/date
17743 }
17744 run_test 221 "make sure fault and truncate race to not cause OOM"
17745
17746 test_222a () {
17747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17748
17749         rm -rf $DIR/$tdir
17750         test_mkdir $DIR/$tdir
17751         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17752         createmany -o $DIR/$tdir/$tfile 10
17753         cancel_lru_locks mdc
17754         cancel_lru_locks osc
17755         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17756         $LCTL set_param fail_loc=0x31a
17757         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17758         $LCTL set_param fail_loc=0
17759         rm -r $DIR/$tdir
17760 }
17761 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17762
17763 test_222b () {
17764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17765
17766         rm -rf $DIR/$tdir
17767         test_mkdir $DIR/$tdir
17768         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17769         createmany -o $DIR/$tdir/$tfile 10
17770         cancel_lru_locks mdc
17771         cancel_lru_locks osc
17772         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17773         $LCTL set_param fail_loc=0x31a
17774         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17775         $LCTL set_param fail_loc=0
17776 }
17777 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17778
17779 test_223 () {
17780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17781
17782         rm -rf $DIR/$tdir
17783         test_mkdir $DIR/$tdir
17784         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17785         createmany -o $DIR/$tdir/$tfile 10
17786         cancel_lru_locks mdc
17787         cancel_lru_locks osc
17788         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17789         $LCTL set_param fail_loc=0x31b
17790         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17791         $LCTL set_param fail_loc=0
17792         rm -r $DIR/$tdir
17793 }
17794 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17795
17796 test_224a() { # LU-1039, MRP-303
17797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17798
17799         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17800         $LCTL set_param fail_loc=0x508
17801         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17802         $LCTL set_param fail_loc=0
17803         df $DIR
17804 }
17805 run_test 224a "Don't panic on bulk IO failure"
17806
17807 test_224b() { # LU-1039, MRP-303
17808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17809
17810         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17811         cancel_lru_locks osc
17812         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17813         $LCTL set_param fail_loc=0x515
17814         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17815         $LCTL set_param fail_loc=0
17816         df $DIR
17817 }
17818 run_test 224b "Don't panic on bulk IO failure"
17819
17820 test_224c() { # LU-6441
17821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17822         remote_mds_nodsh && skip "remote MDS with nodsh"
17823
17824         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17825         save_writethrough $p
17826         set_cache writethrough on
17827
17828         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17829         local at_max=$($LCTL get_param -n at_max)
17830         local timeout=$($LCTL get_param -n timeout)
17831         local test_at="at_max"
17832         local param_at="$FSNAME.sys.at_max"
17833         local test_timeout="timeout"
17834         local param_timeout="$FSNAME.sys.timeout"
17835
17836         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17837
17838         set_persistent_param_and_check client "$test_at" "$param_at" 0
17839         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17840
17841         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17842         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17843         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17844         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17845         sync
17846         do_facet ost1 "$LCTL set_param fail_loc=0"
17847
17848         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17849         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17850                 $timeout
17851
17852         $LCTL set_param -n $pages_per_rpc
17853         restore_lustre_params < $p
17854         rm -f $p
17855 }
17856 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17857
17858 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17859 test_225a () {
17860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17861         if [ -z ${MDSSURVEY} ]; then
17862                 skip_env "mds-survey not found"
17863         fi
17864         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17865                 skip "Need MDS version at least 2.2.51"
17866
17867         local mds=$(facet_host $SINGLEMDS)
17868         local target=$(do_nodes $mds 'lctl dl' |
17869                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17870
17871         local cmd1="file_count=1000 thrhi=4"
17872         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17873         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17874         local cmd="$cmd1 $cmd2 $cmd3"
17875
17876         rm -f ${TMP}/mds_survey*
17877         echo + $cmd
17878         eval $cmd || error "mds-survey with zero-stripe failed"
17879         cat ${TMP}/mds_survey*
17880         rm -f ${TMP}/mds_survey*
17881 }
17882 run_test 225a "Metadata survey sanity with zero-stripe"
17883
17884 test_225b () {
17885         if [ -z ${MDSSURVEY} ]; then
17886                 skip_env "mds-survey not found"
17887         fi
17888         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17889                 skip "Need MDS version at least 2.2.51"
17890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17891         remote_mds_nodsh && skip "remote MDS with nodsh"
17892         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17893                 skip_env "Need to mount OST to test"
17894         fi
17895
17896         local mds=$(facet_host $SINGLEMDS)
17897         local target=$(do_nodes $mds 'lctl dl' |
17898                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17899
17900         local cmd1="file_count=1000 thrhi=4"
17901         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17902         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17903         local cmd="$cmd1 $cmd2 $cmd3"
17904
17905         rm -f ${TMP}/mds_survey*
17906         echo + $cmd
17907         eval $cmd || error "mds-survey with stripe_count failed"
17908         cat ${TMP}/mds_survey*
17909         rm -f ${TMP}/mds_survey*
17910 }
17911 run_test 225b "Metadata survey sanity with stripe_count = 1"
17912
17913 mcreate_path2fid () {
17914         local mode=$1
17915         local major=$2
17916         local minor=$3
17917         local name=$4
17918         local desc=$5
17919         local path=$DIR/$tdir/$name
17920         local fid
17921         local rc
17922         local fid_path
17923
17924         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17925                 error "cannot create $desc"
17926
17927         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17928         rc=$?
17929         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17930
17931         fid_path=$($LFS fid2path $MOUNT $fid)
17932         rc=$?
17933         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17934
17935         [ "$path" == "$fid_path" ] ||
17936                 error "fid2path returned $fid_path, expected $path"
17937
17938         echo "pass with $path and $fid"
17939 }
17940
17941 test_226a () {
17942         rm -rf $DIR/$tdir
17943         mkdir -p $DIR/$tdir
17944
17945         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17946         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17947         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17948         mcreate_path2fid 0040666 0 0 dir "directory"
17949         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17950         mcreate_path2fid 0100666 0 0 file "regular file"
17951         mcreate_path2fid 0120666 0 0 link "symbolic link"
17952         mcreate_path2fid 0140666 0 0 sock "socket"
17953 }
17954 run_test 226a "call path2fid and fid2path on files of all type"
17955
17956 test_226b () {
17957         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17958
17959         local MDTIDX=1
17960
17961         rm -rf $DIR/$tdir
17962         mkdir -p $DIR/$tdir
17963         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17964                 error "create remote directory failed"
17965         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17966         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17967                                 "character special file (null)"
17968         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17969                                 "character special file (no device)"
17970         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17971         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17972                                 "block special file (loop)"
17973         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17974         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17975         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17976 }
17977 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17978
17979 test_226c () {
17980         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17981         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17982                 skip "Need MDS version at least 2.13.55"
17983
17984         local submnt=/mnt/submnt
17985         local srcfile=/etc/passwd
17986         local dstfile=$submnt/passwd
17987         local path
17988         local fid
17989
17990         rm -rf $DIR/$tdir
17991         rm -rf $submnt
17992         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17993                 error "create remote directory failed"
17994         mkdir -p $submnt || error "create $submnt failed"
17995         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17996                 error "mount $submnt failed"
17997         stack_trap "umount $submnt" EXIT
17998
17999         cp $srcfile $dstfile
18000         fid=$($LFS path2fid $dstfile)
18001         path=$($LFS fid2path $submnt "$fid")
18002         [ "$path" = "$dstfile" ] ||
18003                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18004 }
18005 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18006
18007 # LU-1299 Executing or running ldd on a truncated executable does not
18008 # cause an out-of-memory condition.
18009 test_227() {
18010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18011         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18012
18013         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18014         chmod +x $MOUNT/date
18015
18016         $MOUNT/date > /dev/null
18017         ldd $MOUNT/date > /dev/null
18018         rm -f $MOUNT/date
18019 }
18020 run_test 227 "running truncated executable does not cause OOM"
18021
18022 # LU-1512 try to reuse idle OI blocks
18023 test_228a() {
18024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18025         remote_mds_nodsh && skip "remote MDS with nodsh"
18026         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18027
18028         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18029         local myDIR=$DIR/$tdir
18030
18031         mkdir -p $myDIR
18032         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18033         $LCTL set_param fail_loc=0x80001002
18034         createmany -o $myDIR/t- 10000
18035         $LCTL set_param fail_loc=0
18036         # The guard is current the largest FID holder
18037         touch $myDIR/guard
18038         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18039                     tr -d '[')
18040         local IDX=$(($SEQ % 64))
18041
18042         do_facet $SINGLEMDS sync
18043         # Make sure journal flushed.
18044         sleep 6
18045         local blk1=$(do_facet $SINGLEMDS \
18046                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18047                      grep Blockcount | awk '{print $4}')
18048
18049         # Remove old files, some OI blocks will become idle.
18050         unlinkmany $myDIR/t- 10000
18051         # Create new files, idle OI blocks should be reused.
18052         createmany -o $myDIR/t- 2000
18053         do_facet $SINGLEMDS sync
18054         # Make sure journal flushed.
18055         sleep 6
18056         local blk2=$(do_facet $SINGLEMDS \
18057                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18058                      grep Blockcount | awk '{print $4}')
18059
18060         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18061 }
18062 run_test 228a "try to reuse idle OI blocks"
18063
18064 test_228b() {
18065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18066         remote_mds_nodsh && skip "remote MDS with nodsh"
18067         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18068
18069         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18070         local myDIR=$DIR/$tdir
18071
18072         mkdir -p $myDIR
18073         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18074         $LCTL set_param fail_loc=0x80001002
18075         createmany -o $myDIR/t- 10000
18076         $LCTL set_param fail_loc=0
18077         # The guard is current the largest FID holder
18078         touch $myDIR/guard
18079         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18080                     tr -d '[')
18081         local IDX=$(($SEQ % 64))
18082
18083         do_facet $SINGLEMDS sync
18084         # Make sure journal flushed.
18085         sleep 6
18086         local blk1=$(do_facet $SINGLEMDS \
18087                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18088                      grep Blockcount | awk '{print $4}')
18089
18090         # Remove old files, some OI blocks will become idle.
18091         unlinkmany $myDIR/t- 10000
18092
18093         # stop the MDT
18094         stop $SINGLEMDS || error "Fail to stop MDT."
18095         # remount the MDT
18096         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18097
18098         df $MOUNT || error "Fail to df."
18099         # Create new files, idle OI blocks should be reused.
18100         createmany -o $myDIR/t- 2000
18101         do_facet $SINGLEMDS sync
18102         # Make sure journal flushed.
18103         sleep 6
18104         local blk2=$(do_facet $SINGLEMDS \
18105                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18106                      grep Blockcount | awk '{print $4}')
18107
18108         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18109 }
18110 run_test 228b "idle OI blocks can be reused after MDT restart"
18111
18112 #LU-1881
18113 test_228c() {
18114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18115         remote_mds_nodsh && skip "remote MDS with nodsh"
18116         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18117
18118         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18119         local myDIR=$DIR/$tdir
18120
18121         mkdir -p $myDIR
18122         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18123         $LCTL set_param fail_loc=0x80001002
18124         # 20000 files can guarantee there are index nodes in the OI file
18125         createmany -o $myDIR/t- 20000
18126         $LCTL set_param fail_loc=0
18127         # The guard is current the largest FID holder
18128         touch $myDIR/guard
18129         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18130                     tr -d '[')
18131         local IDX=$(($SEQ % 64))
18132
18133         do_facet $SINGLEMDS sync
18134         # Make sure journal flushed.
18135         sleep 6
18136         local blk1=$(do_facet $SINGLEMDS \
18137                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18138                      grep Blockcount | awk '{print $4}')
18139
18140         # Remove old files, some OI blocks will become idle.
18141         unlinkmany $myDIR/t- 20000
18142         rm -f $myDIR/guard
18143         # The OI file should become empty now
18144
18145         # Create new files, idle OI blocks should be reused.
18146         createmany -o $myDIR/t- 2000
18147         do_facet $SINGLEMDS sync
18148         # Make sure journal flushed.
18149         sleep 6
18150         local blk2=$(do_facet $SINGLEMDS \
18151                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18152                      grep Blockcount | awk '{print $4}')
18153
18154         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18155 }
18156 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18157
18158 test_229() { # LU-2482, LU-3448
18159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18160         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18161         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18162                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18163
18164         rm -f $DIR/$tfile
18165
18166         # Create a file with a released layout and stripe count 2.
18167         $MULTIOP $DIR/$tfile H2c ||
18168                 error "failed to create file with released layout"
18169
18170         $LFS getstripe -v $DIR/$tfile
18171
18172         local pattern=$($LFS getstripe -L $DIR/$tfile)
18173         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18174
18175         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18176                 error "getstripe"
18177         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18178         stat $DIR/$tfile || error "failed to stat released file"
18179
18180         chown $RUNAS_ID $DIR/$tfile ||
18181                 error "chown $RUNAS_ID $DIR/$tfile failed"
18182
18183         chgrp $RUNAS_ID $DIR/$tfile ||
18184                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18185
18186         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18187         rm $DIR/$tfile || error "failed to remove released file"
18188 }
18189 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18190
18191 test_230a() {
18192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18193         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18194         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18195                 skip "Need MDS version at least 2.11.52"
18196
18197         local MDTIDX=1
18198
18199         test_mkdir $DIR/$tdir
18200         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18201         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18202         [ $mdt_idx -ne 0 ] &&
18203                 error "create local directory on wrong MDT $mdt_idx"
18204
18205         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18206                         error "create remote directory failed"
18207         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18208         [ $mdt_idx -ne $MDTIDX ] &&
18209                 error "create remote directory on wrong MDT $mdt_idx"
18210
18211         createmany -o $DIR/$tdir/test_230/t- 10 ||
18212                 error "create files on remote directory failed"
18213         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18214         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18215         rm -r $DIR/$tdir || error "unlink remote directory failed"
18216 }
18217 run_test 230a "Create remote directory and files under the remote directory"
18218
18219 test_230b() {
18220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18221         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18222         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18223                 skip "Need MDS version at least 2.11.52"
18224
18225         local MDTIDX=1
18226         local mdt_index
18227         local i
18228         local file
18229         local pid
18230         local stripe_count
18231         local migrate_dir=$DIR/$tdir/migrate_dir
18232         local other_dir=$DIR/$tdir/other_dir
18233
18234         test_mkdir $DIR/$tdir
18235         test_mkdir -i0 -c1 $migrate_dir
18236         test_mkdir -i0 -c1 $other_dir
18237         for ((i=0; i<10; i++)); do
18238                 mkdir -p $migrate_dir/dir_${i}
18239                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18240                         error "create files under remote dir failed $i"
18241         done
18242
18243         cp /etc/passwd $migrate_dir/$tfile
18244         cp /etc/passwd $other_dir/$tfile
18245         chattr +SAD $migrate_dir
18246         chattr +SAD $migrate_dir/$tfile
18247
18248         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18249         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18250         local old_dir_mode=$(stat -c%f $migrate_dir)
18251         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18252
18253         mkdir -p $migrate_dir/dir_default_stripe2
18254         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18255         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18256
18257         mkdir -p $other_dir
18258         ln $migrate_dir/$tfile $other_dir/luna
18259         ln $migrate_dir/$tfile $migrate_dir/sofia
18260         ln $other_dir/$tfile $migrate_dir/david
18261         ln -s $migrate_dir/$tfile $other_dir/zachary
18262         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18263         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18264
18265         local len
18266         local lnktgt
18267
18268         # inline symlink
18269         for len in 58 59 60; do
18270                 lnktgt=$(str_repeat 'l' $len)
18271                 touch $migrate_dir/$lnktgt
18272                 ln -s $lnktgt $migrate_dir/${len}char_ln
18273         done
18274
18275         # PATH_MAX
18276         for len in 4094 4095; do
18277                 lnktgt=$(str_repeat 'l' $len)
18278                 ln -s $lnktgt $migrate_dir/${len}char_ln
18279         done
18280
18281         # NAME_MAX
18282         for len in 254 255; do
18283                 touch $migrate_dir/$(str_repeat 'l' $len)
18284         done
18285
18286         $LFS migrate -m $MDTIDX $migrate_dir ||
18287                 error "fails on migrating remote dir to MDT1"
18288
18289         echo "migratate to MDT1, then checking.."
18290         for ((i = 0; i < 10; i++)); do
18291                 for file in $(find $migrate_dir/dir_${i}); do
18292                         mdt_index=$($LFS getstripe -m $file)
18293                         # broken symlink getstripe will fail
18294                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18295                                 error "$file is not on MDT${MDTIDX}"
18296                 done
18297         done
18298
18299         # the multiple link file should still in MDT0
18300         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18301         [ $mdt_index == 0 ] ||
18302                 error "$file is not on MDT${MDTIDX}"
18303
18304         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18305         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18306                 error " expect $old_dir_flag get $new_dir_flag"
18307
18308         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18309         [ "$old_file_flag" = "$new_file_flag" ] ||
18310                 error " expect $old_file_flag get $new_file_flag"
18311
18312         local new_dir_mode=$(stat -c%f $migrate_dir)
18313         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18314                 error "expect mode $old_dir_mode get $new_dir_mode"
18315
18316         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18317         [ "$old_file_mode" = "$new_file_mode" ] ||
18318                 error "expect mode $old_file_mode get $new_file_mode"
18319
18320         diff /etc/passwd $migrate_dir/$tfile ||
18321                 error "$tfile different after migration"
18322
18323         diff /etc/passwd $other_dir/luna ||
18324                 error "luna different after migration"
18325
18326         diff /etc/passwd $migrate_dir/sofia ||
18327                 error "sofia different after migration"
18328
18329         diff /etc/passwd $migrate_dir/david ||
18330                 error "david different after migration"
18331
18332         diff /etc/passwd $other_dir/zachary ||
18333                 error "zachary different after migration"
18334
18335         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18336                 error "${tfile}_ln different after migration"
18337
18338         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18339                 error "${tfile}_ln_other different after migration"
18340
18341         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18342         [ $stripe_count = 2 ] ||
18343                 error "dir strpe_count $d != 2 after migration."
18344
18345         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18346         [ $stripe_count = 2 ] ||
18347                 error "file strpe_count $d != 2 after migration."
18348
18349         #migrate back to MDT0
18350         MDTIDX=0
18351
18352         $LFS migrate -m $MDTIDX $migrate_dir ||
18353                 error "fails on migrating remote dir to MDT0"
18354
18355         echo "migrate back to MDT0, checking.."
18356         for file in $(find $migrate_dir); do
18357                 mdt_index=$($LFS getstripe -m $file)
18358                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18359                         error "$file is not on MDT${MDTIDX}"
18360         done
18361
18362         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18363         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18364                 error " expect $old_dir_flag get $new_dir_flag"
18365
18366         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18367         [ "$old_file_flag" = "$new_file_flag" ] ||
18368                 error " expect $old_file_flag get $new_file_flag"
18369
18370         local new_dir_mode=$(stat -c%f $migrate_dir)
18371         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18372                 error "expect mode $old_dir_mode get $new_dir_mode"
18373
18374         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18375         [ "$old_file_mode" = "$new_file_mode" ] ||
18376                 error "expect mode $old_file_mode get $new_file_mode"
18377
18378         diff /etc/passwd ${migrate_dir}/$tfile ||
18379                 error "$tfile different after migration"
18380
18381         diff /etc/passwd ${other_dir}/luna ||
18382                 error "luna different after migration"
18383
18384         diff /etc/passwd ${migrate_dir}/sofia ||
18385                 error "sofia different after migration"
18386
18387         diff /etc/passwd ${other_dir}/zachary ||
18388                 error "zachary different after migration"
18389
18390         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18391                 error "${tfile}_ln different after migration"
18392
18393         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18394                 error "${tfile}_ln_other different after migration"
18395
18396         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18397         [ $stripe_count = 2 ] ||
18398                 error "dir strpe_count $d != 2 after migration."
18399
18400         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18401         [ $stripe_count = 2 ] ||
18402                 error "file strpe_count $d != 2 after migration."
18403
18404         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18405 }
18406 run_test 230b "migrate directory"
18407
18408 test_230c() {
18409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18410         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18411         remote_mds_nodsh && skip "remote MDS with nodsh"
18412         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18413                 skip "Need MDS version at least 2.11.52"
18414
18415         local MDTIDX=1
18416         local total=3
18417         local mdt_index
18418         local file
18419         local migrate_dir=$DIR/$tdir/migrate_dir
18420
18421         #If migrating directory fails in the middle, all entries of
18422         #the directory is still accessiable.
18423         test_mkdir $DIR/$tdir
18424         test_mkdir -i0 -c1 $migrate_dir
18425         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18426         stat $migrate_dir
18427         createmany -o $migrate_dir/f $total ||
18428                 error "create files under ${migrate_dir} failed"
18429
18430         # fail after migrating top dir, and this will fail only once, so the
18431         # first sub file migration will fail (currently f3), others succeed.
18432         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18433         do_facet mds1 lctl set_param fail_loc=0x1801
18434         local t=$(ls $migrate_dir | wc -l)
18435         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18436                 error "migrate should fail"
18437         local u=$(ls $migrate_dir | wc -l)
18438         [ "$u" == "$t" ] || error "$u != $t during migration"
18439
18440         # add new dir/file should succeed
18441         mkdir $migrate_dir/dir ||
18442                 error "mkdir failed under migrating directory"
18443         touch $migrate_dir/file ||
18444                 error "create file failed under migrating directory"
18445
18446         # add file with existing name should fail
18447         for file in $migrate_dir/f*; do
18448                 stat $file > /dev/null || error "stat $file failed"
18449                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18450                         error "open(O_CREAT|O_EXCL) $file should fail"
18451                 $MULTIOP $file m && error "create $file should fail"
18452                 touch $DIR/$tdir/remote_dir/$tfile ||
18453                         error "touch $tfile failed"
18454                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18455                         error "link $file should fail"
18456                 mdt_index=$($LFS getstripe -m $file)
18457                 if [ $mdt_index == 0 ]; then
18458                         # file failed to migrate is not allowed to rename to
18459                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18460                                 error "rename to $file should fail"
18461                 else
18462                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18463                                 error "rename to $file failed"
18464                 fi
18465                 echo hello >> $file || error "write $file failed"
18466         done
18467
18468         # resume migration with different options should fail
18469         $LFS migrate -m 0 $migrate_dir &&
18470                 error "migrate -m 0 $migrate_dir should fail"
18471
18472         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18473                 error "migrate -c 2 $migrate_dir should fail"
18474
18475         # resume migration should succeed
18476         $LFS migrate -m $MDTIDX $migrate_dir ||
18477                 error "migrate $migrate_dir failed"
18478
18479         echo "Finish migration, then checking.."
18480         for file in $(find $migrate_dir); do
18481                 mdt_index=$($LFS getstripe -m $file)
18482                 [ $mdt_index == $MDTIDX ] ||
18483                         error "$file is not on MDT${MDTIDX}"
18484         done
18485
18486         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18487 }
18488 run_test 230c "check directory accessiblity if migration failed"
18489
18490 test_230d() {
18491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18493         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18494                 skip "Need MDS version at least 2.11.52"
18495         # LU-11235
18496         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18497
18498         local migrate_dir=$DIR/$tdir/migrate_dir
18499         local old_index
18500         local new_index
18501         local old_count
18502         local new_count
18503         local new_hash
18504         local mdt_index
18505         local i
18506         local j
18507
18508         old_index=$((RANDOM % MDSCOUNT))
18509         old_count=$((MDSCOUNT - old_index))
18510         new_index=$((RANDOM % MDSCOUNT))
18511         new_count=$((MDSCOUNT - new_index))
18512         new_hash=1 # for all_char
18513
18514         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18515         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18516
18517         test_mkdir $DIR/$tdir
18518         test_mkdir -i $old_index -c $old_count $migrate_dir
18519
18520         for ((i=0; i<100; i++)); do
18521                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18522                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18523                         error "create files under remote dir failed $i"
18524         done
18525
18526         echo -n "Migrate from MDT$old_index "
18527         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18528         echo -n "to MDT$new_index"
18529         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18530         echo
18531
18532         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18533         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18534                 error "migrate remote dir error"
18535
18536         echo "Finish migration, then checking.."
18537         for file in $(find $migrate_dir); do
18538                 mdt_index=$($LFS getstripe -m $file)
18539                 if [ $mdt_index -lt $new_index ] ||
18540                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18541                         error "$file is on MDT$mdt_index"
18542                 fi
18543         done
18544
18545         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18546 }
18547 run_test 230d "check migrate big directory"
18548
18549 test_230e() {
18550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18551         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18552         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18553                 skip "Need MDS version at least 2.11.52"
18554
18555         local i
18556         local j
18557         local a_fid
18558         local b_fid
18559
18560         mkdir -p $DIR/$tdir
18561         mkdir $DIR/$tdir/migrate_dir
18562         mkdir $DIR/$tdir/other_dir
18563         touch $DIR/$tdir/migrate_dir/a
18564         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18565         ls $DIR/$tdir/other_dir
18566
18567         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18568                 error "migrate dir fails"
18569
18570         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18571         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18572
18573         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18574         [ $mdt_index == 0 ] || error "a is not on MDT0"
18575
18576         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18577                 error "migrate dir fails"
18578
18579         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18580         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18581
18582         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18583         [ $mdt_index == 1 ] || error "a is not on MDT1"
18584
18585         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18586         [ $mdt_index == 1 ] || error "b is not on MDT1"
18587
18588         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18589         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18590
18591         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18592
18593         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18594 }
18595 run_test 230e "migrate mulitple local link files"
18596
18597 test_230f() {
18598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18599         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18600         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18601                 skip "Need MDS version at least 2.11.52"
18602
18603         local a_fid
18604         local ln_fid
18605
18606         mkdir -p $DIR/$tdir
18607         mkdir $DIR/$tdir/migrate_dir
18608         $LFS mkdir -i1 $DIR/$tdir/other_dir
18609         touch $DIR/$tdir/migrate_dir/a
18610         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18611         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18612         ls $DIR/$tdir/other_dir
18613
18614         # a should be migrated to MDT1, since no other links on MDT0
18615         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18616                 error "#1 migrate dir fails"
18617         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18618         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18619         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18620         [ $mdt_index == 1 ] || error "a is not on MDT1"
18621
18622         # a should stay on MDT1, because it is a mulitple link file
18623         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18624                 error "#2 migrate dir fails"
18625         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18626         [ $mdt_index == 1 ] || error "a is not on MDT1"
18627
18628         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18629                 error "#3 migrate dir fails"
18630
18631         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18632         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18633         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18634
18635         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18636         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18637
18638         # a should be migrated to MDT0, since no other links on MDT1
18639         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18640                 error "#4 migrate dir fails"
18641         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18642         [ $mdt_index == 0 ] || error "a is not on MDT0"
18643
18644         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18645 }
18646 run_test 230f "migrate mulitple remote link files"
18647
18648 test_230g() {
18649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18650         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18651         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18652                 skip "Need MDS version at least 2.11.52"
18653
18654         mkdir -p $DIR/$tdir/migrate_dir
18655
18656         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18657                 error "migrating dir to non-exist MDT succeeds"
18658         true
18659 }
18660 run_test 230g "migrate dir to non-exist MDT"
18661
18662 test_230h() {
18663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18664         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18665         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18666                 skip "Need MDS version at least 2.11.52"
18667
18668         local mdt_index
18669
18670         mkdir -p $DIR/$tdir/migrate_dir
18671
18672         $LFS migrate -m1 $DIR &&
18673                 error "migrating mountpoint1 should fail"
18674
18675         $LFS migrate -m1 $DIR/$tdir/.. &&
18676                 error "migrating mountpoint2 should fail"
18677
18678         # same as mv
18679         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18680                 error "migrating $tdir/migrate_dir/.. should fail"
18681
18682         true
18683 }
18684 run_test 230h "migrate .. and root"
18685
18686 test_230i() {
18687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18688         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18689         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18690                 skip "Need MDS version at least 2.11.52"
18691
18692         mkdir -p $DIR/$tdir/migrate_dir
18693
18694         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18695                 error "migration fails with a tailing slash"
18696
18697         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18698                 error "migration fails with two tailing slashes"
18699 }
18700 run_test 230i "lfs migrate -m tolerates trailing slashes"
18701
18702 test_230j() {
18703         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18704         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18705                 skip "Need MDS version at least 2.11.52"
18706
18707         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18708         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18709                 error "create $tfile failed"
18710         cat /etc/passwd > $DIR/$tdir/$tfile
18711
18712         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18713
18714         cmp /etc/passwd $DIR/$tdir/$tfile ||
18715                 error "DoM file mismatch after migration"
18716 }
18717 run_test 230j "DoM file data not changed after dir migration"
18718
18719 test_230k() {
18720         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18721         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18722                 skip "Need MDS version at least 2.11.56"
18723
18724         local total=20
18725         local files_on_starting_mdt=0
18726
18727         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18728         $LFS getdirstripe $DIR/$tdir
18729         for i in $(seq $total); do
18730                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18731                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18732                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18733         done
18734
18735         echo "$files_on_starting_mdt files on MDT0"
18736
18737         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18738         $LFS getdirstripe $DIR/$tdir
18739
18740         files_on_starting_mdt=0
18741         for i in $(seq $total); do
18742                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18743                         error "file $tfile.$i mismatch after migration"
18744                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18745                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18746         done
18747
18748         echo "$files_on_starting_mdt files on MDT1 after migration"
18749         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18750
18751         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18752         $LFS getdirstripe $DIR/$tdir
18753
18754         files_on_starting_mdt=0
18755         for i in $(seq $total); do
18756                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18757                         error "file $tfile.$i mismatch after 2nd migration"
18758                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18759                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18760         done
18761
18762         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18763         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18764
18765         true
18766 }
18767 run_test 230k "file data not changed after dir migration"
18768
18769 test_230l() {
18770         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18771         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18772                 skip "Need MDS version at least 2.11.56"
18773
18774         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18775         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18776                 error "create files under remote dir failed $i"
18777         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18778 }
18779 run_test 230l "readdir between MDTs won't crash"
18780
18781 test_230m() {
18782         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18783         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18784                 skip "Need MDS version at least 2.11.56"
18785
18786         local MDTIDX=1
18787         local mig_dir=$DIR/$tdir/migrate_dir
18788         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18789         local shortstr="b"
18790         local val
18791
18792         echo "Creating files and dirs with xattrs"
18793         test_mkdir $DIR/$tdir
18794         test_mkdir -i0 -c1 $mig_dir
18795         mkdir $mig_dir/dir
18796         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18797                 error "cannot set xattr attr1 on dir"
18798         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18799                 error "cannot set xattr attr2 on dir"
18800         touch $mig_dir/dir/f0
18801         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18802                 error "cannot set xattr attr1 on file"
18803         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18804                 error "cannot set xattr attr2 on file"
18805         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18806         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18807         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18808         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18809         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18810         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18811         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18812         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18813         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18814
18815         echo "Migrating to MDT1"
18816         $LFS migrate -m $MDTIDX $mig_dir ||
18817                 error "fails on migrating dir to MDT1"
18818
18819         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18820         echo "Checking xattrs"
18821         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18822         [ "$val" = $longstr ] ||
18823                 error "expecting xattr1 $longstr on dir, found $val"
18824         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18825         [ "$val" = $shortstr ] ||
18826                 error "expecting xattr2 $shortstr on dir, found $val"
18827         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18828         [ "$val" = $longstr ] ||
18829                 error "expecting xattr1 $longstr on file, found $val"
18830         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18831         [ "$val" = $shortstr ] ||
18832                 error "expecting xattr2 $shortstr on file, found $val"
18833 }
18834 run_test 230m "xattrs not changed after dir migration"
18835
18836 test_230n() {
18837         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18838         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18839                 skip "Need MDS version at least 2.13.53"
18840
18841         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18842         cat /etc/hosts > $DIR/$tdir/$tfile
18843         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18844         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18845
18846         cmp /etc/hosts $DIR/$tdir/$tfile ||
18847                 error "File data mismatch after migration"
18848 }
18849 run_test 230n "Dir migration with mirrored file"
18850
18851 test_230o() {
18852         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18853         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18854                 skip "Need MDS version at least 2.13.52"
18855
18856         local mdts=$(comma_list $(mdts_nodes))
18857         local timeout=100
18858         local restripe_status
18859         local delta
18860         local i
18861
18862         [[ $mds1_FSTYPE == zfs ]] && timeout=300
18863
18864         # in case "crush" hash type is not set
18865         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18866
18867         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18868                            mdt.*MDT0000.enable_dir_restripe)
18869         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18870         stack_trap "do_nodes $mdts $LCTL set_param \
18871                     mdt.*.enable_dir_restripe=$restripe_status"
18872
18873         mkdir $DIR/$tdir
18874         createmany -m $DIR/$tdir/f 100 ||
18875                 error "create files under remote dir failed $i"
18876         createmany -d $DIR/$tdir/d 100 ||
18877                 error "create dirs under remote dir failed $i"
18878
18879         for i in $(seq 2 $MDSCOUNT); do
18880                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
18881                 $LFS setdirstripe -c $i $DIR/$tdir ||
18882                         error "split -c $i $tdir failed"
18883                 wait_update $HOSTNAME \
18884                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18885                         error "dir split not finished"
18886                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18887                         awk '/migrate/ {sum += $2} END { print sum }')
18888                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
18889                 # delta is around total_files/stripe_count
18890                 (( $delta < 200 / (i - 1) + 4 )) ||
18891                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
18892         done
18893 }
18894 run_test 230o "dir split"
18895
18896 test_230p() {
18897         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18898         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18899                 skip "Need MDS version at least 2.13.52"
18900
18901         local mdts=$(comma_list $(mdts_nodes))
18902         local timeout=100
18903         local restripe_status
18904         local delta
18905         local i
18906
18907         [[ $mds1_FSTYPE == zfs ]] && timeout=300
18908
18909         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18910
18911         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18912                            mdt.*MDT0000.enable_dir_restripe)
18913         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18914         stack_trap "do_nodes $mdts $LCTL set_param \
18915                     mdt.*.enable_dir_restripe=$restripe_status"
18916
18917         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18918         createmany -m $DIR/$tdir/f 100 ||
18919                 error "create files under remote dir failed $i"
18920         createmany -d $DIR/$tdir/d 100 ||
18921                 error "create dirs under remote dir failed $i"
18922
18923         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18924                 local mdt_hash="crush"
18925
18926                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
18927                 $LFS setdirstripe -c $i $DIR/$tdir ||
18928                         error "split -c $i $tdir failed"
18929                 [ $i -eq 1 ] && mdt_hash="none"
18930                 wait_update $HOSTNAME \
18931                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18932                         error "dir merge not finished"
18933                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18934                         awk '/migrate/ {sum += $2} END { print sum }')
18935                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
18936                 # delta is around total_files/stripe_count
18937                 (( $delta < 200 / i + 4 )) ||
18938                         error "$delta files migrated >= $((200 / i + 4))"
18939         done
18940 }
18941 run_test 230p "dir merge"
18942
18943 test_230q() {
18944         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18945         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18946                 skip "Need MDS version at least 2.13.52"
18947
18948         local mdts=$(comma_list $(mdts_nodes))
18949         local saved_threshold=$(do_facet mds1 \
18950                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18951         local saved_delta=$(do_facet mds1 \
18952                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18953         local threshold=100
18954         local delta=2
18955         local total=0
18956         local stripe_count=0
18957         local stripe_index
18958         local nr_files
18959         local create
18960
18961         # test with fewer files on ZFS
18962         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18963
18964         stack_trap "do_nodes $mdts $LCTL set_param \
18965                     mdt.*.dir_split_count=$saved_threshold"
18966         stack_trap "do_nodes $mdts $LCTL set_param \
18967                     mdt.*.dir_split_delta=$saved_delta"
18968         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18969         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18970         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18971         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18972         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18973         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18974
18975         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18976         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18977
18978         create=$((threshold * 3 / 2))
18979         while [ $stripe_count -lt $MDSCOUNT ]; do
18980                 createmany -m $DIR/$tdir/f $total $create ||
18981                         error "create sub files failed"
18982                 stat $DIR/$tdir > /dev/null
18983                 total=$((total + create))
18984                 stripe_count=$((stripe_count + delta))
18985                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18986
18987                 wait_update $HOSTNAME \
18988                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18989                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18990
18991                 wait_update $HOSTNAME \
18992                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18993                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18994
18995                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
18996                 echo "$nr_files/$total files on MDT$stripe_index after split"
18997                 # allow 10% margin of imbalance with crush hash
18998                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
18999                         error "$nr_files files on MDT$stripe_index after split"
19000
19001                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19002                 [ $nr_files -eq $total ] ||
19003                         error "total sub files $nr_files != $total"
19004         done
19005 }
19006 run_test 230q "dir auto split"
19007
19008 test_230r() {
19009         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19010         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19011         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19012                 skip "Need MDS version at least 2.13.54"
19013
19014         # maximum amount of local locks:
19015         # parent striped dir - 2 locks
19016         # new stripe in parent to migrate to - 1 lock
19017         # source and target - 2 locks
19018         # Total 5 locks for regular file
19019         mkdir -p $DIR/$tdir
19020         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19021         touch $DIR/$tdir/dir1/eee
19022
19023         # create 4 hardlink for 4 more locks
19024         # Total: 9 locks > RS_MAX_LOCKS (8)
19025         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19026         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19027         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19028         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19029         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19030         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19031         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19032         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19033
19034         cancel_lru_locks mdc
19035
19036         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19037                 error "migrate dir fails"
19038
19039         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19040 }
19041 run_test 230r "migrate with too many local locks"
19042
19043 test_231a()
19044 {
19045         # For simplicity this test assumes that max_pages_per_rpc
19046         # is the same across all OSCs
19047         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19048         local bulk_size=$((max_pages * PAGE_SIZE))
19049         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19050                                        head -n 1)
19051
19052         mkdir -p $DIR/$tdir
19053         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19054                 error "failed to set stripe with -S ${brw_size}M option"
19055
19056         # clear the OSC stats
19057         $LCTL set_param osc.*.stats=0 &>/dev/null
19058         stop_writeback
19059
19060         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19061         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19062                 oflag=direct &>/dev/null || error "dd failed"
19063
19064         sync; sleep 1; sync # just to be safe
19065         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19066         if [ x$nrpcs != "x1" ]; then
19067                 $LCTL get_param osc.*.stats
19068                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19069         fi
19070
19071         start_writeback
19072         # Drop the OSC cache, otherwise we will read from it
19073         cancel_lru_locks osc
19074
19075         # clear the OSC stats
19076         $LCTL set_param osc.*.stats=0 &>/dev/null
19077
19078         # Client reads $bulk_size.
19079         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19080                 iflag=direct &>/dev/null || error "dd failed"
19081
19082         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19083         if [ x$nrpcs != "x1" ]; then
19084                 $LCTL get_param osc.*.stats
19085                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19086         fi
19087 }
19088 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19089
19090 test_231b() {
19091         mkdir -p $DIR/$tdir
19092         local i
19093         for i in {0..1023}; do
19094                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19095                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19096                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19097         done
19098         sync
19099 }
19100 run_test 231b "must not assert on fully utilized OST request buffer"
19101
19102 test_232a() {
19103         mkdir -p $DIR/$tdir
19104         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19105
19106         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19107         do_facet ost1 $LCTL set_param fail_loc=0x31c
19108
19109         # ignore dd failure
19110         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19111
19112         do_facet ost1 $LCTL set_param fail_loc=0
19113         umount_client $MOUNT || error "umount failed"
19114         mount_client $MOUNT || error "mount failed"
19115         stop ost1 || error "cannot stop ost1"
19116         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19117 }
19118 run_test 232a "failed lock should not block umount"
19119
19120 test_232b() {
19121         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19122                 skip "Need MDS version at least 2.10.58"
19123
19124         mkdir -p $DIR/$tdir
19125         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19126         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19127         sync
19128         cancel_lru_locks osc
19129
19130         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19131         do_facet ost1 $LCTL set_param fail_loc=0x31c
19132
19133         # ignore failure
19134         $LFS data_version $DIR/$tdir/$tfile || true
19135
19136         do_facet ost1 $LCTL set_param fail_loc=0
19137         umount_client $MOUNT || error "umount failed"
19138         mount_client $MOUNT || error "mount failed"
19139         stop ost1 || error "cannot stop ost1"
19140         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19141 }
19142 run_test 232b "failed data version lock should not block umount"
19143
19144 test_233a() {
19145         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19146                 skip "Need MDS version at least 2.3.64"
19147         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19148
19149         local fid=$($LFS path2fid $MOUNT)
19150
19151         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19152                 error "cannot access $MOUNT using its FID '$fid'"
19153 }
19154 run_test 233a "checking that OBF of the FS root succeeds"
19155
19156 test_233b() {
19157         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19158                 skip "Need MDS version at least 2.5.90"
19159         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19160
19161         local fid=$($LFS path2fid $MOUNT/.lustre)
19162
19163         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19164                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19165
19166         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19167         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19168                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19169 }
19170 run_test 233b "checking that OBF of the FS .lustre succeeds"
19171
19172 test_234() {
19173         local p="$TMP/sanityN-$TESTNAME.parameters"
19174         save_lustre_params client "llite.*.xattr_cache" > $p
19175         lctl set_param llite.*.xattr_cache 1 ||
19176                 skip_env "xattr cache is not supported"
19177
19178         mkdir -p $DIR/$tdir || error "mkdir failed"
19179         touch $DIR/$tdir/$tfile || error "touch failed"
19180         # OBD_FAIL_LLITE_XATTR_ENOMEM
19181         $LCTL set_param fail_loc=0x1405
19182         getfattr -n user.attr $DIR/$tdir/$tfile &&
19183                 error "getfattr should have failed with ENOMEM"
19184         $LCTL set_param fail_loc=0x0
19185         rm -rf $DIR/$tdir
19186
19187         restore_lustre_params < $p
19188         rm -f $p
19189 }
19190 run_test 234 "xattr cache should not crash on ENOMEM"
19191
19192 test_235() {
19193         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19194                 skip "Need MDS version at least 2.4.52"
19195
19196         flock_deadlock $DIR/$tfile
19197         local RC=$?
19198         case $RC in
19199                 0)
19200                 ;;
19201                 124) error "process hangs on a deadlock"
19202                 ;;
19203                 *) error "error executing flock_deadlock $DIR/$tfile"
19204                 ;;
19205         esac
19206 }
19207 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19208
19209 #LU-2935
19210 test_236() {
19211         check_swap_layouts_support
19212
19213         local ref1=/etc/passwd
19214         local ref2=/etc/group
19215         local file1=$DIR/$tdir/f1
19216         local file2=$DIR/$tdir/f2
19217
19218         test_mkdir -c1 $DIR/$tdir
19219         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19220         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19221         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19222         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19223         local fd=$(free_fd)
19224         local cmd="exec $fd<>$file2"
19225         eval $cmd
19226         rm $file2
19227         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19228                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19229         cmd="exec $fd>&-"
19230         eval $cmd
19231         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19232
19233         #cleanup
19234         rm -rf $DIR/$tdir
19235 }
19236 run_test 236 "Layout swap on open unlinked file"
19237
19238 # LU-4659 linkea consistency
19239 test_238() {
19240         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19241                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19242                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19243                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19244
19245         touch $DIR/$tfile
19246         ln $DIR/$tfile $DIR/$tfile.lnk
19247         touch $DIR/$tfile.new
19248         mv $DIR/$tfile.new $DIR/$tfile
19249         local fid1=$($LFS path2fid $DIR/$tfile)
19250         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19251         local path1=$($LFS fid2path $FSNAME "$fid1")
19252         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19253         local path2=$($LFS fid2path $FSNAME "$fid2")
19254         [ $tfile.lnk == $path2 ] ||
19255                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19256         rm -f $DIR/$tfile*
19257 }
19258 run_test 238 "Verify linkea consistency"
19259
19260 test_239A() { # was test_239
19261         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19262                 skip "Need MDS version at least 2.5.60"
19263
19264         local list=$(comma_list $(mdts_nodes))
19265
19266         mkdir -p $DIR/$tdir
19267         createmany -o $DIR/$tdir/f- 5000
19268         unlinkmany $DIR/$tdir/f- 5000
19269         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19270                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19271         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19272                         osp.*MDT*.sync_in_flight" | calc_sum)
19273         [ "$changes" -eq 0 ] || error "$changes not synced"
19274 }
19275 run_test 239A "osp_sync test"
19276
19277 test_239a() { #LU-5297
19278         remote_mds_nodsh && skip "remote MDS with nodsh"
19279
19280         touch $DIR/$tfile
19281         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19282         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19283         chgrp $RUNAS_GID $DIR/$tfile
19284         wait_delete_completed
19285 }
19286 run_test 239a "process invalid osp sync record correctly"
19287
19288 test_239b() { #LU-5297
19289         remote_mds_nodsh && skip "remote MDS with nodsh"
19290
19291         touch $DIR/$tfile1
19292         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19293         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19294         chgrp $RUNAS_GID $DIR/$tfile1
19295         wait_delete_completed
19296         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19297         touch $DIR/$tfile2
19298         chgrp $RUNAS_GID $DIR/$tfile2
19299         wait_delete_completed
19300 }
19301 run_test 239b "process osp sync record with ENOMEM error correctly"
19302
19303 test_240() {
19304         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19305         remote_mds_nodsh && skip "remote MDS with nodsh"
19306
19307         mkdir -p $DIR/$tdir
19308
19309         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19310                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19311         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19312                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19313
19314         umount_client $MOUNT || error "umount failed"
19315         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19316         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19317         mount_client $MOUNT || error "failed to mount client"
19318
19319         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19320         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19321 }
19322 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19323
19324 test_241_bio() {
19325         local count=$1
19326         local bsize=$2
19327
19328         for LOOP in $(seq $count); do
19329                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19330                 cancel_lru_locks $OSC || true
19331         done
19332 }
19333
19334 test_241_dio() {
19335         local count=$1
19336         local bsize=$2
19337
19338         for LOOP in $(seq $1); do
19339                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19340                         2>/dev/null
19341         done
19342 }
19343
19344 test_241a() { # was test_241
19345         local bsize=$PAGE_SIZE
19346
19347         (( bsize < 40960 )) && bsize=40960
19348         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19349         ls -la $DIR/$tfile
19350         cancel_lru_locks $OSC
19351         test_241_bio 1000 $bsize &
19352         PID=$!
19353         test_241_dio 1000 $bsize
19354         wait $PID
19355 }
19356 run_test 241a "bio vs dio"
19357
19358 test_241b() {
19359         local bsize=$PAGE_SIZE
19360
19361         (( bsize < 40960 )) && bsize=40960
19362         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19363         ls -la $DIR/$tfile
19364         test_241_dio 1000 $bsize &
19365         PID=$!
19366         test_241_dio 1000 $bsize
19367         wait $PID
19368 }
19369 run_test 241b "dio vs dio"
19370
19371 test_242() {
19372         remote_mds_nodsh && skip "remote MDS with nodsh"
19373
19374         mkdir -p $DIR/$tdir
19375         touch $DIR/$tdir/$tfile
19376
19377         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19378         do_facet mds1 lctl set_param fail_loc=0x105
19379         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19380
19381         do_facet mds1 lctl set_param fail_loc=0
19382         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19383 }
19384 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19385
19386 test_243()
19387 {
19388         test_mkdir $DIR/$tdir
19389         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19390 }
19391 run_test 243 "various group lock tests"
19392
19393 test_244a()
19394 {
19395         test_mkdir $DIR/$tdir
19396         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19397         sendfile_grouplock $DIR/$tdir/$tfile || \
19398                 error "sendfile+grouplock failed"
19399         rm -rf $DIR/$tdir
19400 }
19401 run_test 244a "sendfile with group lock tests"
19402
19403 test_244b()
19404 {
19405         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19406
19407         local threads=50
19408         local size=$((1024*1024))
19409
19410         test_mkdir $DIR/$tdir
19411         for i in $(seq 1 $threads); do
19412                 local file=$DIR/$tdir/file_$((i / 10))
19413                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19414                 local pids[$i]=$!
19415         done
19416         for i in $(seq 1 $threads); do
19417                 wait ${pids[$i]}
19418         done
19419 }
19420 run_test 244b "multi-threaded write with group lock"
19421
19422 test_245() {
19423         local flagname="multi_mod_rpcs"
19424         local connect_data_name="max_mod_rpcs"
19425         local out
19426
19427         # check if multiple modify RPCs flag is set
19428         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19429                 grep "connect_flags:")
19430         echo "$out"
19431
19432         echo "$out" | grep -qw $flagname
19433         if [ $? -ne 0 ]; then
19434                 echo "connect flag $flagname is not set"
19435                 return
19436         fi
19437
19438         # check if multiple modify RPCs data is set
19439         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19440         echo "$out"
19441
19442         echo "$out" | grep -qw $connect_data_name ||
19443                 error "import should have connect data $connect_data_name"
19444 }
19445 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19446
19447 cleanup_247() {
19448         local submount=$1
19449
19450         trap 0
19451         umount_client $submount
19452         rmdir $submount
19453 }
19454
19455 test_247a() {
19456         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19457                 grep -q subtree ||
19458                 skip_env "Fileset feature is not supported"
19459
19460         local submount=${MOUNT}_$tdir
19461
19462         mkdir $MOUNT/$tdir
19463         mkdir -p $submount || error "mkdir $submount failed"
19464         FILESET="$FILESET/$tdir" mount_client $submount ||
19465                 error "mount $submount failed"
19466         trap "cleanup_247 $submount" EXIT
19467         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19468         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19469                 error "read $MOUNT/$tdir/$tfile failed"
19470         cleanup_247 $submount
19471 }
19472 run_test 247a "mount subdir as fileset"
19473
19474 test_247b() {
19475         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19476                 skip_env "Fileset feature is not supported"
19477
19478         local submount=${MOUNT}_$tdir
19479
19480         rm -rf $MOUNT/$tdir
19481         mkdir -p $submount || error "mkdir $submount failed"
19482         SKIP_FILESET=1
19483         FILESET="$FILESET/$tdir" mount_client $submount &&
19484                 error "mount $submount should fail"
19485         rmdir $submount
19486 }
19487 run_test 247b "mount subdir that dose not exist"
19488
19489 test_247c() {
19490         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19491                 skip_env "Fileset feature is not supported"
19492
19493         local submount=${MOUNT}_$tdir
19494
19495         mkdir -p $MOUNT/$tdir/dir1
19496         mkdir -p $submount || error "mkdir $submount failed"
19497         trap "cleanup_247 $submount" EXIT
19498         FILESET="$FILESET/$tdir" mount_client $submount ||
19499                 error "mount $submount failed"
19500         local fid=$($LFS path2fid $MOUNT/)
19501         $LFS fid2path $submount $fid && error "fid2path should fail"
19502         cleanup_247 $submount
19503 }
19504 run_test 247c "running fid2path outside subdirectory root"
19505
19506 test_247d() {
19507         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19508                 skip "Fileset feature is not supported"
19509
19510         local submount=${MOUNT}_$tdir
19511
19512         mkdir -p $MOUNT/$tdir/dir1
19513         mkdir -p $submount || error "mkdir $submount failed"
19514         FILESET="$FILESET/$tdir" mount_client $submount ||
19515                 error "mount $submount failed"
19516         trap "cleanup_247 $submount" EXIT
19517
19518         local td=$submount/dir1
19519         local fid=$($LFS path2fid $td)
19520         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19521
19522         # check that we get the same pathname back
19523         local rootpath
19524         local found
19525         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19526                 echo "$rootpath $fid"
19527                 found=$($LFS fid2path $rootpath "$fid")
19528                 [ -n "found" ] || error "fid2path should succeed"
19529                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19530         done
19531         # check wrong root path format
19532         rootpath=$submount"_wrong"
19533         found=$($LFS fid2path $rootpath "$fid")
19534         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19535
19536         cleanup_247 $submount
19537 }
19538 run_test 247d "running fid2path inside subdirectory root"
19539
19540 # LU-8037
19541 test_247e() {
19542         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19543                 grep -q subtree ||
19544                 skip "Fileset feature is not supported"
19545
19546         local submount=${MOUNT}_$tdir
19547
19548         mkdir $MOUNT/$tdir
19549         mkdir -p $submount || error "mkdir $submount failed"
19550         FILESET="$FILESET/.." mount_client $submount &&
19551                 error "mount $submount should fail"
19552         rmdir $submount
19553 }
19554 run_test 247e "mount .. as fileset"
19555
19556 test_247f() {
19557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19558         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19559                 skip "Need at least version 2.13.52"
19560         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
19561                 skip "Need at least version 2.14.50"
19562         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19563                 grep -q subtree ||
19564                 skip "Fileset feature is not supported"
19565
19566         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19567         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19568                 error "mkdir remote failed"
19569         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19570         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
19571                 error "mkdir striped failed"
19572         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19573
19574         local submount=${MOUNT}_$tdir
19575
19576         mkdir -p $submount || error "mkdir $submount failed"
19577         stack_trap "rmdir $submount"
19578
19579         local dir
19580         local stat
19581         local fileset=$FILESET
19582         local mdts=$(comma_list $(mdts_nodes))
19583
19584         stat=$(do_facet mds1 $LCTL get_param -n \
19585                 mdt.*MDT0000.enable_remote_subdir_mount)
19586         stack_trap "do_nodes $mdts $LCTL set_param \
19587                 mdt.*.enable_remote_subdir_mount=$stat"
19588
19589         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
19590         stack_trap "umount_client $submount"
19591         FILESET="$fileset/$tdir/remote" mount_client $submount &&
19592                 error "mount remote dir $dir should fail"
19593
19594         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
19595                 $tdir/striped/. ; do
19596                 FILESET="$fileset/$dir" mount_client $submount ||
19597                         error "mount $dir failed"
19598                 umount_client $submount
19599         done
19600
19601         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
19602         FILESET="$fileset/$tdir/remote" mount_client $submount ||
19603                 error "mount $tdir/remote failed"
19604 }
19605 run_test 247f "mount striped or remote directory as fileset"
19606
19607 test_247g() {
19608         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
19609         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
19610                 skip "Need at least version 2.14.50"
19611
19612         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
19613                 error "mkdir $tdir failed"
19614         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
19615
19616         local submount=${MOUNT}_$tdir
19617
19618         mkdir -p $submount || error "mkdir $submount failed"
19619         stack_trap "rmdir $submount"
19620
19621         FILESET="$fileset/$tdir" mount_client $submount ||
19622                 error "mount $dir failed"
19623         stack_trap "umount $submount"
19624
19625         local mdts=$(comma_list $(mdts_nodes))
19626
19627         local nrpcs
19628
19629         stat $submount > /dev/null
19630         cancel_lru_locks $MDC
19631         stat $submount > /dev/null
19632         stat $submount/$tfile > /dev/null
19633         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
19634         stat $submount/$tfile > /dev/null
19635         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
19636                 awk '/getattr/ {sum += $2} END {print sum}')
19637
19638         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
19639 }
19640 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
19641
19642 test_248a() {
19643         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19644         [ -z "$fast_read_sav" ] && skip "no fast read support"
19645
19646         # create a large file for fast read verification
19647         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19648
19649         # make sure the file is created correctly
19650         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19651                 { rm -f $DIR/$tfile; skip "file creation error"; }
19652
19653         echo "Test 1: verify that fast read is 4 times faster on cache read"
19654
19655         # small read with fast read enabled
19656         $LCTL set_param -n llite.*.fast_read=1
19657         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19658                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19659                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19660         # small read with fast read disabled
19661         $LCTL set_param -n llite.*.fast_read=0
19662         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19663                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19664                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19665
19666         # verify that fast read is 4 times faster for cache read
19667         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19668                 error_not_in_vm "fast read was not 4 times faster: " \
19669                            "$t_fast vs $t_slow"
19670
19671         echo "Test 2: verify the performance between big and small read"
19672         $LCTL set_param -n llite.*.fast_read=1
19673
19674         # 1k non-cache read
19675         cancel_lru_locks osc
19676         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19677                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19678                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19679
19680         # 1M non-cache read
19681         cancel_lru_locks osc
19682         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19683                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19684                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19685
19686         # verify that big IO is not 4 times faster than small IO
19687         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19688                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19689
19690         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19691         rm -f $DIR/$tfile
19692 }
19693 run_test 248a "fast read verification"
19694
19695 test_248b() {
19696         # Default short_io_bytes=16384, try both smaller and larger sizes.
19697         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19698         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19699         echo "bs=53248 count=113 normal buffered write"
19700         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19701                 error "dd of initial data file failed"
19702         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19703
19704         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19705         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19706                 error "dd with sync normal writes failed"
19707         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19708
19709         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19710         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19711                 error "dd with sync small writes failed"
19712         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19713
19714         cancel_lru_locks osc
19715
19716         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19717         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19718         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19719         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19720                 iflag=direct || error "dd with O_DIRECT small read failed"
19721         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19722         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19723                 error "compare $TMP/$tfile.1 failed"
19724
19725         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19726         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19727
19728         # just to see what the maximum tunable value is, and test parsing
19729         echo "test invalid parameter 2MB"
19730         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19731                 error "too-large short_io_bytes allowed"
19732         echo "test maximum parameter 512KB"
19733         # if we can set a larger short_io_bytes, run test regardless of version
19734         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19735                 # older clients may not allow setting it this large, that's OK
19736                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19737                         skip "Need at least client version 2.13.50"
19738                 error "medium short_io_bytes failed"
19739         fi
19740         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19741         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19742
19743         echo "test large parameter 64KB"
19744         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19745         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19746
19747         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19748         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19749                 error "dd with sync large writes failed"
19750         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19751
19752         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19753         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19754         num=$((113 * 4096 / PAGE_SIZE))
19755         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19756         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19757                 error "dd with O_DIRECT large writes failed"
19758         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19759                 error "compare $DIR/$tfile.3 failed"
19760
19761         cancel_lru_locks osc
19762
19763         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19764         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19765                 error "dd with O_DIRECT large read failed"
19766         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19767                 error "compare $TMP/$tfile.2 failed"
19768
19769         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19770         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19771                 error "dd with O_DIRECT large read failed"
19772         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19773                 error "compare $TMP/$tfile.3 failed"
19774 }
19775 run_test 248b "test short_io read and write for both small and large sizes"
19776
19777 test_249() { # LU-7890
19778         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19779                 skip "Need at least version 2.8.54"
19780
19781         rm -f $DIR/$tfile
19782         $LFS setstripe -c 1 $DIR/$tfile
19783         # Offset 2T == 4k * 512M
19784         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19785                 error "dd to 2T offset failed"
19786 }
19787 run_test 249 "Write above 2T file size"
19788
19789 test_250() {
19790         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19791          && skip "no 16TB file size limit on ZFS"
19792
19793         $LFS setstripe -c 1 $DIR/$tfile
19794         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19795         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19796         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19797         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19798                 conv=notrunc,fsync && error "append succeeded"
19799         return 0
19800 }
19801 run_test 250 "Write above 16T limit"
19802
19803 test_251() {
19804         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19805
19806         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19807         #Skip once - writing the first stripe will succeed
19808         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19809         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19810                 error "short write happened"
19811
19812         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19813         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19814                 error "short read happened"
19815
19816         rm -f $DIR/$tfile
19817 }
19818 run_test 251 "Handling short read and write correctly"
19819
19820 test_252() {
19821         remote_mds_nodsh && skip "remote MDS with nodsh"
19822         remote_ost_nodsh && skip "remote OST with nodsh"
19823         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19824                 skip_env "ldiskfs only test"
19825         fi
19826
19827         local tgt
19828         local dev
19829         local out
19830         local uuid
19831         local num
19832         local gen
19833
19834         # check lr_reader on OST0000
19835         tgt=ost1
19836         dev=$(facet_device $tgt)
19837         out=$(do_facet $tgt $LR_READER $dev)
19838         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19839         echo "$out"
19840         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19841         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19842                 error "Invalid uuid returned by $LR_READER on target $tgt"
19843         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19844
19845         # check lr_reader -c on MDT0000
19846         tgt=mds1
19847         dev=$(facet_device $tgt)
19848         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19849                 skip "$LR_READER does not support additional options"
19850         fi
19851         out=$(do_facet $tgt $LR_READER -c $dev)
19852         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19853         echo "$out"
19854         num=$(echo "$out" | grep -c "mdtlov")
19855         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19856                 error "Invalid number of mdtlov clients returned by $LR_READER"
19857         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19858
19859         # check lr_reader -cr on MDT0000
19860         out=$(do_facet $tgt $LR_READER -cr $dev)
19861         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19862         echo "$out"
19863         echo "$out" | grep -q "^reply_data:$" ||
19864                 error "$LR_READER should have returned 'reply_data' section"
19865         num=$(echo "$out" | grep -c "client_generation")
19866         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19867 }
19868 run_test 252 "check lr_reader tool"
19869
19870 test_253() {
19871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19872         remote_mds_nodsh && skip "remote MDS with nodsh"
19873         remote_mgs_nodsh && skip "remote MGS with nodsh"
19874
19875         local ostidx=0
19876         local rc=0
19877         local ost_name=$(ostname_from_index $ostidx)
19878
19879         # on the mdt's osc
19880         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19881         do_facet $SINGLEMDS $LCTL get_param -n \
19882                 osp.$mdtosc_proc1.reserved_mb_high ||
19883                 skip  "remote MDS does not support reserved_mb_high"
19884
19885         rm -rf $DIR/$tdir
19886         wait_mds_ost_sync
19887         wait_delete_completed
19888         mkdir $DIR/$tdir
19889
19890         pool_add $TESTNAME || error "Pool creation failed"
19891         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19892
19893         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19894                 error "Setstripe failed"
19895
19896         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19897
19898         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19899                     grep "watermarks")
19900         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19901
19902         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19903                         osp.$mdtosc_proc1.prealloc_status)
19904         echo "prealloc_status $oa_status"
19905
19906         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19907                 error "File creation should fail"
19908
19909         #object allocation was stopped, but we still able to append files
19910         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19911                 oflag=append || error "Append failed"
19912
19913         rm -f $DIR/$tdir/$tfile.0
19914
19915         # For this test, we want to delete the files we created to go out of
19916         # space but leave the watermark, so we remain nearly out of space
19917         ost_watermarks_enospc_delete_files $tfile $ostidx
19918
19919         wait_delete_completed
19920
19921         sleep_maxage
19922
19923         for i in $(seq 10 12); do
19924                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19925                         2>/dev/null || error "File creation failed after rm"
19926         done
19927
19928         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19929                         osp.$mdtosc_proc1.prealloc_status)
19930         echo "prealloc_status $oa_status"
19931
19932         if (( oa_status != 0 )); then
19933                 error "Object allocation still disable after rm"
19934         fi
19935 }
19936 run_test 253 "Check object allocation limit"
19937
19938 test_254() {
19939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19940         remote_mds_nodsh && skip "remote MDS with nodsh"
19941         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19942                 skip "MDS does not support changelog_size"
19943
19944         local cl_user
19945         local MDT0=$(facet_svc $SINGLEMDS)
19946
19947         changelog_register || error "changelog_register failed"
19948
19949         changelog_clear 0 || error "changelog_clear failed"
19950
19951         local size1=$(do_facet $SINGLEMDS \
19952                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19953         echo "Changelog size $size1"
19954
19955         rm -rf $DIR/$tdir
19956         $LFS mkdir -i 0 $DIR/$tdir
19957         # change something
19958         mkdir -p $DIR/$tdir/pics/2008/zachy
19959         touch $DIR/$tdir/pics/2008/zachy/timestamp
19960         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19961         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19962         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19963         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19964         rm $DIR/$tdir/pics/desktop.jpg
19965
19966         local size2=$(do_facet $SINGLEMDS \
19967                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19968         echo "Changelog size after work $size2"
19969
19970         (( $size2 > $size1 )) ||
19971                 error "new Changelog size=$size2 less than old size=$size1"
19972 }
19973 run_test 254 "Check changelog size"
19974
19975 ladvise_no_type()
19976 {
19977         local type=$1
19978         local file=$2
19979
19980         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19981                 awk -F: '{print $2}' | grep $type > /dev/null
19982         if [ $? -ne 0 ]; then
19983                 return 0
19984         fi
19985         return 1
19986 }
19987
19988 ladvise_no_ioctl()
19989 {
19990         local file=$1
19991
19992         lfs ladvise -a willread $file > /dev/null 2>&1
19993         if [ $? -eq 0 ]; then
19994                 return 1
19995         fi
19996
19997         lfs ladvise -a willread $file 2>&1 |
19998                 grep "Inappropriate ioctl for device" > /dev/null
19999         if [ $? -eq 0 ]; then
20000                 return 0
20001         fi
20002         return 1
20003 }
20004
20005 percent() {
20006         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20007 }
20008
20009 # run a random read IO workload
20010 # usage: random_read_iops <filename> <filesize> <iosize>
20011 random_read_iops() {
20012         local file=$1
20013         local fsize=$2
20014         local iosize=${3:-4096}
20015
20016         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20017                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20018 }
20019
20020 drop_file_oss_cache() {
20021         local file="$1"
20022         local nodes="$2"
20023
20024         $LFS ladvise -a dontneed $file 2>/dev/null ||
20025                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20026 }
20027
20028 ladvise_willread_performance()
20029 {
20030         local repeat=10
20031         local average_origin=0
20032         local average_cache=0
20033         local average_ladvise=0
20034
20035         for ((i = 1; i <= $repeat; i++)); do
20036                 echo "Iter $i/$repeat: reading without willread hint"
20037                 cancel_lru_locks osc
20038                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20039                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20040                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20041                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20042
20043                 cancel_lru_locks osc
20044                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20045                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20046                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20047
20048                 cancel_lru_locks osc
20049                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20050                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20051                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20052                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20053                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20054         done
20055         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20056         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20057         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20058
20059         speedup_cache=$(percent $average_cache $average_origin)
20060         speedup_ladvise=$(percent $average_ladvise $average_origin)
20061
20062         echo "Average uncached read: $average_origin"
20063         echo "Average speedup with OSS cached read: " \
20064                 "$average_cache = +$speedup_cache%"
20065         echo "Average speedup with ladvise willread: " \
20066                 "$average_ladvise = +$speedup_ladvise%"
20067
20068         local lowest_speedup=20
20069         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20070                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20071                         "got $average_cache%. Skipping ladvise willread check."
20072                 return 0
20073         fi
20074
20075         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20076         # it is still good to run until then to exercise 'ladvise willread'
20077         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20078                 [ "$ost1_FSTYPE" = "zfs" ] &&
20079                 echo "osd-zfs does not support dontneed or drop_caches" &&
20080                 return 0
20081
20082         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20083         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20084                 error_not_in_vm "Speedup with willread is less than " \
20085                         "$lowest_speedup%, got $average_ladvise%"
20086 }
20087
20088 test_255a() {
20089         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20090                 skip "lustre < 2.8.54 does not support ladvise "
20091         remote_ost_nodsh && skip "remote OST with nodsh"
20092
20093         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20094
20095         ladvise_no_type willread $DIR/$tfile &&
20096                 skip "willread ladvise is not supported"
20097
20098         ladvise_no_ioctl $DIR/$tfile &&
20099                 skip "ladvise ioctl is not supported"
20100
20101         local size_mb=100
20102         local size=$((size_mb * 1048576))
20103         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20104                 error "dd to $DIR/$tfile failed"
20105
20106         lfs ladvise -a willread $DIR/$tfile ||
20107                 error "Ladvise failed with no range argument"
20108
20109         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20110                 error "Ladvise failed with no -l or -e argument"
20111
20112         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20113                 error "Ladvise failed with only -e argument"
20114
20115         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20116                 error "Ladvise failed with only -l argument"
20117
20118         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20119                 error "End offset should not be smaller than start offset"
20120
20121         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20122                 error "End offset should not be equal to start offset"
20123
20124         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20125                 error "Ladvise failed with overflowing -s argument"
20126
20127         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20128                 error "Ladvise failed with overflowing -e argument"
20129
20130         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20131                 error "Ladvise failed with overflowing -l argument"
20132
20133         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20134                 error "Ladvise succeeded with conflicting -l and -e arguments"
20135
20136         echo "Synchronous ladvise should wait"
20137         local delay=4
20138 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20139         do_nodes $(comma_list $(osts_nodes)) \
20140                 $LCTL set_param fail_val=$delay fail_loc=0x237
20141
20142         local start_ts=$SECONDS
20143         lfs ladvise -a willread $DIR/$tfile ||
20144                 error "Ladvise failed with no range argument"
20145         local end_ts=$SECONDS
20146         local inteval_ts=$((end_ts - start_ts))
20147
20148         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20149                 error "Synchronous advice didn't wait reply"
20150         fi
20151
20152         echo "Asynchronous ladvise shouldn't wait"
20153         local start_ts=$SECONDS
20154         lfs ladvise -a willread -b $DIR/$tfile ||
20155                 error "Ladvise failed with no range argument"
20156         local end_ts=$SECONDS
20157         local inteval_ts=$((end_ts - start_ts))
20158
20159         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20160                 error "Asynchronous advice blocked"
20161         fi
20162
20163         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20164         ladvise_willread_performance
20165 }
20166 run_test 255a "check 'lfs ladvise -a willread'"
20167
20168 facet_meminfo() {
20169         local facet=$1
20170         local info=$2
20171
20172         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20173 }
20174
20175 test_255b() {
20176         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20177                 skip "lustre < 2.8.54 does not support ladvise "
20178         remote_ost_nodsh && skip "remote OST with nodsh"
20179
20180         lfs setstripe -c 1 -i 0 $DIR/$tfile
20181
20182         ladvise_no_type dontneed $DIR/$tfile &&
20183                 skip "dontneed ladvise is not supported"
20184
20185         ladvise_no_ioctl $DIR/$tfile &&
20186                 skip "ladvise ioctl is not supported"
20187
20188         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20189                 [ "$ost1_FSTYPE" = "zfs" ] &&
20190                 skip "zfs-osd does not support 'ladvise dontneed'"
20191
20192         local size_mb=100
20193         local size=$((size_mb * 1048576))
20194         # In order to prevent disturbance of other processes, only check 3/4
20195         # of the memory usage
20196         local kibibytes=$((size_mb * 1024 * 3 / 4))
20197
20198         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20199                 error "dd to $DIR/$tfile failed"
20200
20201         #force write to complete before dropping OST cache & checking memory
20202         sync
20203
20204         local total=$(facet_meminfo ost1 MemTotal)
20205         echo "Total memory: $total KiB"
20206
20207         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20208         local before_read=$(facet_meminfo ost1 Cached)
20209         echo "Cache used before read: $before_read KiB"
20210
20211         lfs ladvise -a willread $DIR/$tfile ||
20212                 error "Ladvise willread failed"
20213         local after_read=$(facet_meminfo ost1 Cached)
20214         echo "Cache used after read: $after_read KiB"
20215
20216         lfs ladvise -a dontneed $DIR/$tfile ||
20217                 error "Ladvise dontneed again failed"
20218         local no_read=$(facet_meminfo ost1 Cached)
20219         echo "Cache used after dontneed ladvise: $no_read KiB"
20220
20221         if [ $total -lt $((before_read + kibibytes)) ]; then
20222                 echo "Memory is too small, abort checking"
20223                 return 0
20224         fi
20225
20226         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20227                 error "Ladvise willread should use more memory" \
20228                         "than $kibibytes KiB"
20229         fi
20230
20231         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20232                 error "Ladvise dontneed should release more memory" \
20233                         "than $kibibytes KiB"
20234         fi
20235 }
20236 run_test 255b "check 'lfs ladvise -a dontneed'"
20237
20238 test_255c() {
20239         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20240                 skip "lustre < 2.10.50 does not support lockahead"
20241
20242         local ost1_imp=$(get_osc_import_name client ost1)
20243         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20244                          cut -d'.' -f2)
20245         local count
20246         local new_count
20247         local difference
20248         local i
20249         local rc
20250
20251         test_mkdir -p $DIR/$tdir
20252         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20253
20254         #test 10 returns only success/failure
20255         i=10
20256         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20257         rc=$?
20258         if [ $rc -eq 255 ]; then
20259                 error "Ladvise test${i} failed, ${rc}"
20260         fi
20261
20262         #test 11 counts lock enqueue requests, all others count new locks
20263         i=11
20264         count=$(do_facet ost1 \
20265                 $LCTL get_param -n ost.OSS.ost.stats)
20266         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20267
20268         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20269         rc=$?
20270         if [ $rc -eq 255 ]; then
20271                 error "Ladvise test${i} failed, ${rc}"
20272         fi
20273
20274         new_count=$(do_facet ost1 \
20275                 $LCTL get_param -n ost.OSS.ost.stats)
20276         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20277                    awk '{ print $2 }')
20278
20279         difference="$((new_count - count))"
20280         if [ $difference -ne $rc ]; then
20281                 error "Ladvise test${i}, bad enqueue count, returned " \
20282                       "${rc}, actual ${difference}"
20283         fi
20284
20285         for i in $(seq 12 21); do
20286                 # If we do not do this, we run the risk of having too many
20287                 # locks and starting lock cancellation while we are checking
20288                 # lock counts.
20289                 cancel_lru_locks osc
20290
20291                 count=$($LCTL get_param -n \
20292                        ldlm.namespaces.$imp_name.lock_unused_count)
20293
20294                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20295                 rc=$?
20296                 if [ $rc -eq 255 ]; then
20297                         error "Ladvise test ${i} failed, ${rc}"
20298                 fi
20299
20300                 new_count=$($LCTL get_param -n \
20301                        ldlm.namespaces.$imp_name.lock_unused_count)
20302                 difference="$((new_count - count))"
20303
20304                 # Test 15 output is divided by 100 to map down to valid return
20305                 if [ $i -eq 15 ]; then
20306                         rc="$((rc * 100))"
20307                 fi
20308
20309                 if [ $difference -ne $rc ]; then
20310                         error "Ladvise test ${i}, bad lock count, returned " \
20311                               "${rc}, actual ${difference}"
20312                 fi
20313         done
20314
20315         #test 22 returns only success/failure
20316         i=22
20317         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20318         rc=$?
20319         if [ $rc -eq 255 ]; then
20320                 error "Ladvise test${i} failed, ${rc}"
20321         fi
20322 }
20323 run_test 255c "suite of ladvise lockahead tests"
20324
20325 test_256() {
20326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20327         remote_mds_nodsh && skip "remote MDS with nodsh"
20328         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20329         changelog_users $SINGLEMDS | grep "^cl" &&
20330                 skip "active changelog user"
20331
20332         local cl_user
20333         local cat_sl
20334         local mdt_dev
20335
20336         mdt_dev=$(mdsdevname 1)
20337         echo $mdt_dev
20338
20339         changelog_register || error "changelog_register failed"
20340
20341         rm -rf $DIR/$tdir
20342         mkdir -p $DIR/$tdir
20343
20344         changelog_clear 0 || error "changelog_clear failed"
20345
20346         # change something
20347         touch $DIR/$tdir/{1..10}
20348
20349         # stop the MDT
20350         stop $SINGLEMDS || error "Fail to stop MDT"
20351
20352         # remount the MDT
20353
20354         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20355
20356         #after mount new plainllog is used
20357         touch $DIR/$tdir/{11..19}
20358         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20359         stack_trap "rm -f $tmpfile"
20360         cat_sl=$(do_facet $SINGLEMDS "sync; \
20361                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20362                  llog_reader $tmpfile | grep -c type=1064553b")
20363         do_facet $SINGLEMDS llog_reader $tmpfile
20364
20365         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20366
20367         changelog_clear 0 || error "changelog_clear failed"
20368
20369         cat_sl=$(do_facet $SINGLEMDS "sync; \
20370                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20371                  llog_reader $tmpfile | grep -c type=1064553b")
20372
20373         if (( cat_sl == 2 )); then
20374                 error "Empty plain llog was not deleted from changelog catalog"
20375         elif (( cat_sl != 1 )); then
20376                 error "Active plain llog shouldn't be deleted from catalog"
20377         fi
20378 }
20379 run_test 256 "Check llog delete for empty and not full state"
20380
20381 test_257() {
20382         remote_mds_nodsh && skip "remote MDS with nodsh"
20383         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20384                 skip "Need MDS version at least 2.8.55"
20385
20386         test_mkdir $DIR/$tdir
20387
20388         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20389                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20390         stat $DIR/$tdir
20391
20392 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20393         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20394         local facet=mds$((mdtidx + 1))
20395         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20396         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20397
20398         stop $facet || error "stop MDS failed"
20399         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20400                 error "start MDS fail"
20401         wait_recovery_complete $facet
20402 }
20403 run_test 257 "xattr locks are not lost"
20404
20405 # Verify we take the i_mutex when security requires it
20406 test_258a() {
20407 #define OBD_FAIL_IMUTEX_SEC 0x141c
20408         $LCTL set_param fail_loc=0x141c
20409         touch $DIR/$tfile
20410         chmod u+s $DIR/$tfile
20411         chmod a+rwx $DIR/$tfile
20412         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20413         RC=$?
20414         if [ $RC -ne 0 ]; then
20415                 error "error, failed to take i_mutex, rc=$?"
20416         fi
20417         rm -f $DIR/$tfile
20418 }
20419 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20420
20421 # Verify we do NOT take the i_mutex in the normal case
20422 test_258b() {
20423 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20424         $LCTL set_param fail_loc=0x141d
20425         touch $DIR/$tfile
20426         chmod a+rwx $DIR
20427         chmod a+rw $DIR/$tfile
20428         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20429         RC=$?
20430         if [ $RC -ne 0 ]; then
20431                 error "error, took i_mutex unnecessarily, rc=$?"
20432         fi
20433         rm -f $DIR/$tfile
20434
20435 }
20436 run_test 258b "verify i_mutex security behavior"
20437
20438 test_259() {
20439         local file=$DIR/$tfile
20440         local before
20441         local after
20442
20443         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20444
20445         stack_trap "rm -f $file" EXIT
20446
20447         wait_delete_completed
20448         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20449         echo "before: $before"
20450
20451         $LFS setstripe -i 0 -c 1 $file
20452         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20453         sync_all_data
20454         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20455         echo "after write: $after"
20456
20457 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20458         do_facet ost1 $LCTL set_param fail_loc=0x2301
20459         $TRUNCATE $file 0
20460         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20461         echo "after truncate: $after"
20462
20463         stop ost1
20464         do_facet ost1 $LCTL set_param fail_loc=0
20465         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20466         sleep 2
20467         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20468         echo "after restart: $after"
20469         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20470                 error "missing truncate?"
20471
20472         return 0
20473 }
20474 run_test 259 "crash at delayed truncate"
20475
20476 test_260() {
20477 #define OBD_FAIL_MDC_CLOSE               0x806
20478         $LCTL set_param fail_loc=0x80000806
20479         touch $DIR/$tfile
20480
20481 }
20482 run_test 260 "Check mdc_close fail"
20483
20484 ### Data-on-MDT sanity tests ###
20485 test_270a() {
20486         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20487                 skip "Need MDS version at least 2.10.55 for DoM"
20488
20489         # create DoM file
20490         local dom=$DIR/$tdir/dom_file
20491         local tmp=$DIR/$tdir/tmp_file
20492
20493         mkdir -p $DIR/$tdir
20494
20495         # basic checks for DoM component creation
20496         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20497                 error "Can set MDT layout to non-first entry"
20498
20499         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20500                 error "Can define multiple entries as MDT layout"
20501
20502         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20503
20504         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20505         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20506         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20507
20508         local mdtidx=$($LFS getstripe -m $dom)
20509         local mdtname=MDT$(printf %04x $mdtidx)
20510         local facet=mds$((mdtidx + 1))
20511         local space_check=1
20512
20513         # Skip free space checks with ZFS
20514         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20515
20516         # write
20517         sync
20518         local size_tmp=$((65536 * 3))
20519         local mdtfree1=$(do_facet $facet \
20520                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20521
20522         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20523         # check also direct IO along write
20524         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20525         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20526         sync
20527         cmp $tmp $dom || error "file data is different"
20528         [ $(stat -c%s $dom) == $size_tmp ] ||
20529                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20530         if [ $space_check == 1 ]; then
20531                 local mdtfree2=$(do_facet $facet \
20532                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20533
20534                 # increase in usage from by $size_tmp
20535                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20536                         error "MDT free space wrong after write: " \
20537                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20538         fi
20539
20540         # truncate
20541         local size_dom=10000
20542
20543         $TRUNCATE $dom $size_dom
20544         [ $(stat -c%s $dom) == $size_dom ] ||
20545                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20546         if [ $space_check == 1 ]; then
20547                 mdtfree1=$(do_facet $facet \
20548                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20549                 # decrease in usage from $size_tmp to new $size_dom
20550                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20551                   $(((size_tmp - size_dom) / 1024)) ] ||
20552                         error "MDT free space is wrong after truncate: " \
20553                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20554         fi
20555
20556         # append
20557         cat $tmp >> $dom
20558         sync
20559         size_dom=$((size_dom + size_tmp))
20560         [ $(stat -c%s $dom) == $size_dom ] ||
20561                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20562         if [ $space_check == 1 ]; then
20563                 mdtfree2=$(do_facet $facet \
20564                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20565                 # increase in usage by $size_tmp from previous
20566                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20567                         error "MDT free space is wrong after append: " \
20568                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20569         fi
20570
20571         # delete
20572         rm $dom
20573         if [ $space_check == 1 ]; then
20574                 mdtfree1=$(do_facet $facet \
20575                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20576                 # decrease in usage by $size_dom from previous
20577                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20578                         error "MDT free space is wrong after removal: " \
20579                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20580         fi
20581
20582         # combined striping
20583         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20584                 error "Can't create DoM + OST striping"
20585
20586         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20587         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20588         # check also direct IO along write
20589         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20590         sync
20591         cmp $tmp $dom || error "file data is different"
20592         [ $(stat -c%s $dom) == $size_tmp ] ||
20593                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20594         rm $dom $tmp
20595
20596         return 0
20597 }
20598 run_test 270a "DoM: basic functionality tests"
20599
20600 test_270b() {
20601         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20602                 skip "Need MDS version at least 2.10.55"
20603
20604         local dom=$DIR/$tdir/dom_file
20605         local max_size=1048576
20606
20607         mkdir -p $DIR/$tdir
20608         $LFS setstripe -E $max_size -L mdt $dom
20609
20610         # truncate over the limit
20611         $TRUNCATE $dom $(($max_size + 1)) &&
20612                 error "successful truncate over the maximum size"
20613         # write over the limit
20614         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20615                 error "successful write over the maximum size"
20616         # append over the limit
20617         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20618         echo "12345" >> $dom && error "successful append over the maximum size"
20619         rm $dom
20620
20621         return 0
20622 }
20623 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20624
20625 test_270c() {
20626         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20627                 skip "Need MDS version at least 2.10.55"
20628
20629         mkdir -p $DIR/$tdir
20630         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20631
20632         # check files inherit DoM EA
20633         touch $DIR/$tdir/first
20634         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20635                 error "bad pattern"
20636         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20637                 error "bad stripe count"
20638         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20639                 error "bad stripe size"
20640
20641         # check directory inherits DoM EA and uses it as default
20642         mkdir $DIR/$tdir/subdir
20643         touch $DIR/$tdir/subdir/second
20644         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20645                 error "bad pattern in sub-directory"
20646         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20647                 error "bad stripe count in sub-directory"
20648         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20649                 error "bad stripe size in sub-directory"
20650         return 0
20651 }
20652 run_test 270c "DoM: DoM EA inheritance tests"
20653
20654 test_270d() {
20655         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20656                 skip "Need MDS version at least 2.10.55"
20657
20658         mkdir -p $DIR/$tdir
20659         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20660
20661         # inherit default DoM striping
20662         mkdir $DIR/$tdir/subdir
20663         touch $DIR/$tdir/subdir/f1
20664
20665         # change default directory striping
20666         $LFS setstripe -c 1 $DIR/$tdir/subdir
20667         touch $DIR/$tdir/subdir/f2
20668         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20669                 error "wrong default striping in file 2"
20670         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20671                 error "bad pattern in file 2"
20672         return 0
20673 }
20674 run_test 270d "DoM: change striping from DoM to RAID0"
20675
20676 test_270e() {
20677         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20678                 skip "Need MDS version at least 2.10.55"
20679
20680         mkdir -p $DIR/$tdir/dom
20681         mkdir -p $DIR/$tdir/norm
20682         DOMFILES=20
20683         NORMFILES=10
20684         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20685         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20686
20687         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20688         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20689
20690         # find DoM files by layout
20691         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20692         [ $NUM -eq  $DOMFILES ] ||
20693                 error "lfs find -L: found $NUM, expected $DOMFILES"
20694         echo "Test 1: lfs find 20 DOM files by layout: OK"
20695
20696         # there should be 1 dir with default DOM striping
20697         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20698         [ $NUM -eq  1 ] ||
20699                 error "lfs find -L: found $NUM, expected 1 dir"
20700         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20701
20702         # find DoM files by stripe size
20703         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20704         [ $NUM -eq  $DOMFILES ] ||
20705                 error "lfs find -S: found $NUM, expected $DOMFILES"
20706         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20707
20708         # find files by stripe offset except DoM files
20709         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20710         [ $NUM -eq  $NORMFILES ] ||
20711                 error "lfs find -i: found $NUM, expected $NORMFILES"
20712         echo "Test 5: lfs find no DOM files by stripe index: OK"
20713         return 0
20714 }
20715 run_test 270e "DoM: lfs find with DoM files test"
20716
20717 test_270f() {
20718         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20719                 skip "Need MDS version at least 2.10.55"
20720
20721         local mdtname=${FSNAME}-MDT0000-mdtlov
20722         local dom=$DIR/$tdir/dom_file
20723         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20724                                                 lod.$mdtname.dom_stripesize)
20725         local dom_limit=131072
20726
20727         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20728         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20729                                                 lod.$mdtname.dom_stripesize)
20730         [ ${dom_limit} -eq ${dom_current} ] ||
20731                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20732
20733         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20734         $LFS setstripe -d $DIR/$tdir
20735         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20736                 error "Can't set directory default striping"
20737
20738         # exceed maximum stripe size
20739         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20740                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20741         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20742                 error "Able to create DoM component size more than LOD limit"
20743
20744         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20745         dom_current=$(do_facet mds1 $LCTL get_param -n \
20746                                                 lod.$mdtname.dom_stripesize)
20747         [ 0 -eq ${dom_current} ] ||
20748                 error "Can't set zero DoM stripe limit"
20749         rm $dom
20750
20751         # attempt to create DoM file on server with disabled DoM should
20752         # remove DoM entry from layout and be succeed
20753         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20754                 error "Can't create DoM file (DoM is disabled)"
20755         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20756                 error "File has DoM component while DoM is disabled"
20757         rm $dom
20758
20759         # attempt to create DoM file with only DoM stripe should return error
20760         $LFS setstripe -E $dom_limit -L mdt $dom &&
20761                 error "Able to create DoM-only file while DoM is disabled"
20762
20763         # too low values to be aligned with smallest stripe size 64K
20764         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20765         dom_current=$(do_facet mds1 $LCTL get_param -n \
20766                                                 lod.$mdtname.dom_stripesize)
20767         [ 30000 -eq ${dom_current} ] &&
20768                 error "Can set too small DoM stripe limit"
20769
20770         # 64K is a minimal stripe size in Lustre, expect limit of that size
20771         [ 65536 -eq ${dom_current} ] ||
20772                 error "Limit is not set to 64K but ${dom_current}"
20773
20774         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20775         dom_current=$(do_facet mds1 $LCTL get_param -n \
20776                                                 lod.$mdtname.dom_stripesize)
20777         echo $dom_current
20778         [ 2147483648 -eq ${dom_current} ] &&
20779                 error "Can set too large DoM stripe limit"
20780
20781         do_facet mds1 $LCTL set_param -n \
20782                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20783         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20784                 error "Can't create DoM component size after limit change"
20785         do_facet mds1 $LCTL set_param -n \
20786                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20787         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20788                 error "Can't create DoM file after limit decrease"
20789         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20790                 error "Can create big DoM component after limit decrease"
20791         touch ${dom}_def ||
20792                 error "Can't create file with old default layout"
20793
20794         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20795         return 0
20796 }
20797 run_test 270f "DoM: maximum DoM stripe size checks"
20798
20799 test_270g() {
20800         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20801                 skip "Need MDS version at least 2.13.52"
20802         local dom=$DIR/$tdir/$tfile
20803
20804         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20805         local lodname=${FSNAME}-MDT0000-mdtlov
20806
20807         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20808         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20809         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20810         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20811
20812         local dom_limit=1024
20813         local dom_threshold="50%"
20814
20815         $LFS setstripe -d $DIR/$tdir
20816         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20817                 error "Can't set directory default striping"
20818
20819         do_facet mds1 $LCTL set_param -n \
20820                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20821         # set 0 threshold and create DOM file to change tunable stripesize
20822         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20823         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20824                 error "Failed to create $dom file"
20825         # now tunable dom_cur_stripesize should reach maximum
20826         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20827                                         lod.${lodname}.dom_stripesize_cur_kb)
20828         [[ $dom_current == $dom_limit ]] ||
20829                 error "Current DOM stripesize is not maximum"
20830         rm $dom
20831
20832         # set threshold for further tests
20833         do_facet mds1 $LCTL set_param -n \
20834                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20835         echo "DOM threshold is $dom_threshold free space"
20836         local dom_def
20837         local dom_set
20838         # Spoof bfree to exceed threshold
20839         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20840         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20841         for spfree in 40 20 0 15 30 55; do
20842                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20843                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20844                         error "Failed to create $dom file"
20845                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20846                                         lod.${lodname}.dom_stripesize_cur_kb)
20847                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20848                 [[ $dom_def != $dom_current ]] ||
20849                         error "Default stripe size was not changed"
20850                 if [[ $spfree > 0 ]] ; then
20851                         dom_set=$($LFS getstripe -S $dom)
20852                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20853                                 error "DOM component size is still old"
20854                 else
20855                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20856                                 error "DoM component is set with no free space"
20857                 fi
20858                 rm $dom
20859                 dom_current=$dom_def
20860         done
20861 }
20862 run_test 270g "DoM: default DoM stripe size depends on free space"
20863
20864 test_270h() {
20865         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20866                 skip "Need MDS version at least 2.13.53"
20867
20868         local mdtname=${FSNAME}-MDT0000-mdtlov
20869         local dom=$DIR/$tdir/$tfile
20870         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20871
20872         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20873         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20874
20875         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20876         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20877                 error "can't create OST file"
20878         # mirrored file with DOM entry in the second mirror
20879         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20880                 error "can't create mirror with DoM component"
20881
20882         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20883
20884         # DOM component in the middle and has other enries in the same mirror,
20885         # should succeed but lost DoM component
20886         $LFS setstripe --copy=${dom}_1 $dom ||
20887                 error "Can't create file from OST|DOM mirror layout"
20888         # check new file has no DoM layout after all
20889         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20890                 error "File has DoM component while DoM is disabled"
20891 }
20892 run_test 270h "DoM: DoM stripe removal when disabled on server"
20893
20894 test_271a() {
20895         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20896                 skip "Need MDS version at least 2.10.55"
20897
20898         local dom=$DIR/$tdir/dom
20899
20900         mkdir -p $DIR/$tdir
20901
20902         $LFS setstripe -E 1024K -L mdt $dom
20903
20904         lctl set_param -n mdc.*.stats=clear
20905         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20906         cat $dom > /dev/null
20907         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20908         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20909         ls $dom
20910         rm -f $dom
20911 }
20912 run_test 271a "DoM: data is cached for read after write"
20913
20914 test_271b() {
20915         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20916                 skip "Need MDS version at least 2.10.55"
20917
20918         local dom=$DIR/$tdir/dom
20919
20920         mkdir -p $DIR/$tdir
20921
20922         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20923
20924         lctl set_param -n mdc.*.stats=clear
20925         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20926         cancel_lru_locks mdc
20927         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20928         # second stat to check size is cached on client
20929         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20930         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20931         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20932         rm -f $dom
20933 }
20934 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20935
20936 test_271ba() {
20937         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20938                 skip "Need MDS version at least 2.10.55"
20939
20940         local dom=$DIR/$tdir/dom
20941
20942         mkdir -p $DIR/$tdir
20943
20944         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20945
20946         lctl set_param -n mdc.*.stats=clear
20947         lctl set_param -n osc.*.stats=clear
20948         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20949         cancel_lru_locks mdc
20950         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20951         # second stat to check size is cached on client
20952         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20953         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20954         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20955         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20956         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20957         rm -f $dom
20958 }
20959 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20960
20961
20962 get_mdc_stats() {
20963         local mdtidx=$1
20964         local param=$2
20965         local mdt=MDT$(printf %04x $mdtidx)
20966
20967         if [ -z $param ]; then
20968                 lctl get_param -n mdc.*$mdt*.stats
20969         else
20970                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20971         fi
20972 }
20973
20974 test_271c() {
20975         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20976                 skip "Need MDS version at least 2.10.55"
20977
20978         local dom=$DIR/$tdir/dom
20979
20980         mkdir -p $DIR/$tdir
20981
20982         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20983
20984         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20985         local facet=mds$((mdtidx + 1))
20986
20987         cancel_lru_locks mdc
20988         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20989         createmany -o $dom 1000
20990         lctl set_param -n mdc.*.stats=clear
20991         smalliomany -w $dom 1000 200
20992         get_mdc_stats $mdtidx
20993         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20994         # Each file has 1 open, 1 IO enqueues, total 2000
20995         # but now we have also +1 getxattr for security.capability, total 3000
20996         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20997         unlinkmany $dom 1000
20998
20999         cancel_lru_locks mdc
21000         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21001         createmany -o $dom 1000
21002         lctl set_param -n mdc.*.stats=clear
21003         smalliomany -w $dom 1000 200
21004         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21005         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21006         # for OPEN and IO lock.
21007         [ $((enq - enq_2)) -ge 1000 ] ||
21008                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21009         unlinkmany $dom 1000
21010         return 0
21011 }
21012 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21013
21014 cleanup_271def_tests() {
21015         trap 0
21016         rm -f $1
21017 }
21018
21019 test_271d() {
21020         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21021                 skip "Need MDS version at least 2.10.57"
21022
21023         local dom=$DIR/$tdir/dom
21024         local tmp=$TMP/$tfile
21025         trap "cleanup_271def_tests $tmp" EXIT
21026
21027         mkdir -p $DIR/$tdir
21028
21029         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21030
21031         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21032
21033         cancel_lru_locks mdc
21034         dd if=/dev/urandom of=$tmp bs=1000 count=1
21035         dd if=$tmp of=$dom bs=1000 count=1
21036         cancel_lru_locks mdc
21037
21038         cat /etc/hosts >> $tmp
21039         lctl set_param -n mdc.*.stats=clear
21040
21041         # append data to the same file it should update local page
21042         echo "Append to the same page"
21043         cat /etc/hosts >> $dom
21044         local num=$(get_mdc_stats $mdtidx ost_read)
21045         local ra=$(get_mdc_stats $mdtidx req_active)
21046         local rw=$(get_mdc_stats $mdtidx req_waittime)
21047
21048         [ -z $num ] || error "$num READ RPC occured"
21049         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21050         echo "... DONE"
21051
21052         # compare content
21053         cmp $tmp $dom || error "file miscompare"
21054
21055         cancel_lru_locks mdc
21056         lctl set_param -n mdc.*.stats=clear
21057
21058         echo "Open and read file"
21059         cat $dom > /dev/null
21060         local num=$(get_mdc_stats $mdtidx ost_read)
21061         local ra=$(get_mdc_stats $mdtidx req_active)
21062         local rw=$(get_mdc_stats $mdtidx req_waittime)
21063
21064         [ -z $num ] || error "$num READ RPC occured"
21065         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21066         echo "... DONE"
21067
21068         # compare content
21069         cmp $tmp $dom || error "file miscompare"
21070
21071         return 0
21072 }
21073 run_test 271d "DoM: read on open (1K file in reply buffer)"
21074
21075 test_271f() {
21076         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21077                 skip "Need MDS version at least 2.10.57"
21078
21079         local dom=$DIR/$tdir/dom
21080         local tmp=$TMP/$tfile
21081         trap "cleanup_271def_tests $tmp" EXIT
21082
21083         mkdir -p $DIR/$tdir
21084
21085         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21086
21087         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21088
21089         cancel_lru_locks mdc
21090         dd if=/dev/urandom of=$tmp bs=265000 count=1
21091         dd if=$tmp of=$dom bs=265000 count=1
21092         cancel_lru_locks mdc
21093         cat /etc/hosts >> $tmp
21094         lctl set_param -n mdc.*.stats=clear
21095
21096         echo "Append to the same page"
21097         cat /etc/hosts >> $dom
21098         local num=$(get_mdc_stats $mdtidx ost_read)
21099         local ra=$(get_mdc_stats $mdtidx req_active)
21100         local rw=$(get_mdc_stats $mdtidx req_waittime)
21101
21102         [ -z $num ] || error "$num READ RPC occured"
21103         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21104         echo "... DONE"
21105
21106         # compare content
21107         cmp $tmp $dom || error "file miscompare"
21108
21109         cancel_lru_locks mdc
21110         lctl set_param -n mdc.*.stats=clear
21111
21112         echo "Open and read file"
21113         cat $dom > /dev/null
21114         local num=$(get_mdc_stats $mdtidx ost_read)
21115         local ra=$(get_mdc_stats $mdtidx req_active)
21116         local rw=$(get_mdc_stats $mdtidx req_waittime)
21117
21118         [ -z $num ] && num=0
21119         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21120         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21121         echo "... DONE"
21122
21123         # compare content
21124         cmp $tmp $dom || error "file miscompare"
21125
21126         return 0
21127 }
21128 run_test 271f "DoM: read on open (200K file and read tail)"
21129
21130 test_271g() {
21131         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21132                 skip "Skipping due to old client or server version"
21133
21134         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21135         # to get layout
21136         $CHECKSTAT -t file $DIR1/$tfile
21137
21138         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21139         MULTIOP_PID=$!
21140         sleep 1
21141         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21142         $LCTL set_param fail_loc=0x80000314
21143         rm $DIR1/$tfile || error "Unlink fails"
21144         RC=$?
21145         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21146         [ $RC -eq 0 ] || error "Failed write to stale object"
21147 }
21148 run_test 271g "Discard DoM data vs client flush race"
21149
21150 test_272a() {
21151         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21152                 skip "Need MDS version at least 2.11.50"
21153
21154         local dom=$DIR/$tdir/dom
21155         mkdir -p $DIR/$tdir
21156
21157         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21158         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21159                 error "failed to write data into $dom"
21160         local old_md5=$(md5sum $dom)
21161
21162         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21163                 error "failed to migrate to the same DoM component"
21164
21165         local new_md5=$(md5sum $dom)
21166
21167         [ "$old_md5" == "$new_md5" ] ||
21168                 error "md5sum differ: $old_md5, $new_md5"
21169
21170         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21171                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21172 }
21173 run_test 272a "DoM migration: new layout with the same DOM component"
21174
21175 test_272b() {
21176         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21177                 skip "Need MDS version at least 2.11.50"
21178
21179         local dom=$DIR/$tdir/dom
21180         mkdir -p $DIR/$tdir
21181         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21182
21183         local mdtidx=$($LFS getstripe -m $dom)
21184         local mdtname=MDT$(printf %04x $mdtidx)
21185         local facet=mds$((mdtidx + 1))
21186
21187         local mdtfree1=$(do_facet $facet \
21188                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21189         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21190                 error "failed to write data into $dom"
21191         local old_md5=$(md5sum $dom)
21192         cancel_lru_locks mdc
21193         local mdtfree1=$(do_facet $facet \
21194                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21195
21196         $LFS migrate -c2 $dom ||
21197                 error "failed to migrate to the new composite layout"
21198         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21199                 error "MDT stripe was not removed"
21200
21201         cancel_lru_locks mdc
21202         local new_md5=$(md5sum $dom)
21203         [ "$old_md5" == "$new_md5" ] ||
21204                 error "$old_md5 != $new_md5"
21205
21206         # Skip free space checks with ZFS
21207         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21208                 local mdtfree2=$(do_facet $facet \
21209                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21210                 [ $mdtfree2 -gt $mdtfree1 ] ||
21211                         error "MDT space is not freed after migration"
21212         fi
21213         return 0
21214 }
21215 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21216
21217 test_272c() {
21218         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21219                 skip "Need MDS version at least 2.11.50"
21220
21221         local dom=$DIR/$tdir/$tfile
21222         mkdir -p $DIR/$tdir
21223         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21224
21225         local mdtidx=$($LFS getstripe -m $dom)
21226         local mdtname=MDT$(printf %04x $mdtidx)
21227         local facet=mds$((mdtidx + 1))
21228
21229         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21230                 error "failed to write data into $dom"
21231         local old_md5=$(md5sum $dom)
21232         cancel_lru_locks mdc
21233         local mdtfree1=$(do_facet $facet \
21234                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21235
21236         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21237                 error "failed to migrate to the new composite layout"
21238         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21239                 error "MDT stripe was not removed"
21240
21241         cancel_lru_locks mdc
21242         local new_md5=$(md5sum $dom)
21243         [ "$old_md5" == "$new_md5" ] ||
21244                 error "$old_md5 != $new_md5"
21245
21246         # Skip free space checks with ZFS
21247         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21248                 local mdtfree2=$(do_facet $facet \
21249                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21250                 [ $mdtfree2 -gt $mdtfree1 ] ||
21251                         error "MDS space is not freed after migration"
21252         fi
21253         return 0
21254 }
21255 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21256
21257 test_272d() {
21258         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21259                 skip "Need MDS version at least 2.12.55"
21260
21261         local dom=$DIR/$tdir/$tfile
21262         mkdir -p $DIR/$tdir
21263         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21264
21265         local mdtidx=$($LFS getstripe -m $dom)
21266         local mdtname=MDT$(printf %04x $mdtidx)
21267         local facet=mds$((mdtidx + 1))
21268
21269         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21270                 error "failed to write data into $dom"
21271         local old_md5=$(md5sum $dom)
21272         cancel_lru_locks mdc
21273         local mdtfree1=$(do_facet $facet \
21274                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21275
21276         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21277                 error "failed mirroring to the new composite layout"
21278         $LFS mirror resync $dom ||
21279                 error "failed mirror resync"
21280         $LFS mirror split --mirror-id 1 -d $dom ||
21281                 error "failed mirror split"
21282
21283         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21284                 error "MDT stripe was not removed"
21285
21286         cancel_lru_locks mdc
21287         local new_md5=$(md5sum $dom)
21288         [ "$old_md5" == "$new_md5" ] ||
21289                 error "$old_md5 != $new_md5"
21290
21291         # Skip free space checks with ZFS
21292         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21293                 local mdtfree2=$(do_facet $facet \
21294                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21295                 [ $mdtfree2 -gt $mdtfree1 ] ||
21296                         error "MDS space is not freed after DOM mirror deletion"
21297         fi
21298         return 0
21299 }
21300 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21301
21302 test_272e() {
21303         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21304                 skip "Need MDS version at least 2.12.55"
21305
21306         local dom=$DIR/$tdir/$tfile
21307         mkdir -p $DIR/$tdir
21308         $LFS setstripe -c 2 $dom
21309
21310         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21311                 error "failed to write data into $dom"
21312         local old_md5=$(md5sum $dom)
21313         cancel_lru_locks mdc
21314
21315         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21316                 error "failed mirroring to the DOM layout"
21317         $LFS mirror resync $dom ||
21318                 error "failed mirror resync"
21319         $LFS mirror split --mirror-id 1 -d $dom ||
21320                 error "failed mirror split"
21321
21322         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21323                 error "MDT stripe was not removed"
21324
21325         cancel_lru_locks mdc
21326         local new_md5=$(md5sum $dom)
21327         [ "$old_md5" == "$new_md5" ] ||
21328                 error "$old_md5 != $new_md5"
21329
21330         return 0
21331 }
21332 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21333
21334 test_272f() {
21335         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21336                 skip "Need MDS version at least 2.12.55"
21337
21338         local dom=$DIR/$tdir/$tfile
21339         mkdir -p $DIR/$tdir
21340         $LFS setstripe -c 2 $dom
21341
21342         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21343                 error "failed to write data into $dom"
21344         local old_md5=$(md5sum $dom)
21345         cancel_lru_locks mdc
21346
21347         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21348                 error "failed migrating to the DOM file"
21349
21350         cancel_lru_locks mdc
21351         local new_md5=$(md5sum $dom)
21352         [ "$old_md5" != "$new_md5" ] &&
21353                 error "$old_md5 != $new_md5"
21354
21355         return 0
21356 }
21357 run_test 272f "DoM migration: OST-striped file to DOM file"
21358
21359 test_273a() {
21360         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21361                 skip "Need MDS version at least 2.11.50"
21362
21363         # Layout swap cannot be done if either file has DOM component,
21364         # this will never be supported, migration should be used instead
21365
21366         local dom=$DIR/$tdir/$tfile
21367         mkdir -p $DIR/$tdir
21368
21369         $LFS setstripe -c2 ${dom}_plain
21370         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21371         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21372                 error "can swap layout with DoM component"
21373         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21374                 error "can swap layout with DoM component"
21375
21376         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21377         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21378                 error "can swap layout with DoM component"
21379         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21380                 error "can swap layout with DoM component"
21381         return 0
21382 }
21383 run_test 273a "DoM: layout swapping should fail with DOM"
21384
21385 test_273b() {
21386         mkdir -p $DIR/$tdir
21387         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
21388
21389 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
21390         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
21391
21392         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
21393 }
21394 run_test 273b "DoM: race writeback and object destroy"
21395
21396 test_275() {
21397         remote_ost_nodsh && skip "remote OST with nodsh"
21398         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21399                 skip "Need OST version >= 2.10.57"
21400
21401         local file=$DIR/$tfile
21402         local oss
21403
21404         oss=$(comma_list $(osts_nodes))
21405
21406         dd if=/dev/urandom of=$file bs=1M count=2 ||
21407                 error "failed to create a file"
21408         cancel_lru_locks osc
21409
21410         #lock 1
21411         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21412                 error "failed to read a file"
21413
21414 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21415         $LCTL set_param fail_loc=0x8000031f
21416
21417         cancel_lru_locks osc &
21418         sleep 1
21419
21420 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21421         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21422         #IO takes another lock, but matches the PENDING one
21423         #and places it to the IO RPC
21424         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21425                 error "failed to read a file with PENDING lock"
21426 }
21427 run_test 275 "Read on a canceled duplicate lock"
21428
21429 test_276() {
21430         remote_ost_nodsh && skip "remote OST with nodsh"
21431         local pid
21432
21433         do_facet ost1 "(while true; do \
21434                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21435                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21436         pid=$!
21437
21438         for LOOP in $(seq 20); do
21439                 stop ost1
21440                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21441         done
21442         kill -9 $pid
21443         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21444                 rm $TMP/sanity_276_pid"
21445 }
21446 run_test 276 "Race between mount and obd_statfs"
21447
21448 test_277() {
21449         $LCTL set_param ldlm.namespaces.*.lru_size=0
21450         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21451         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21452                         grep ^used_mb | awk '{print $2}')
21453         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21454         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21455                 oflag=direct conv=notrunc
21456         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21457                         grep ^used_mb | awk '{print $2}')
21458         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21459 }
21460 run_test 277 "Direct IO shall drop page cache"
21461
21462 test_278() {
21463         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21465         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21466                 skip "needs the same host for mdt1 mdt2" && return
21467
21468         local pid1
21469         local pid2
21470
21471 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21472         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21473         stop mds2 &
21474         pid2=$!
21475
21476         stop mds1
21477
21478         echo "Starting MDTs"
21479         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21480         wait $pid2
21481 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21482 #will return NULL
21483         do_facet mds2 $LCTL set_param fail_loc=0
21484
21485         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21486         wait_recovery_complete mds2
21487 }
21488 run_test 278 "Race starting MDS between MDTs stop/start"
21489
21490 test_280() {
21491         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21492                 skip "Need MGS version at least 2.13.52"
21493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21494         combined_mgs_mds || skip "needs combined MGS/MDT"
21495
21496         umount_client $MOUNT
21497 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21498         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21499
21500         mount_client $MOUNT &
21501         sleep 1
21502         stop mgs || error "stop mgs failed"
21503         #for a race mgs would crash
21504         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21505         # make sure we unmount client before remounting
21506         wait
21507         umount_client $MOUNT
21508         mount_client $MOUNT || error "mount client failed"
21509 }
21510 run_test 280 "Race between MGS umount and client llog processing"
21511
21512 cleanup_test_300() {
21513         trap 0
21514         umask $SAVE_UMASK
21515 }
21516 test_striped_dir() {
21517         local mdt_index=$1
21518         local stripe_count
21519         local stripe_index
21520
21521         mkdir -p $DIR/$tdir
21522
21523         SAVE_UMASK=$(umask)
21524         trap cleanup_test_300 RETURN EXIT
21525
21526         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21527                                                 $DIR/$tdir/striped_dir ||
21528                 error "set striped dir error"
21529
21530         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21531         [ "$mode" = "755" ] || error "expect 755 got $mode"
21532
21533         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21534                 error "getdirstripe failed"
21535         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21536         if [ "$stripe_count" != "2" ]; then
21537                 error "1:stripe_count is $stripe_count, expect 2"
21538         fi
21539         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21540         if [ "$stripe_count" != "2" ]; then
21541                 error "2:stripe_count is $stripe_count, expect 2"
21542         fi
21543
21544         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21545         if [ "$stripe_index" != "$mdt_index" ]; then
21546                 error "stripe_index is $stripe_index, expect $mdt_index"
21547         fi
21548
21549         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21550                 error "nlink error after create striped dir"
21551
21552         mkdir $DIR/$tdir/striped_dir/a
21553         mkdir $DIR/$tdir/striped_dir/b
21554
21555         stat $DIR/$tdir/striped_dir/a ||
21556                 error "create dir under striped dir failed"
21557         stat $DIR/$tdir/striped_dir/b ||
21558                 error "create dir under striped dir failed"
21559
21560         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21561                 error "nlink error after mkdir"
21562
21563         rmdir $DIR/$tdir/striped_dir/a
21564         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21565                 error "nlink error after rmdir"
21566
21567         rmdir $DIR/$tdir/striped_dir/b
21568         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21569                 error "nlink error after rmdir"
21570
21571         chattr +i $DIR/$tdir/striped_dir
21572         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21573                 error "immutable flags not working under striped dir!"
21574         chattr -i $DIR/$tdir/striped_dir
21575
21576         rmdir $DIR/$tdir/striped_dir ||
21577                 error "rmdir striped dir error"
21578
21579         cleanup_test_300
21580
21581         true
21582 }
21583
21584 test_300a() {
21585         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21586                 skip "skipped for lustre < 2.7.0"
21587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21588         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21589
21590         test_striped_dir 0 || error "failed on striped dir on MDT0"
21591         test_striped_dir 1 || error "failed on striped dir on MDT0"
21592 }
21593 run_test 300a "basic striped dir sanity test"
21594
21595 test_300b() {
21596         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21597                 skip "skipped for lustre < 2.7.0"
21598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21599         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21600
21601         local i
21602         local mtime1
21603         local mtime2
21604         local mtime3
21605
21606         test_mkdir $DIR/$tdir || error "mkdir fail"
21607         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21608                 error "set striped dir error"
21609         for i in {0..9}; do
21610                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21611                 sleep 1
21612                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21613                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21614                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21615                 sleep 1
21616                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21617                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21618                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21619         done
21620         true
21621 }
21622 run_test 300b "check ctime/mtime for striped dir"
21623
21624 test_300c() {
21625         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21626                 skip "skipped for lustre < 2.7.0"
21627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21628         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21629
21630         local file_count
21631
21632         mkdir -p $DIR/$tdir
21633         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21634                 error "set striped dir error"
21635
21636         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21637                 error "chown striped dir failed"
21638
21639         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21640                 error "create 5k files failed"
21641
21642         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21643
21644         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21645
21646         rm -rf $DIR/$tdir
21647 }
21648 run_test 300c "chown && check ls under striped directory"
21649
21650 test_300d() {
21651         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21652                 skip "skipped for lustre < 2.7.0"
21653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21654         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21655
21656         local stripe_count
21657         local file
21658
21659         mkdir -p $DIR/$tdir
21660         $LFS setstripe -c 2 $DIR/$tdir
21661
21662         #local striped directory
21663         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21664                 error "set striped dir error"
21665         #look at the directories for debug purposes
21666         ls -l $DIR/$tdir
21667         $LFS getdirstripe $DIR/$tdir
21668         ls -l $DIR/$tdir/striped_dir
21669         $LFS getdirstripe $DIR/$tdir/striped_dir
21670         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21671                 error "create 10 files failed"
21672
21673         #remote striped directory
21674         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21675                 error "set striped dir error"
21676         #look at the directories for debug purposes
21677         ls -l $DIR/$tdir
21678         $LFS getdirstripe $DIR/$tdir
21679         ls -l $DIR/$tdir/remote_striped_dir
21680         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21681         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21682                 error "create 10 files failed"
21683
21684         for file in $(find $DIR/$tdir); do
21685                 stripe_count=$($LFS getstripe -c $file)
21686                 [ $stripe_count -eq 2 ] ||
21687                         error "wrong stripe $stripe_count for $file"
21688         done
21689
21690         rm -rf $DIR/$tdir
21691 }
21692 run_test 300d "check default stripe under striped directory"
21693
21694 test_300e() {
21695         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21696                 skip "Need MDS version at least 2.7.55"
21697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21698         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21699
21700         local stripe_count
21701         local file
21702
21703         mkdir -p $DIR/$tdir
21704
21705         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21706                 error "set striped dir error"
21707
21708         touch $DIR/$tdir/striped_dir/a
21709         touch $DIR/$tdir/striped_dir/b
21710         touch $DIR/$tdir/striped_dir/c
21711
21712         mkdir $DIR/$tdir/striped_dir/dir_a
21713         mkdir $DIR/$tdir/striped_dir/dir_b
21714         mkdir $DIR/$tdir/striped_dir/dir_c
21715
21716         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21717                 error "set striped adir under striped dir error"
21718
21719         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21720                 error "set striped bdir under striped dir error"
21721
21722         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21723                 error "set striped cdir under striped dir error"
21724
21725         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21726                 error "rename dir under striped dir fails"
21727
21728         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21729                 error "rename dir under different stripes fails"
21730
21731         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21732                 error "rename file under striped dir should succeed"
21733
21734         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21735                 error "rename dir under striped dir should succeed"
21736
21737         rm -rf $DIR/$tdir
21738 }
21739 run_test 300e "check rename under striped directory"
21740
21741 test_300f() {
21742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21743         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21744         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21745                 skip "Need MDS version at least 2.7.55"
21746
21747         local stripe_count
21748         local file
21749
21750         rm -rf $DIR/$tdir
21751         mkdir -p $DIR/$tdir
21752
21753         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21754                 error "set striped dir error"
21755
21756         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21757                 error "set striped dir error"
21758
21759         touch $DIR/$tdir/striped_dir/a
21760         mkdir $DIR/$tdir/striped_dir/dir_a
21761         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21762                 error "create striped dir under striped dir fails"
21763
21764         touch $DIR/$tdir/striped_dir1/b
21765         mkdir $DIR/$tdir/striped_dir1/dir_b
21766         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21767                 error "create striped dir under striped dir fails"
21768
21769         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21770                 error "rename dir under different striped dir should fail"
21771
21772         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21773                 error "rename striped dir under diff striped dir should fail"
21774
21775         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21776                 error "rename file under diff striped dirs fails"
21777
21778         rm -rf $DIR/$tdir
21779 }
21780 run_test 300f "check rename cross striped directory"
21781
21782 test_300_check_default_striped_dir()
21783 {
21784         local dirname=$1
21785         local default_count=$2
21786         local default_index=$3
21787         local stripe_count
21788         local stripe_index
21789         local dir_stripe_index
21790         local dir
21791
21792         echo "checking $dirname $default_count $default_index"
21793         $LFS setdirstripe -D -c $default_count -i $default_index \
21794                                 -H all_char $DIR/$tdir/$dirname ||
21795                 error "set default stripe on striped dir error"
21796         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21797         [ $stripe_count -eq $default_count ] ||
21798                 error "expect $default_count get $stripe_count for $dirname"
21799
21800         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21801         [ $stripe_index -eq $default_index ] ||
21802                 error "expect $default_index get $stripe_index for $dirname"
21803
21804         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21805                                                 error "create dirs failed"
21806
21807         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21808         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21809         for dir in $(find $DIR/$tdir/$dirname/*); do
21810                 stripe_count=$($LFS getdirstripe -c $dir)
21811                 (( $stripe_count == $default_count )) ||
21812                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
21813                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
21814                 error "stripe count $default_count != $stripe_count for $dir"
21815
21816                 stripe_index=$($LFS getdirstripe -i $dir)
21817                 [ $default_index -eq -1 ] ||
21818                         [ $stripe_index -eq $default_index ] ||
21819                         error "$stripe_index != $default_index for $dir"
21820
21821                 #check default stripe
21822                 stripe_count=$($LFS getdirstripe -D -c $dir)
21823                 [ $stripe_count -eq $default_count ] ||
21824                 error "default count $default_count != $stripe_count for $dir"
21825
21826                 stripe_index=$($LFS getdirstripe -D -i $dir)
21827                 [ $stripe_index -eq $default_index ] ||
21828                 error "default index $default_index != $stripe_index for $dir"
21829         done
21830         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21831 }
21832
21833 test_300g() {
21834         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21835         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21836                 skip "Need MDS version at least 2.7.55"
21837
21838         local dir
21839         local stripe_count
21840         local stripe_index
21841
21842         mkdir $DIR/$tdir
21843         mkdir $DIR/$tdir/normal_dir
21844
21845         #Checking when client cache stripe index
21846         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21847         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21848                 error "create striped_dir failed"
21849
21850         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21851                 error "create dir0 fails"
21852         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21853         [ $stripe_index -eq 0 ] ||
21854                 error "dir0 expect index 0 got $stripe_index"
21855
21856         mkdir $DIR/$tdir/striped_dir/dir1 ||
21857                 error "create dir1 fails"
21858         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21859         [ $stripe_index -eq 1 ] ||
21860                 error "dir1 expect index 1 got $stripe_index"
21861
21862         #check default stripe count/stripe index
21863         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21864         test_300_check_default_striped_dir normal_dir 1 0
21865         test_300_check_default_striped_dir normal_dir -1 1
21866         test_300_check_default_striped_dir normal_dir 2 -1
21867
21868         #delete default stripe information
21869         echo "delete default stripeEA"
21870         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21871                 error "set default stripe on striped dir error"
21872
21873         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21874         for dir in $(find $DIR/$tdir/normal_dir/*); do
21875                 stripe_count=$($LFS getdirstripe -c $dir)
21876                 [ $stripe_count -eq 0 ] ||
21877                         error "expect 1 get $stripe_count for $dir"
21878                 stripe_index=$($LFS getdirstripe -i $dir)
21879                 [ $stripe_index -eq 0 ] ||
21880                         error "expect 0 get $stripe_index for $dir"
21881         done
21882 }
21883 run_test 300g "check default striped directory for normal directory"
21884
21885 test_300h() {
21886         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21887         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21888                 skip "Need MDS version at least 2.7.55"
21889
21890         local dir
21891         local stripe_count
21892
21893         mkdir $DIR/$tdir
21894         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21895                 error "set striped dir error"
21896
21897         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21898         test_300_check_default_striped_dir striped_dir 1 0
21899         test_300_check_default_striped_dir striped_dir -1 1
21900         test_300_check_default_striped_dir striped_dir 2 -1
21901
21902         #delete default stripe information
21903         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21904                 error "set default stripe on striped dir error"
21905
21906         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21907         for dir in $(find $DIR/$tdir/striped_dir/*); do
21908                 stripe_count=$($LFS getdirstripe -c $dir)
21909                 [ $stripe_count -eq 0 ] ||
21910                         error "expect 1 get $stripe_count for $dir"
21911         done
21912 }
21913 run_test 300h "check default striped directory for striped directory"
21914
21915 test_300i() {
21916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21917         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21918         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21919                 skip "Need MDS version at least 2.7.55"
21920
21921         local stripe_count
21922         local file
21923
21924         mkdir $DIR/$tdir
21925
21926         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21927                 error "set striped dir error"
21928
21929         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21930                 error "create files under striped dir failed"
21931
21932         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21933                 error "set striped hashdir error"
21934
21935         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21936                 error "create dir0 under hash dir failed"
21937         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21938                 error "create dir1 under hash dir failed"
21939
21940         # unfortunately, we need to umount to clear dir layout cache for now
21941         # once we fully implement dir layout, we can drop this
21942         umount_client $MOUNT || error "umount failed"
21943         mount_client $MOUNT || error "mount failed"
21944
21945         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21946         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21947         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21948
21949         #set the stripe to be unknown hash type
21950         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21951         $LCTL set_param fail_loc=0x1901
21952         for ((i = 0; i < 10; i++)); do
21953                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21954                         error "stat f-$i failed"
21955                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21956         done
21957
21958         touch $DIR/$tdir/striped_dir/f0 &&
21959                 error "create under striped dir with unknown hash should fail"
21960
21961         $LCTL set_param fail_loc=0
21962
21963         umount_client $MOUNT || error "umount failed"
21964         mount_client $MOUNT || error "mount failed"
21965
21966         return 0
21967 }
21968 run_test 300i "client handle unknown hash type striped directory"
21969
21970 test_300j() {
21971         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21973         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21974                 skip "Need MDS version at least 2.7.55"
21975
21976         local stripe_count
21977         local file
21978
21979         mkdir $DIR/$tdir
21980
21981         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21982         $LCTL set_param fail_loc=0x1702
21983         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21984                 error "set striped dir error"
21985
21986         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21987                 error "create files under striped dir failed"
21988
21989         $LCTL set_param fail_loc=0
21990
21991         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21992
21993         return 0
21994 }
21995 run_test 300j "test large update record"
21996
21997 test_300k() {
21998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21999         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22000         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22001                 skip "Need MDS version at least 2.7.55"
22002
22003         # this test needs a huge transaction
22004         local kb
22005         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22006              osd*.$FSNAME-MDT0000.kbytestotal")
22007         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22008
22009         local stripe_count
22010         local file
22011
22012         mkdir $DIR/$tdir
22013
22014         #define OBD_FAIL_LARGE_STRIPE   0x1703
22015         $LCTL set_param fail_loc=0x1703
22016         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22017                 error "set striped dir error"
22018         $LCTL set_param fail_loc=0
22019
22020         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22021                 error "getstripeddir fails"
22022         rm -rf $DIR/$tdir/striped_dir ||
22023                 error "unlink striped dir fails"
22024
22025         return 0
22026 }
22027 run_test 300k "test large striped directory"
22028
22029 test_300l() {
22030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22031         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22032         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22033                 skip "Need MDS version at least 2.7.55"
22034
22035         local stripe_index
22036
22037         test_mkdir -p $DIR/$tdir/striped_dir
22038         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22039                         error "chown $RUNAS_ID failed"
22040         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22041                 error "set default striped dir failed"
22042
22043         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22044         $LCTL set_param fail_loc=0x80000158
22045         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22046
22047         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22048         [ $stripe_index -eq 1 ] ||
22049                 error "expect 1 get $stripe_index for $dir"
22050 }
22051 run_test 300l "non-root user to create dir under striped dir with stale layout"
22052
22053 test_300m() {
22054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22055         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22056         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22057                 skip "Need MDS version at least 2.7.55"
22058
22059         mkdir -p $DIR/$tdir/striped_dir
22060         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22061                 error "set default stripes dir error"
22062
22063         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22064
22065         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22066         [ $stripe_count -eq 0 ] ||
22067                         error "expect 0 get $stripe_count for a"
22068
22069         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22070                 error "set default stripes dir error"
22071
22072         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22073
22074         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22075         [ $stripe_count -eq 0 ] ||
22076                         error "expect 0 get $stripe_count for b"
22077
22078         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22079                 error "set default stripes dir error"
22080
22081         mkdir $DIR/$tdir/striped_dir/c &&
22082                 error "default stripe_index is invalid, mkdir c should fails"
22083
22084         rm -rf $DIR/$tdir || error "rmdir fails"
22085 }
22086 run_test 300m "setstriped directory on single MDT FS"
22087
22088 cleanup_300n() {
22089         local list=$(comma_list $(mdts_nodes))
22090
22091         trap 0
22092         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22093 }
22094
22095 test_300n() {
22096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22097         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22098         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22099                 skip "Need MDS version at least 2.7.55"
22100         remote_mds_nodsh && skip "remote MDS with nodsh"
22101
22102         local stripe_index
22103         local list=$(comma_list $(mdts_nodes))
22104
22105         trap cleanup_300n RETURN EXIT
22106         mkdir -p $DIR/$tdir
22107         chmod 777 $DIR/$tdir
22108         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22109                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22110                 error "create striped dir succeeds with gid=0"
22111
22112         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22113         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22114                 error "create striped dir fails with gid=-1"
22115
22116         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22117         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22118                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22119                 error "set default striped dir succeeds with gid=0"
22120
22121
22122         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22123         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22124                 error "set default striped dir fails with gid=-1"
22125
22126
22127         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22128         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22129                                         error "create test_dir fails"
22130         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22131                                         error "create test_dir1 fails"
22132         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22133                                         error "create test_dir2 fails"
22134         cleanup_300n
22135 }
22136 run_test 300n "non-root user to create dir under striped dir with default EA"
22137
22138 test_300o() {
22139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22140         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22141         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22142                 skip "Need MDS version at least 2.7.55"
22143
22144         local numfree1
22145         local numfree2
22146
22147         mkdir -p $DIR/$tdir
22148
22149         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22150         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22151         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22152                 skip "not enough free inodes $numfree1 $numfree2"
22153         fi
22154
22155         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22156         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22157         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22158                 skip "not enough free space $numfree1 $numfree2"
22159         fi
22160
22161         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22162                 error "setdirstripe fails"
22163
22164         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22165                 error "create dirs fails"
22166
22167         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22168         ls $DIR/$tdir/striped_dir > /dev/null ||
22169                 error "ls striped dir fails"
22170         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22171                 error "unlink big striped dir fails"
22172 }
22173 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22174
22175 test_300p() {
22176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22177         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22178         remote_mds_nodsh && skip "remote MDS with nodsh"
22179
22180         mkdir -p $DIR/$tdir
22181
22182         #define OBD_FAIL_OUT_ENOSPC     0x1704
22183         do_facet mds2 lctl set_param fail_loc=0x80001704
22184         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22185                  && error "create striped directory should fail"
22186
22187         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22188
22189         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22190         true
22191 }
22192 run_test 300p "create striped directory without space"
22193
22194 test_300q() {
22195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22196         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22197
22198         local fd=$(free_fd)
22199         local cmd="exec $fd<$tdir"
22200         cd $DIR
22201         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22202         eval $cmd
22203         cmd="exec $fd<&-"
22204         trap "eval $cmd" EXIT
22205         cd $tdir || error "cd $tdir fails"
22206         rmdir  ../$tdir || error "rmdir $tdir fails"
22207         mkdir local_dir && error "create dir succeeds"
22208         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22209         eval $cmd
22210         return 0
22211 }
22212 run_test 300q "create remote directory under orphan directory"
22213
22214 test_300r() {
22215         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22216                 skip "Need MDS version at least 2.7.55" && return
22217         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22218
22219         mkdir $DIR/$tdir
22220
22221         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22222                 error "set striped dir error"
22223
22224         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22225                 error "getstripeddir fails"
22226
22227         local stripe_count
22228         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22229                       awk '/lmv_stripe_count:/ { print $2 }')
22230
22231         [ $MDSCOUNT -ne $stripe_count ] &&
22232                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22233
22234         rm -rf $DIR/$tdir/striped_dir ||
22235                 error "unlink striped dir fails"
22236 }
22237 run_test 300r "test -1 striped directory"
22238
22239 test_300s_helper() {
22240         local count=$1
22241
22242         local stripe_dir=$DIR/$tdir/striped_dir.$count
22243
22244         $LFS mkdir -c $count $stripe_dir ||
22245                 error "lfs mkdir -c error"
22246
22247         $LFS getdirstripe $stripe_dir ||
22248                 error "lfs getdirstripe fails"
22249
22250         local stripe_count
22251         stripe_count=$($LFS getdirstripe $stripe_dir |
22252                       awk '/lmv_stripe_count:/ { print $2 }')
22253
22254         [ $count -ne $stripe_count ] &&
22255                 error_noexit "bad stripe count $stripe_count expected $count"
22256
22257         local dupe_stripes
22258         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22259                 awk '/0x/ {count[$1] += 1}; END {
22260                         for (idx in count) {
22261                                 if (count[idx]>1) {
22262                                         print "index " idx " count " count[idx]
22263                                 }
22264                         }
22265                 }')
22266
22267         if [[ -n "$dupe_stripes" ]] ; then
22268                 lfs getdirstripe $stripe_dir
22269                 error_noexit "Dupe MDT above: $dupe_stripes "
22270         fi
22271
22272         rm -rf $stripe_dir ||
22273                 error_noexit "unlink $stripe_dir fails"
22274 }
22275
22276 test_300s() {
22277         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22278                 skip "Need MDS version at least 2.7.55" && return
22279         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22280
22281         mkdir $DIR/$tdir
22282         for count in $(seq 2 $MDSCOUNT); do
22283                 test_300s_helper $count
22284         done
22285 }
22286 run_test 300s "test lfs mkdir -c without -i"
22287
22288
22289 prepare_remote_file() {
22290         mkdir $DIR/$tdir/src_dir ||
22291                 error "create remote source failed"
22292
22293         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22294                  error "cp to remote source failed"
22295         touch $DIR/$tdir/src_dir/a
22296
22297         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22298                 error "create remote target dir failed"
22299
22300         touch $DIR/$tdir/tgt_dir/b
22301
22302         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22303                 error "rename dir cross MDT failed!"
22304
22305         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22306                 error "src_child still exists after rename"
22307
22308         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22309                 error "missing file(a) after rename"
22310
22311         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22312                 error "diff after rename"
22313 }
22314
22315 test_310a() {
22316         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22318
22319         local remote_file=$DIR/$tdir/tgt_dir/b
22320
22321         mkdir -p $DIR/$tdir
22322
22323         prepare_remote_file || error "prepare remote file failed"
22324
22325         #open-unlink file
22326         $OPENUNLINK $remote_file $remote_file ||
22327                 error "openunlink $remote_file failed"
22328         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22329 }
22330 run_test 310a "open unlink remote file"
22331
22332 test_310b() {
22333         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22335
22336         local remote_file=$DIR/$tdir/tgt_dir/b
22337
22338         mkdir -p $DIR/$tdir
22339
22340         prepare_remote_file || error "prepare remote file failed"
22341
22342         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22343         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22344         $CHECKSTAT -t file $remote_file || error "check file failed"
22345 }
22346 run_test 310b "unlink remote file with multiple links while open"
22347
22348 test_310c() {
22349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22350         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22351
22352         local remote_file=$DIR/$tdir/tgt_dir/b
22353
22354         mkdir -p $DIR/$tdir
22355
22356         prepare_remote_file || error "prepare remote file failed"
22357
22358         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22359         multiop_bg_pause $remote_file O_uc ||
22360                         error "mulitop failed for remote file"
22361         MULTIPID=$!
22362         $MULTIOP $DIR/$tfile Ouc
22363         kill -USR1 $MULTIPID
22364         wait $MULTIPID
22365 }
22366 run_test 310c "open-unlink remote file with multiple links"
22367
22368 #LU-4825
22369 test_311() {
22370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22371         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22372         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22373                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22374         remote_mds_nodsh && skip "remote MDS with nodsh"
22375
22376         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22377         local mdts=$(comma_list $(mdts_nodes))
22378
22379         mkdir -p $DIR/$tdir
22380         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22381         createmany -o $DIR/$tdir/$tfile. 1000
22382
22383         # statfs data is not real time, let's just calculate it
22384         old_iused=$((old_iused + 1000))
22385
22386         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22387                         osp.*OST0000*MDT0000.create_count")
22388         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22389                                 osp.*OST0000*MDT0000.max_create_count")
22390         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22391
22392         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22393         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22394         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22395
22396         unlinkmany $DIR/$tdir/$tfile. 1000
22397
22398         do_nodes $mdts "$LCTL set_param -n \
22399                         osp.*OST0000*.max_create_count=$max_count"
22400         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22401                 do_nodes $mdts "$LCTL set_param -n \
22402                                 osp.*OST0000*.create_count=$count"
22403         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22404                         grep "=0" && error "create_count is zero"
22405
22406         local new_iused
22407         for i in $(seq 120); do
22408                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22409                 # system may be too busy to destroy all objs in time, use
22410                 # a somewhat small value to not fail autotest
22411                 [ $((old_iused - new_iused)) -gt 400 ] && break
22412                 sleep 1
22413         done
22414
22415         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22416         [ $((old_iused - new_iused)) -gt 400 ] ||
22417                 error "objs not destroyed after unlink"
22418 }
22419 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22420
22421 zfs_oid_to_objid()
22422 {
22423         local ost=$1
22424         local objid=$2
22425
22426         local vdevdir=$(dirname $(facet_vdevice $ost))
22427         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22428         local zfs_zapid=$(do_facet $ost $cmd |
22429                           grep -w "/O/0/d$((objid%32))" -C 5 |
22430                           awk '/Object/{getline; print $1}')
22431         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22432                           awk "/$objid = /"'{printf $3}')
22433
22434         echo $zfs_objid
22435 }
22436
22437 zfs_object_blksz() {
22438         local ost=$1
22439         local objid=$2
22440
22441         local vdevdir=$(dirname $(facet_vdevice $ost))
22442         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22443         local blksz=$(do_facet $ost $cmd $objid |
22444                       awk '/dblk/{getline; printf $4}')
22445
22446         case "${blksz: -1}" in
22447                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22448                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22449                 *) ;;
22450         esac
22451
22452         echo $blksz
22453 }
22454
22455 test_312() { # LU-4856
22456         remote_ost_nodsh && skip "remote OST with nodsh"
22457         [ "$ost1_FSTYPE" = "zfs" ] ||
22458                 skip_env "the test only applies to zfs"
22459
22460         local max_blksz=$(do_facet ost1 \
22461                           $ZFS get -p recordsize $(facet_device ost1) |
22462                           awk '!/VALUE/{print $3}')
22463
22464         # to make life a little bit easier
22465         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22466         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22467
22468         local tf=$DIR/$tdir/$tfile
22469         touch $tf
22470         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22471
22472         # Get ZFS object id
22473         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22474         # block size change by sequential overwrite
22475         local bs
22476
22477         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22478                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22479
22480                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22481                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22482         done
22483         rm -f $tf
22484
22485         # block size change by sequential append write
22486         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22487         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22488         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22489         local count
22490
22491         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22492                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22493                         oflag=sync conv=notrunc
22494
22495                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22496                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22497                         error "blksz error, actual $blksz, " \
22498                                 "expected: 2 * $count * $PAGE_SIZE"
22499         done
22500         rm -f $tf
22501
22502         # random write
22503         touch $tf
22504         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22505         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22506
22507         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22508         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22509         [ $blksz -eq $PAGE_SIZE ] ||
22510                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22511
22512         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22513         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22514         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22515
22516         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22517         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22518         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22519 }
22520 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22521
22522 test_313() {
22523         remote_ost_nodsh && skip "remote OST with nodsh"
22524
22525         local file=$DIR/$tfile
22526
22527         rm -f $file
22528         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22529
22530         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22531         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22532         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22533                 error "write should failed"
22534         do_facet ost1 "$LCTL set_param fail_loc=0"
22535         rm -f $file
22536 }
22537 run_test 313 "io should fail after last_rcvd update fail"
22538
22539 test_314() {
22540         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22541
22542         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22543         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22544         rm -f $DIR/$tfile
22545         wait_delete_completed
22546         do_facet ost1 "$LCTL set_param fail_loc=0"
22547 }
22548 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22549
22550 test_315() { # LU-618
22551         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22552
22553         local file=$DIR/$tfile
22554         rm -f $file
22555
22556         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22557                 error "multiop file write failed"
22558         $MULTIOP $file oO_RDONLY:r4063232_c &
22559         PID=$!
22560
22561         sleep 2
22562
22563         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22564         kill -USR1 $PID
22565
22566         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22567         rm -f $file
22568 }
22569 run_test 315 "read should be accounted"
22570
22571 test_316() {
22572         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22573         large_xattr_enabled || skip_env "ea_inode feature disabled"
22574
22575         rm -rf $DIR/$tdir/d
22576         mkdir -p $DIR/$tdir/d
22577         chown nobody $DIR/$tdir/d
22578         touch $DIR/$tdir/d/file
22579
22580         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22581 }
22582 run_test 316 "lfs mv"
22583
22584 test_317() {
22585         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22586                 skip "Need MDS version at least 2.11.53"
22587         if [ "$ost1_FSTYPE" == "zfs" ]; then
22588                 skip "LU-10370: no implementation for ZFS"
22589         fi
22590
22591         local trunc_sz
22592         local grant_blk_size
22593
22594         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22595                         awk '/grant_block_size:/ { print $2; exit; }')
22596         #
22597         # Create File of size 5M. Truncate it to below size's and verify
22598         # blocks count.
22599         #
22600         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22601                 error "Create file $DIR/$tfile failed"
22602         stack_trap "rm -f $DIR/$tfile" EXIT
22603
22604         for trunc_sz in 2097152 4097 4000 509 0; do
22605                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22606                         error "truncate $tfile to $trunc_sz failed"
22607                 local sz=$(stat --format=%s $DIR/$tfile)
22608                 local blk=$(stat --format=%b $DIR/$tfile)
22609                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22610                                      grant_blk_size) * 8))
22611
22612                 if [[ $blk -ne $trunc_blk ]]; then
22613                         $(which stat) $DIR/$tfile
22614                         error "Expected Block $trunc_blk got $blk for $tfile"
22615                 fi
22616
22617                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22618                         error "Expected Size $trunc_sz got $sz for $tfile"
22619         done
22620
22621         #
22622         # sparse file test
22623         # Create file with a hole and write actual two blocks. Block count
22624         # must be 16.
22625         #
22626         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22627                 conv=fsync || error "Create file : $DIR/$tfile"
22628
22629         # Calculate the final truncate size.
22630         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22631
22632         #
22633         # truncate to size $trunc_sz bytes. Strip the last block
22634         # The block count must drop to 8
22635         #
22636         $TRUNCATE $DIR/$tfile $trunc_sz ||
22637                 error "truncate $tfile to $trunc_sz failed"
22638
22639         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22640         sz=$(stat --format=%s $DIR/$tfile)
22641         blk=$(stat --format=%b $DIR/$tfile)
22642
22643         if [[ $blk -ne $trunc_bsz ]]; then
22644                 $(which stat) $DIR/$tfile
22645                 error "Expected Block $trunc_bsz got $blk for $tfile"
22646         fi
22647
22648         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22649                 error "Expected Size $trunc_sz got $sz for $tfile"
22650 }
22651 run_test 317 "Verify blocks get correctly update after truncate"
22652
22653 test_318() {
22654         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
22655         local old_max_active=$($LCTL get_param -n \
22656                             ${llite_name}.max_read_ahead_async_active \
22657                             2>/dev/null)
22658
22659         $LCTL set_param llite.*.max_read_ahead_async_active=256
22660         local max_active=$($LCTL get_param -n \
22661                            ${llite_name}.max_read_ahead_async_active \
22662                            2>/dev/null)
22663         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22664
22665         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22666                 error "set max_read_ahead_async_active should succeed"
22667
22668         $LCTL set_param llite.*.max_read_ahead_async_active=512
22669         max_active=$($LCTL get_param -n \
22670                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
22671         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22672
22673         # restore @max_active
22674         [ $old_max_active -ne 0 ] && $LCTL set_param \
22675                 llite.*.max_read_ahead_async_active=$old_max_active
22676
22677         local old_threshold=$($LCTL get_param -n \
22678                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
22679         local max_per_file_mb=$($LCTL get_param -n \
22680                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
22681
22682         local invalid=$(($max_per_file_mb + 1))
22683         $LCTL set_param \
22684                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22685                         && error "set $invalid should fail"
22686
22687         local valid=$(($invalid - 1))
22688         $LCTL set_param \
22689                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22690                         error "set $valid should succeed"
22691         local threshold=$($LCTL get_param -n \
22692                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
22693         [ $threshold -eq $valid ] || error \
22694                 "expect threshold $valid got $threshold"
22695         $LCTL set_param \
22696                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22697 }
22698 run_test 318 "Verify async readahead tunables"
22699
22700 test_319() {
22701         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22702
22703         local before=$(date +%s)
22704         local evict
22705         local mdir=$DIR/$tdir
22706         local file=$mdir/xxx
22707
22708         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22709         touch $file
22710
22711 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22712         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22713         $LFS mv -m1 $file &
22714
22715         sleep 1
22716         dd if=$file of=/dev/null
22717         wait
22718         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22719           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22720
22721         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22722 }
22723 run_test 319 "lost lease lock on migrate error"
22724
22725 test_398a() { # LU-4198
22726         local ost1_imp=$(get_osc_import_name client ost1)
22727         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22728                          cut -d'.' -f2)
22729
22730         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22731         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22732
22733         # request a new lock on client
22734         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22735
22736         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22737         local lock_count=$($LCTL get_param -n \
22738                            ldlm.namespaces.$imp_name.lru_size)
22739         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22740
22741         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22742
22743         # no lock cached, should use lockless IO and not enqueue new lock
22744         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22745         lock_count=$($LCTL get_param -n \
22746                      ldlm.namespaces.$imp_name.lru_size)
22747         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22748 }
22749 run_test 398a "direct IO should cancel lock otherwise lockless"
22750
22751 test_398b() { # LU-4198
22752         which fio || skip_env "no fio installed"
22753         $LFS setstripe -c -1 $DIR/$tfile
22754
22755         local size=12
22756         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22757
22758         local njobs=4
22759         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22760         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22761                 --numjobs=$njobs --fallocate=none \
22762                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22763                 --filename=$DIR/$tfile &
22764         bg_pid=$!
22765
22766         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22767         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22768                 --numjobs=$njobs --fallocate=none \
22769                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22770                 --filename=$DIR/$tfile || true
22771         wait $bg_pid
22772
22773         rm -rf $DIR/$tfile
22774 }
22775 run_test 398b "DIO and buffer IO race"
22776
22777 test_398c() { # LU-4198
22778         local ost1_imp=$(get_osc_import_name client ost1)
22779         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22780                          cut -d'.' -f2)
22781
22782         which fio || skip_env "no fio installed"
22783
22784         saved_debug=$($LCTL get_param -n debug)
22785         $LCTL set_param debug=0
22786
22787         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22788         ((size /= 1024)) # by megabytes
22789         ((size /= 2)) # write half of the OST at most
22790         [ $size -gt 40 ] && size=40 #reduce test time anyway
22791
22792         $LFS setstripe -c 1 $DIR/$tfile
22793
22794         # it seems like ldiskfs reserves more space than necessary if the
22795         # writing blocks are not mapped, so it extends the file firstly
22796         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22797         cancel_lru_locks osc
22798
22799         # clear and verify rpc_stats later
22800         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22801
22802         local njobs=4
22803         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22804         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22805                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22806                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22807                 --filename=$DIR/$tfile
22808         [ $? -eq 0 ] || error "fio write error"
22809
22810         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
22811                 error "Locks were requested while doing AIO"
22812
22813         # get the percentage of 1-page I/O
22814         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
22815                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22816                 awk '{print $7}')
22817         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22818
22819         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22820         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22821                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22822                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22823                 --filename=$DIR/$tfile
22824         [ $? -eq 0 ] || error "fio mixed read write error"
22825
22826         echo "AIO with large block size ${size}M"
22827         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22828                 --numjobs=1 --fallocate=none --ioengine=libaio \
22829                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22830                 --filename=$DIR/$tfile
22831         [ $? -eq 0 ] || error "fio large block size failed"
22832
22833         rm -rf $DIR/$tfile
22834         $LCTL set_param debug="$saved_debug"
22835 }
22836 run_test 398c "run fio to test AIO"
22837
22838 test_398d() { #  LU-13846
22839         test -f aiocp || skip_env "no aiocp installed"
22840         local aio_file=$DIR/aio_file
22841
22842         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22843
22844         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22845         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22846
22847         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22848
22849         # make sure we don't crash and fail properly
22850         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22851                 error "aio not aligned with PAGE SIZE should fail"
22852
22853         rm -rf $DIR/$tfile $aio_file
22854 }
22855 run_test 398d "run aiocp to verify block size > stripe size"
22856
22857 test_398e() {
22858         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
22859         touch $DIR/$tfile.new
22860         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
22861 }
22862 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
22863
22864 test_fake_rw() {
22865         local read_write=$1
22866         if [ "$read_write" = "write" ]; then
22867                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22868         elif [ "$read_write" = "read" ]; then
22869                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22870         else
22871                 error "argument error"
22872         fi
22873
22874         # turn off debug for performance testing
22875         local saved_debug=$($LCTL get_param -n debug)
22876         $LCTL set_param debug=0
22877
22878         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22879
22880         # get ost1 size - $FSNAME-OST0000
22881         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
22882         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22883         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22884
22885         if [ "$read_write" = "read" ]; then
22886                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22887         fi
22888
22889         local start_time=$(date +%s.%N)
22890         $dd_cmd bs=1M count=$blocks oflag=sync ||
22891                 error "real dd $read_write error"
22892         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22893
22894         if [ "$read_write" = "write" ]; then
22895                 rm -f $DIR/$tfile
22896         fi
22897
22898         # define OBD_FAIL_OST_FAKE_RW           0x238
22899         do_facet ost1 $LCTL set_param fail_loc=0x238
22900
22901         local start_time=$(date +%s.%N)
22902         $dd_cmd bs=1M count=$blocks oflag=sync ||
22903                 error "fake dd $read_write error"
22904         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22905
22906         if [ "$read_write" = "write" ]; then
22907                 # verify file size
22908                 cancel_lru_locks osc
22909                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22910                         error "$tfile size not $blocks MB"
22911         fi
22912         do_facet ost1 $LCTL set_param fail_loc=0
22913
22914         echo "fake $read_write $duration_fake vs. normal $read_write" \
22915                 "$duration in seconds"
22916         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22917                 error_not_in_vm "fake write is slower"
22918
22919         $LCTL set_param -n debug="$saved_debug"
22920         rm -f $DIR/$tfile
22921 }
22922 test_399a() { # LU-7655 for OST fake write
22923         remote_ost_nodsh && skip "remote OST with nodsh"
22924
22925         test_fake_rw write
22926 }
22927 run_test 399a "fake write should not be slower than normal write"
22928
22929 test_399b() { # LU-8726 for OST fake read
22930         remote_ost_nodsh && skip "remote OST with nodsh"
22931         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22932                 skip_env "ldiskfs only test"
22933         fi
22934
22935         test_fake_rw read
22936 }
22937 run_test 399b "fake read should not be slower than normal read"
22938
22939 test_400a() { # LU-1606, was conf-sanity test_74
22940         if ! which $CC > /dev/null 2>&1; then
22941                 skip_env "$CC is not installed"
22942         fi
22943
22944         local extra_flags=''
22945         local out=$TMP/$tfile
22946         local prefix=/usr/include/lustre
22947         local prog
22948
22949         # Oleg removes c files in his test rig so test if any c files exist
22950         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22951                 skip_env "Needed c test files are missing"
22952
22953         if ! [[ -d $prefix ]]; then
22954                 # Assume we're running in tree and fixup the include path.
22955                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22956                 extra_flags+=" -L$LUSTRE/utils/.lib"
22957         fi
22958
22959         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22960                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22961                         error "client api broken"
22962         done
22963         rm -f $out
22964 }
22965 run_test 400a "Lustre client api program can compile and link"
22966
22967 test_400b() { # LU-1606, LU-5011
22968         local header
22969         local out=$TMP/$tfile
22970         local prefix=/usr/include/linux/lustre
22971
22972         # We use a hard coded prefix so that this test will not fail
22973         # when run in tree. There are headers in lustre/include/lustre/
22974         # that are not packaged (like lustre_idl.h) and have more
22975         # complicated include dependencies (like config.h and lnet/types.h).
22976         # Since this test about correct packaging we just skip them when
22977         # they don't exist (see below) rather than try to fixup cppflags.
22978
22979         if ! which $CC > /dev/null 2>&1; then
22980                 skip_env "$CC is not installed"
22981         fi
22982
22983         for header in $prefix/*.h; do
22984                 if ! [[ -f "$header" ]]; then
22985                         continue
22986                 fi
22987
22988                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22989                         continue # lustre_ioctl.h is internal header
22990                 fi
22991
22992                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22993                         error "cannot compile '$header'"
22994         done
22995         rm -f $out
22996 }
22997 run_test 400b "packaged headers can be compiled"
22998
22999 test_401a() { #LU-7437
23000         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23001         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23002
23003         #count the number of parameters by "list_param -R"
23004         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23005         #count the number of parameters by listing proc files
23006         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23007         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23008         echo "proc_dirs='$proc_dirs'"
23009         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23010         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23011                       sort -u | wc -l)
23012
23013         [ $params -eq $procs ] ||
23014                 error "found $params parameters vs. $procs proc files"
23015
23016         # test the list_param -D option only returns directories
23017         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23018         #count the number of parameters by listing proc directories
23019         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23020                 sort -u | wc -l)
23021
23022         [ $params -eq $procs ] ||
23023                 error "found $params parameters vs. $procs proc files"
23024 }
23025 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23026
23027 test_401b() {
23028         # jobid_var may not allow arbitrary values, so use jobid_name
23029         # if available
23030         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23031                 local testname=jobid_name tmp='testing%p'
23032         else
23033                 local testname=jobid_var tmp=testing
23034         fi
23035
23036         local save=$($LCTL get_param -n $testname)
23037
23038         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23039                 error "no error returned when setting bad parameters"
23040
23041         local jobid_new=$($LCTL get_param -n foe $testname baz)
23042         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23043
23044         $LCTL set_param -n fog=bam $testname=$save bat=fog
23045         local jobid_old=$($LCTL get_param -n foe $testname bag)
23046         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23047 }
23048 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23049
23050 test_401c() {
23051         # jobid_var may not allow arbitrary values, so use jobid_name
23052         # if available
23053         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23054                 local testname=jobid_name
23055         else
23056                 local testname=jobid_var
23057         fi
23058
23059         local jobid_var_old=$($LCTL get_param -n $testname)
23060         local jobid_var_new
23061
23062         $LCTL set_param $testname= &&
23063                 error "no error returned for 'set_param a='"
23064
23065         jobid_var_new=$($LCTL get_param -n $testname)
23066         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23067                 error "$testname was changed by setting without value"
23068
23069         $LCTL set_param $testname &&
23070                 error "no error returned for 'set_param a'"
23071
23072         jobid_var_new=$($LCTL get_param -n $testname)
23073         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23074                 error "$testname was changed by setting without value"
23075 }
23076 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23077
23078 test_401d() {
23079         # jobid_var may not allow arbitrary values, so use jobid_name
23080         # if available
23081         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23082                 local testname=jobid_name new_value='foo=bar%p'
23083         else
23084                 local testname=jobid_var new_valuie=foo=bar
23085         fi
23086
23087         local jobid_var_old=$($LCTL get_param -n $testname)
23088         local jobid_var_new
23089
23090         $LCTL set_param $testname=$new_value ||
23091                 error "'set_param a=b' did not accept a value containing '='"
23092
23093         jobid_var_new=$($LCTL get_param -n $testname)
23094         [[ "$jobid_var_new" == "$new_value" ]] ||
23095                 error "'set_param a=b' failed on a value containing '='"
23096
23097         # Reset the $testname to test the other format
23098         $LCTL set_param $testname=$jobid_var_old
23099         jobid_var_new=$($LCTL get_param -n $testname)
23100         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23101                 error "failed to reset $testname"
23102
23103         $LCTL set_param $testname $new_value ||
23104                 error "'set_param a b' did not accept a value containing '='"
23105
23106         jobid_var_new=$($LCTL get_param -n $testname)
23107         [[ "$jobid_var_new" == "$new_value" ]] ||
23108                 error "'set_param a b' failed on a value containing '='"
23109
23110         $LCTL set_param $testname $jobid_var_old
23111         jobid_var_new=$($LCTL get_param -n $testname)
23112         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23113                 error "failed to reset $testname"
23114 }
23115 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23116
23117 test_402() {
23118         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23119         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23120                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23121         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23122                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23123                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23124         remote_mds_nodsh && skip "remote MDS with nodsh"
23125
23126         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23127 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23128         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23129         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23130                 echo "Touch failed - OK"
23131 }
23132 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23133
23134 test_403() {
23135         local file1=$DIR/$tfile.1
23136         local file2=$DIR/$tfile.2
23137         local tfile=$TMP/$tfile
23138
23139         rm -f $file1 $file2 $tfile
23140
23141         touch $file1
23142         ln $file1 $file2
23143
23144         # 30 sec OBD_TIMEOUT in ll_getattr()
23145         # right before populating st_nlink
23146         $LCTL set_param fail_loc=0x80001409
23147         stat -c %h $file1 > $tfile &
23148
23149         # create an alias, drop all locks and reclaim the dentry
23150         < $file2
23151         cancel_lru_locks mdc
23152         cancel_lru_locks osc
23153         sysctl -w vm.drop_caches=2
23154
23155         wait
23156
23157         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23158
23159         rm -f $tfile $file1 $file2
23160 }
23161 run_test 403 "i_nlink should not drop to zero due to aliasing"
23162
23163 test_404() { # LU-6601
23164         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23165                 skip "Need server version newer than 2.8.52"
23166         remote_mds_nodsh && skip "remote MDS with nodsh"
23167
23168         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23169                 awk '/osp .*-osc-MDT/ { print $4}')
23170
23171         local osp
23172         for osp in $mosps; do
23173                 echo "Deactivate: " $osp
23174                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23175                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23176                         awk -vp=$osp '$4 == p { print $2 }')
23177                 [ $stat = IN ] || {
23178                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23179                         error "deactivate error"
23180                 }
23181                 echo "Activate: " $osp
23182                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23183                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23184                         awk -vp=$osp '$4 == p { print $2 }')
23185                 [ $stat = UP ] || {
23186                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23187                         error "activate error"
23188                 }
23189         done
23190 }
23191 run_test 404 "validate manual {de}activated works properly for OSPs"
23192
23193 test_405() {
23194         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23195         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23196                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23197                         skip "Layout swap lock is not supported"
23198
23199         check_swap_layouts_support
23200         check_swap_layout_no_dom $DIR
23201
23202         test_mkdir $DIR/$tdir
23203         swap_lock_test -d $DIR/$tdir ||
23204                 error "One layout swap locked test failed"
23205 }
23206 run_test 405 "Various layout swap lock tests"
23207
23208 test_406() {
23209         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23210         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23211         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23213         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23214                 skip "Need MDS version at least 2.8.50"
23215
23216         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23217         local test_pool=$TESTNAME
23218
23219         pool_add $test_pool || error "pool_add failed"
23220         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23221                 error "pool_add_targets failed"
23222
23223         save_layout_restore_at_exit $MOUNT
23224
23225         # parent set default stripe count only, child will stripe from both
23226         # parent and fs default
23227         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23228                 error "setstripe $MOUNT failed"
23229         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23230         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23231         for i in $(seq 10); do
23232                 local f=$DIR/$tdir/$tfile.$i
23233                 touch $f || error "touch failed"
23234                 local count=$($LFS getstripe -c $f)
23235                 [ $count -eq $OSTCOUNT ] ||
23236                         error "$f stripe count $count != $OSTCOUNT"
23237                 local offset=$($LFS getstripe -i $f)
23238                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23239                 local size=$($LFS getstripe -S $f)
23240                 [ $size -eq $((def_stripe_size * 2)) ] ||
23241                         error "$f stripe size $size != $((def_stripe_size * 2))"
23242                 local pool=$($LFS getstripe -p $f)
23243                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23244         done
23245
23246         # change fs default striping, delete parent default striping, now child
23247         # will stripe from new fs default striping only
23248         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23249                 error "change $MOUNT default stripe failed"
23250         $LFS setstripe -c 0 $DIR/$tdir ||
23251                 error "delete $tdir default stripe failed"
23252         for i in $(seq 11 20); do
23253                 local f=$DIR/$tdir/$tfile.$i
23254                 touch $f || error "touch $f failed"
23255                 local count=$($LFS getstripe -c $f)
23256                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23257                 local offset=$($LFS getstripe -i $f)
23258                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23259                 local size=$($LFS getstripe -S $f)
23260                 [ $size -eq $def_stripe_size ] ||
23261                         error "$f stripe size $size != $def_stripe_size"
23262                 local pool=$($LFS getstripe -p $f)
23263                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23264         done
23265
23266         unlinkmany $DIR/$tdir/$tfile. 1 20
23267
23268         local f=$DIR/$tdir/$tfile
23269         pool_remove_all_targets $test_pool $f
23270         pool_remove $test_pool $f
23271 }
23272 run_test 406 "DNE support fs default striping"
23273
23274 test_407() {
23275         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23276         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23277                 skip "Need MDS version at least 2.8.55"
23278         remote_mds_nodsh && skip "remote MDS with nodsh"
23279
23280         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23281                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23282         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23283                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23284         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23285
23286         #define OBD_FAIL_DT_TXN_STOP    0x2019
23287         for idx in $(seq $MDSCOUNT); do
23288                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23289         done
23290         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23291         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23292                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23293         true
23294 }
23295 run_test 407 "transaction fail should cause operation fail"
23296
23297 test_408() {
23298         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23299
23300         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23301         lctl set_param fail_loc=0x8000040a
23302         # let ll_prepare_partial_page() fail
23303         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23304
23305         rm -f $DIR/$tfile
23306
23307         # create at least 100 unused inodes so that
23308         # shrink_icache_memory(0) should not return 0
23309         touch $DIR/$tfile-{0..100}
23310         rm -f $DIR/$tfile-{0..100}
23311         sync
23312
23313         echo 2 > /proc/sys/vm/drop_caches
23314 }
23315 run_test 408 "drop_caches should not hang due to page leaks"
23316
23317 test_409()
23318 {
23319         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23320
23321         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23322         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23323         touch $DIR/$tdir/guard || error "(2) Fail to create"
23324
23325         local PREFIX=$(str_repeat 'A' 128)
23326         echo "Create 1K hard links start at $(date)"
23327         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23328                 error "(3) Fail to hard link"
23329
23330         echo "Links count should be right although linkEA overflow"
23331         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23332         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23333         [ $linkcount -eq 1001 ] ||
23334                 error "(5) Unexpected hard links count: $linkcount"
23335
23336         echo "List all links start at $(date)"
23337         ls -l $DIR/$tdir/foo > /dev/null ||
23338                 error "(6) Fail to list $DIR/$tdir/foo"
23339
23340         echo "Unlink hard links start at $(date)"
23341         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23342                 error "(7) Fail to unlink"
23343         echo "Unlink hard links finished at $(date)"
23344 }
23345 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23346
23347 test_410()
23348 {
23349         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23350                 skip "Need client version at least 2.9.59"
23351         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23352                 skip "Need MODULES build"
23353
23354         # Create a file, and stat it from the kernel
23355         local testfile=$DIR/$tfile
23356         touch $testfile
23357
23358         local run_id=$RANDOM
23359         local my_ino=$(stat --format "%i" $testfile)
23360
23361         # Try to insert the module. This will always fail as the
23362         # module is designed to not be inserted.
23363         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23364             &> /dev/null
23365
23366         # Anything but success is a test failure
23367         dmesg | grep -q \
23368             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23369             error "no inode match"
23370 }
23371 run_test 410 "Test inode number returned from kernel thread"
23372
23373 cleanup_test411_cgroup() {
23374         trap 0
23375         rmdir "$1"
23376 }
23377
23378 test_411() {
23379         local cg_basedir=/sys/fs/cgroup/memory
23380         # LU-9966
23381         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23382                 skip "no setup for cgroup"
23383
23384         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23385                 error "test file creation failed"
23386         cancel_lru_locks osc
23387
23388         # Create a very small memory cgroup to force a slab allocation error
23389         local cgdir=$cg_basedir/osc_slab_alloc
23390         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23391         trap "cleanup_test411_cgroup $cgdir" EXIT
23392         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23393         echo 1M > $cgdir/memory.limit_in_bytes
23394
23395         # Should not LBUG, just be killed by oom-killer
23396         # dd will return 0 even allocation failure in some environment.
23397         # So don't check return value
23398         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23399         cleanup_test411_cgroup $cgdir
23400
23401         return 0
23402 }
23403 run_test 411 "Slab allocation error with cgroup does not LBUG"
23404
23405 test_412() {
23406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23407         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23408                 skip "Need server version at least 2.10.55"
23409         fi
23410
23411         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23412                 error "mkdir failed"
23413         $LFS getdirstripe $DIR/$tdir
23414         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23415         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23416                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23417         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23418         [ $stripe_count -eq 2 ] ||
23419                 error "expect 2 get $stripe_count"
23420 }
23421 run_test 412 "mkdir on specific MDTs"
23422
23423 test_qos_mkdir() {
23424         local mkdir_cmd=$1
23425         local stripe_count=$2
23426         local mdts=$(comma_list $(mdts_nodes))
23427
23428         local testdir
23429         local lmv_qos_prio_free
23430         local lmv_qos_threshold_rr
23431         local lmv_qos_maxage
23432         local lod_qos_prio_free
23433         local lod_qos_threshold_rr
23434         local lod_qos_maxage
23435         local count
23436         local i
23437
23438         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23439         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23440         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23441                 head -n1)
23442         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23443         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23444         stack_trap "$LCTL set_param \
23445                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23446         stack_trap "$LCTL set_param \
23447                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23448         stack_trap "$LCTL set_param \
23449                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23450
23451         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23452                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23453         lod_qos_prio_free=${lod_qos_prio_free%%%}
23454         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23455                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23456         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23457         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23458                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23459         stack_trap "do_nodes $mdts $LCTL set_param \
23460                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23461         stack_trap "do_nodes $mdts $LCTL set_param \
23462                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23463                 EXIT
23464         stack_trap "do_nodes $mdts $LCTL set_param \
23465                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23466
23467         echo
23468         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23469
23470         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23471         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23472
23473         testdir=$DIR/$tdir-s$stripe_count/rr
23474
23475         for i in $(seq $((100 * MDSCOUNT))); do
23476                 eval $mkdir_cmd $testdir/subdir$i ||
23477                         error "$mkdir_cmd subdir$i failed"
23478         done
23479
23480         for i in $(seq $MDSCOUNT); do
23481                 count=$($LFS getdirstripe -i $testdir/* |
23482                                 grep ^$((i - 1))$ | wc -l)
23483                 echo "$count directories created on MDT$((i - 1))"
23484                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23485
23486                 if [ $stripe_count -gt 1 ]; then
23487                         count=$($LFS getdirstripe $testdir/* |
23488                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23489                         echo "$count stripes created on MDT$((i - 1))"
23490                         # deviation should < 5% of average
23491                         [ $count -lt $((95 * stripe_count)) ] ||
23492                         [ $count -gt $((105 * stripe_count)) ] &&
23493                                 error "stripes are not evenly distributed"
23494                 fi
23495         done
23496
23497         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23498         do_nodes $mdts $LCTL set_param \
23499                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23500
23501         echo
23502         echo "Check for uneven MDTs: "
23503
23504         local ffree
23505         local bavail
23506         local max
23507         local min
23508         local max_index
23509         local min_index
23510         local tmp
23511
23512         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23513         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23514         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23515
23516         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23517         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23518         max_index=0
23519         min_index=0
23520         for ((i = 1; i < ${#ffree[@]}; i++)); do
23521                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23522                 if [ $tmp -gt $max ]; then
23523                         max=$tmp
23524                         max_index=$i
23525                 fi
23526                 if [ $tmp -lt $min ]; then
23527                         min=$tmp
23528                         min_index=$i
23529                 fi
23530         done
23531
23532         [ ${ffree[min_index]} -eq 0 ] &&
23533                 skip "no free files in MDT$min_index"
23534         [ ${ffree[min_index]} -gt 100000000 ] &&
23535                 skip "too much free files in MDT$min_index"
23536
23537         # Check if we need to generate uneven MDTs
23538         local threshold=50
23539         local diff=$(((max - min) * 100 / min))
23540         local value="$(generate_string 1024)"
23541
23542         while [ $diff -lt $threshold ]; do
23543                 # generate uneven MDTs, create till $threshold% diff
23544                 echo -n "weight diff=$diff% must be > $threshold% ..."
23545                 count=$((${ffree[min_index]} / 10))
23546                 # 50 sec per 10000 files in vm
23547                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23548                         skip "$count files to create"
23549                 echo "Fill MDT$min_index with $count files"
23550                 [ -d $DIR/$tdir-MDT$min_index ] ||
23551                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23552                         error "mkdir $tdir-MDT$min_index failed"
23553                 for i in $(seq $count); do
23554                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23555                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23556                                 error "create f$j_$i failed"
23557                         setfattr -n user.413b -v $value \
23558                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23559                                 error "setfattr f$j_$i failed"
23560                 done
23561
23562                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23563                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23564                 max=$(((${ffree[max_index]} >> 8) * \
23565                         (${bavail[max_index]} * bsize >> 16)))
23566                 min=$(((${ffree[min_index]} >> 8) * \
23567                         (${bavail[min_index]} * bsize >> 16)))
23568                 diff=$(((max - min) * 100 / min))
23569         done
23570
23571         echo "MDT filesfree available: ${ffree[@]}"
23572         echo "MDT blocks available: ${bavail[@]}"
23573         echo "weight diff=$diff%"
23574
23575         echo
23576         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23577
23578         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23579         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23580         # decrease statfs age, so that it can be updated in time
23581         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23582         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23583
23584         sleep 1
23585
23586         testdir=$DIR/$tdir-s$stripe_count/qos
23587
23588         for i in $(seq $((100 * MDSCOUNT))); do
23589                 eval $mkdir_cmd $testdir/subdir$i ||
23590                         error "$mkdir_cmd subdir$i failed"
23591         done
23592
23593         for i in $(seq $MDSCOUNT); do
23594                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23595                         wc -l)
23596                 echo "$count directories created on MDT$((i - 1))"
23597
23598                 if [ $stripe_count -gt 1 ]; then
23599                         count=$($LFS getdirstripe $testdir/* |
23600                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23601                         echo "$count stripes created on MDT$((i - 1))"
23602                 fi
23603         done
23604
23605         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23606         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23607
23608         # D-value should > 10% of averge
23609         [ $((max - min)) -lt 10 ] &&
23610                 error "subdirs shouldn't be evenly distributed"
23611
23612         # ditto
23613         if [ $stripe_count -gt 1 ]; then
23614                 max=$($LFS getdirstripe $testdir/* |
23615                         grep -P "^\s+$max_index\t" | wc -l)
23616                 min=$($LFS getdirstripe $testdir/* |
23617                         grep -P "^\s+$min_index\t" | wc -l)
23618                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23619                         error "stripes shouldn't be evenly distributed"|| true
23620         fi
23621 }
23622
23623 test_413a() {
23624         [ $MDSCOUNT -lt 2 ] &&
23625                 skip "We need at least 2 MDTs for this test"
23626
23627         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23628                 skip "Need server version at least 2.12.52"
23629
23630         local stripe_count
23631
23632         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23633                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23634                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23635                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23636                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23637         done
23638 }
23639 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23640
23641 test_413b() {
23642         [ $MDSCOUNT -lt 2 ] &&
23643                 skip "We need at least 2 MDTs for this test"
23644
23645         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23646                 skip "Need server version at least 2.12.52"
23647
23648         local stripe_count
23649
23650         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23651                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23652                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23653                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23654                 $LFS setdirstripe -D -c $stripe_count \
23655                         $DIR/$tdir-s$stripe_count/rr ||
23656                         error "setdirstripe failed"
23657                 $LFS setdirstripe -D -c $stripe_count \
23658                         $DIR/$tdir-s$stripe_count/qos ||
23659                         error "setdirstripe failed"
23660                 test_qos_mkdir "mkdir" $stripe_count
23661         done
23662 }
23663 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23664
23665 test_414() {
23666 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23667         $LCTL set_param fail_loc=0x80000521
23668         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23669         rm -f $DIR/$tfile
23670 }
23671 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23672
23673 test_415() {
23674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23675         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23676                 skip "Need server version at least 2.11.52"
23677
23678         # LU-11102
23679         local total
23680         local setattr_pid
23681         local start_time
23682         local end_time
23683         local duration
23684
23685         total=500
23686         # this test may be slow on ZFS
23687         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23688
23689         # though this test is designed for striped directory, let's test normal
23690         # directory too since lock is always saved as CoS lock.
23691         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23692         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23693
23694         (
23695                 while true; do
23696                         touch $DIR/$tdir
23697                 done
23698         ) &
23699         setattr_pid=$!
23700
23701         start_time=$(date +%s)
23702         for i in $(seq $total); do
23703                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23704                         > /dev/null
23705         done
23706         end_time=$(date +%s)
23707         duration=$((end_time - start_time))
23708
23709         kill -9 $setattr_pid
23710
23711         echo "rename $total files took $duration sec"
23712         [ $duration -lt 100 ] || error "rename took $duration sec"
23713 }
23714 run_test 415 "lock revoke is not missing"
23715
23716 test_416() {
23717         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23718                 skip "Need server version at least 2.11.55"
23719
23720         # define OBD_FAIL_OSD_TXN_START    0x19a
23721         do_facet mds1 lctl set_param fail_loc=0x19a
23722
23723         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23724
23725         true
23726 }
23727 run_test 416 "transaction start failure won't cause system hung"
23728
23729 cleanup_417() {
23730         trap 0
23731         do_nodes $(comma_list $(mdts_nodes)) \
23732                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23733         do_nodes $(comma_list $(mdts_nodes)) \
23734                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23735         do_nodes $(comma_list $(mdts_nodes)) \
23736                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23737 }
23738
23739 test_417() {
23740         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23741         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23742                 skip "Need MDS version at least 2.11.56"
23743
23744         trap cleanup_417 RETURN EXIT
23745
23746         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23747         do_nodes $(comma_list $(mdts_nodes)) \
23748                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23749         $LFS migrate -m 0 $DIR/$tdir.1 &&
23750                 error "migrate dir $tdir.1 should fail"
23751
23752         do_nodes $(comma_list $(mdts_nodes)) \
23753                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23754         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23755                 error "create remote dir $tdir.2 should fail"
23756
23757         do_nodes $(comma_list $(mdts_nodes)) \
23758                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23759         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23760                 error "create striped dir $tdir.3 should fail"
23761         true
23762 }
23763 run_test 417 "disable remote dir, striped dir and dir migration"
23764
23765 # Checks that the outputs of df [-i] and lfs df [-i] match
23766 #
23767 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23768 check_lfs_df() {
23769         local dir=$2
23770         local inodes
23771         local df_out
23772         local lfs_df_out
23773         local count
23774         local passed=false
23775
23776         # blocks or inodes
23777         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23778
23779         for count in {1..100}; do
23780                 cancel_lru_locks
23781                 sync; sleep 0.2
23782
23783                 # read the lines of interest
23784                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23785                         error "df $inodes $dir | tail -n +2 failed"
23786                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23787                         error "lfs df $inodes $dir | grep summary: failed"
23788
23789                 # skip first substrings of each output as they are different
23790                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23791                 # compare the two outputs
23792                 passed=true
23793                 for i in {1..5}; do
23794                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23795                 done
23796                 $passed && break
23797         done
23798
23799         if ! $passed; then
23800                 df -P $inodes $dir
23801                 echo
23802                 lfs df $inodes $dir
23803                 error "df and lfs df $1 output mismatch: "      \
23804                       "df ${inodes}: ${df_out[*]}, "            \
23805                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23806         fi
23807 }
23808
23809 test_418() {
23810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23811
23812         local dir=$DIR/$tdir
23813         local numfiles=$((RANDOM % 4096 + 2))
23814         local numblocks=$((RANDOM % 256 + 1))
23815
23816         wait_delete_completed
23817         test_mkdir $dir
23818
23819         # check block output
23820         check_lfs_df blocks $dir
23821         # check inode output
23822         check_lfs_df inodes $dir
23823
23824         # create a single file and retest
23825         echo "Creating a single file and testing"
23826         createmany -o $dir/$tfile- 1 &>/dev/null ||
23827                 error "creating 1 file in $dir failed"
23828         check_lfs_df blocks $dir
23829         check_lfs_df inodes $dir
23830
23831         # create a random number of files
23832         echo "Creating $((numfiles - 1)) files and testing"
23833         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23834                 error "creating $((numfiles - 1)) files in $dir failed"
23835
23836         # write a random number of blocks to the first test file
23837         echo "Writing $numblocks 4K blocks and testing"
23838         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23839                 count=$numblocks &>/dev/null ||
23840                 error "dd to $dir/${tfile}-0 failed"
23841
23842         # retest
23843         check_lfs_df blocks $dir
23844         check_lfs_df inodes $dir
23845
23846         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23847                 error "unlinking $numfiles files in $dir failed"
23848 }
23849 run_test 418 "df and lfs df outputs match"
23850
23851 test_419()
23852 {
23853         local dir=$DIR/$tdir
23854
23855         mkdir -p $dir
23856         touch $dir/file
23857
23858         cancel_lru_locks mdc
23859
23860         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23861         $LCTL set_param fail_loc=0x1410
23862         cat $dir/file
23863         $LCTL set_param fail_loc=0
23864         rm -rf $dir
23865 }
23866 run_test 419 "Verify open file by name doesn't crash kernel"
23867
23868 test_420()
23869 {
23870         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23871                 skip "Need MDS version at least 2.12.53"
23872
23873         local SAVE_UMASK=$(umask)
23874         local dir=$DIR/$tdir
23875         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23876
23877         mkdir -p $dir
23878         umask 0000
23879         mkdir -m03777 $dir/testdir
23880         ls -dn $dir/testdir
23881         # Need to remove trailing '.' when SELinux is enabled
23882         local dirperms=$(ls -dn $dir/testdir |
23883                          awk '{ sub(/\.$/, "", $1); print $1}')
23884         [ $dirperms == "drwxrwsrwt" ] ||
23885                 error "incorrect perms on $dir/testdir"
23886
23887         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23888                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23889         ls -n $dir/testdir/testfile
23890         local fileperms=$(ls -n $dir/testdir/testfile |
23891                           awk '{ sub(/\.$/, "", $1); print $1}')
23892         [ $fileperms == "-rwxr-xr-x" ] ||
23893                 error "incorrect perms on $dir/testdir/testfile"
23894
23895         umask $SAVE_UMASK
23896 }
23897 run_test 420 "clear SGID bit on non-directories for non-members"
23898
23899 test_421a() {
23900         local cnt
23901         local fid1
23902         local fid2
23903
23904         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23905                 skip "Need MDS version at least 2.12.54"
23906
23907         test_mkdir $DIR/$tdir
23908         createmany -o $DIR/$tdir/f 3
23909         cnt=$(ls -1 $DIR/$tdir | wc -l)
23910         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23911
23912         fid1=$(lfs path2fid $DIR/$tdir/f1)
23913         fid2=$(lfs path2fid $DIR/$tdir/f2)
23914         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23915
23916         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23917         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23918
23919         cnt=$(ls -1 $DIR/$tdir | wc -l)
23920         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23921
23922         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23923         createmany -o $DIR/$tdir/f 3
23924         cnt=$(ls -1 $DIR/$tdir | wc -l)
23925         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23926
23927         fid1=$(lfs path2fid $DIR/$tdir/f1)
23928         fid2=$(lfs path2fid $DIR/$tdir/f2)
23929         echo "remove using fsname $FSNAME"
23930         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23931
23932         cnt=$(ls -1 $DIR/$tdir | wc -l)
23933         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23934 }
23935 run_test 421a "simple rm by fid"
23936
23937 test_421b() {
23938         local cnt
23939         local FID1
23940         local FID2
23941
23942         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23943                 skip "Need MDS version at least 2.12.54"
23944
23945         test_mkdir $DIR/$tdir
23946         createmany -o $DIR/$tdir/f 3
23947         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23948         MULTIPID=$!
23949
23950         FID1=$(lfs path2fid $DIR/$tdir/f1)
23951         FID2=$(lfs path2fid $DIR/$tdir/f2)
23952         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23953
23954         kill -USR1 $MULTIPID
23955         wait
23956
23957         cnt=$(ls $DIR/$tdir | wc -l)
23958         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23959 }
23960 run_test 421b "rm by fid on open file"
23961
23962 test_421c() {
23963         local cnt
23964         local FIDS
23965
23966         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23967                 skip "Need MDS version at least 2.12.54"
23968
23969         test_mkdir $DIR/$tdir
23970         createmany -o $DIR/$tdir/f 3
23971         touch $DIR/$tdir/$tfile
23972         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23973         cnt=$(ls -1 $DIR/$tdir | wc -l)
23974         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23975
23976         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23977         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23978
23979         cnt=$(ls $DIR/$tdir | wc -l)
23980         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23981 }
23982 run_test 421c "rm by fid against hardlinked files"
23983
23984 test_421d() {
23985         local cnt
23986         local FIDS
23987
23988         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23989                 skip "Need MDS version at least 2.12.54"
23990
23991         test_mkdir $DIR/$tdir
23992         createmany -o $DIR/$tdir/f 4097
23993         cnt=$(ls -1 $DIR/$tdir | wc -l)
23994         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23995
23996         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23997         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23998
23999         cnt=$(ls $DIR/$tdir | wc -l)
24000         rm -rf $DIR/$tdir
24001         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24002 }
24003 run_test 421d "rmfid en masse"
24004
24005 test_421e() {
24006         local cnt
24007         local FID
24008
24009         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24010         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24011                 skip "Need MDS version at least 2.12.54"
24012
24013         mkdir -p $DIR/$tdir
24014         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24015         createmany -o $DIR/$tdir/striped_dir/f 512
24016         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24017         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24018
24019         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24020                 sed "s/[/][^:]*://g")
24021         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24022
24023         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24024         rm -rf $DIR/$tdir
24025         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24026 }
24027 run_test 421e "rmfid in DNE"
24028
24029 test_421f() {
24030         local cnt
24031         local FID
24032
24033         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24034                 skip "Need MDS version at least 2.12.54"
24035
24036         test_mkdir $DIR/$tdir
24037         touch $DIR/$tdir/f
24038         cnt=$(ls -1 $DIR/$tdir | wc -l)
24039         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24040
24041         FID=$(lfs path2fid $DIR/$tdir/f)
24042         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24043         # rmfid should fail
24044         cnt=$(ls -1 $DIR/$tdir | wc -l)
24045         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24046
24047         chmod a+rw $DIR/$tdir
24048         ls -la $DIR/$tdir
24049         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24050         # rmfid should fail
24051         cnt=$(ls -1 $DIR/$tdir | wc -l)
24052         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24053
24054         rm -f $DIR/$tdir/f
24055         $RUNAS touch $DIR/$tdir/f
24056         FID=$(lfs path2fid $DIR/$tdir/f)
24057         echo "rmfid as root"
24058         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24059         cnt=$(ls -1 $DIR/$tdir | wc -l)
24060         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24061
24062         rm -f $DIR/$tdir/f
24063         $RUNAS touch $DIR/$tdir/f
24064         cnt=$(ls -1 $DIR/$tdir | wc -l)
24065         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24066         FID=$(lfs path2fid $DIR/$tdir/f)
24067         # rmfid w/o user_fid2path mount option should fail
24068         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24069         cnt=$(ls -1 $DIR/$tdir | wc -l)
24070         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24071
24072         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24073         stack_trap "rmdir $tmpdir"
24074         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24075                 error "failed to mount client'"
24076         stack_trap "umount_client $tmpdir"
24077
24078         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24079         # rmfid should succeed
24080         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24081         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24082
24083         # rmfid shouldn't allow to remove files due to dir's permission
24084         chmod a+rwx $tmpdir/$tdir
24085         touch $tmpdir/$tdir/f
24086         ls -la $tmpdir/$tdir
24087         FID=$(lfs path2fid $tmpdir/$tdir/f)
24088         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24089         return 0
24090 }
24091 run_test 421f "rmfid checks permissions"
24092
24093 test_421g() {
24094         local cnt
24095         local FIDS
24096
24097         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24098         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24099                 skip "Need MDS version at least 2.12.54"
24100
24101         mkdir -p $DIR/$tdir
24102         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24103         createmany -o $DIR/$tdir/striped_dir/f 512
24104         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24105         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24106
24107         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24108                 sed "s/[/][^:]*://g")
24109
24110         rm -f $DIR/$tdir/striped_dir/f1*
24111         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24112         removed=$((512 - cnt))
24113
24114         # few files have been just removed, so we expect
24115         # rmfid to fail on their fids
24116         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24117         [ $removed != $errors ] && error "$errors != $removed"
24118
24119         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24120         rm -rf $DIR/$tdir
24121         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24122 }
24123 run_test 421g "rmfid to return errors properly"
24124
24125 test_422() {
24126         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24127         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24128         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24129         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24130         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24131
24132         local amc=$(at_max_get client)
24133         local amo=$(at_max_get mds1)
24134         local timeout=`lctl get_param -n timeout`
24135
24136         at_max_set 0 client
24137         at_max_set 0 mds1
24138
24139 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24140         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24141                         fail_val=$(((2*timeout + 10)*1000))
24142         touch $DIR/$tdir/d3/file &
24143         sleep 2
24144 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24145         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24146                         fail_val=$((2*timeout + 5))
24147         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24148         local pid=$!
24149         sleep 1
24150         kill -9 $pid
24151         sleep $((2 * timeout))
24152         echo kill $pid
24153         kill -9 $pid
24154         lctl mark touch
24155         touch $DIR/$tdir/d2/file3
24156         touch $DIR/$tdir/d2/file4
24157         touch $DIR/$tdir/d2/file5
24158
24159         wait
24160         at_max_set $amc client
24161         at_max_set $amo mds1
24162
24163         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24164         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24165                 error "Watchdog is always throttled"
24166 }
24167 run_test 422 "kill a process with RPC in progress"
24168
24169 stat_test() {
24170     df -h $MOUNT &
24171     df -h $MOUNT &
24172     df -h $MOUNT &
24173     df -h $MOUNT &
24174     df -h $MOUNT &
24175     df -h $MOUNT &
24176 }
24177
24178 test_423() {
24179     local _stats
24180     # ensure statfs cache is expired
24181     sleep 2;
24182
24183     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24184     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24185
24186     return 0
24187 }
24188 run_test 423 "statfs should return a right data"
24189
24190 test_424() {
24191 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24192         $LCTL set_param fail_loc=0x80000522
24193         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24194         rm -f $DIR/$tfile
24195 }
24196 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24197
24198 test_425() {
24199         test_mkdir -c -1 $DIR/$tdir
24200         $LFS setstripe -c -1 $DIR/$tdir
24201
24202         lru_resize_disable "" 100
24203         stack_trap "lru_resize_enable" EXIT
24204
24205         sleep 5
24206
24207         for i in $(seq $((MDSCOUNT * 125))); do
24208                 local t=$DIR/$tdir/$tfile_$i
24209
24210                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24211                         error_noexit "Create file $t"
24212         done
24213         stack_trap "rm -rf $DIR/$tdir" EXIT
24214
24215         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24216                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24217                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24218
24219                 [ $lock_count -le $lru_size ] ||
24220                         error "osc lock count $lock_count > lru size $lru_size"
24221         done
24222
24223         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24224                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24225                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24226
24227                 [ $lock_count -le $lru_size ] ||
24228                         error "mdc lock count $lock_count > lru size $lru_size"
24229         done
24230 }
24231 run_test 425 "lock count should not exceed lru size"
24232
24233 test_426() {
24234         splice-test -r $DIR/$tfile
24235         splice-test -rd $DIR/$tfile
24236         splice-test $DIR/$tfile
24237         splice-test -d $DIR/$tfile
24238 }
24239 run_test 426 "splice test on Lustre"
24240
24241 test_427() {
24242         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24243         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24244                 skip "Need MDS version at least 2.12.4"
24245         local log
24246
24247         mkdir $DIR/$tdir
24248         mkdir $DIR/$tdir/1
24249         mkdir $DIR/$tdir/2
24250         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24251         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24252
24253         $LFS getdirstripe $DIR/$tdir/1/dir
24254
24255         #first setfattr for creating updatelog
24256         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24257
24258 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24259         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24260         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24261         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24262
24263         sleep 2
24264         fail mds2
24265         wait_recovery_complete mds2 $((2*TIMEOUT))
24266
24267         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24268         echo $log | grep "get update log failed" &&
24269                 error "update log corruption is detected" || true
24270 }
24271 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24272
24273 test_428() {
24274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24275         local cache_limit=$CACHE_MAX
24276
24277         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
24278         $LCTL set_param -n llite.*.max_cached_mb=64
24279
24280         mkdir $DIR/$tdir
24281         $LFS setstripe -c 1 $DIR/$tdir
24282         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
24283         stack_trap "rm -f $DIR/$tdir/$tfile.*"
24284         #test write
24285         for f in $(seq 4); do
24286                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
24287         done
24288         wait
24289
24290         cancel_lru_locks osc
24291         # Test read
24292         for f in $(seq 4); do
24293                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
24294         done
24295         wait
24296 }
24297 run_test 428 "large block size IO should not hang"
24298
24299 lseek_test_430() {
24300         local offset
24301         local file=$1
24302
24303         # data at [200K, 400K)
24304         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24305                 error "256K->512K dd fails"
24306         # data at [2M, 3M)
24307         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24308                 error "2M->3M dd fails"
24309         # data at [4M, 5M)
24310         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24311                 error "4M->5M dd fails"
24312         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24313         # start at first component hole #1
24314         printf "Seeking hole from 1000 ... "
24315         offset=$(lseek_test -l 1000 $file)
24316         echo $offset
24317         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24318         printf "Seeking data from 1000 ... "
24319         offset=$(lseek_test -d 1000 $file)
24320         echo $offset
24321         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24322
24323         # start at first component data block
24324         printf "Seeking hole from 300000 ... "
24325         offset=$(lseek_test -l 300000 $file)
24326         echo $offset
24327         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24328         printf "Seeking data from 300000 ... "
24329         offset=$(lseek_test -d 300000 $file)
24330         echo $offset
24331         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24332
24333         # start at the first component but beyond end of object size
24334         printf "Seeking hole from 1000000 ... "
24335         offset=$(lseek_test -l 1000000 $file)
24336         echo $offset
24337         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24338         printf "Seeking data from 1000000 ... "
24339         offset=$(lseek_test -d 1000000 $file)
24340         echo $offset
24341         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24342
24343         # start at second component stripe 2 (empty file)
24344         printf "Seeking hole from 1500000 ... "
24345         offset=$(lseek_test -l 1500000 $file)
24346         echo $offset
24347         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
24348         printf "Seeking data from 1500000 ... "
24349         offset=$(lseek_test -d 1500000 $file)
24350         echo $offset
24351         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24352
24353         # start at second component stripe 1 (all data)
24354         printf "Seeking hole from 3000000 ... "
24355         offset=$(lseek_test -l 3000000 $file)
24356         echo $offset
24357         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
24358         printf "Seeking data from 3000000 ... "
24359         offset=$(lseek_test -d 3000000 $file)
24360         echo $offset
24361         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
24362
24363         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
24364                 error "2nd dd fails"
24365         echo "Add data block at 640K...1280K"
24366
24367         # start at before new data block, in hole
24368         printf "Seeking hole from 600000 ... "
24369         offset=$(lseek_test -l 600000 $file)
24370         echo $offset
24371         [[ $offset == 600000 ]] || error "offset $offset != 600000"
24372         printf "Seeking data from 600000 ... "
24373         offset=$(lseek_test -d 600000 $file)
24374         echo $offset
24375         [[ $offset == 655360 ]] || error "offset $offset != 655360"
24376
24377         # start at the first component new data block
24378         printf "Seeking hole from 1000000 ... "
24379         offset=$(lseek_test -l 1000000 $file)
24380         echo $offset
24381         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24382         printf "Seeking data from 1000000 ... "
24383         offset=$(lseek_test -d 1000000 $file)
24384         echo $offset
24385         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24386
24387         # start at second component stripe 2, new data
24388         printf "Seeking hole from 1200000 ... "
24389         offset=$(lseek_test -l 1200000 $file)
24390         echo $offset
24391         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24392         printf "Seeking data from 1200000 ... "
24393         offset=$(lseek_test -d 1200000 $file)
24394         echo $offset
24395         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
24396
24397         # start beyond file end
24398         printf "Using offset > filesize ... "
24399         lseek_test -l 4000000 $file && error "lseek should fail"
24400         printf "Using offset > filesize ... "
24401         lseek_test -d 4000000 $file && error "lseek should fail"
24402
24403         printf "Done\n\n"
24404 }
24405
24406 test_430a() {
24407         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
24408                 skip "MDT does not support SEEK_HOLE"
24409
24410         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24411                 skip "OST does not support SEEK_HOLE"
24412
24413         local file=$DIR/$tdir/$tfile
24414
24415         mkdir -p $DIR/$tdir
24416
24417         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
24418         # OST stripe #1 will have continuous data at [1M, 3M)
24419         # OST stripe #2 is empty
24420         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
24421         lseek_test_430 $file
24422         rm $file
24423         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
24424         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
24425         lseek_test_430 $file
24426         rm $file
24427         $LFS setstripe -c2 -S 512K $file
24428         echo "Two stripes, stripe size 512K"
24429         lseek_test_430 $file
24430         rm $file
24431         # FLR with stale mirror
24432         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
24433                        -N -c2 -S 1M $file
24434         echo "Mirrored file:"
24435         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
24436         echo "Plain 2 stripes 1M"
24437         lseek_test_430 $file
24438         rm $file
24439 }
24440 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
24441
24442 test_430b() {
24443         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24444                 skip "OST does not support SEEK_HOLE"
24445
24446         local offset
24447         local file=$DIR/$tdir/$tfile
24448
24449         mkdir -p $DIR/$tdir
24450         # Empty layout lseek should fail
24451         $MCREATE $file
24452         # seek from 0
24453         printf "Seeking hole from 0 ... "
24454         lseek_test -l 0 $file && error "lseek should fail"
24455         printf "Seeking data from 0 ... "
24456         lseek_test -d 0 $file && error "lseek should fail"
24457         rm $file
24458
24459         # 1M-hole file
24460         $LFS setstripe -E 1M -c2 -E eof $file
24461         $TRUNCATE $file 1048576
24462         printf "Seeking hole from 1000000 ... "
24463         offset=$(lseek_test -l 1000000 $file)
24464         echo $offset
24465         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24466         printf "Seeking data from 1000000 ... "
24467         lseek_test -d 1000000 $file && error "lseek should fail"
24468         rm $file
24469
24470         # full component followed by non-inited one
24471         $LFS setstripe -E 1M -c2 -E eof $file
24472         dd if=/dev/urandom of=$file bs=1M count=1
24473         printf "Seeking hole from 1000000 ... "
24474         offset=$(lseek_test -l 1000000 $file)
24475         echo $offset
24476         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24477         printf "Seeking hole from 1048576 ... "
24478         lseek_test -l 1048576 $file && error "lseek should fail"
24479         # init second component and truncate back
24480         echo "123" >> $file
24481         $TRUNCATE $file 1048576
24482         printf "Seeking hole from 1000000 ... "
24483         offset=$(lseek_test -l 1000000 $file)
24484         echo $offset
24485         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24486         printf "Seeking hole from 1048576 ... "
24487         lseek_test -l 1048576 $file && error "lseek should fail"
24488         # boundary checks for big values
24489         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
24490         offset=$(lseek_test -d 0 $file.10g)
24491         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
24492         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
24493         offset=$(lseek_test -d 0 $file.100g)
24494         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
24495         return 0
24496 }
24497 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
24498
24499 test_430c() {
24500         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24501                 skip "OST does not support SEEK_HOLE"
24502
24503         local file=$DIR/$tdir/$tfile
24504         local start
24505
24506         mkdir -p $DIR/$tdir
24507         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
24508
24509         # cp version 8.33+ prefers lseek over fiemap
24510         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
24511                 start=$SECONDS
24512                 time cp $file /dev/null
24513                 (( SECONDS - start < 5 )) ||
24514                         error "cp: too long runtime $((SECONDS - start))"
24515
24516         fi
24517         # tar version 1.29+ supports SEEK_HOLE/DATA
24518         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
24519                 start=$SECONDS
24520                 time tar cS $file - | cat > /dev/null
24521                 (( SECONDS - start < 5 )) ||
24522                         error "tar: too long runtime $((SECONDS - start))"
24523         fi
24524 }
24525 run_test 430c "lseek: external tools check"
24526
24527 test_431() { # LU-14187
24528         local file=$DIR/$tdir/$tfile
24529
24530         mkdir -p $DIR/$tdir
24531         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
24532         dd if=/dev/urandom of=$file bs=4k count=1
24533         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
24534         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
24535         #define OBD_FAIL_OST_RESTART_IO 0x251
24536         do_facet ost1 "$LCTL set_param fail_loc=0x251"
24537         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
24538         cp $file $file.0
24539         cancel_lru_locks
24540         sync_all_data
24541         echo 3 > /proc/sys/vm/drop_caches
24542         diff  $file $file.0 || error "data diff"
24543 }
24544 run_test 431 "Restart transaction for IO"
24545
24546 prep_801() {
24547         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24548         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24549                 skip "Need server version at least 2.9.55"
24550
24551         start_full_debug_logging
24552 }
24553
24554 post_801() {
24555         stop_full_debug_logging
24556 }
24557
24558 barrier_stat() {
24559         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24560                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24561                            awk '/The barrier for/ { print $7 }')
24562                 echo $st
24563         else
24564                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24565                 echo \'$st\'
24566         fi
24567 }
24568
24569 barrier_expired() {
24570         local expired
24571
24572         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24573                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24574                           awk '/will be expired/ { print $7 }')
24575         else
24576                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24577         fi
24578
24579         echo $expired
24580 }
24581
24582 test_801a() {
24583         prep_801
24584
24585         echo "Start barrier_freeze at: $(date)"
24586         #define OBD_FAIL_BARRIER_DELAY          0x2202
24587         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24588         # Do not reduce barrier time - See LU-11873
24589         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24590
24591         sleep 2
24592         local b_status=$(barrier_stat)
24593         echo "Got barrier status at: $(date)"
24594         [ "$b_status" = "'freezing_p1'" ] ||
24595                 error "(1) unexpected barrier status $b_status"
24596
24597         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24598         wait
24599         b_status=$(barrier_stat)
24600         [ "$b_status" = "'frozen'" ] ||
24601                 error "(2) unexpected barrier status $b_status"
24602
24603         local expired=$(barrier_expired)
24604         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24605         sleep $((expired + 3))
24606
24607         b_status=$(barrier_stat)
24608         [ "$b_status" = "'expired'" ] ||
24609                 error "(3) unexpected barrier status $b_status"
24610
24611         # Do not reduce barrier time - See LU-11873
24612         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24613                 error "(4) fail to freeze barrier"
24614
24615         b_status=$(barrier_stat)
24616         [ "$b_status" = "'frozen'" ] ||
24617                 error "(5) unexpected barrier status $b_status"
24618
24619         echo "Start barrier_thaw at: $(date)"
24620         #define OBD_FAIL_BARRIER_DELAY          0x2202
24621         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24622         do_facet mgs $LCTL barrier_thaw $FSNAME &
24623
24624         sleep 2
24625         b_status=$(barrier_stat)
24626         echo "Got barrier status at: $(date)"
24627         [ "$b_status" = "'thawing'" ] ||
24628                 error "(6) unexpected barrier status $b_status"
24629
24630         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24631         wait
24632         b_status=$(barrier_stat)
24633         [ "$b_status" = "'thawed'" ] ||
24634                 error "(7) unexpected barrier status $b_status"
24635
24636         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24637         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24638         do_facet mgs $LCTL barrier_freeze $FSNAME
24639
24640         b_status=$(barrier_stat)
24641         [ "$b_status" = "'failed'" ] ||
24642                 error "(8) unexpected barrier status $b_status"
24643
24644         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24645         do_facet mgs $LCTL barrier_thaw $FSNAME
24646
24647         post_801
24648 }
24649 run_test 801a "write barrier user interfaces and stat machine"
24650
24651 test_801b() {
24652         prep_801
24653
24654         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24655         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24656         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24657         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24658         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24659
24660         cancel_lru_locks mdc
24661
24662         # 180 seconds should be long enough
24663         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24664
24665         local b_status=$(barrier_stat)
24666         [ "$b_status" = "'frozen'" ] ||
24667                 error "(6) unexpected barrier status $b_status"
24668
24669         mkdir $DIR/$tdir/d0/d10 &
24670         mkdir_pid=$!
24671
24672         touch $DIR/$tdir/d1/f13 &
24673         touch_pid=$!
24674
24675         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24676         ln_pid=$!
24677
24678         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24679         mv_pid=$!
24680
24681         rm -f $DIR/$tdir/d4/f12 &
24682         rm_pid=$!
24683
24684         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24685
24686         # To guarantee taht the 'stat' is not blocked
24687         b_status=$(barrier_stat)
24688         [ "$b_status" = "'frozen'" ] ||
24689                 error "(8) unexpected barrier status $b_status"
24690
24691         # let above commands to run at background
24692         sleep 5
24693
24694         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24695         ps -p $touch_pid || error "(10) touch should be blocked"
24696         ps -p $ln_pid || error "(11) link should be blocked"
24697         ps -p $mv_pid || error "(12) rename should be blocked"
24698         ps -p $rm_pid || error "(13) unlink should be blocked"
24699
24700         b_status=$(barrier_stat)
24701         [ "$b_status" = "'frozen'" ] ||
24702                 error "(14) unexpected barrier status $b_status"
24703
24704         do_facet mgs $LCTL barrier_thaw $FSNAME
24705         b_status=$(barrier_stat)
24706         [ "$b_status" = "'thawed'" ] ||
24707                 error "(15) unexpected barrier status $b_status"
24708
24709         wait $mkdir_pid || error "(16) mkdir should succeed"
24710         wait $touch_pid || error "(17) touch should succeed"
24711         wait $ln_pid || error "(18) link should succeed"
24712         wait $mv_pid || error "(19) rename should succeed"
24713         wait $rm_pid || error "(20) unlink should succeed"
24714
24715         post_801
24716 }
24717 run_test 801b "modification will be blocked by write barrier"
24718
24719 test_801c() {
24720         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24721
24722         prep_801
24723
24724         stop mds2 || error "(1) Fail to stop mds2"
24725
24726         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24727
24728         local b_status=$(barrier_stat)
24729         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24730                 do_facet mgs $LCTL barrier_thaw $FSNAME
24731                 error "(2) unexpected barrier status $b_status"
24732         }
24733
24734         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24735                 error "(3) Fail to rescan barrier bitmap"
24736
24737         # Do not reduce barrier time - See LU-11873
24738         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24739
24740         b_status=$(barrier_stat)
24741         [ "$b_status" = "'frozen'" ] ||
24742                 error "(4) unexpected barrier status $b_status"
24743
24744         do_facet mgs $LCTL barrier_thaw $FSNAME
24745         b_status=$(barrier_stat)
24746         [ "$b_status" = "'thawed'" ] ||
24747                 error "(5) unexpected barrier status $b_status"
24748
24749         local devname=$(mdsdevname 2)
24750
24751         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24752
24753         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24754                 error "(7) Fail to rescan barrier bitmap"
24755
24756         post_801
24757 }
24758 run_test 801c "rescan barrier bitmap"
24759
24760 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24761 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24762 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24763 saved_MOUNT_OPTS=$MOUNT_OPTS
24764
24765 cleanup_802a() {
24766         trap 0
24767
24768         stopall
24769         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24770         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24771         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24772         MOUNT_OPTS=$saved_MOUNT_OPTS
24773         setupall
24774 }
24775
24776 test_802a() {
24777         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24778         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24779         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24780                 skip "Need server version at least 2.9.55"
24781
24782         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24783
24784         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24785
24786         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24787                 error "(2) Fail to copy"
24788
24789         trap cleanup_802a EXIT
24790
24791         # sync by force before remount as readonly
24792         sync; sync_all_data; sleep 3; sync_all_data
24793
24794         stopall
24795
24796         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24797         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24798         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24799
24800         echo "Mount the server as read only"
24801         setupall server_only || error "(3) Fail to start servers"
24802
24803         echo "Mount client without ro should fail"
24804         mount_client $MOUNT &&
24805                 error "(4) Mount client without 'ro' should fail"
24806
24807         echo "Mount client with ro should succeed"
24808         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24809         mount_client $MOUNT ||
24810                 error "(5) Mount client with 'ro' should succeed"
24811
24812         echo "Modify should be refused"
24813         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24814
24815         echo "Read should be allowed"
24816         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24817                 error "(7) Read should succeed under ro mode"
24818
24819         cleanup_802a
24820 }
24821 run_test 802a "simulate readonly device"
24822
24823 test_802b() {
24824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24825         remote_mds_nodsh && skip "remote MDS with nodsh"
24826
24827         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24828                 skip "readonly option not available"
24829
24830         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24831
24832         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24833                 error "(2) Fail to copy"
24834
24835         # write back all cached data before setting MDT to readonly
24836         cancel_lru_locks
24837         sync_all_data
24838
24839         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24840         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24841
24842         echo "Modify should be refused"
24843         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24844
24845         echo "Read should be allowed"
24846         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24847                 error "(7) Read should succeed under ro mode"
24848
24849         # disable readonly
24850         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24851 }
24852 run_test 802b "be able to set MDTs to readonly"
24853
24854 test_803a() {
24855         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24856         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24857                 skip "MDS needs to be newer than 2.10.54"
24858
24859         mkdir -p $DIR/$tdir
24860         # Create some objects on all MDTs to trigger related logs objects
24861         for idx in $(seq $MDSCOUNT); do
24862                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24863                         $DIR/$tdir/dir${idx} ||
24864                         error "Fail to create $DIR/$tdir/dir${idx}"
24865         done
24866
24867         sync; sleep 3
24868         wait_delete_completed # ensure old test cleanups are finished
24869         echo "before create:"
24870         $LFS df -i $MOUNT
24871         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24872
24873         for i in {1..10}; do
24874                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24875                         error "Fail to create $DIR/$tdir/foo$i"
24876         done
24877
24878         sync; sleep 3
24879         echo "after create:"
24880         $LFS df -i $MOUNT
24881         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24882
24883         # allow for an llog to be cleaned up during the test
24884         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24885                 error "before ($before_used) + 10 > after ($after_used)"
24886
24887         for i in {1..10}; do
24888                 rm -rf $DIR/$tdir/foo$i ||
24889                         error "Fail to remove $DIR/$tdir/foo$i"
24890         done
24891
24892         sleep 3 # avoid MDT return cached statfs
24893         wait_delete_completed
24894         echo "after unlink:"
24895         $LFS df -i $MOUNT
24896         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24897
24898         # allow for an llog to be created during the test
24899         [ $after_used -le $((before_used + 1)) ] ||
24900                 error "after ($after_used) > before ($before_used) + 1"
24901 }
24902 run_test 803a "verify agent object for remote object"
24903
24904 test_803b() {
24905         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24906         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24907                 skip "MDS needs to be newer than 2.13.56"
24908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24909
24910         for i in $(seq 0 $((MDSCOUNT - 1))); do
24911                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24912         done
24913
24914         local before=0
24915         local after=0
24916
24917         local tmp
24918
24919         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24920         for i in $(seq 0 $((MDSCOUNT - 1))); do
24921                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24922                         awk '/getattr/ { print $2 }')
24923                 before=$((before + tmp))
24924         done
24925         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24926         for i in $(seq 0 $((MDSCOUNT - 1))); do
24927                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24928                         awk '/getattr/ { print $2 }')
24929                 after=$((after + tmp))
24930         done
24931
24932         [ $before -eq $after ] || error "getattr count $before != $after"
24933 }
24934 run_test 803b "remote object can getattr from cache"
24935
24936 test_804() {
24937         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24938         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24939                 skip "MDS needs to be newer than 2.10.54"
24940         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24941
24942         mkdir -p $DIR/$tdir
24943         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24944                 error "Fail to create $DIR/$tdir/dir0"
24945
24946         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24947         local dev=$(mdsdevname 2)
24948
24949         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24950                 grep ${fid} || error "NOT found agent entry for dir0"
24951
24952         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24953                 error "Fail to create $DIR/$tdir/dir1"
24954
24955         touch $DIR/$tdir/dir1/foo0 ||
24956                 error "Fail to create $DIR/$tdir/dir1/foo0"
24957         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24958         local rc=0
24959
24960         for idx in $(seq $MDSCOUNT); do
24961                 dev=$(mdsdevname $idx)
24962                 do_facet mds${idx} \
24963                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24964                         grep ${fid} && rc=$idx
24965         done
24966
24967         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24968                 error "Fail to rename foo0 to foo1"
24969         if [ $rc -eq 0 ]; then
24970                 for idx in $(seq $MDSCOUNT); do
24971                         dev=$(mdsdevname $idx)
24972                         do_facet mds${idx} \
24973                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24974                         grep ${fid} && rc=$idx
24975                 done
24976         fi
24977
24978         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24979                 error "Fail to rename foo1 to foo2"
24980         if [ $rc -eq 0 ]; then
24981                 for idx in $(seq $MDSCOUNT); do
24982                         dev=$(mdsdevname $idx)
24983                         do_facet mds${idx} \
24984                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24985                         grep ${fid} && rc=$idx
24986                 done
24987         fi
24988
24989         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24990
24991         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24992                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24993         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24994                 error "Fail to rename foo2 to foo0"
24995         unlink $DIR/$tdir/dir1/foo0 ||
24996                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24997         rm -rf $DIR/$tdir/dir0 ||
24998                 error "Fail to rm $DIR/$tdir/dir0"
24999
25000         for idx in $(seq $MDSCOUNT); do
25001                 dev=$(mdsdevname $idx)
25002                 rc=0
25003
25004                 stop mds${idx}
25005                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25006                         rc=$?
25007                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25008                         error "mount mds$idx failed"
25009                 df $MOUNT > /dev/null 2>&1
25010
25011                 # e2fsck should not return error
25012                 [ $rc -eq 0 ] ||
25013                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25014         done
25015 }
25016 run_test 804 "verify agent entry for remote entry"
25017
25018 cleanup_805() {
25019         do_facet $SINGLEMDS zfs set quota=$old $fsset
25020         unlinkmany $DIR/$tdir/f- 1000000
25021         trap 0
25022 }
25023
25024 test_805() {
25025         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25026         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25027         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25028                 skip "netfree not implemented before 0.7"
25029         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25030                 skip "Need MDS version at least 2.10.57"
25031
25032         local fsset
25033         local freekb
25034         local usedkb
25035         local old
25036         local quota
25037         local pref="osd-zfs.$FSNAME-MDT0000."
25038
25039         # limit available space on MDS dataset to meet nospace issue
25040         # quickly. then ZFS 0.7.2 can use reserved space if asked
25041         # properly (using netfree flag in osd_declare_destroy()
25042         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25043         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25044                 gawk '{print $3}')
25045         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25046         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25047         let "usedkb=usedkb-freekb"
25048         let "freekb=freekb/2"
25049         if let "freekb > 5000"; then
25050                 let "freekb=5000"
25051         fi
25052         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25053         trap cleanup_805 EXIT
25054         mkdir $DIR/$tdir
25055         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25056                 error "Can't set PFL layout"
25057         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25058         rm -rf $DIR/$tdir || error "not able to remove"
25059         do_facet $SINGLEMDS zfs set quota=$old $fsset
25060         trap 0
25061 }
25062 run_test 805 "ZFS can remove from full fs"
25063
25064 # Size-on-MDS test
25065 check_lsom_data()
25066 {
25067         local file=$1
25068         local size=$($LFS getsom -s $file)
25069         local expect=$(stat -c %s $file)
25070
25071         [[ $size == $expect ]] ||
25072                 error "$file expected size: $expect, got: $size"
25073
25074         local blocks=$($LFS getsom -b $file)
25075         expect=$(stat -c %b $file)
25076         [[ $blocks == $expect ]] ||
25077                 error "$file expected blocks: $expect, got: $blocks"
25078 }
25079
25080 check_lsom_size()
25081 {
25082         local size=$($LFS getsom -s $1)
25083         local expect=$2
25084
25085         [[ $size == $expect ]] ||
25086                 error "$file expected size: $expect, got: $size"
25087 }
25088
25089 test_806() {
25090         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25091                 skip "Need MDS version at least 2.11.52"
25092
25093         local bs=1048576
25094
25095         touch $DIR/$tfile || error "touch $tfile failed"
25096
25097         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25098         save_lustre_params client "llite.*.xattr_cache" > $save
25099         lctl set_param llite.*.xattr_cache=0
25100         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25101
25102         # single-threaded write
25103         echo "Test SOM for single-threaded write"
25104         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25105                 error "write $tfile failed"
25106         check_lsom_size $DIR/$tfile $bs
25107
25108         local num=32
25109         local size=$(($num * $bs))
25110         local offset=0
25111         local i
25112
25113         echo "Test SOM for single client multi-threaded($num) write"
25114         $TRUNCATE $DIR/$tfile 0
25115         for ((i = 0; i < $num; i++)); do
25116                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25117                 local pids[$i]=$!
25118                 offset=$((offset + $bs))
25119         done
25120         for (( i=0; i < $num; i++ )); do
25121                 wait ${pids[$i]}
25122         done
25123         check_lsom_size $DIR/$tfile $size
25124
25125         $TRUNCATE $DIR/$tfile 0
25126         for ((i = 0; i < $num; i++)); do
25127                 offset=$((offset - $bs))
25128                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25129                 local pids[$i]=$!
25130         done
25131         for (( i=0; i < $num; i++ )); do
25132                 wait ${pids[$i]}
25133         done
25134         check_lsom_size $DIR/$tfile $size
25135
25136         # multi-client writes
25137         num=$(get_node_count ${CLIENTS//,/ })
25138         size=$(($num * $bs))
25139         offset=0
25140         i=0
25141
25142         echo "Test SOM for multi-client ($num) writes"
25143         $TRUNCATE $DIR/$tfile 0
25144         for client in ${CLIENTS//,/ }; do
25145                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25146                 local pids[$i]=$!
25147                 i=$((i + 1))
25148                 offset=$((offset + $bs))
25149         done
25150         for (( i=0; i < $num; i++ )); do
25151                 wait ${pids[$i]}
25152         done
25153         check_lsom_size $DIR/$tfile $offset
25154
25155         i=0
25156         $TRUNCATE $DIR/$tfile 0
25157         for client in ${CLIENTS//,/ }; do
25158                 offset=$((offset - $bs))
25159                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25160                 local pids[$i]=$!
25161                 i=$((i + 1))
25162         done
25163         for (( i=0; i < $num; i++ )); do
25164                 wait ${pids[$i]}
25165         done
25166         check_lsom_size $DIR/$tfile $size
25167
25168         # verify truncate
25169         echo "Test SOM for truncate"
25170         $TRUNCATE $DIR/$tfile 1048576
25171         check_lsom_size $DIR/$tfile 1048576
25172         $TRUNCATE $DIR/$tfile 1234
25173         check_lsom_size $DIR/$tfile 1234
25174
25175         # verify SOM blocks count
25176         echo "Verify SOM block count"
25177         $TRUNCATE $DIR/$tfile 0
25178         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25179                 error "failed to write file $tfile"
25180         check_lsom_data $DIR/$tfile
25181 }
25182 run_test 806 "Verify Lazy Size on MDS"
25183
25184 test_807() {
25185         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25186         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25187                 skip "Need MDS version at least 2.11.52"
25188
25189         # Registration step
25190         changelog_register || error "changelog_register failed"
25191         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25192         changelog_users $SINGLEMDS | grep -q $cl_user ||
25193                 error "User $cl_user not found in changelog_users"
25194
25195         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25196         save_lustre_params client "llite.*.xattr_cache" > $save
25197         lctl set_param llite.*.xattr_cache=0
25198         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25199
25200         rm -rf $DIR/$tdir || error "rm $tdir failed"
25201         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25202         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25203         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25204         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25205                 error "truncate $tdir/trunc failed"
25206
25207         local bs=1048576
25208         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25209                 error "write $tfile failed"
25210
25211         # multi-client wirtes
25212         local num=$(get_node_count ${CLIENTS//,/ })
25213         local offset=0
25214         local i=0
25215
25216         echo "Test SOM for multi-client ($num) writes"
25217         touch $DIR/$tfile || error "touch $tfile failed"
25218         $TRUNCATE $DIR/$tfile 0
25219         for client in ${CLIENTS//,/ }; do
25220                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25221                 local pids[$i]=$!
25222                 i=$((i + 1))
25223                 offset=$((offset + $bs))
25224         done
25225         for (( i=0; i < $num; i++ )); do
25226                 wait ${pids[$i]}
25227         done
25228
25229         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25230         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25231         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25232         check_lsom_data $DIR/$tdir/trunc
25233         check_lsom_data $DIR/$tdir/single_dd
25234         check_lsom_data $DIR/$tfile
25235
25236         rm -rf $DIR/$tdir
25237         # Deregistration step
25238         changelog_deregister || error "changelog_deregister failed"
25239 }
25240 run_test 807 "verify LSOM syncing tool"
25241
25242 check_som_nologged()
25243 {
25244         local lines=$($LFS changelog $FSNAME-MDT0000 |
25245                 grep 'x=trusted.som' | wc -l)
25246         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25247 }
25248
25249 test_808() {
25250         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25251                 skip "Need MDS version at least 2.11.55"
25252
25253         # Registration step
25254         changelog_register || error "changelog_register failed"
25255
25256         touch $DIR/$tfile || error "touch $tfile failed"
25257         check_som_nologged
25258
25259         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25260                 error "write $tfile failed"
25261         check_som_nologged
25262
25263         $TRUNCATE $DIR/$tfile 1234
25264         check_som_nologged
25265
25266         $TRUNCATE $DIR/$tfile 1048576
25267         check_som_nologged
25268
25269         # Deregistration step
25270         changelog_deregister || error "changelog_deregister failed"
25271 }
25272 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25273
25274 check_som_nodata()
25275 {
25276         $LFS getsom $1
25277         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25278 }
25279
25280 test_809() {
25281         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25282                 skip "Need MDS version at least 2.11.56"
25283
25284         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25285                 error "failed to create DoM-only file $DIR/$tfile"
25286         touch $DIR/$tfile || error "touch $tfile failed"
25287         check_som_nodata $DIR/$tfile
25288
25289         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25290                 error "write $tfile failed"
25291         check_som_nodata $DIR/$tfile
25292
25293         $TRUNCATE $DIR/$tfile 1234
25294         check_som_nodata $DIR/$tfile
25295
25296         $TRUNCATE $DIR/$tfile 4097
25297         check_som_nodata $DIR/$file
25298 }
25299 run_test 809 "Verify no SOM xattr store for DoM-only files"
25300
25301 test_810() {
25302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25303         $GSS && skip_env "could not run with gss"
25304         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25305                 skip "OST < 2.12.58 doesn't align checksum"
25306
25307         set_checksums 1
25308         stack_trap "set_checksums $ORIG_CSUM" EXIT
25309         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25310
25311         local csum
25312         local before
25313         local after
25314         for csum in $CKSUM_TYPES; do
25315                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25316                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25317                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25318                         eval set -- $i
25319                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25320                         before=$(md5sum $DIR/$tfile)
25321                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25322                         after=$(md5sum $DIR/$tfile)
25323                         [ "$before" == "$after" ] ||
25324                                 error "$csum: $before != $after bs=$1 seek=$2"
25325                 done
25326         done
25327 }
25328 run_test 810 "partial page writes on ZFS (LU-11663)"
25329
25330 test_812a() {
25331         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25332                 skip "OST < 2.12.51 doesn't support this fail_loc"
25333
25334         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25335         # ensure ost1 is connected
25336         stat $DIR/$tfile >/dev/null || error "can't stat"
25337         wait_osc_import_state client ost1 FULL
25338         # no locks, no reqs to let the connection idle
25339         cancel_lru_locks osc
25340
25341         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25342 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25343         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25344         wait_osc_import_state client ost1 CONNECTING
25345         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25346
25347         stat $DIR/$tfile >/dev/null || error "can't stat file"
25348 }
25349 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
25350
25351 test_812b() { # LU-12378
25352         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25353                 skip "OST < 2.12.51 doesn't support this fail_loc"
25354
25355         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
25356         # ensure ost1 is connected
25357         stat $DIR/$tfile >/dev/null || error "can't stat"
25358         wait_osc_import_state client ost1 FULL
25359         # no locks, no reqs to let the connection idle
25360         cancel_lru_locks osc
25361
25362         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25363 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25364         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25365         wait_osc_import_state client ost1 CONNECTING
25366         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25367
25368         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
25369         wait_osc_import_state client ost1 IDLE
25370 }
25371 run_test 812b "do not drop no resend request for idle connect"
25372
25373 test_813() {
25374         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
25375         [ -z "$file_heat_sav" ] && skip "no file heat support"
25376
25377         local readsample
25378         local writesample
25379         local readbyte
25380         local writebyte
25381         local readsample1
25382         local writesample1
25383         local readbyte1
25384         local writebyte1
25385
25386         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
25387         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
25388
25389         $LCTL set_param -n llite.*.file_heat=1
25390         echo "Turn on file heat"
25391         echo "Period second: $period_second, Decay percentage: $decay_pct"
25392
25393         echo "QQQQ" > $DIR/$tfile
25394         echo "QQQQ" > $DIR/$tfile
25395         echo "QQQQ" > $DIR/$tfile
25396         cat $DIR/$tfile > /dev/null
25397         cat $DIR/$tfile > /dev/null
25398         cat $DIR/$tfile > /dev/null
25399         cat $DIR/$tfile > /dev/null
25400
25401         local out=$($LFS heat_get $DIR/$tfile)
25402
25403         $LFS heat_get $DIR/$tfile
25404         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25405         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25406         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25407         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25408
25409         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
25410         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
25411         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
25412         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
25413
25414         sleep $((period_second + 3))
25415         echo "Sleep $((period_second + 3)) seconds..."
25416         # The recursion formula to calculate the heat of the file f is as
25417         # follow:
25418         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
25419         # Where Hi is the heat value in the period between time points i*I and
25420         # (i+1)*I; Ci is the access count in the period; the symbol P refers
25421         # to the weight of Ci.
25422         out=$($LFS heat_get $DIR/$tfile)
25423         $LFS heat_get $DIR/$tfile
25424         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25425         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25426         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25427         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25428
25429         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
25430                 error "read sample ($readsample) is wrong"
25431         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
25432                 error "write sample ($writesample) is wrong"
25433         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
25434                 error "read bytes ($readbyte) is wrong"
25435         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
25436                 error "write bytes ($writebyte) is wrong"
25437
25438         echo "QQQQ" > $DIR/$tfile
25439         echo "QQQQ" > $DIR/$tfile
25440         echo "QQQQ" > $DIR/$tfile
25441         cat $DIR/$tfile > /dev/null
25442         cat $DIR/$tfile > /dev/null
25443         cat $DIR/$tfile > /dev/null
25444         cat $DIR/$tfile > /dev/null
25445
25446         sleep $((period_second + 3))
25447         echo "Sleep $((period_second + 3)) seconds..."
25448
25449         out=$($LFS heat_get $DIR/$tfile)
25450         $LFS heat_get $DIR/$tfile
25451         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25452         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25453         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25454         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25455
25456         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
25457                 4 * $decay_pct) / 100") -eq 1 ] ||
25458                 error "read sample ($readsample1) is wrong"
25459         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
25460                 3 * $decay_pct) / 100") -eq 1 ] ||
25461                 error "write sample ($writesample1) is wrong"
25462         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
25463                 20 * $decay_pct) / 100") -eq 1 ] ||
25464                 error "read bytes ($readbyte1) is wrong"
25465         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
25466                 15 * $decay_pct) / 100") -eq 1 ] ||
25467                 error "write bytes ($writebyte1) is wrong"
25468
25469         echo "Turn off file heat for the file $DIR/$tfile"
25470         $LFS heat_set -o $DIR/$tfile
25471
25472         echo "QQQQ" > $DIR/$tfile
25473         echo "QQQQ" > $DIR/$tfile
25474         echo "QQQQ" > $DIR/$tfile
25475         cat $DIR/$tfile > /dev/null
25476         cat $DIR/$tfile > /dev/null
25477         cat $DIR/$tfile > /dev/null
25478         cat $DIR/$tfile > /dev/null
25479
25480         out=$($LFS heat_get $DIR/$tfile)
25481         $LFS heat_get $DIR/$tfile
25482         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25483         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25484         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25485         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25486
25487         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25488         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25489         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25490         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25491
25492         echo "Trun on file heat for the file $DIR/$tfile"
25493         $LFS heat_set -O $DIR/$tfile
25494
25495         echo "QQQQ" > $DIR/$tfile
25496         echo "QQQQ" > $DIR/$tfile
25497         echo "QQQQ" > $DIR/$tfile
25498         cat $DIR/$tfile > /dev/null
25499         cat $DIR/$tfile > /dev/null
25500         cat $DIR/$tfile > /dev/null
25501         cat $DIR/$tfile > /dev/null
25502
25503         out=$($LFS heat_get $DIR/$tfile)
25504         $LFS heat_get $DIR/$tfile
25505         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25506         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25507         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25508         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25509
25510         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
25511         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
25512         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
25513         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
25514
25515         $LFS heat_set -c $DIR/$tfile
25516         $LCTL set_param -n llite.*.file_heat=0
25517         echo "Turn off file heat support for the Lustre filesystem"
25518
25519         echo "QQQQ" > $DIR/$tfile
25520         echo "QQQQ" > $DIR/$tfile
25521         echo "QQQQ" > $DIR/$tfile
25522         cat $DIR/$tfile > /dev/null
25523         cat $DIR/$tfile > /dev/null
25524         cat $DIR/$tfile > /dev/null
25525         cat $DIR/$tfile > /dev/null
25526
25527         out=$($LFS heat_get $DIR/$tfile)
25528         $LFS heat_get $DIR/$tfile
25529         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25530         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25531         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25532         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25533
25534         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25535         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25536         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25537         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25538
25539         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
25540         rm -f $DIR/$tfile
25541 }
25542 run_test 813 "File heat verfication"
25543
25544 test_814()
25545 {
25546         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25547         echo -n y >> $DIR/$tfile
25548         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25549         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25550 }
25551 run_test 814 "sparse cp works as expected (LU-12361)"
25552
25553 test_815()
25554 {
25555         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25556         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25557 }
25558 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25559
25560 test_816() {
25561         local ost1_imp=$(get_osc_import_name client ost1)
25562         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25563                          cut -d'.' -f2)
25564
25565         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25566         # ensure ost1 is connected
25567
25568         stat $DIR/$tfile >/dev/null || error "can't stat"
25569         wait_osc_import_state client ost1 FULL
25570         # no locks, no reqs to let the connection idle
25571         cancel_lru_locks osc
25572         lru_resize_disable osc
25573         local before
25574         local now
25575         before=$($LCTL get_param -n \
25576                  ldlm.namespaces.$imp_name.lru_size)
25577
25578         wait_osc_import_state client ost1 IDLE
25579         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25580         now=$($LCTL get_param -n \
25581               ldlm.namespaces.$imp_name.lru_size)
25582         [ $before == $now ] || error "lru_size changed $before != $now"
25583 }
25584 run_test 816 "do not reset lru_resize on idle reconnect"
25585
25586 cleanup_817() {
25587         umount $tmpdir
25588         exportfs -u localhost:$DIR/nfsexp
25589         rm -rf $DIR/nfsexp
25590 }
25591
25592 test_817() {
25593         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25594
25595         mkdir -p $DIR/nfsexp
25596         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25597                 error "failed to export nfs"
25598
25599         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25600         stack_trap cleanup_817 EXIT
25601
25602         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25603                 error "failed to mount nfs to $tmpdir"
25604
25605         cp /bin/true $tmpdir
25606         $DIR/nfsexp/true || error "failed to execute 'true' command"
25607 }
25608 run_test 817 "nfsd won't cache write lock for exec file"
25609
25610 test_818() {
25611         mkdir $DIR/$tdir
25612         $LFS setstripe -c1 -i0 $DIR/$tfile
25613         $LFS setstripe -c1 -i1 $DIR/$tfile
25614         stop $SINGLEMDS
25615         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25616         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25617         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25618                 error "start $SINGLEMDS failed"
25619         rm -rf $DIR/$tdir
25620 }
25621 run_test 818 "unlink with failed llog"
25622
25623 test_819a() {
25624         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25625         cancel_lru_locks osc
25626         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25627         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25628         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25629         rm -f $TDIR/$tfile
25630 }
25631 run_test 819a "too big niobuf in read"
25632
25633 test_819b() {
25634         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25635         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25636         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25637         cancel_lru_locks osc
25638         sleep 1
25639         rm -f $TDIR/$tfile
25640 }
25641 run_test 819b "too big niobuf in write"
25642
25643
25644 function test_820_start_ost() {
25645         sleep 5
25646
25647         for num in $(seq $OSTCOUNT); do
25648                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25649         done
25650 }
25651
25652 test_820() {
25653         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25654
25655         mkdir $DIR/$tdir
25656         umount_client $MOUNT || error "umount failed"
25657         for num in $(seq $OSTCOUNT); do
25658                 stop ost$num
25659         done
25660
25661         # mount client with no active OSTs
25662         # so that the client can't initialize max LOV EA size
25663         # from OSC notifications
25664         mount_client $MOUNT || error "mount failed"
25665         # delay OST starting to keep this 0 max EA size for a while
25666         test_820_start_ost &
25667
25668         # create a directory on MDS2
25669         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25670                 error "Failed to create directory"
25671         # open intent should update default EA size
25672         # see mdc_update_max_ea_from_body()
25673         # notice this is the very first RPC to MDS2
25674         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25675         ret=$?
25676         echo $out
25677         # With SSK, this situation can lead to -EPERM being returned.
25678         # In that case, simply retry.
25679         if [ $ret -ne 0 ] && $SHARED_KEY; then
25680                 if echo "$out" | grep -q "not permitted"; then
25681                         cp /etc/services $DIR/$tdir/mds2
25682                         ret=$?
25683                 fi
25684         fi
25685         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25686 }
25687 run_test 820 "update max EA from open intent"
25688
25689 test_822() {
25690         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
25691
25692         save_lustre_params mds1 \
25693                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
25694         do_facet $SINGLEMDS "$LCTL set_param -n \
25695                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
25696         do_facet $SINGLEMDS "$LCTL set_param -n \
25697                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
25698
25699         # wait for statfs update to clear OS_STATFS_NOPRECREATE
25700         local maxage=$(do_facet mds1 $LCTL get_param -n \
25701                        osp.$FSNAME-OST0000*MDT0000.maxage)
25702         sleep $((maxage + 1))
25703
25704         #define OBD_FAIL_NET_ERROR_RPC          0x532
25705         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
25706
25707         stack_trap "restore_lustre_params < $p; rm $p"
25708
25709         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
25710                       osp.$FSNAME-OST0000*MDT0000.create_count")
25711         for i in $(seq 1 $count); do
25712                 touch $DIR/$tfile.${i} || error "touch failed"
25713         done
25714 }
25715 run_test 822 "test precreate failure"
25716
25717 #
25718 # tests that do cleanup/setup should be run at the end
25719 #
25720
25721 test_900() {
25722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25723         local ls
25724
25725         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25726         $LCTL set_param fail_loc=0x903
25727
25728         cancel_lru_locks MGC
25729
25730         FAIL_ON_ERROR=true cleanup
25731         FAIL_ON_ERROR=true setup
25732 }
25733 run_test 900 "umount should not race with any mgc requeue thread"
25734
25735 # LUS-6253/LU-11185
25736 test_901() {
25737         local oldc
25738         local newc
25739         local olds
25740         local news
25741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25742
25743         # some get_param have a bug to handle dot in param name
25744         cancel_lru_locks MGC
25745         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25746         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25747         umount_client $MOUNT || error "umount failed"
25748         mount_client $MOUNT || error "mount failed"
25749         cancel_lru_locks MGC
25750         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25751         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25752
25753         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25754         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25755
25756         return 0
25757 }
25758 run_test 901 "don't leak a mgc lock on client umount"
25759
25760 # LU-13377
25761 test_902() {
25762         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25763                 skip "client does not have LU-13377 fix"
25764         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25765         $LCTL set_param fail_loc=0x1415
25766         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25767         cancel_lru_locks osc
25768         rm -f $DIR/$tfile
25769 }
25770 run_test 902 "test short write doesn't hang lustre"
25771
25772 complete $SECONDS
25773 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25774 check_and_cleanup_lustre
25775 if [ "$I_MOUNTED" != "yes" ]; then
25776         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25777 fi
25778 exit_status