Whamcloud - gitweb
75b356566e8c9927eab4c376e0e3c52950e4ffdd
[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=true
3958         test_mkdir $DIR/$tdir
3959         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3960
3961         sync
3962         for ostnum in $(seq $OSTCOUNT); do
3963                 # test-framework's OST numbering is one-based, while Lustre's
3964                 # is zero-based
3965                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3966                 # check if at least some write_bytes stats are counted
3967                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3968                               obdfilter.$ostname.stats |
3969                               awk '/^write_bytes/ {print $7}' )
3970                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
3971                 if (( ${write_bytes:-0} > 0 )); then
3972                         all_zeros=false
3973                         break
3974                 fi
3975         done
3976
3977         $all_zeros || return 0
3978
3979         # Write four bytes
3980         echo foo > $DIR/$tdir/bar
3981         # Really write them
3982         sync
3983
3984         # Total up write_bytes after writing.  We'd better find non-zeros.
3985         for ostnum in $(seq $OSTCOUNT); do
3986                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3987                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3988                               obdfilter/$ostname/stats |
3989                               awk '/^write_bytes/ {print $7}' )
3990                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
3991                 if (( ${write_bytes:-0} > 0 )); then
3992                         all_zeros=false
3993                         break
3994                 fi
3995         done
3996
3997         if $all_zeros; then
3998                 for ostnum in $(seq $OSTCOUNT); do
3999                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4000                         echo "Check write_bytes is in obdfilter.*.stats:"
4001                         do_facet ost$ostnum lctl get_param -n \
4002                                 obdfilter.$ostname.stats
4003                 done
4004                 error "OST not keeping write_bytes stats (b=22312)"
4005         fi
4006 }
4007 run_test 33c "test write_bytes stats"
4008
4009 test_33d() {
4010         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4012
4013         local MDTIDX=1
4014         local remote_dir=$DIR/$tdir/remote_dir
4015
4016         test_mkdir $DIR/$tdir
4017         $LFS mkdir -i $MDTIDX $remote_dir ||
4018                 error "create remote directory failed"
4019
4020         touch $remote_dir/$tfile
4021         chmod 444 $remote_dir/$tfile
4022         chown $RUNAS_ID $remote_dir/$tfile
4023
4024         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4025
4026         chown $RUNAS_ID $remote_dir
4027         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4028                                         error "create" || true
4029         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4030                                     error "open RDWR" || true
4031         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4032 }
4033 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4034
4035 test_33e() {
4036         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4037
4038         mkdir $DIR/$tdir
4039
4040         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4041         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4042         mkdir $DIR/$tdir/local_dir
4043
4044         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4045         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4046         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4047
4048         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4049                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4050
4051         rmdir $DIR/$tdir/* || error "rmdir failed"
4052
4053         umask 777
4054         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4055         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4056         mkdir $DIR/$tdir/local_dir
4057
4058         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4059         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4060         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4061
4062         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4063                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4064
4065         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4066
4067         umask 000
4068         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4069         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4070         mkdir $DIR/$tdir/local_dir
4071
4072         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4073         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4074         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4075
4076         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4077                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4078 }
4079 run_test 33e "mkdir and striped directory should have same mode"
4080
4081 cleanup_33f() {
4082         trap 0
4083         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4084 }
4085
4086 test_33f() {
4087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4088         remote_mds_nodsh && skip "remote MDS with nodsh"
4089
4090         mkdir $DIR/$tdir
4091         chmod go+rwx $DIR/$tdir
4092         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4093         trap cleanup_33f EXIT
4094
4095         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4096                 error "cannot create striped directory"
4097
4098         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4099                 error "cannot create files in striped directory"
4100
4101         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4102                 error "cannot remove files in striped directory"
4103
4104         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4105                 error "cannot remove striped directory"
4106
4107         cleanup_33f
4108 }
4109 run_test 33f "nonroot user can create, access, and remove a striped directory"
4110
4111 test_33g() {
4112         mkdir -p $DIR/$tdir/dir2
4113
4114         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4115         echo $err
4116         [[ $err =~ "exists" ]] || error "Not exists error"
4117 }
4118 run_test 33g "nonroot user create already existing root created file"
4119
4120 test_33h() {
4121         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4122         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4123                 skip "Need MDS version at least 2.13.50"
4124
4125         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4126                 error "mkdir $tdir failed"
4127         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4128
4129         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4130         local index2
4131
4132         for fname in $DIR/$tdir/$tfile.bak \
4133                      $DIR/$tdir/$tfile.SAV \
4134                      $DIR/$tdir/$tfile.orig \
4135                      $DIR/$tdir/$tfile~; do
4136                 touch $fname  || error "touch $fname failed"
4137                 index2=$($LFS getstripe -m $fname)
4138                 [ $index -eq $index2 ] ||
4139                         error "$fname MDT index mismatch $index != $index2"
4140         done
4141
4142         local failed=0
4143         for i in {1..250}; do
4144                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4145                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4146                         touch $fname  || error "touch $fname failed"
4147                         index2=$($LFS getstripe -m $fname)
4148                         if [[ $index != $index2 ]]; then
4149                                 failed=$((failed + 1))
4150                                 echo "$fname MDT index mismatch $index != $index2"
4151                         fi
4152                 done
4153         done
4154         echo "$failed MDT index mismatches"
4155         (( failed < 20 )) || error "MDT index mismatch $failed times"
4156
4157 }
4158 run_test 33h "temp file is located on the same MDT as target"
4159
4160 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4161 test_34a() {
4162         rm -f $DIR/f34
4163         $MCREATE $DIR/f34 || error "mcreate failed"
4164         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4165                 error "getstripe failed"
4166         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4167         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4168                 error "getstripe failed"
4169         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4170                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4171 }
4172 run_test 34a "truncate file that has not been opened ==========="
4173
4174 test_34b() {
4175         [ ! -f $DIR/f34 ] && test_34a
4176         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4177                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4178         $OPENFILE -f O_RDONLY $DIR/f34
4179         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4180                 error "getstripe failed"
4181         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4182                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4183 }
4184 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4185
4186 test_34c() {
4187         [ ! -f $DIR/f34 ] && test_34a
4188         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4189                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4190         $OPENFILE -f O_RDWR $DIR/f34
4191         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4192                 error "$LFS getstripe failed"
4193         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4194                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4195 }
4196 run_test 34c "O_RDWR opening file-with-size works =============="
4197
4198 test_34d() {
4199         [ ! -f $DIR/f34 ] && test_34a
4200         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4201                 error "dd failed"
4202         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4203                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4204         rm $DIR/f34
4205 }
4206 run_test 34d "write to sparse file ============================="
4207
4208 test_34e() {
4209         rm -f $DIR/f34e
4210         $MCREATE $DIR/f34e || error "mcreate failed"
4211         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4212         $CHECKSTAT -s 1000 $DIR/f34e ||
4213                 error "Size of $DIR/f34e not equal to 1000 bytes"
4214         $OPENFILE -f O_RDWR $DIR/f34e
4215         $CHECKSTAT -s 1000 $DIR/f34e ||
4216                 error "Size of $DIR/f34e not equal to 1000 bytes"
4217 }
4218 run_test 34e "create objects, some with size and some without =="
4219
4220 test_34f() { # bug 6242, 6243
4221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4222
4223         SIZE34F=48000
4224         rm -f $DIR/f34f
4225         $MCREATE $DIR/f34f || error "mcreate failed"
4226         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4227         dd if=$DIR/f34f of=$TMP/f34f
4228         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4229         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4230         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4231         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4232         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4233 }
4234 run_test 34f "read from a file with no objects until EOF ======="
4235
4236 test_34g() {
4237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4238
4239         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4240                 error "dd failed"
4241         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4242         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4243                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4244         cancel_lru_locks osc
4245         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4246                 error "wrong size after lock cancel"
4247
4248         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4249         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4250                 error "expanding truncate failed"
4251         cancel_lru_locks osc
4252         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4253                 error "wrong expanded size after lock cancel"
4254 }
4255 run_test 34g "truncate long file ==============================="
4256
4257 test_34h() {
4258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4259
4260         local gid=10
4261         local sz=1000
4262
4263         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4264         sync # Flush the cache so that multiop below does not block on cache
4265              # flush when getting the group lock
4266         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4267         MULTIPID=$!
4268
4269         # Since just timed wait is not good enough, let's do a sync write
4270         # that way we are sure enough time for a roundtrip + processing
4271         # passed + 2 seconds of extra margin.
4272         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4273         rm $DIR/${tfile}-1
4274         sleep 2
4275
4276         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4277                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4278                 kill -9 $MULTIPID
4279         fi
4280         wait $MULTIPID
4281         local nsz=`stat -c %s $DIR/$tfile`
4282         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4283 }
4284 run_test 34h "ftruncate file under grouplock should not block"
4285
4286 test_35a() {
4287         cp /bin/sh $DIR/f35a
4288         chmod 444 $DIR/f35a
4289         chown $RUNAS_ID $DIR/f35a
4290         $RUNAS $DIR/f35a && error || true
4291         rm $DIR/f35a
4292 }
4293 run_test 35a "exec file with mode 444 (should return and not leak)"
4294
4295 test_36a() {
4296         rm -f $DIR/f36
4297         utime $DIR/f36 || error "utime failed for MDS"
4298 }
4299 run_test 36a "MDS utime check (mknod, utime)"
4300
4301 test_36b() {
4302         echo "" > $DIR/f36
4303         utime $DIR/f36 || error "utime failed for OST"
4304 }
4305 run_test 36b "OST utime check (open, utime)"
4306
4307 test_36c() {
4308         rm -f $DIR/d36/f36
4309         test_mkdir $DIR/d36
4310         chown $RUNAS_ID $DIR/d36
4311         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4312 }
4313 run_test 36c "non-root MDS utime check (mknod, utime)"
4314
4315 test_36d() {
4316         [ ! -d $DIR/d36 ] && test_36c
4317         echo "" > $DIR/d36/f36
4318         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4319 }
4320 run_test 36d "non-root OST utime check (open, utime)"
4321
4322 test_36e() {
4323         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4324
4325         test_mkdir $DIR/$tdir
4326         touch $DIR/$tdir/$tfile
4327         $RUNAS utime $DIR/$tdir/$tfile &&
4328                 error "utime worked, expected failure" || true
4329 }
4330 run_test 36e "utime on non-owned file (should return error)"
4331
4332 subr_36fh() {
4333         local fl="$1"
4334         local LANG_SAVE=$LANG
4335         local LC_LANG_SAVE=$LC_LANG
4336         export LANG=C LC_LANG=C # for date language
4337
4338         DATESTR="Dec 20  2000"
4339         test_mkdir $DIR/$tdir
4340         lctl set_param fail_loc=$fl
4341         date; date +%s
4342         cp /etc/hosts $DIR/$tdir/$tfile
4343         sync & # write RPC generated with "current" inode timestamp, but delayed
4344         sleep 1
4345         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4346         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4347         cancel_lru_locks $OSC
4348         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4349         date; date +%s
4350         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4351                 echo "BEFORE: $LS_BEFORE" && \
4352                 echo "AFTER : $LS_AFTER" && \
4353                 echo "WANT  : $DATESTR" && \
4354                 error "$DIR/$tdir/$tfile timestamps changed" || true
4355
4356         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4357 }
4358
4359 test_36f() {
4360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4361
4362         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4363         subr_36fh "0x80000214"
4364 }
4365 run_test 36f "utime on file racing with OST BRW write =========="
4366
4367 test_36g() {
4368         remote_ost_nodsh && skip "remote OST with nodsh"
4369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4370         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4371                 skip "Need MDS version at least 2.12.51"
4372
4373         local fmd_max_age
4374         local fmd
4375         local facet="ost1"
4376         local tgt="obdfilter"
4377
4378         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4379
4380         test_mkdir $DIR/$tdir
4381         fmd_max_age=$(do_facet $facet \
4382                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4383                 head -n 1")
4384
4385         echo "FMD max age: ${fmd_max_age}s"
4386         touch $DIR/$tdir/$tfile
4387         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4388                 gawk '{cnt=cnt+$1}  END{print cnt}')
4389         echo "FMD before: $fmd"
4390         [[ $fmd == 0 ]] &&
4391                 error "FMD wasn't create by touch"
4392         sleep $((fmd_max_age + 12))
4393         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4394                 gawk '{cnt=cnt+$1}  END{print cnt}')
4395         echo "FMD after: $fmd"
4396         [[ $fmd == 0 ]] ||
4397                 error "FMD wasn't expired by ping"
4398 }
4399 run_test 36g "FMD cache expiry ====================="
4400
4401 test_36h() {
4402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4403
4404         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4405         subr_36fh "0x80000227"
4406 }
4407 run_test 36h "utime on file racing with OST BRW write =========="
4408
4409 test_36i() {
4410         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4411
4412         test_mkdir $DIR/$tdir
4413         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4414
4415         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4416         local new_mtime=$((mtime + 200))
4417
4418         #change Modify time of striped dir
4419         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4420                         error "change mtime failed"
4421
4422         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4423
4424         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4425 }
4426 run_test 36i "change mtime on striped directory"
4427
4428 # test_37 - duplicate with tests 32q 32r
4429
4430 test_38() {
4431         local file=$DIR/$tfile
4432         touch $file
4433         openfile -f O_DIRECTORY $file
4434         local RC=$?
4435         local ENOTDIR=20
4436         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4437         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4438 }
4439 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4440
4441 test_39a() { # was test_39
4442         touch $DIR/$tfile
4443         touch $DIR/${tfile}2
4444 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4445 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4446 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4447         sleep 2
4448         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4449         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4450                 echo "mtime"
4451                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4452                 echo "atime"
4453                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4454                 echo "ctime"
4455                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4456                 error "O_TRUNC didn't change timestamps"
4457         fi
4458 }
4459 run_test 39a "mtime changed on create"
4460
4461 test_39b() {
4462         test_mkdir -c1 $DIR/$tdir
4463         cp -p /etc/passwd $DIR/$tdir/fopen
4464         cp -p /etc/passwd $DIR/$tdir/flink
4465         cp -p /etc/passwd $DIR/$tdir/funlink
4466         cp -p /etc/passwd $DIR/$tdir/frename
4467         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4468
4469         sleep 1
4470         echo "aaaaaa" >> $DIR/$tdir/fopen
4471         echo "aaaaaa" >> $DIR/$tdir/flink
4472         echo "aaaaaa" >> $DIR/$tdir/funlink
4473         echo "aaaaaa" >> $DIR/$tdir/frename
4474
4475         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4476         local link_new=`stat -c %Y $DIR/$tdir/flink`
4477         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4478         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4479
4480         cat $DIR/$tdir/fopen > /dev/null
4481         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4482         rm -f $DIR/$tdir/funlink2
4483         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4484
4485         for (( i=0; i < 2; i++ )) ; do
4486                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4487                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4488                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4489                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4490
4491                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4492                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4493                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4494                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4495
4496                 cancel_lru_locks $OSC
4497                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4498         done
4499 }
4500 run_test 39b "mtime change on open, link, unlink, rename  ======"
4501
4502 # this should be set to past
4503 TEST_39_MTIME=`date -d "1 year ago" +%s`
4504
4505 # bug 11063
4506 test_39c() {
4507         touch $DIR1/$tfile
4508         sleep 2
4509         local mtime0=`stat -c %Y $DIR1/$tfile`
4510
4511         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4512         local mtime1=`stat -c %Y $DIR1/$tfile`
4513         [ "$mtime1" = $TEST_39_MTIME ] || \
4514                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4515
4516         local d1=`date +%s`
4517         echo hello >> $DIR1/$tfile
4518         local d2=`date +%s`
4519         local mtime2=`stat -c %Y $DIR1/$tfile`
4520         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4521                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4522
4523         mv $DIR1/$tfile $DIR1/$tfile-1
4524
4525         for (( i=0; i < 2; i++ )) ; do
4526                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4527                 [ "$mtime2" = "$mtime3" ] || \
4528                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4529
4530                 cancel_lru_locks $OSC
4531                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4532         done
4533 }
4534 run_test 39c "mtime change on rename ==========================="
4535
4536 # bug 21114
4537 test_39d() {
4538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4539
4540         touch $DIR1/$tfile
4541         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4542
4543         for (( i=0; i < 2; i++ )) ; do
4544                 local mtime=`stat -c %Y $DIR1/$tfile`
4545                 [ $mtime = $TEST_39_MTIME ] || \
4546                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4547
4548                 cancel_lru_locks $OSC
4549                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4550         done
4551 }
4552 run_test 39d "create, utime, stat =============================="
4553
4554 # bug 21114
4555 test_39e() {
4556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4557
4558         touch $DIR1/$tfile
4559         local mtime1=`stat -c %Y $DIR1/$tfile`
4560
4561         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4562
4563         for (( i=0; i < 2; i++ )) ; do
4564                 local mtime2=`stat -c %Y $DIR1/$tfile`
4565                 [ $mtime2 = $TEST_39_MTIME ] || \
4566                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4567
4568                 cancel_lru_locks $OSC
4569                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4570         done
4571 }
4572 run_test 39e "create, stat, utime, stat ========================"
4573
4574 # bug 21114
4575 test_39f() {
4576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4577
4578         touch $DIR1/$tfile
4579         mtime1=`stat -c %Y $DIR1/$tfile`
4580
4581         sleep 2
4582         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4583
4584         for (( i=0; i < 2; i++ )) ; do
4585                 local mtime2=`stat -c %Y $DIR1/$tfile`
4586                 [ $mtime2 = $TEST_39_MTIME ] || \
4587                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4588
4589                 cancel_lru_locks $OSC
4590                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4591         done
4592 }
4593 run_test 39f "create, stat, sleep, utime, stat ================="
4594
4595 # bug 11063
4596 test_39g() {
4597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4598
4599         echo hello >> $DIR1/$tfile
4600         local mtime1=`stat -c %Y $DIR1/$tfile`
4601
4602         sleep 2
4603         chmod o+r $DIR1/$tfile
4604
4605         for (( i=0; i < 2; i++ )) ; do
4606                 local mtime2=`stat -c %Y $DIR1/$tfile`
4607                 [ "$mtime1" = "$mtime2" ] || \
4608                         error "lost mtime: $mtime2, should be $mtime1"
4609
4610                 cancel_lru_locks $OSC
4611                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4612         done
4613 }
4614 run_test 39g "write, chmod, stat ==============================="
4615
4616 # bug 11063
4617 test_39h() {
4618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4619
4620         touch $DIR1/$tfile
4621         sleep 1
4622
4623         local d1=`date`
4624         echo hello >> $DIR1/$tfile
4625         local mtime1=`stat -c %Y $DIR1/$tfile`
4626
4627         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4628         local d2=`date`
4629         if [ "$d1" != "$d2" ]; then
4630                 echo "write and touch not within one second"
4631         else
4632                 for (( i=0; i < 2; i++ )) ; do
4633                         local mtime2=`stat -c %Y $DIR1/$tfile`
4634                         [ "$mtime2" = $TEST_39_MTIME ] || \
4635                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4636
4637                         cancel_lru_locks $OSC
4638                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4639                 done
4640         fi
4641 }
4642 run_test 39h "write, utime within one second, stat ============="
4643
4644 test_39i() {
4645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4646
4647         touch $DIR1/$tfile
4648         sleep 1
4649
4650         echo hello >> $DIR1/$tfile
4651         local mtime1=`stat -c %Y $DIR1/$tfile`
4652
4653         mv $DIR1/$tfile $DIR1/$tfile-1
4654
4655         for (( i=0; i < 2; i++ )) ; do
4656                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4657
4658                 [ "$mtime1" = "$mtime2" ] || \
4659                         error "lost mtime: $mtime2, should be $mtime1"
4660
4661                 cancel_lru_locks $OSC
4662                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4663         done
4664 }
4665 run_test 39i "write, rename, stat =============================="
4666
4667 test_39j() {
4668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4669
4670         start_full_debug_logging
4671         touch $DIR1/$tfile
4672         sleep 1
4673
4674         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4675         lctl set_param fail_loc=0x80000412
4676         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4677                 error "multiop failed"
4678         local multipid=$!
4679         local mtime1=`stat -c %Y $DIR1/$tfile`
4680
4681         mv $DIR1/$tfile $DIR1/$tfile-1
4682
4683         kill -USR1 $multipid
4684         wait $multipid || error "multiop close failed"
4685
4686         for (( i=0; i < 2; i++ )) ; do
4687                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4688                 [ "$mtime1" = "$mtime2" ] ||
4689                         error "mtime is lost on close: $mtime2, " \
4690                               "should be $mtime1"
4691
4692                 cancel_lru_locks
4693                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4694         done
4695         lctl set_param fail_loc=0
4696         stop_full_debug_logging
4697 }
4698 run_test 39j "write, rename, close, stat ======================="
4699
4700 test_39k() {
4701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4702
4703         touch $DIR1/$tfile
4704         sleep 1
4705
4706         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4707         local multipid=$!
4708         local mtime1=`stat -c %Y $DIR1/$tfile`
4709
4710         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4711
4712         kill -USR1 $multipid
4713         wait $multipid || error "multiop close failed"
4714
4715         for (( i=0; i < 2; i++ )) ; do
4716                 local mtime2=`stat -c %Y $DIR1/$tfile`
4717
4718                 [ "$mtime2" = $TEST_39_MTIME ] || \
4719                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4720
4721                 cancel_lru_locks
4722                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4723         done
4724 }
4725 run_test 39k "write, utime, close, stat ========================"
4726
4727 # this should be set to future
4728 TEST_39_ATIME=`date -d "1 year" +%s`
4729
4730 test_39l() {
4731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4732         remote_mds_nodsh && skip "remote MDS with nodsh"
4733
4734         local atime_diff=$(do_facet $SINGLEMDS \
4735                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4736         rm -rf $DIR/$tdir
4737         mkdir -p $DIR/$tdir
4738
4739         # test setting directory atime to future
4740         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4741         local atime=$(stat -c %X $DIR/$tdir)
4742         [ "$atime" = $TEST_39_ATIME ] ||
4743                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4744
4745         # test setting directory atime from future to now
4746         local now=$(date +%s)
4747         touch -a -d @$now $DIR/$tdir
4748
4749         atime=$(stat -c %X $DIR/$tdir)
4750         [ "$atime" -eq "$now"  ] ||
4751                 error "atime is not updated from future: $atime, $now"
4752
4753         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4754         sleep 3
4755
4756         # test setting directory atime when now > dir atime + atime_diff
4757         local d1=$(date +%s)
4758         ls $DIR/$tdir
4759         local d2=$(date +%s)
4760         cancel_lru_locks mdc
4761         atime=$(stat -c %X $DIR/$tdir)
4762         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4763                 error "atime is not updated  : $atime, should be $d2"
4764
4765         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4766         sleep 3
4767
4768         # test not setting directory atime when now < dir atime + atime_diff
4769         ls $DIR/$tdir
4770         cancel_lru_locks mdc
4771         atime=$(stat -c %X $DIR/$tdir)
4772         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4773                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4774
4775         do_facet $SINGLEMDS \
4776                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4777 }
4778 run_test 39l "directory atime update ==========================="
4779
4780 test_39m() {
4781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4782
4783         touch $DIR1/$tfile
4784         sleep 2
4785         local far_past_mtime=$(date -d "May 29 1953" +%s)
4786         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4787
4788         touch -m -d @$far_past_mtime $DIR1/$tfile
4789         touch -a -d @$far_past_atime $DIR1/$tfile
4790
4791         for (( i=0; i < 2; i++ )) ; do
4792                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4793                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4794                         error "atime or mtime set incorrectly"
4795
4796                 cancel_lru_locks $OSC
4797                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4798         done
4799 }
4800 run_test 39m "test atime and mtime before 1970"
4801
4802 test_39n() { # LU-3832
4803         remote_mds_nodsh && skip "remote MDS with nodsh"
4804
4805         local atime_diff=$(do_facet $SINGLEMDS \
4806                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4807         local atime0
4808         local atime1
4809         local atime2
4810
4811         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4812
4813         rm -rf $DIR/$tfile
4814         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4815         atime0=$(stat -c %X $DIR/$tfile)
4816
4817         sleep 5
4818         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4819         atime1=$(stat -c %X $DIR/$tfile)
4820
4821         sleep 5
4822         cancel_lru_locks mdc
4823         cancel_lru_locks osc
4824         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4825         atime2=$(stat -c %X $DIR/$tfile)
4826
4827         do_facet $SINGLEMDS \
4828                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4829
4830         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4831         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4832 }
4833 run_test 39n "check that O_NOATIME is honored"
4834
4835 test_39o() {
4836         TESTDIR=$DIR/$tdir/$tfile
4837         [ -e $TESTDIR ] && rm -rf $TESTDIR
4838         mkdir -p $TESTDIR
4839         cd $TESTDIR
4840         links1=2
4841         ls
4842         mkdir a b
4843         ls
4844         links2=$(stat -c %h .)
4845         [ $(($links1 + 2)) != $links2 ] &&
4846                 error "wrong links count $(($links1 + 2)) != $links2"
4847         rmdir b
4848         links3=$(stat -c %h .)
4849         [ $(($links1 + 1)) != $links3 ] &&
4850                 error "wrong links count $links1 != $links3"
4851         return 0
4852 }
4853 run_test 39o "directory cached attributes updated after create"
4854
4855 test_39p() {
4856         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4857
4858         local MDTIDX=1
4859         TESTDIR=$DIR/$tdir/$tdir
4860         [ -e $TESTDIR ] && rm -rf $TESTDIR
4861         test_mkdir -p $TESTDIR
4862         cd $TESTDIR
4863         links1=2
4864         ls
4865         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4866         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4867         ls
4868         links2=$(stat -c %h .)
4869         [ $(($links1 + 2)) != $links2 ] &&
4870                 error "wrong links count $(($links1 + 2)) != $links2"
4871         rmdir remote_dir2
4872         links3=$(stat -c %h .)
4873         [ $(($links1 + 1)) != $links3 ] &&
4874                 error "wrong links count $links1 != $links3"
4875         return 0
4876 }
4877 run_test 39p "remote directory cached attributes updated after create ========"
4878
4879 test_39r() {
4880         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4881                 skip "no atime update on old OST"
4882         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4883                 skip_env "ldiskfs only test"
4884         fi
4885
4886         local saved_adiff
4887         saved_adiff=$(do_facet ost1 \
4888                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4889         stack_trap "do_facet ost1 \
4890                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4891
4892         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4893
4894         $LFS setstripe -i 0 $DIR/$tfile
4895         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4896                 error "can't write initial file"
4897         cancel_lru_locks osc
4898
4899         # exceed atime_diff and access file
4900         sleep 6
4901         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4902                 error "can't udpate atime"
4903
4904         local atime_cli=$(stat -c %X $DIR/$tfile)
4905         echo "client atime: $atime_cli"
4906         # allow atime update to be written to device
4907         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4908         sleep 5
4909
4910         local ostdev=$(ostdevname 1)
4911         local fid=($(lfs getstripe -y $DIR/$tfile |
4912                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4913         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4914         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4915
4916         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4917         local atime_ost=$(do_facet ost1 "$cmd" |&
4918                           awk -F'[: ]' '/atime:/ { print $4 }')
4919         (( atime_cli == atime_ost )) ||
4920                 error "atime on client $atime_cli != ost $atime_ost"
4921 }
4922 run_test 39r "lazy atime update on OST"
4923
4924 test_39q() { # LU-8041
4925         local testdir=$DIR/$tdir
4926         mkdir -p $testdir
4927         multiop_bg_pause $testdir D_c || error "multiop failed"
4928         local multipid=$!
4929         cancel_lru_locks mdc
4930         kill -USR1 $multipid
4931         local atime=$(stat -c %X $testdir)
4932         [ "$atime" -ne 0 ] || error "atime is zero"
4933 }
4934 run_test 39q "close won't zero out atime"
4935
4936 test_40() {
4937         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4938         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4939                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4940         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4941                 error "$tfile is not 4096 bytes in size"
4942 }
4943 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4944
4945 test_41() {
4946         # bug 1553
4947         small_write $DIR/f41 18
4948 }
4949 run_test 41 "test small file write + fstat ====================="
4950
4951 count_ost_writes() {
4952         lctl get_param -n ${OSC}.*.stats |
4953                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4954                         END { printf("%0.0f", writes) }'
4955 }
4956
4957 # decent default
4958 WRITEBACK_SAVE=500
4959 DIRTY_RATIO_SAVE=40
4960 MAX_DIRTY_RATIO=50
4961 BG_DIRTY_RATIO_SAVE=10
4962 MAX_BG_DIRTY_RATIO=25
4963
4964 start_writeback() {
4965         trap 0
4966         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4967         # dirty_ratio, dirty_background_ratio
4968         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4969                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4970                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4971                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4972         else
4973                 # if file not here, we are a 2.4 kernel
4974                 kill -CONT `pidof kupdated`
4975         fi
4976 }
4977
4978 stop_writeback() {
4979         # setup the trap first, so someone cannot exit the test at the
4980         # exact wrong time and mess up a machine
4981         trap start_writeback EXIT
4982         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4983         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4984                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4985                 sysctl -w vm.dirty_writeback_centisecs=0
4986                 sysctl -w vm.dirty_writeback_centisecs=0
4987                 # save and increase /proc/sys/vm/dirty_ratio
4988                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4989                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4990                 # save and increase /proc/sys/vm/dirty_background_ratio
4991                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4992                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4993         else
4994                 # if file not here, we are a 2.4 kernel
4995                 kill -STOP `pidof kupdated`
4996         fi
4997 }
4998
4999 # ensure that all stripes have some grant before we test client-side cache
5000 setup_test42() {
5001         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5002                 dd if=/dev/zero of=$i bs=4k count=1
5003                 rm $i
5004         done
5005 }
5006
5007 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5008 # file truncation, and file removal.
5009 test_42a() {
5010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5011
5012         setup_test42
5013         cancel_lru_locks $OSC
5014         stop_writeback
5015         sync; sleep 1; sync # just to be safe
5016         BEFOREWRITES=`count_ost_writes`
5017         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5018         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5019         AFTERWRITES=`count_ost_writes`
5020         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5021                 error "$BEFOREWRITES < $AFTERWRITES"
5022         start_writeback
5023 }
5024 run_test 42a "ensure that we don't flush on close"
5025
5026 test_42b() {
5027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5028
5029         setup_test42
5030         cancel_lru_locks $OSC
5031         stop_writeback
5032         sync
5033         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5034         BEFOREWRITES=$(count_ost_writes)
5035         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5036         AFTERWRITES=$(count_ost_writes)
5037         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5038                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5039         fi
5040         BEFOREWRITES=$(count_ost_writes)
5041         sync || error "sync: $?"
5042         AFTERWRITES=$(count_ost_writes)
5043         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5044                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5045         fi
5046         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5047         start_writeback
5048         return 0
5049 }
5050 run_test 42b "test destroy of file with cached dirty data ======"
5051
5052 # if these tests just want to test the effect of truncation,
5053 # they have to be very careful.  consider:
5054 # - the first open gets a {0,EOF}PR lock
5055 # - the first write conflicts and gets a {0, count-1}PW
5056 # - the rest of the writes are under {count,EOF}PW
5057 # - the open for truncate tries to match a {0,EOF}PR
5058 #   for the filesize and cancels the PWs.
5059 # any number of fixes (don't get {0,EOF} on open, match
5060 # composite locks, do smarter file size management) fix
5061 # this, but for now we want these tests to verify that
5062 # the cancellation with truncate intent works, so we
5063 # start the file with a full-file pw lock to match against
5064 # until the truncate.
5065 trunc_test() {
5066         test=$1
5067         file=$DIR/$test
5068         offset=$2
5069         cancel_lru_locks $OSC
5070         stop_writeback
5071         # prime the file with 0,EOF PW to match
5072         touch $file
5073         $TRUNCATE $file 0
5074         sync; sync
5075         # now the real test..
5076         dd if=/dev/zero of=$file bs=1024 count=100
5077         BEFOREWRITES=`count_ost_writes`
5078         $TRUNCATE $file $offset
5079         cancel_lru_locks $OSC
5080         AFTERWRITES=`count_ost_writes`
5081         start_writeback
5082 }
5083
5084 test_42c() {
5085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5086
5087         trunc_test 42c 1024
5088         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5089                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5090         rm $file
5091 }
5092 run_test 42c "test partial truncate of file with cached dirty data"
5093
5094 test_42d() {
5095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5096
5097         trunc_test 42d 0
5098         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5099                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5100         rm $file
5101 }
5102 run_test 42d "test complete truncate of file with cached dirty data"
5103
5104 test_42e() { # bug22074
5105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5106
5107         local TDIR=$DIR/${tdir}e
5108         local pages=16 # hardcoded 16 pages, don't change it.
5109         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5110         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5111         local max_dirty_mb
5112         local warmup_files
5113
5114         test_mkdir $DIR/${tdir}e
5115         $LFS setstripe -c 1 $TDIR
5116         createmany -o $TDIR/f $files
5117
5118         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5119
5120         # we assume that with $OSTCOUNT files, at least one of them will
5121         # be allocated on OST0.
5122         warmup_files=$((OSTCOUNT * max_dirty_mb))
5123         createmany -o $TDIR/w $warmup_files
5124
5125         # write a large amount of data into one file and sync, to get good
5126         # avail_grant number from OST.
5127         for ((i=0; i<$warmup_files; i++)); do
5128                 idx=$($LFS getstripe -i $TDIR/w$i)
5129                 [ $idx -ne 0 ] && continue
5130                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5131                 break
5132         done
5133         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5134         sync
5135         $LCTL get_param $proc_osc0/cur_dirty_bytes
5136         $LCTL get_param $proc_osc0/cur_grant_bytes
5137
5138         # create as much dirty pages as we can while not to trigger the actual
5139         # RPCs directly. but depends on the env, VFS may trigger flush during this
5140         # period, hopefully we are good.
5141         for ((i=0; i<$warmup_files; i++)); do
5142                 idx=$($LFS getstripe -i $TDIR/w$i)
5143                 [ $idx -ne 0 ] && continue
5144                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5145         done
5146         $LCTL get_param $proc_osc0/cur_dirty_bytes
5147         $LCTL get_param $proc_osc0/cur_grant_bytes
5148
5149         # perform the real test
5150         $LCTL set_param $proc_osc0/rpc_stats 0
5151         for ((;i<$files; i++)); do
5152                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5153                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5154         done
5155         sync
5156         $LCTL get_param $proc_osc0/rpc_stats
5157
5158         local percent=0
5159         local have_ppr=false
5160         $LCTL get_param $proc_osc0/rpc_stats |
5161                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5162                         # skip lines until we are at the RPC histogram data
5163                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5164                         $have_ppr || continue
5165
5166                         # we only want the percent stat for < 16 pages
5167                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5168
5169                         percent=$((percent + WPCT))
5170                         if [[ $percent -gt 15 ]]; then
5171                                 error "less than 16-pages write RPCs" \
5172                                       "$percent% > 15%"
5173                                 break
5174                         fi
5175                 done
5176         rm -rf $TDIR
5177 }
5178 run_test 42e "verify sub-RPC writes are not done synchronously"
5179
5180 test_43A() { # was test_43
5181         test_mkdir $DIR/$tdir
5182         cp -p /bin/ls $DIR/$tdir/$tfile
5183         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5184         pid=$!
5185         # give multiop a chance to open
5186         sleep 1
5187
5188         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5189         kill -USR1 $pid
5190         # Wait for multiop to exit
5191         wait $pid
5192 }
5193 run_test 43A "execution of file opened for write should return -ETXTBSY"
5194
5195 test_43a() {
5196         test_mkdir $DIR/$tdir
5197         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5198         $DIR/$tdir/sleep 60 &
5199         SLEEP_PID=$!
5200         # Make sure exec of $tdir/sleep wins race with truncate
5201         sleep 1
5202         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5203         kill $SLEEP_PID
5204 }
5205 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5206
5207 test_43b() {
5208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5209
5210         test_mkdir $DIR/$tdir
5211         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5212         $DIR/$tdir/sleep 60 &
5213         SLEEP_PID=$!
5214         # Make sure exec of $tdir/sleep wins race with truncate
5215         sleep 1
5216         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5217         kill $SLEEP_PID
5218 }
5219 run_test 43b "truncate of file being executed should return -ETXTBSY"
5220
5221 test_43c() {
5222         local testdir="$DIR/$tdir"
5223         test_mkdir $testdir
5224         cp $SHELL $testdir/
5225         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5226                 ( cd $testdir && md5sum -c )
5227 }
5228 run_test 43c "md5sum of copy into lustre"
5229
5230 test_44A() { # was test_44
5231         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5232
5233         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5234         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5235 }
5236 run_test 44A "zero length read from a sparse stripe"
5237
5238 test_44a() {
5239         local nstripe=$($LFS getstripe -c -d $DIR)
5240         [ -z "$nstripe" ] && skip "can't get stripe info"
5241         [[ $nstripe -gt $OSTCOUNT ]] &&
5242                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5243
5244         local stride=$($LFS getstripe -S -d $DIR)
5245         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5246                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5247         fi
5248
5249         OFFSETS="0 $((stride/2)) $((stride-1))"
5250         for offset in $OFFSETS; do
5251                 for i in $(seq 0 $((nstripe-1))); do
5252                         local GLOBALOFFSETS=""
5253                         # size in Bytes
5254                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5255                         local myfn=$DIR/d44a-$size
5256                         echo "--------writing $myfn at $size"
5257                         ll_sparseness_write $myfn $size ||
5258                                 error "ll_sparseness_write"
5259                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5260                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5261                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5262
5263                         for j in $(seq 0 $((nstripe-1))); do
5264                                 # size in Bytes
5265                                 size=$((((j + $nstripe )*$stride + $offset)))
5266                                 ll_sparseness_write $myfn $size ||
5267                                         error "ll_sparseness_write"
5268                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5269                         done
5270                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5271                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5272                         rm -f $myfn
5273                 done
5274         done
5275 }
5276 run_test 44a "test sparse pwrite ==============================="
5277
5278 dirty_osc_total() {
5279         tot=0
5280         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5281                 tot=$(($tot + $d))
5282         done
5283         echo $tot
5284 }
5285 do_dirty_record() {
5286         before=`dirty_osc_total`
5287         echo executing "\"$*\""
5288         eval $*
5289         after=`dirty_osc_total`
5290         echo before $before, after $after
5291 }
5292 test_45() {
5293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5294
5295         f="$DIR/f45"
5296         # Obtain grants from OST if it supports it
5297         echo blah > ${f}_grant
5298         stop_writeback
5299         sync
5300         do_dirty_record "echo blah > $f"
5301         [[ $before -eq $after ]] && error "write wasn't cached"
5302         do_dirty_record "> $f"
5303         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5304         do_dirty_record "echo blah > $f"
5305         [[ $before -eq $after ]] && error "write wasn't cached"
5306         do_dirty_record "sync"
5307         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5308         do_dirty_record "echo blah > $f"
5309         [[ $before -eq $after ]] && error "write wasn't cached"
5310         do_dirty_record "cancel_lru_locks osc"
5311         [[ $before -gt $after ]] ||
5312                 error "lock cancellation didn't lower dirty count"
5313         start_writeback
5314 }
5315 run_test 45 "osc io page accounting ============================"
5316
5317 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5318 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5319 # objects offset and an assert hit when an rpc was built with 1023's mapped
5320 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5321 test_46() {
5322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5323
5324         f="$DIR/f46"
5325         stop_writeback
5326         sync
5327         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5328         sync
5329         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5330         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5331         sync
5332         start_writeback
5333 }
5334 run_test 46 "dirtying a previously written page ================"
5335
5336 # test_47 is removed "Device nodes check" is moved to test_28
5337
5338 test_48a() { # bug 2399
5339         [ "$mds1_FSTYPE" = "zfs" ] &&
5340         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5341                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5342
5343         test_mkdir $DIR/$tdir
5344         cd $DIR/$tdir
5345         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5346         test_mkdir $DIR/$tdir
5347         touch foo || error "'touch foo' failed after recreating cwd"
5348         test_mkdir bar
5349         touch .foo || error "'touch .foo' failed after recreating cwd"
5350         test_mkdir .bar
5351         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5352         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5353         cd . || error "'cd .' failed after recreating cwd"
5354         mkdir . && error "'mkdir .' worked after recreating cwd"
5355         rmdir . && error "'rmdir .' worked after recreating cwd"
5356         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5357         cd .. || error "'cd ..' failed after recreating cwd"
5358 }
5359 run_test 48a "Access renamed working dir (should return errors)="
5360
5361 test_48b() { # bug 2399
5362         rm -rf $DIR/$tdir
5363         test_mkdir $DIR/$tdir
5364         cd $DIR/$tdir
5365         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5366         touch foo && error "'touch foo' worked after removing cwd"
5367         mkdir foo && error "'mkdir foo' worked after removing cwd"
5368         touch .foo && error "'touch .foo' worked after removing cwd"
5369         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5370         ls . > /dev/null && error "'ls .' worked after removing cwd"
5371         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5372         mkdir . && error "'mkdir .' worked after removing cwd"
5373         rmdir . && error "'rmdir .' worked after removing cwd"
5374         ln -s . foo && error "'ln -s .' worked after removing cwd"
5375         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5376 }
5377 run_test 48b "Access removed working dir (should return errors)="
5378
5379 test_48c() { # bug 2350
5380         #lctl set_param debug=-1
5381         #set -vx
5382         rm -rf $DIR/$tdir
5383         test_mkdir -p $DIR/$tdir/dir
5384         cd $DIR/$tdir/dir
5385         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5386         $TRACE touch foo && error "touch foo worked after removing cwd"
5387         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5388         touch .foo && error "touch .foo worked after removing cwd"
5389         mkdir .foo && error "mkdir .foo worked after removing cwd"
5390         $TRACE ls . && error "'ls .' worked after removing cwd"
5391         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5392         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5393         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5394         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5395         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5396 }
5397 run_test 48c "Access removed working subdir (should return errors)"
5398
5399 test_48d() { # bug 2350
5400         #lctl set_param debug=-1
5401         #set -vx
5402         rm -rf $DIR/$tdir
5403         test_mkdir -p $DIR/$tdir/dir
5404         cd $DIR/$tdir/dir
5405         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5406         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5407         $TRACE touch foo && error "'touch foo' worked after removing parent"
5408         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5409         touch .foo && error "'touch .foo' worked after removing parent"
5410         mkdir .foo && error "mkdir .foo worked after removing parent"
5411         $TRACE ls . && error "'ls .' worked after removing parent"
5412         $TRACE ls .. && error "'ls ..' worked after removing parent"
5413         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5414         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5415         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5416         true
5417 }
5418 run_test 48d "Access removed parent subdir (should return errors)"
5419
5420 test_48e() { # bug 4134
5421         #lctl set_param debug=-1
5422         #set -vx
5423         rm -rf $DIR/$tdir
5424         test_mkdir -p $DIR/$tdir/dir
5425         cd $DIR/$tdir/dir
5426         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5427         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5428         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5429         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5430         # On a buggy kernel addition of "touch foo" after cd .. will
5431         # produce kernel oops in lookup_hash_it
5432         touch ../foo && error "'cd ..' worked after recreate parent"
5433         cd $DIR
5434         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5435 }
5436 run_test 48e "Access to recreated parent subdir (should return errors)"
5437
5438 test_48f() {
5439         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5440                 skip "need MDS >= 2.13.55"
5441         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5442         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5443                 skip "needs different host for mdt1 mdt2"
5444         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5445
5446         $LFS mkdir -i0 $DIR/$tdir
5447         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5448
5449         for d in sub1 sub2 sub3; do
5450                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5451                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5452                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5453         done
5454
5455         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5456 }
5457 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5458
5459 test_49() { # LU-1030
5460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5461         remote_ost_nodsh && skip "remote OST with nodsh"
5462
5463         # get ost1 size - $FSNAME-OST0000
5464         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5465                 awk '{ print $4 }')
5466         # write 800M at maximum
5467         [[ $ost1_size -lt 2 ]] && ost1_size=2
5468         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5469
5470         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5471         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5472         local dd_pid=$!
5473
5474         # change max_pages_per_rpc while writing the file
5475         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5476         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5477         # loop until dd process exits
5478         while ps ax -opid | grep -wq $dd_pid; do
5479                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5480                 sleep $((RANDOM % 5 + 1))
5481         done
5482         # restore original max_pages_per_rpc
5483         $LCTL set_param $osc1_mppc=$orig_mppc
5484         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5485 }
5486 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5487
5488 test_50() {
5489         # bug 1485
5490         test_mkdir $DIR/$tdir
5491         cd $DIR/$tdir
5492         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5493 }
5494 run_test 50 "special situations: /proc symlinks  ==============="
5495
5496 test_51a() {    # was test_51
5497         # bug 1516 - create an empty entry right after ".." then split dir
5498         test_mkdir -c1 $DIR/$tdir
5499         touch $DIR/$tdir/foo
5500         $MCREATE $DIR/$tdir/bar
5501         rm $DIR/$tdir/foo
5502         createmany -m $DIR/$tdir/longfile 201
5503         FNUM=202
5504         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5505                 $MCREATE $DIR/$tdir/longfile$FNUM
5506                 FNUM=$(($FNUM + 1))
5507                 echo -n "+"
5508         done
5509         echo
5510         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5511 }
5512 run_test 51a "special situations: split htree with empty entry =="
5513
5514 cleanup_print_lfs_df () {
5515         trap 0
5516         $LFS df
5517         $LFS df -i
5518 }
5519
5520 test_51b() {
5521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5522
5523         local dir=$DIR/$tdir
5524         local nrdirs=$((65536 + 100))
5525
5526         # cleanup the directory
5527         rm -fr $dir
5528
5529         test_mkdir -c1 $dir
5530
5531         $LFS df
5532         $LFS df -i
5533         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5534         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5535         [[ $numfree -lt $nrdirs ]] &&
5536                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5537
5538         # need to check free space for the directories as well
5539         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5540         numfree=$(( blkfree / $(fs_inode_ksize) ))
5541         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5542
5543         trap cleanup_print_lfs_df EXIT
5544
5545         # create files
5546         createmany -d $dir/d $nrdirs || {
5547                 unlinkmany $dir/d $nrdirs
5548                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5549         }
5550
5551         # really created :
5552         nrdirs=$(ls -U $dir | wc -l)
5553
5554         # unlink all but 100 subdirectories, then check it still works
5555         local left=100
5556         local delete=$((nrdirs - left))
5557
5558         $LFS df
5559         $LFS df -i
5560
5561         # for ldiskfs the nlink count should be 1, but this is OSD specific
5562         # and so this is listed for informational purposes only
5563         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5564         unlinkmany -d $dir/d $delete ||
5565                 error "unlink of first $delete subdirs failed"
5566
5567         echo "nlink between: $(stat -c %h $dir)"
5568         local found=$(ls -U $dir | wc -l)
5569         [ $found -ne $left ] &&
5570                 error "can't find subdirs: found only $found, expected $left"
5571
5572         unlinkmany -d $dir/d $delete $left ||
5573                 error "unlink of second $left subdirs failed"
5574         # regardless of whether the backing filesystem tracks nlink accurately
5575         # or not, the nlink count shouldn't be more than "." and ".." here
5576         local after=$(stat -c %h $dir)
5577         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5578                 echo "nlink after: $after"
5579
5580         cleanup_print_lfs_df
5581 }
5582 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5583
5584 test_51d() {
5585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5586         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5587
5588         test_mkdir $DIR/$tdir
5589         createmany -o $DIR/$tdir/t- 1000
5590         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5591         for N in $(seq 0 $((OSTCOUNT - 1))); do
5592                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5593                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5594                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5595                         '($1 == '$N') { objs += 1 } \
5596                         END { printf("%0.0f", objs) }')
5597                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5598         done
5599         unlinkmany $DIR/$tdir/t- 1000
5600
5601         NLAST=0
5602         for N in $(seq 1 $((OSTCOUNT - 1))); do
5603                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5604                         error "OST $N has less objects vs OST $NLAST" \
5605                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5606                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5607                         error "OST $N has less objects vs OST $NLAST" \
5608                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5609
5610                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5611                         error "OST $N has less #0 objects vs OST $NLAST" \
5612                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5613                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5614                         error "OST $N has less #0 objects vs OST $NLAST" \
5615                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5616                 NLAST=$N
5617         done
5618         rm -f $TMP/$tfile
5619 }
5620 run_test 51d "check object distribution"
5621
5622 test_51e() {
5623         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5624                 skip_env "ldiskfs only test"
5625         fi
5626
5627         test_mkdir -c1 $DIR/$tdir
5628         test_mkdir -c1 $DIR/$tdir/d0
5629
5630         touch $DIR/$tdir/d0/foo
5631         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5632                 error "file exceed 65000 nlink limit!"
5633         unlinkmany $DIR/$tdir/d0/f- 65001
5634         return 0
5635 }
5636 run_test 51e "check file nlink limit"
5637
5638 test_51f() {
5639         test_mkdir $DIR/$tdir
5640
5641         local max=100000
5642         local ulimit_old=$(ulimit -n)
5643         local spare=20 # number of spare fd's for scripts/libraries, etc.
5644         local mdt=$($LFS getstripe -m $DIR/$tdir)
5645         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5646
5647         echo "MDT$mdt numfree=$numfree, max=$max"
5648         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5649         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5650                 while ! ulimit -n $((numfree + spare)); do
5651                         numfree=$((numfree * 3 / 4))
5652                 done
5653                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5654         else
5655                 echo "left ulimit at $ulimit_old"
5656         fi
5657
5658         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5659                 unlinkmany $DIR/$tdir/f $numfree
5660                 error "create+open $numfree files in $DIR/$tdir failed"
5661         }
5662         ulimit -n $ulimit_old
5663
5664         # if createmany exits at 120s there will be fewer than $numfree files
5665         unlinkmany $DIR/$tdir/f $numfree || true
5666 }
5667 run_test 51f "check many open files limit"
5668
5669 test_52a() {
5670         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5671         test_mkdir $DIR/$tdir
5672         touch $DIR/$tdir/foo
5673         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5674         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5675         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5676         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5677         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5678                                         error "link worked"
5679         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5680         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5681         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5682                                                      error "lsattr"
5683         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5684         cp -r $DIR/$tdir $TMP/
5685         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5686 }
5687 run_test 52a "append-only flag test (should return errors)"
5688
5689 test_52b() {
5690         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5691         test_mkdir $DIR/$tdir
5692         touch $DIR/$tdir/foo
5693         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5694         cat test > $DIR/$tdir/foo && error "cat test worked"
5695         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5696         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5697         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5698                                         error "link worked"
5699         echo foo >> $DIR/$tdir/foo && error "echo worked"
5700         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5701         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5702         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5703         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5704                                                         error "lsattr"
5705         chattr -i $DIR/$tdir/foo || error "chattr failed"
5706
5707         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5708 }
5709 run_test 52b "immutable flag test (should return errors) ======="
5710
5711 test_53() {
5712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5713         remote_mds_nodsh && skip "remote MDS with nodsh"
5714         remote_ost_nodsh && skip "remote OST with nodsh"
5715
5716         local param
5717         local param_seq
5718         local ostname
5719         local mds_last
5720         local mds_last_seq
5721         local ost_last
5722         local ost_last_seq
5723         local ost_last_id
5724         local ostnum
5725         local node
5726         local found=false
5727         local support_last_seq=true
5728
5729         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5730                 support_last_seq=false
5731
5732         # only test MDT0000
5733         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5734         local value
5735         for value in $(do_facet $SINGLEMDS \
5736                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5737                 param=$(echo ${value[0]} | cut -d "=" -f1)
5738                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5739
5740                 if $support_last_seq; then
5741                         param_seq=$(echo $param |
5742                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5743                         mds_last_seq=$(do_facet $SINGLEMDS \
5744                                        $LCTL get_param -n $param_seq)
5745                 fi
5746                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5747
5748                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5749                 node=$(facet_active_host ost$((ostnum+1)))
5750                 param="obdfilter.$ostname.last_id"
5751                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5752                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5753                         ost_last_id=$ost_last
5754
5755                         if $support_last_seq; then
5756                                 ost_last_id=$(echo $ost_last |
5757                                               awk -F':' '{print $2}' |
5758                                               sed -e "s/^0x//g")
5759                                 ost_last_seq=$(echo $ost_last |
5760                                                awk -F':' '{print $1}')
5761                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5762                         fi
5763
5764                         if [[ $ost_last_id != $mds_last ]]; then
5765                                 error "$ost_last_id != $mds_last"
5766                         else
5767                                 found=true
5768                                 break
5769                         fi
5770                 done
5771         done
5772         $found || error "can not match last_seq/last_id for $mdtosc"
5773         return 0
5774 }
5775 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5776
5777 test_54a() {
5778         perl -MSocket -e ';' || skip "no Socket perl module installed"
5779
5780         $SOCKETSERVER $DIR/socket ||
5781                 error "$SOCKETSERVER $DIR/socket failed: $?"
5782         $SOCKETCLIENT $DIR/socket ||
5783                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5784         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5785 }
5786 run_test 54a "unix domain socket test =========================="
5787
5788 test_54b() {
5789         f="$DIR/f54b"
5790         mknod $f c 1 3
5791         chmod 0666 $f
5792         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5793 }
5794 run_test 54b "char device works in lustre ======================"
5795
5796 find_loop_dev() {
5797         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5798         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5799         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5800
5801         for i in $(seq 3 7); do
5802                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5803                 LOOPDEV=$LOOPBASE$i
5804                 LOOPNUM=$i
5805                 break
5806         done
5807 }
5808
5809 cleanup_54c() {
5810         local rc=0
5811         loopdev="$DIR/loop54c"
5812
5813         trap 0
5814         $UMOUNT $DIR/$tdir || rc=$?
5815         losetup -d $loopdev || true
5816         losetup -d $LOOPDEV || true
5817         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5818         return $rc
5819 }
5820
5821 test_54c() {
5822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5823
5824         loopdev="$DIR/loop54c"
5825
5826         find_loop_dev
5827         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5828         trap cleanup_54c EXIT
5829         mknod $loopdev b 7 $LOOPNUM
5830         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5831         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5832         losetup $loopdev $DIR/$tfile ||
5833                 error "can't set up $loopdev for $DIR/$tfile"
5834         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5835         test_mkdir $DIR/$tdir
5836         mount -t ext2 $loopdev $DIR/$tdir ||
5837                 error "error mounting $loopdev on $DIR/$tdir"
5838         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5839                 error "dd write"
5840         df $DIR/$tdir
5841         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5842                 error "dd read"
5843         cleanup_54c
5844 }
5845 run_test 54c "block device works in lustre ====================="
5846
5847 test_54d() {
5848         f="$DIR/f54d"
5849         string="aaaaaa"
5850         mknod $f p
5851         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5852 }
5853 run_test 54d "fifo device works in lustre ======================"
5854
5855 test_54e() {
5856         f="$DIR/f54e"
5857         string="aaaaaa"
5858         cp -aL /dev/console $f
5859         echo $string > $f || error "echo $string to $f failed"
5860 }
5861 run_test 54e "console/tty device works in lustre ======================"
5862
5863 test_56a() {
5864         local numfiles=3
5865         local dir=$DIR/$tdir
5866
5867         rm -rf $dir
5868         test_mkdir -p $dir/dir
5869         for i in $(seq $numfiles); do
5870                 touch $dir/file$i
5871                 touch $dir/dir/file$i
5872         done
5873
5874         local numcomp=$($LFS getstripe --component-count $dir)
5875
5876         [[ $numcomp == 0 ]] && numcomp=1
5877
5878         # test lfs getstripe with --recursive
5879         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5880
5881         [[ $filenum -eq $((numfiles * 2)) ]] ||
5882                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5883         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5884         [[ $filenum -eq $numfiles ]] ||
5885                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5886         echo "$LFS getstripe showed obdidx or l_ost_idx"
5887
5888         # test lfs getstripe with file instead of dir
5889         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5890         [[ $filenum -eq 1 ]] ||
5891                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5892         echo "$LFS getstripe file1 passed"
5893
5894         #test lfs getstripe with --verbose
5895         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5896         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5897                 error "$LFS getstripe --verbose $dir: "\
5898                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5899         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5900                 error "$LFS getstripe $dir: showed lmm_magic"
5901
5902         #test lfs getstripe with -v prints lmm_fid
5903         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5904         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5905                 error "$LFS getstripe -v $dir: "\
5906                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5907         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5908                 error "$LFS getstripe $dir: showed lmm_fid by default"
5909         echo "$LFS getstripe --verbose passed"
5910
5911         #check for FID information
5912         local fid1=$($LFS getstripe --fid $dir/file1)
5913         local fid2=$($LFS getstripe --verbose $dir/file1 |
5914                      awk '/lmm_fid: / { print $2; exit; }')
5915         local fid3=$($LFS path2fid $dir/file1)
5916
5917         [ "$fid1" != "$fid2" ] &&
5918                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5919         [ "$fid1" != "$fid3" ] &&
5920                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5921         echo "$LFS getstripe --fid passed"
5922
5923         #test lfs getstripe with --obd
5924         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5925                 error "$LFS getstripe --obd wrong_uuid: should return error"
5926
5927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5928
5929         local ostidx=1
5930         local obduuid=$(ostuuid_from_index $ostidx)
5931         local found=$($LFS getstripe -r --obd $obduuid $dir |
5932                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5933
5934         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5935         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5936                 ((filenum--))
5937         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5938                 ((filenum--))
5939
5940         [[ $found -eq $filenum ]] ||
5941                 error "$LFS getstripe --obd: found $found expect $filenum"
5942         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5943                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5944                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5945                 error "$LFS getstripe --obd: should not show file on other obd"
5946         echo "$LFS getstripe --obd passed"
5947 }
5948 run_test 56a "check $LFS getstripe"
5949
5950 test_56b() {
5951         local dir=$DIR/$tdir
5952         local numdirs=3
5953
5954         test_mkdir $dir
5955         for i in $(seq $numdirs); do
5956                 test_mkdir $dir/dir$i
5957         done
5958
5959         # test lfs getdirstripe default mode is non-recursion, which is
5960         # different from lfs getstripe
5961         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5962
5963         [[ $dircnt -eq 1 ]] ||
5964                 error "$LFS getdirstripe: found $dircnt, not 1"
5965         dircnt=$($LFS getdirstripe --recursive $dir |
5966                 grep -c lmv_stripe_count)
5967         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5968                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5969 }
5970 run_test 56b "check $LFS getdirstripe"
5971
5972 test_56c() {
5973         remote_ost_nodsh && skip "remote OST with nodsh"
5974
5975         local ost_idx=0
5976         local ost_name=$(ostname_from_index $ost_idx)
5977         local old_status=$(ost_dev_status $ost_idx)
5978         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5979
5980         [[ -z "$old_status" ]] ||
5981                 skip_env "OST $ost_name is in $old_status status"
5982
5983         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5984         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5985                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5986         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5987                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5988                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5989         fi
5990
5991         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5992                 error "$LFS df -v showing inactive devices"
5993         sleep_maxage
5994
5995         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5996
5997         [[ "$new_status" =~ "D" ]] ||
5998                 error "$ost_name status is '$new_status', missing 'D'"
5999         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6000                 [[ "$new_status" =~ "N" ]] ||
6001                         error "$ost_name status is '$new_status', missing 'N'"
6002         fi
6003         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6004                 [[ "$new_status" =~ "f" ]] ||
6005                         error "$ost_name status is '$new_status', missing 'f'"
6006         fi
6007
6008         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6009         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6010                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6011         [[ -z "$p" ]] && restore_lustre_params < $p || true
6012         sleep_maxage
6013
6014         new_status=$(ost_dev_status $ost_idx)
6015         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6016                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6017         # can't check 'f' as devices may actually be on flash
6018 }
6019 run_test 56c "check 'lfs df' showing device status"
6020
6021 test_56d() {
6022         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6023         local osts=$($LFS df -v $MOUNT | grep -c OST)
6024
6025         $LFS df $MOUNT
6026
6027         (( mdts == MDSCOUNT )) ||
6028                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6029         (( osts == OSTCOUNT )) ||
6030                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6031 }
6032 run_test 56d "'lfs df -v' prints only configured devices"
6033
6034 NUMFILES=3
6035 NUMDIRS=3
6036 setup_56() {
6037         local local_tdir="$1"
6038         local local_numfiles="$2"
6039         local local_numdirs="$3"
6040         local dir_params="$4"
6041         local dir_stripe_params="$5"
6042
6043         if [ ! -d "$local_tdir" ] ; then
6044                 test_mkdir -p $dir_stripe_params $local_tdir
6045                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6046                 for i in $(seq $local_numfiles) ; do
6047                         touch $local_tdir/file$i
6048                 done
6049                 for i in $(seq $local_numdirs) ; do
6050                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6051                         for j in $(seq $local_numfiles) ; do
6052                                 touch $local_tdir/dir$i/file$j
6053                         done
6054                 done
6055         fi
6056 }
6057
6058 setup_56_special() {
6059         local local_tdir=$1
6060         local local_numfiles=$2
6061         local local_numdirs=$3
6062
6063         setup_56 $local_tdir $local_numfiles $local_numdirs
6064
6065         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6066                 for i in $(seq $local_numfiles) ; do
6067                         mknod $local_tdir/loop${i}b b 7 $i
6068                         mknod $local_tdir/null${i}c c 1 3
6069                         ln -s $local_tdir/file1 $local_tdir/link${i}
6070                 done
6071                 for i in $(seq $local_numdirs) ; do
6072                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6073                         mknod $local_tdir/dir$i/null${i}c c 1 3
6074                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6075                 done
6076         fi
6077 }
6078
6079 test_56g() {
6080         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6081         local expected=$(($NUMDIRS + 2))
6082
6083         setup_56 $dir $NUMFILES $NUMDIRS
6084
6085         # test lfs find with -name
6086         for i in $(seq $NUMFILES) ; do
6087                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6088
6089                 [ $nums -eq $expected ] ||
6090                         error "lfs find -name '*$i' $dir wrong: "\
6091                               "found $nums, expected $expected"
6092         done
6093 }
6094 run_test 56g "check lfs find -name"
6095
6096 test_56h() {
6097         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6098         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6099
6100         setup_56 $dir $NUMFILES $NUMDIRS
6101
6102         # test lfs find with ! -name
6103         for i in $(seq $NUMFILES) ; do
6104                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6105
6106                 [ $nums -eq $expected ] ||
6107                         error "lfs find ! -name '*$i' $dir wrong: "\
6108                               "found $nums, expected $expected"
6109         done
6110 }
6111 run_test 56h "check lfs find ! -name"
6112
6113 test_56i() {
6114         local dir=$DIR/$tdir
6115
6116         test_mkdir $dir
6117
6118         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6119         local out=$($cmd)
6120
6121         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6122 }
6123 run_test 56i "check 'lfs find -ost UUID' skips directories"
6124
6125 test_56j() {
6126         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6127
6128         setup_56_special $dir $NUMFILES $NUMDIRS
6129
6130         local expected=$((NUMDIRS + 1))
6131         local cmd="$LFS find -type d $dir"
6132         local nums=$($cmd | wc -l)
6133
6134         [ $nums -eq $expected ] ||
6135                 error "'$cmd' wrong: found $nums, expected $expected"
6136 }
6137 run_test 56j "check lfs find -type d"
6138
6139 test_56k() {
6140         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6141
6142         setup_56_special $dir $NUMFILES $NUMDIRS
6143
6144         local expected=$(((NUMDIRS + 1) * NUMFILES))
6145         local cmd="$LFS find -type f $dir"
6146         local nums=$($cmd | wc -l)
6147
6148         [ $nums -eq $expected ] ||
6149                 error "'$cmd' wrong: found $nums, expected $expected"
6150 }
6151 run_test 56k "check lfs find -type f"
6152
6153 test_56l() {
6154         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6155
6156         setup_56_special $dir $NUMFILES $NUMDIRS
6157
6158         local expected=$((NUMDIRS + NUMFILES))
6159         local cmd="$LFS find -type b $dir"
6160         local nums=$($cmd | wc -l)
6161
6162         [ $nums -eq $expected ] ||
6163                 error "'$cmd' wrong: found $nums, expected $expected"
6164 }
6165 run_test 56l "check lfs find -type b"
6166
6167 test_56m() {
6168         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6169
6170         setup_56_special $dir $NUMFILES $NUMDIRS
6171
6172         local expected=$((NUMDIRS + NUMFILES))
6173         local cmd="$LFS find -type c $dir"
6174         local nums=$($cmd | wc -l)
6175         [ $nums -eq $expected ] ||
6176                 error "'$cmd' wrong: found $nums, expected $expected"
6177 }
6178 run_test 56m "check lfs find -type c"
6179
6180 test_56n() {
6181         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6182         setup_56_special $dir $NUMFILES $NUMDIRS
6183
6184         local expected=$((NUMDIRS + NUMFILES))
6185         local cmd="$LFS find -type l $dir"
6186         local nums=$($cmd | wc -l)
6187
6188         [ $nums -eq $expected ] ||
6189                 error "'$cmd' wrong: found $nums, expected $expected"
6190 }
6191 run_test 56n "check lfs find -type l"
6192
6193 test_56o() {
6194         local dir=$DIR/$tdir
6195
6196         setup_56 $dir $NUMFILES $NUMDIRS
6197         utime $dir/file1 > /dev/null || error "utime (1)"
6198         utime $dir/file2 > /dev/null || error "utime (2)"
6199         utime $dir/dir1 > /dev/null || error "utime (3)"
6200         utime $dir/dir2 > /dev/null || error "utime (4)"
6201         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6202         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6203
6204         local expected=4
6205         local nums=$($LFS find -mtime +0 $dir | wc -l)
6206
6207         [ $nums -eq $expected ] ||
6208                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6209
6210         expected=12
6211         cmd="$LFS find -mtime 0 $dir"
6212         nums=$($cmd | wc -l)
6213         [ $nums -eq $expected ] ||
6214                 error "'$cmd' wrong: found $nums, expected $expected"
6215 }
6216 run_test 56o "check lfs find -mtime for old files"
6217
6218 test_56ob() {
6219         local dir=$DIR/$tdir
6220         local expected=1
6221         local count=0
6222
6223         # just to make sure there is something that won't be found
6224         test_mkdir $dir
6225         touch $dir/$tfile.now
6226
6227         for age in year week day hour min; do
6228                 count=$((count + 1))
6229
6230                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6231                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6232                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6233
6234                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6235                 local nums=$($cmd | wc -l)
6236                 [ $nums -eq $expected ] ||
6237                         error "'$cmd' wrong: found $nums, expected $expected"
6238
6239                 cmd="$LFS find $dir -atime $count${age:0:1}"
6240                 nums=$($cmd | wc -l)
6241                 [ $nums -eq $expected ] ||
6242                         error "'$cmd' wrong: found $nums, expected $expected"
6243         done
6244
6245         sleep 2
6246         cmd="$LFS find $dir -ctime +1s -type f"
6247         nums=$($cmd | wc -l)
6248         (( $nums == $count * 2 + 1)) ||
6249                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6250 }
6251 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6252
6253 test_newerXY_base() {
6254         local x=$1
6255         local y=$2
6256         local dir=$DIR/$tdir
6257         local ref
6258         local negref
6259
6260         if [ $y == "t" ]; then
6261                 if [ $x == "b" ]; then
6262                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6263                 else
6264                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6265                 fi
6266         else
6267                 ref=$DIR/$tfile.newer.$x$y
6268                 touch $ref || error "touch $ref failed"
6269         fi
6270
6271         echo "before = $ref"
6272         sleep 2
6273         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6274         sleep 2
6275         if [ $y == "t" ]; then
6276                 if [ $x == "b" ]; then
6277                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6278                 else
6279                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6280                 fi
6281         else
6282                 negref=$DIR/$tfile.negnewer.$x$y
6283                 touch $negref || error "touch $negref failed"
6284         fi
6285
6286         echo "after = $negref"
6287         local cmd="$LFS find $dir -newer$x$y $ref"
6288         local nums=$(eval $cmd | wc -l)
6289         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6290
6291         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6292                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6293
6294         cmd="$LFS find $dir ! -newer$x$y $negref"
6295         nums=$(eval $cmd | wc -l)
6296         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6297                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6298
6299         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6300         nums=$(eval $cmd | wc -l)
6301         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6302                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6303
6304         rm -rf $DIR/*
6305 }
6306
6307 test_56oc() {
6308         test_newerXY_base "a" "a"
6309         test_newerXY_base "a" "m"
6310         test_newerXY_base "a" "c"
6311         test_newerXY_base "m" "a"
6312         test_newerXY_base "m" "m"
6313         test_newerXY_base "m" "c"
6314         test_newerXY_base "c" "a"
6315         test_newerXY_base "c" "m"
6316         test_newerXY_base "c" "c"
6317
6318         [[ -n "$sles_version" ]] &&
6319                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6320
6321         test_newerXY_base "a" "t"
6322         test_newerXY_base "m" "t"
6323         test_newerXY_base "c" "t"
6324
6325         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6326            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6327                 ! btime_supported && echo "btime unsupported" && return 0
6328
6329         test_newerXY_base "b" "b"
6330         test_newerXY_base "b" "t"
6331 }
6332 run_test 56oc "check lfs find -newerXY work"
6333
6334 btime_supported() {
6335         local dir=$DIR/$tdir
6336         local rc
6337
6338         mkdir -p $dir
6339         touch $dir/$tfile
6340         $LFS find $dir -btime -1d -type f
6341         rc=$?
6342         rm -rf $dir
6343         return $rc
6344 }
6345
6346 test_56od() {
6347         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6348                 ! btime_supported && skip "btime unsupported on MDS"
6349
6350         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6351                 ! btime_supported && skip "btime unsupported on clients"
6352
6353         local dir=$DIR/$tdir
6354         local ref=$DIR/$tfile.ref
6355         local negref=$DIR/$tfile.negref
6356
6357         mkdir $dir || error "mkdir $dir failed"
6358         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6359         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6360         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6361         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6362         touch $ref || error "touch $ref failed"
6363         # sleep 3 seconds at least
6364         sleep 3
6365
6366         local before=$(do_facet mds1 date +%s)
6367         local skew=$(($(date +%s) - before + 1))
6368
6369         if (( skew < 0 && skew > -5 )); then
6370                 sleep $((0 - skew + 1))
6371                 skew=0
6372         fi
6373
6374         # Set the dir stripe params to limit files all on MDT0,
6375         # otherwise we need to calc the max clock skew between
6376         # the client and MDTs.
6377         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6378         sleep 2
6379         touch $negref || error "touch $negref failed"
6380
6381         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6382         local nums=$($cmd | wc -l)
6383         local expected=$(((NUMFILES + 1) * NUMDIRS))
6384
6385         [ $nums -eq $expected ] ||
6386                 error "'$cmd' wrong: found $nums, expected $expected"
6387
6388         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6389         nums=$($cmd | wc -l)
6390         expected=$((NUMFILES + 1))
6391         [ $nums -eq $expected ] ||
6392                 error "'$cmd' wrong: found $nums, expected $expected"
6393
6394         [ $skew -lt 0 ] && return
6395
6396         local after=$(do_facet mds1 date +%s)
6397         local age=$((after - before + 1 + skew))
6398
6399         cmd="$LFS find $dir -btime -${age}s -type f"
6400         nums=$($cmd | wc -l)
6401         expected=$(((NUMFILES + 1) * NUMDIRS))
6402
6403         echo "Clock skew between client and server: $skew, age:$age"
6404         [ $nums -eq $expected ] ||
6405                 error "'$cmd' wrong: found $nums, expected $expected"
6406
6407         expected=$(($NUMDIRS + 1))
6408         cmd="$LFS find $dir -btime -${age}s -type d"
6409         nums=$($cmd | wc -l)
6410         [ $nums -eq $expected ] ||
6411                 error "'$cmd' wrong: found $nums, expected $expected"
6412         rm -f $ref $negref || error "Failed to remove $ref $negref"
6413 }
6414 run_test 56od "check lfs find -btime with units"
6415
6416 test_56p() {
6417         [ $RUNAS_ID -eq $UID ] &&
6418                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6419
6420         local dir=$DIR/$tdir
6421
6422         setup_56 $dir $NUMFILES $NUMDIRS
6423         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6424
6425         local expected=$NUMFILES
6426         local cmd="$LFS find -uid $RUNAS_ID $dir"
6427         local nums=$($cmd | wc -l)
6428
6429         [ $nums -eq $expected ] ||
6430                 error "'$cmd' wrong: found $nums, expected $expected"
6431
6432         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6433         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6434         nums=$($cmd | wc -l)
6435         [ $nums -eq $expected ] ||
6436                 error "'$cmd' wrong: found $nums, expected $expected"
6437 }
6438 run_test 56p "check lfs find -uid and ! -uid"
6439
6440 test_56q() {
6441         [ $RUNAS_ID -eq $UID ] &&
6442                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6443
6444         local dir=$DIR/$tdir
6445
6446         setup_56 $dir $NUMFILES $NUMDIRS
6447         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6448
6449         local expected=$NUMFILES
6450         local cmd="$LFS find -gid $RUNAS_GID $dir"
6451         local nums=$($cmd | wc -l)
6452
6453         [ $nums -eq $expected ] ||
6454                 error "'$cmd' wrong: found $nums, expected $expected"
6455
6456         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6457         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6458         nums=$($cmd | wc -l)
6459         [ $nums -eq $expected ] ||
6460                 error "'$cmd' wrong: found $nums, expected $expected"
6461 }
6462 run_test 56q "check lfs find -gid and ! -gid"
6463
6464 test_56r() {
6465         local dir=$DIR/$tdir
6466
6467         setup_56 $dir $NUMFILES $NUMDIRS
6468
6469         local expected=12
6470         local cmd="$LFS find -size 0 -type f -lazy $dir"
6471         local nums=$($cmd | wc -l)
6472
6473         [ $nums -eq $expected ] ||
6474                 error "'$cmd' wrong: found $nums, expected $expected"
6475         cmd="$LFS find -size 0 -type f $dir"
6476         nums=$($cmd | wc -l)
6477         [ $nums -eq $expected ] ||
6478                 error "'$cmd' wrong: found $nums, expected $expected"
6479
6480         expected=0
6481         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6482         nums=$($cmd | wc -l)
6483         [ $nums -eq $expected ] ||
6484                 error "'$cmd' wrong: found $nums, expected $expected"
6485         cmd="$LFS find ! -size 0 -type f $dir"
6486         nums=$($cmd | wc -l)
6487         [ $nums -eq $expected ] ||
6488                 error "'$cmd' wrong: found $nums, expected $expected"
6489
6490         echo "test" > $dir/$tfile
6491         echo "test2" > $dir/$tfile.2 && sync
6492         expected=1
6493         cmd="$LFS find -size 5 -type f -lazy $dir"
6494         nums=$($cmd | wc -l)
6495         [ $nums -eq $expected ] ||
6496                 error "'$cmd' wrong: found $nums, expected $expected"
6497         cmd="$LFS find -size 5 -type f $dir"
6498         nums=$($cmd | wc -l)
6499         [ $nums -eq $expected ] ||
6500                 error "'$cmd' wrong: found $nums, expected $expected"
6501
6502         expected=1
6503         cmd="$LFS find -size +5 -type f -lazy $dir"
6504         nums=$($cmd | wc -l)
6505         [ $nums -eq $expected ] ||
6506                 error "'$cmd' wrong: found $nums, expected $expected"
6507         cmd="$LFS find -size +5 -type f $dir"
6508         nums=$($cmd | wc -l)
6509         [ $nums -eq $expected ] ||
6510                 error "'$cmd' wrong: found $nums, expected $expected"
6511
6512         expected=2
6513         cmd="$LFS find -size +0 -type f -lazy $dir"
6514         nums=$($cmd | wc -l)
6515         [ $nums -eq $expected ] ||
6516                 error "'$cmd' wrong: found $nums, expected $expected"
6517         cmd="$LFS find -size +0 -type f $dir"
6518         nums=$($cmd | wc -l)
6519         [ $nums -eq $expected ] ||
6520                 error "'$cmd' wrong: found $nums, expected $expected"
6521
6522         expected=2
6523         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6524         nums=$($cmd | wc -l)
6525         [ $nums -eq $expected ] ||
6526                 error "'$cmd' wrong: found $nums, expected $expected"
6527         cmd="$LFS find ! -size -5 -type f $dir"
6528         nums=$($cmd | wc -l)
6529         [ $nums -eq $expected ] ||
6530                 error "'$cmd' wrong: found $nums, expected $expected"
6531
6532         expected=12
6533         cmd="$LFS find -size -5 -type f -lazy $dir"
6534         nums=$($cmd | wc -l)
6535         [ $nums -eq $expected ] ||
6536                 error "'$cmd' wrong: found $nums, expected $expected"
6537         cmd="$LFS find -size -5 -type f $dir"
6538         nums=$($cmd | wc -l)
6539         [ $nums -eq $expected ] ||
6540                 error "'$cmd' wrong: found $nums, expected $expected"
6541 }
6542 run_test 56r "check lfs find -size works"
6543
6544 test_56ra_sub() {
6545         local expected=$1
6546         local glimpses=$2
6547         local cmd="$3"
6548
6549         cancel_lru_locks $OSC
6550
6551         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6552         local nums=$($cmd | wc -l)
6553
6554         [ $nums -eq $expected ] ||
6555                 error "'$cmd' wrong: found $nums, expected $expected"
6556
6557         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6558
6559         if (( rpcs_before + glimpses != rpcs_after )); then
6560                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6561                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6562
6563                 if [[ $glimpses == 0 ]]; then
6564                         error "'$cmd' should not send glimpse RPCs to OST"
6565                 else
6566                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6567                 fi
6568         fi
6569 }
6570
6571 test_56ra() {
6572         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6573                 skip "MDS < 2.12.58 doesn't return LSOM data"
6574         local dir=$DIR/$tdir
6575         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6576
6577         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6578
6579         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6580         $LCTL set_param -n llite.*.statahead_agl=0
6581         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6582
6583         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6584         # open and close all files to ensure LSOM is updated
6585         cancel_lru_locks $OSC
6586         find $dir -type f | xargs cat > /dev/null
6587
6588         #   expect_found  glimpse_rpcs  command_to_run
6589         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6590         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6591         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6592         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6593
6594         echo "test" > $dir/$tfile
6595         echo "test2" > $dir/$tfile.2 && sync
6596         cancel_lru_locks $OSC
6597         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6598
6599         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6600         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6601         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6602         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6603
6604         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6605         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6606         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6607         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6608         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6609         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6610 }
6611 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6612
6613 test_56rb() {
6614         local dir=$DIR/$tdir
6615         local tmp=$TMP/$tfile.log
6616         local mdt_idx;
6617
6618         test_mkdir -p $dir || error "failed to mkdir $dir"
6619         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6620                 error "failed to setstripe $dir/$tfile"
6621         mdt_idx=$($LFS getdirstripe -i $dir)
6622         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6623
6624         stack_trap "rm -f $tmp" EXIT
6625         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6626         ! grep -q obd_uuid $tmp ||
6627                 error "failed to find --size +100K --ost 0 $dir"
6628         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6629         ! grep -q obd_uuid $tmp ||
6630                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6631 }
6632 run_test 56rb "check lfs find --size --ost/--mdt works"
6633
6634 test_56s() { # LU-611 #LU-9369
6635         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6636
6637         local dir=$DIR/$tdir
6638         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6639
6640         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6641         for i in $(seq $NUMDIRS); do
6642                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6643         done
6644
6645         local expected=$NUMDIRS
6646         local cmd="$LFS find -c $OSTCOUNT $dir"
6647         local nums=$($cmd | wc -l)
6648
6649         [ $nums -eq $expected ] || {
6650                 $LFS getstripe -R $dir
6651                 error "'$cmd' wrong: found $nums, expected $expected"
6652         }
6653
6654         expected=$((NUMDIRS + onestripe))
6655         cmd="$LFS find -stripe-count +0 -type f $dir"
6656         nums=$($cmd | wc -l)
6657         [ $nums -eq $expected ] || {
6658                 $LFS getstripe -R $dir
6659                 error "'$cmd' wrong: found $nums, expected $expected"
6660         }
6661
6662         expected=$onestripe
6663         cmd="$LFS find -stripe-count 1 -type f $dir"
6664         nums=$($cmd | wc -l)
6665         [ $nums -eq $expected ] || {
6666                 $LFS getstripe -R $dir
6667                 error "'$cmd' wrong: found $nums, expected $expected"
6668         }
6669
6670         cmd="$LFS find -stripe-count -2 -type f $dir"
6671         nums=$($cmd | wc -l)
6672         [ $nums -eq $expected ] || {
6673                 $LFS getstripe -R $dir
6674                 error "'$cmd' wrong: found $nums, expected $expected"
6675         }
6676
6677         expected=0
6678         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6679         nums=$($cmd | wc -l)
6680         [ $nums -eq $expected ] || {
6681                 $LFS getstripe -R $dir
6682                 error "'$cmd' wrong: found $nums, expected $expected"
6683         }
6684 }
6685 run_test 56s "check lfs find -stripe-count works"
6686
6687 test_56t() { # LU-611 #LU-9369
6688         local dir=$DIR/$tdir
6689
6690         setup_56 $dir 0 $NUMDIRS
6691         for i in $(seq $NUMDIRS); do
6692                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6693         done
6694
6695         local expected=$NUMDIRS
6696         local cmd="$LFS find -S 8M $dir"
6697         local nums=$($cmd | wc -l)
6698
6699         [ $nums -eq $expected ] || {
6700                 $LFS getstripe -R $dir
6701                 error "'$cmd' wrong: found $nums, expected $expected"
6702         }
6703         rm -rf $dir
6704
6705         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6706
6707         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6708
6709         expected=$(((NUMDIRS + 1) * NUMFILES))
6710         cmd="$LFS find -stripe-size 512k -type f $dir"
6711         nums=$($cmd | wc -l)
6712         [ $nums -eq $expected ] ||
6713                 error "'$cmd' wrong: found $nums, expected $expected"
6714
6715         cmd="$LFS find -stripe-size +320k -type f $dir"
6716         nums=$($cmd | wc -l)
6717         [ $nums -eq $expected ] ||
6718                 error "'$cmd' wrong: found $nums, expected $expected"
6719
6720         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6721         cmd="$LFS find -stripe-size +200k -type f $dir"
6722         nums=$($cmd | wc -l)
6723         [ $nums -eq $expected ] ||
6724                 error "'$cmd' wrong: found $nums, expected $expected"
6725
6726         cmd="$LFS find -stripe-size -640k -type f $dir"
6727         nums=$($cmd | wc -l)
6728         [ $nums -eq $expected ] ||
6729                 error "'$cmd' wrong: found $nums, expected $expected"
6730
6731         expected=4
6732         cmd="$LFS find -stripe-size 256k -type f $dir"
6733         nums=$($cmd | wc -l)
6734         [ $nums -eq $expected ] ||
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736
6737         cmd="$LFS find -stripe-size -320k -type f $dir"
6738         nums=$($cmd | wc -l)
6739         [ $nums -eq $expected ] ||
6740                 error "'$cmd' wrong: found $nums, expected $expected"
6741
6742         expected=0
6743         cmd="$LFS find -stripe-size 1024k -type f $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] ||
6746                 error "'$cmd' wrong: found $nums, expected $expected"
6747 }
6748 run_test 56t "check lfs find -stripe-size works"
6749
6750 test_56u() { # LU-611
6751         local dir=$DIR/$tdir
6752
6753         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6754
6755         if [[ $OSTCOUNT -gt 1 ]]; then
6756                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6757                 onestripe=4
6758         else
6759                 onestripe=0
6760         fi
6761
6762         local expected=$(((NUMDIRS + 1) * NUMFILES))
6763         local cmd="$LFS find -stripe-index 0 -type f $dir"
6764         local nums=$($cmd | wc -l)
6765
6766         [ $nums -eq $expected ] ||
6767                 error "'$cmd' wrong: found $nums, expected $expected"
6768
6769         expected=$onestripe
6770         cmd="$LFS find -stripe-index 1 -type f $dir"
6771         nums=$($cmd | wc -l)
6772         [ $nums -eq $expected ] ||
6773                 error "'$cmd' wrong: found $nums, expected $expected"
6774
6775         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6776         nums=$($cmd | wc -l)
6777         [ $nums -eq $expected ] ||
6778                 error "'$cmd' wrong: found $nums, expected $expected"
6779
6780         expected=0
6781         # This should produce an error and not return any files
6782         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6783         nums=$($cmd 2>/dev/null | wc -l)
6784         [ $nums -eq $expected ] ||
6785                 error "'$cmd' wrong: found $nums, expected $expected"
6786
6787         if [[ $OSTCOUNT -gt 1 ]]; then
6788                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6789                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6790                 nums=$($cmd | wc -l)
6791                 [ $nums -eq $expected ] ||
6792                         error "'$cmd' wrong: found $nums, expected $expected"
6793         fi
6794 }
6795 run_test 56u "check lfs find -stripe-index works"
6796
6797 test_56v() {
6798         local mdt_idx=0
6799         local dir=$DIR/$tdir
6800
6801         setup_56 $dir $NUMFILES $NUMDIRS
6802
6803         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6804         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6805
6806         for file in $($LFS find -m $UUID $dir); do
6807                 file_midx=$($LFS getstripe -m $file)
6808                 [ $file_midx -eq $mdt_idx ] ||
6809                         error "lfs find -m $UUID != getstripe -m $file_midx"
6810         done
6811 }
6812 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6813
6814 test_56w() {
6815         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6817
6818         local dir=$DIR/$tdir
6819
6820         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6821
6822         local stripe_size=$($LFS getstripe -S -d $dir) ||
6823                 error "$LFS getstripe -S -d $dir failed"
6824         stripe_size=${stripe_size%% *}
6825
6826         local file_size=$((stripe_size * OSTCOUNT))
6827         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6828         local required_space=$((file_num * file_size))
6829         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6830                            head -n1)
6831         [[ $free_space -le $((required_space / 1024)) ]] &&
6832                 skip_env "need $required_space, have $free_space kbytes"
6833
6834         local dd_bs=65536
6835         local dd_count=$((file_size / dd_bs))
6836
6837         # write data into the files
6838         local i
6839         local j
6840         local file
6841
6842         for i in $(seq $NUMFILES); do
6843                 file=$dir/file$i
6844                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6845                         error "write data into $file failed"
6846         done
6847         for i in $(seq $NUMDIRS); do
6848                 for j in $(seq $NUMFILES); do
6849                         file=$dir/dir$i/file$j
6850                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6851                                 error "write data into $file failed"
6852                 done
6853         done
6854
6855         # $LFS_MIGRATE will fail if hard link migration is unsupported
6856         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6857                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6858                         error "creating links to $dir/dir1/file1 failed"
6859         fi
6860
6861         local expected=-1
6862
6863         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6864
6865         # lfs_migrate file
6866         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6867
6868         echo "$cmd"
6869         eval $cmd || error "$cmd failed"
6870
6871         check_stripe_count $dir/file1 $expected
6872
6873         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6874         then
6875                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6876                 # OST 1 if it is on OST 0. This file is small enough to
6877                 # be on only one stripe.
6878                 file=$dir/migr_1_ost
6879                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6880                         error "write data into $file failed"
6881                 local obdidx=$($LFS getstripe -i $file)
6882                 local oldmd5=$(md5sum $file)
6883                 local newobdidx=0
6884
6885                 [[ $obdidx -eq 0 ]] && newobdidx=1
6886                 cmd="$LFS migrate -i $newobdidx $file"
6887                 echo $cmd
6888                 eval $cmd || error "$cmd failed"
6889
6890                 local realobdix=$($LFS getstripe -i $file)
6891                 local newmd5=$(md5sum $file)
6892
6893                 [[ $newobdidx -ne $realobdix ]] &&
6894                         error "new OST is different (was=$obdidx, "\
6895                               "wanted=$newobdidx, got=$realobdix)"
6896                 [[ "$oldmd5" != "$newmd5" ]] &&
6897                         error "md5sum differ: $oldmd5, $newmd5"
6898         fi
6899
6900         # lfs_migrate dir
6901         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6902         echo "$cmd"
6903         eval $cmd || error "$cmd failed"
6904
6905         for j in $(seq $NUMFILES); do
6906                 check_stripe_count $dir/dir1/file$j $expected
6907         done
6908
6909         # lfs_migrate works with lfs find
6910         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6911              $LFS_MIGRATE -y -c $expected"
6912         echo "$cmd"
6913         eval $cmd || error "$cmd failed"
6914
6915         for i in $(seq 2 $NUMFILES); do
6916                 check_stripe_count $dir/file$i $expected
6917         done
6918         for i in $(seq 2 $NUMDIRS); do
6919                 for j in $(seq $NUMFILES); do
6920                 check_stripe_count $dir/dir$i/file$j $expected
6921                 done
6922         done
6923 }
6924 run_test 56w "check lfs_migrate -c stripe_count works"
6925
6926 test_56wb() {
6927         local file1=$DIR/$tdir/file1
6928         local create_pool=false
6929         local initial_pool=$($LFS getstripe -p $DIR)
6930         local pool_list=()
6931         local pool=""
6932
6933         echo -n "Creating test dir..."
6934         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6935         echo "done."
6936
6937         echo -n "Creating test file..."
6938         touch $file1 || error "cannot create file"
6939         echo "done."
6940
6941         echo -n "Detecting existing pools..."
6942         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6943
6944         if [ ${#pool_list[@]} -gt 0 ]; then
6945                 echo "${pool_list[@]}"
6946                 for thispool in "${pool_list[@]}"; do
6947                         if [[ -z "$initial_pool" ||
6948                               "$initial_pool" != "$thispool" ]]; then
6949                                 pool="$thispool"
6950                                 echo "Using existing pool '$pool'"
6951                                 break
6952                         fi
6953                 done
6954         else
6955                 echo "none detected."
6956         fi
6957         if [ -z "$pool" ]; then
6958                 pool=${POOL:-testpool}
6959                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6960                 echo -n "Creating pool '$pool'..."
6961                 create_pool=true
6962                 pool_add $pool &> /dev/null ||
6963                         error "pool_add failed"
6964                 echo "done."
6965
6966                 echo -n "Adding target to pool..."
6967                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6968                         error "pool_add_targets failed"
6969                 echo "done."
6970         fi
6971
6972         echo -n "Setting pool using -p option..."
6973         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6974                 error "migrate failed rc = $?"
6975         echo "done."
6976
6977         echo -n "Verifying test file is in pool after migrating..."
6978         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6979                 error "file was not migrated to pool $pool"
6980         echo "done."
6981
6982         echo -n "Removing test file from pool '$pool'..."
6983         # "lfs migrate $file" won't remove the file from the pool
6984         # until some striping information is changed.
6985         $LFS migrate -c 1 $file1 &> /dev/null ||
6986                 error "cannot remove from pool"
6987         [ "$($LFS getstripe -p $file1)" ] &&
6988                 error "pool still set"
6989         echo "done."
6990
6991         echo -n "Setting pool using --pool option..."
6992         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6993                 error "migrate failed rc = $?"
6994         echo "done."
6995
6996         # Clean up
6997         rm -f $file1
6998         if $create_pool; then
6999                 destroy_test_pools 2> /dev/null ||
7000                         error "destroy test pools failed"
7001         fi
7002 }
7003 run_test 56wb "check lfs_migrate pool support"
7004
7005 test_56wc() {
7006         local file1="$DIR/$tdir/file1"
7007         local parent_ssize
7008         local parent_scount
7009         local cur_ssize
7010         local cur_scount
7011         local orig_ssize
7012
7013         echo -n "Creating test dir..."
7014         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7015         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7016                 error "cannot set stripe by '-S 1M -c 1'"
7017         echo "done"
7018
7019         echo -n "Setting initial stripe for test file..."
7020         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7021                 error "cannot set stripe"
7022         cur_ssize=$($LFS getstripe -S "$file1")
7023         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7024         echo "done."
7025
7026         # File currently set to -S 512K -c 1
7027
7028         # Ensure -c and -S options are rejected when -R is set
7029         echo -n "Verifying incompatible options are detected..."
7030         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7031                 error "incompatible -c and -R options not detected"
7032         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7033                 error "incompatible -S and -R options not detected"
7034         echo "done."
7035
7036         # Ensure unrecognized options are passed through to 'lfs migrate'
7037         echo -n "Verifying -S option is passed through to lfs migrate..."
7038         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7039                 error "migration failed"
7040         cur_ssize=$($LFS getstripe -S "$file1")
7041         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7042         echo "done."
7043
7044         # File currently set to -S 1M -c 1
7045
7046         # Ensure long options are supported
7047         echo -n "Verifying long options supported..."
7048         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7049                 error "long option without argument not supported"
7050         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7051                 error "long option with argument not supported"
7052         cur_ssize=$($LFS getstripe -S "$file1")
7053         [ $cur_ssize -eq 524288 ] ||
7054                 error "migrate --stripe-size $cur_ssize != 524288"
7055         echo "done."
7056
7057         # File currently set to -S 512K -c 1
7058
7059         if [ "$OSTCOUNT" -gt 1 ]; then
7060                 echo -n "Verifying explicit stripe count can be set..."
7061                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7062                         error "migrate failed"
7063                 cur_scount=$($LFS getstripe -c "$file1")
7064                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7065                 echo "done."
7066         fi
7067
7068         # File currently set to -S 512K -c 1 or -S 512K -c 2
7069
7070         # Ensure parent striping is used if -R is set, and no stripe
7071         # count or size is specified
7072         echo -n "Setting stripe for parent directory..."
7073         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7074                 error "cannot set stripe '-S 2M -c 1'"
7075         echo "done."
7076
7077         echo -n "Verifying restripe option uses parent stripe settings..."
7078         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7079         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7080         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7081                 error "migrate failed"
7082         cur_ssize=$($LFS getstripe -S "$file1")
7083         [ $cur_ssize -eq $parent_ssize ] ||
7084                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7085         cur_scount=$($LFS getstripe -c "$file1")
7086         [ $cur_scount -eq $parent_scount ] ||
7087                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7088         echo "done."
7089
7090         # File currently set to -S 1M -c 1
7091
7092         # Ensure striping is preserved if -R is not set, and no stripe
7093         # count or size is specified
7094         echo -n "Verifying striping size preserved when not specified..."
7095         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7096         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7097                 error "cannot set stripe on parent directory"
7098         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7099                 error "migrate failed"
7100         cur_ssize=$($LFS getstripe -S "$file1")
7101         [ $cur_ssize -eq $orig_ssize ] ||
7102                 error "migrate by default $cur_ssize != $orig_ssize"
7103         echo "done."
7104
7105         # Ensure file name properly detected when final option has no argument
7106         echo -n "Verifying file name properly detected..."
7107         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7108                 error "file name interpreted as option argument"
7109         echo "done."
7110
7111         # Clean up
7112         rm -f "$file1"
7113 }
7114 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7115
7116 test_56wd() {
7117         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7118
7119         local file1=$DIR/$tdir/file1
7120
7121         echo -n "Creating test dir..."
7122         test_mkdir $DIR/$tdir || error "cannot create dir"
7123         echo "done."
7124
7125         echo -n "Creating test file..."
7126         touch $file1
7127         echo "done."
7128
7129         # Ensure 'lfs migrate' will fail by using a non-existent option,
7130         # and make sure rsync is not called to recover
7131         echo -n "Make sure --no-rsync option works..."
7132         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7133                 grep -q 'refusing to fall back to rsync' ||
7134                 error "rsync was called with --no-rsync set"
7135         echo "done."
7136
7137         # Ensure rsync is called without trying 'lfs migrate' first
7138         echo -n "Make sure --rsync option works..."
7139         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7140                 grep -q 'falling back to rsync' &&
7141                 error "lfs migrate was called with --rsync set"
7142         echo "done."
7143
7144         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7145         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7146                 grep -q 'at the same time' ||
7147                 error "--rsync and --no-rsync accepted concurrently"
7148         echo "done."
7149
7150         # Clean up
7151         rm -f $file1
7152 }
7153 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7154
7155 test_56we() {
7156         local td=$DIR/$tdir
7157         local tf=$td/$tfile
7158
7159         test_mkdir $td || error "cannot create $td"
7160         touch $tf || error "cannot touch $tf"
7161
7162         echo -n "Make sure --non-direct|-D works..."
7163         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7164                 grep -q "lfs migrate --non-direct" ||
7165                 error "--non-direct option cannot work correctly"
7166         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7167                 grep -q "lfs migrate -D" ||
7168                 error "-D option cannot work correctly"
7169         echo "done."
7170 }
7171 run_test 56we "check lfs_migrate --non-direct|-D support"
7172
7173 test_56x() {
7174         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7175         check_swap_layouts_support
7176
7177         local dir=$DIR/$tdir
7178         local ref1=/etc/passwd
7179         local file1=$dir/file1
7180
7181         test_mkdir $dir || error "creating dir $dir"
7182         $LFS setstripe -c 2 $file1
7183         cp $ref1 $file1
7184         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7185         stripe=$($LFS getstripe -c $file1)
7186         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7187         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7188
7189         # clean up
7190         rm -f $file1
7191 }
7192 run_test 56x "lfs migration support"
7193
7194 test_56xa() {
7195         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7196         check_swap_layouts_support
7197
7198         local dir=$DIR/$tdir/$testnum
7199
7200         test_mkdir -p $dir
7201
7202         local ref1=/etc/passwd
7203         local file1=$dir/file1
7204
7205         $LFS setstripe -c 2 $file1
7206         cp $ref1 $file1
7207         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7208
7209         local stripe=$($LFS getstripe -c $file1)
7210
7211         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7212         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7213
7214         # clean up
7215         rm -f $file1
7216 }
7217 run_test 56xa "lfs migration --block support"
7218
7219 check_migrate_links() {
7220         local dir="$1"
7221         local file1="$dir/file1"
7222         local begin="$2"
7223         local count="$3"
7224         local runas="$4"
7225         local total_count=$(($begin + $count - 1))
7226         local symlink_count=10
7227         local uniq_count=10
7228
7229         if [ ! -f "$file1" ]; then
7230                 echo -n "creating initial file..."
7231                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7232                         error "cannot setstripe initial file"
7233                 echo "done"
7234
7235                 echo -n "creating symlinks..."
7236                 for s in $(seq 1 $symlink_count); do
7237                         ln -s "$file1" "$dir/slink$s" ||
7238                                 error "cannot create symlinks"
7239                 done
7240                 echo "done"
7241
7242                 echo -n "creating nonlinked files..."
7243                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7244                         error "cannot create nonlinked files"
7245                 echo "done"
7246         fi
7247
7248         # create hard links
7249         if [ ! -f "$dir/file$total_count" ]; then
7250                 echo -n "creating hard links $begin:$total_count..."
7251                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7252                         /dev/null || error "cannot create hard links"
7253                 echo "done"
7254         fi
7255
7256         echo -n "checking number of hard links listed in xattrs..."
7257         local fid=$($LFS getstripe -F "$file1")
7258         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7259
7260         echo "${#paths[*]}"
7261         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7262                         skip "hard link list has unexpected size, skipping test"
7263         fi
7264         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7265                         error "link names should exceed xattrs size"
7266         fi
7267
7268         echo -n "migrating files..."
7269         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7270         local rc=$?
7271         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7272         echo "done"
7273
7274         # make sure all links have been properly migrated
7275         echo -n "verifying files..."
7276         fid=$($LFS getstripe -F "$file1") ||
7277                 error "cannot get fid for file $file1"
7278         for i in $(seq 2 $total_count); do
7279                 local fid2=$($LFS getstripe -F $dir/file$i)
7280
7281                 [ "$fid2" == "$fid" ] ||
7282                         error "migrated hard link has mismatched FID"
7283         done
7284
7285         # make sure hard links were properly detected, and migration was
7286         # performed only once for the entire link set; nonlinked files should
7287         # also be migrated
7288         local actual=$(grep -c 'done' <<< "$migrate_out")
7289         local expected=$(($uniq_count + 1))
7290
7291         [ "$actual" -eq  "$expected" ] ||
7292                 error "hard links individually migrated ($actual != $expected)"
7293
7294         # make sure the correct number of hard links are present
7295         local hardlinks=$(stat -c '%h' "$file1")
7296
7297         [ $hardlinks -eq $total_count ] ||
7298                 error "num hard links $hardlinks != $total_count"
7299         echo "done"
7300
7301         return 0
7302 }
7303
7304 test_56xb() {
7305         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7306                 skip "Need MDS version at least 2.10.55"
7307
7308         local dir="$DIR/$tdir"
7309
7310         test_mkdir "$dir" || error "cannot create dir $dir"
7311
7312         echo "testing lfs migrate mode when all links fit within xattrs"
7313         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7314
7315         echo "testing rsync mode when all links fit within xattrs"
7316         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7317
7318         echo "testing lfs migrate mode when all links do not fit within xattrs"
7319         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7320
7321         echo "testing rsync mode when all links do not fit within xattrs"
7322         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7323
7324         chown -R $RUNAS_ID $dir
7325         echo "testing non-root lfs migrate mode when not all links are in xattr"
7326         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7327
7328         # clean up
7329         rm -rf $dir
7330 }
7331 run_test 56xb "lfs migration hard link support"
7332
7333 test_56xc() {
7334         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7335
7336         local dir="$DIR/$tdir"
7337
7338         test_mkdir "$dir" || error "cannot create dir $dir"
7339
7340         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7341         echo -n "Setting initial stripe for 20MB test file..."
7342         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7343                 error "cannot setstripe 20MB file"
7344         echo "done"
7345         echo -n "Sizing 20MB test file..."
7346         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7347         echo "done"
7348         echo -n "Verifying small file autostripe count is 1..."
7349         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7350                 error "cannot migrate 20MB file"
7351         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7352                 error "cannot get stripe for $dir/20mb"
7353         [ $stripe_count -eq 1 ] ||
7354                 error "unexpected stripe count $stripe_count for 20MB file"
7355         rm -f "$dir/20mb"
7356         echo "done"
7357
7358         # Test 2: File is small enough to fit within the available space on
7359         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7360         # have at least an additional 1KB for each desired stripe for test 3
7361         echo -n "Setting stripe for 1GB test file..."
7362         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7363         echo "done"
7364         echo -n "Sizing 1GB test file..."
7365         # File size is 1GB + 3KB
7366         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7367         echo "done"
7368
7369         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7370         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7371         if (( avail > 524288 * OSTCOUNT )); then
7372                 echo -n "Migrating 1GB file..."
7373                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7374                         error "cannot migrate 1GB file"
7375                 echo "done"
7376                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7377                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7378                         error "cannot getstripe for 1GB file"
7379                 [ $stripe_count -eq 2 ] ||
7380                         error "unexpected stripe count $stripe_count != 2"
7381                 echo "done"
7382         fi
7383
7384         # Test 3: File is too large to fit within the available space on
7385         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7386         if [ $OSTCOUNT -ge 3 ]; then
7387                 # The required available space is calculated as
7388                 # file size (1GB + 3KB) / OST count (3).
7389                 local kb_per_ost=349526
7390
7391                 echo -n "Migrating 1GB file with limit..."
7392                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7393                         error "cannot migrate 1GB file with limit"
7394                 echo "done"
7395
7396                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7397                 echo -n "Verifying 1GB autostripe count with limited space..."
7398                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7399                         error "unexpected stripe count $stripe_count (min 3)"
7400                 echo "done"
7401         fi
7402
7403         # clean up
7404         rm -rf $dir
7405 }
7406 run_test 56xc "lfs migration autostripe"
7407
7408 test_56xd() {
7409         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7410
7411         local dir=$DIR/$tdir
7412         local f_mgrt=$dir/$tfile.mgrt
7413         local f_yaml=$dir/$tfile.yaml
7414         local f_copy=$dir/$tfile.copy
7415         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7416         local layout_copy="-c 2 -S 2M -i 1"
7417         local yamlfile=$dir/yamlfile
7418         local layout_before;
7419         local layout_after;
7420
7421         test_mkdir "$dir" || error "cannot create dir $dir"
7422         $LFS setstripe $layout_yaml $f_yaml ||
7423                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7424         $LFS getstripe --yaml $f_yaml > $yamlfile
7425         $LFS setstripe $layout_copy $f_copy ||
7426                 error "cannot setstripe $f_copy with layout $layout_copy"
7427         touch $f_mgrt
7428         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7429
7430         # 1. test option --yaml
7431         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7432                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7433         layout_before=$(get_layout_param $f_yaml)
7434         layout_after=$(get_layout_param $f_mgrt)
7435         [ "$layout_after" == "$layout_before" ] ||
7436                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7437
7438         # 2. test option --copy
7439         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7440                 error "cannot migrate $f_mgrt with --copy $f_copy"
7441         layout_before=$(get_layout_param $f_copy)
7442         layout_after=$(get_layout_param $f_mgrt)
7443         [ "$layout_after" == "$layout_before" ] ||
7444                 error "lfs_migrate --copy: $layout_after != $layout_before"
7445 }
7446 run_test 56xd "check lfs_migrate --yaml and --copy support"
7447
7448 test_56xe() {
7449         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7450
7451         local dir=$DIR/$tdir
7452         local f_comp=$dir/$tfile
7453         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7454         local layout_before=""
7455         local layout_after=""
7456
7457         test_mkdir "$dir" || error "cannot create dir $dir"
7458         $LFS setstripe $layout $f_comp ||
7459                 error "cannot setstripe $f_comp with layout $layout"
7460         layout_before=$(get_layout_param $f_comp)
7461         dd if=/dev/zero of=$f_comp bs=1M count=4
7462
7463         # 1. migrate a comp layout file by lfs_migrate
7464         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7465         layout_after=$(get_layout_param $f_comp)
7466         [ "$layout_before" == "$layout_after" ] ||
7467                 error "lfs_migrate: $layout_before != $layout_after"
7468
7469         # 2. migrate a comp layout file by lfs migrate
7470         $LFS migrate $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 run_test 56xe "migrate a composite layout file"
7476
7477 test_56xf() {
7478         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7479
7480         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7481                 skip "Need server version at least 2.13.53"
7482
7483         local dir=$DIR/$tdir
7484         local f_comp=$dir/$tfile
7485         local layout="-E 1M -c1 -E -1 -c2"
7486         local fid_before=""
7487         local fid_after=""
7488
7489         test_mkdir "$dir" || error "cannot create dir $dir"
7490         $LFS setstripe $layout $f_comp ||
7491                 error "cannot setstripe $f_comp with layout $layout"
7492         fid_before=$($LFS getstripe --fid $f_comp)
7493         dd if=/dev/zero of=$f_comp bs=1M count=4
7494
7495         # 1. migrate a comp layout file to a comp layout
7496         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7497         fid_after=$($LFS getstripe --fid $f_comp)
7498         [ "$fid_before" == "$fid_after" ] ||
7499                 error "comp-to-comp migrate: $fid_before != $fid_after"
7500
7501         # 2. migrate a comp layout file to a plain layout
7502         $LFS migrate -c2 $f_comp ||
7503                 error "cannot migrate $f_comp by lfs migrate"
7504         fid_after=$($LFS getstripe --fid $f_comp)
7505         [ "$fid_before" == "$fid_after" ] ||
7506                 error "comp-to-plain migrate: $fid_before != $fid_after"
7507
7508         # 3. migrate a plain layout file to a comp layout
7509         $LFS migrate $layout $f_comp ||
7510                 error "cannot migrate $f_comp by lfs migrate"
7511         fid_after=$($LFS getstripe --fid $f_comp)
7512         [ "$fid_before" == "$fid_after" ] ||
7513                 error "plain-to-comp migrate: $fid_before != $fid_after"
7514 }
7515 run_test 56xf "FID is not lost during migration of a composite layout file"
7516
7517 test_56y() {
7518         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7519                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7520
7521         local res=""
7522         local dir=$DIR/$tdir
7523         local f1=$dir/file1
7524         local f2=$dir/file2
7525
7526         test_mkdir -p $dir || error "creating dir $dir"
7527         touch $f1 || error "creating std file $f1"
7528         $MULTIOP $f2 H2c || error "creating released file $f2"
7529
7530         # a directory can be raid0, so ask only for files
7531         res=$($LFS find $dir -L raid0 -type f | wc -l)
7532         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7533
7534         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7535         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7536
7537         # only files can be released, so no need to force file search
7538         res=$($LFS find $dir -L released)
7539         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7540
7541         res=$($LFS find $dir -type f \! -L released)
7542         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7543 }
7544 run_test 56y "lfs find -L raid0|released"
7545
7546 test_56z() { # LU-4824
7547         # This checks to make sure 'lfs find' continues after errors
7548         # There are two classes of errors that should be caught:
7549         # - If multiple paths are provided, all should be searched even if one
7550         #   errors out
7551         # - If errors are encountered during the search, it should not terminate
7552         #   early
7553         local dir=$DIR/$tdir
7554         local i
7555
7556         test_mkdir $dir
7557         for i in d{0..9}; do
7558                 test_mkdir $dir/$i
7559                 touch $dir/$i/$tfile
7560         done
7561         $LFS find $DIR/non_existent_dir $dir &&
7562                 error "$LFS find did not return an error"
7563         # Make a directory unsearchable. This should NOT be the last entry in
7564         # directory order.  Arbitrarily pick the 6th entry
7565         chmod 700 $($LFS find $dir -type d | sed '6!d')
7566
7567         $RUNAS $LFS find $DIR/non_existent $dir
7568         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7569
7570         # The user should be able to see 10 directories and 9 files
7571         (( count == 19 )) ||
7572                 error "$LFS find found $count != 19 entries after error"
7573 }
7574 run_test 56z "lfs find should continue after an error"
7575
7576 test_56aa() { # LU-5937
7577         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7578
7579         local dir=$DIR/$tdir
7580
7581         mkdir $dir
7582         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7583
7584         createmany -o $dir/striped_dir/${tfile}- 1024
7585         local dirs=$($LFS find --size +8k $dir/)
7586
7587         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7588 }
7589 run_test 56aa "lfs find --size under striped dir"
7590
7591 test_56ab() { # LU-10705
7592         test_mkdir $DIR/$tdir
7593         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7594         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7595         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7596         # Flush writes to ensure valid blocks.  Need to be more thorough for
7597         # ZFS, since blocks are not allocated/returned to client immediately.
7598         sync_all_data
7599         wait_zfs_commit ost1 2
7600         cancel_lru_locks osc
7601         ls -ls $DIR/$tdir
7602
7603         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7604
7605         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7606
7607         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7608         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7609
7610         rm -f $DIR/$tdir/$tfile.[123]
7611 }
7612 run_test 56ab "lfs find --blocks"
7613
7614 test_56ba() {
7615         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7616                 skip "Need MDS version at least 2.10.50"
7617
7618         # Create composite files with one component
7619         local dir=$DIR/$tdir
7620
7621         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7622         # Create composite files with three components
7623         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7624         # Create non-composite files
7625         createmany -o $dir/${tfile}- 10
7626
7627         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7628
7629         [[ $nfiles == 10 ]] ||
7630                 error "lfs find -E 1M found $nfiles != 10 files"
7631
7632         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7633         [[ $nfiles == 25 ]] ||
7634                 error "lfs find ! -E 1M found $nfiles != 25 files"
7635
7636         # All files have a component that starts at 0
7637         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7638         [[ $nfiles == 35 ]] ||
7639                 error "lfs find --component-start 0 - $nfiles != 35 files"
7640
7641         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7642         [[ $nfiles == 15 ]] ||
7643                 error "lfs find --component-start 2M - $nfiles != 15 files"
7644
7645         # All files created here have a componenet that does not starts at 2M
7646         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7647         [[ $nfiles == 35 ]] ||
7648                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7649
7650         # Find files with a specified number of components
7651         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7652         [[ $nfiles == 15 ]] ||
7653                 error "lfs find --component-count 3 - $nfiles != 15 files"
7654
7655         # Remember non-composite files have a component count of zero
7656         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7657         [[ $nfiles == 10 ]] ||
7658                 error "lfs find --component-count 0 - $nfiles != 10 files"
7659
7660         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7661         [[ $nfiles == 20 ]] ||
7662                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7663
7664         # All files have a flag called "init"
7665         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7666         [[ $nfiles == 35 ]] ||
7667                 error "lfs find --component-flags init - $nfiles != 35 files"
7668
7669         # Multi-component files will have a component not initialized
7670         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7671         [[ $nfiles == 15 ]] ||
7672                 error "lfs find !--component-flags init - $nfiles != 15 files"
7673
7674         rm -rf $dir
7675
7676 }
7677 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7678
7679 test_56ca() {
7680         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7681                 skip "Need MDS version at least 2.10.57"
7682
7683         local td=$DIR/$tdir
7684         local tf=$td/$tfile
7685         local dir
7686         local nfiles
7687         local cmd
7688         local i
7689         local j
7690
7691         # create mirrored directories and mirrored files
7692         mkdir $td || error "mkdir $td failed"
7693         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7694         createmany -o $tf- 10 || error "create $tf- failed"
7695
7696         for i in $(seq 2); do
7697                 dir=$td/dir$i
7698                 mkdir $dir || error "mkdir $dir failed"
7699                 $LFS mirror create -N$((3 + i)) $dir ||
7700                         error "create mirrored dir $dir failed"
7701                 createmany -o $dir/$tfile- 10 ||
7702                         error "create $dir/$tfile- failed"
7703         done
7704
7705         # change the states of some mirrored files
7706         echo foo > $tf-6
7707         for i in $(seq 2); do
7708                 dir=$td/dir$i
7709                 for j in $(seq 4 9); do
7710                         echo foo > $dir/$tfile-$j
7711                 done
7712         done
7713
7714         # find mirrored files with specific mirror count
7715         cmd="$LFS find --mirror-count 3 --type f $td"
7716         nfiles=$($cmd | wc -l)
7717         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7718
7719         cmd="$LFS find ! --mirror-count 3 --type f $td"
7720         nfiles=$($cmd | wc -l)
7721         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7722
7723         cmd="$LFS find --mirror-count +2 --type f $td"
7724         nfiles=$($cmd | wc -l)
7725         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7726
7727         cmd="$LFS find --mirror-count -6 --type f $td"
7728         nfiles=$($cmd | wc -l)
7729         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7730
7731         # find mirrored files with specific file state
7732         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7733         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7734
7735         cmd="$LFS find --mirror-state=ro --type f $td"
7736         nfiles=$($cmd | wc -l)
7737         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7738
7739         cmd="$LFS find ! --mirror-state=ro --type f $td"
7740         nfiles=$($cmd | wc -l)
7741         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7742
7743         cmd="$LFS find --mirror-state=wp --type f $td"
7744         nfiles=$($cmd | wc -l)
7745         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7746
7747         cmd="$LFS find ! --mirror-state=sp --type f $td"
7748         nfiles=$($cmd | wc -l)
7749         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7750 }
7751 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7752
7753 test_56da() { # LU-14179
7754         local path=$DIR/$tdir
7755
7756         test_mkdir $path
7757         cd $path
7758
7759         local longdir=$(str_repeat 'a' 255)
7760
7761         for i in {1..15}; do
7762                 path=$path/$longdir
7763                 test_mkdir $longdir
7764                 cd $longdir
7765         done
7766
7767         local len=${#path}
7768         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7769
7770         test_mkdir $lastdir
7771         cd $lastdir
7772         # PATH_MAX-1
7773         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7774
7775         # NAME_MAX
7776         touch $(str_repeat 'f' 255)
7777
7778         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7779                 error "lfs find reported an error"
7780
7781         rm -rf $DIR/$tdir
7782 }
7783 run_test 56da "test lfs find with long paths"
7784
7785 test_57a() {
7786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7787         # note test will not do anything if MDS is not local
7788         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7789                 skip_env "ldiskfs only test"
7790         fi
7791         remote_mds_nodsh && skip "remote MDS with nodsh"
7792
7793         local MNTDEV="osd*.*MDT*.mntdev"
7794         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7795         [ -z "$DEV" ] && error "can't access $MNTDEV"
7796         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7797                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7798                         error "can't access $DEV"
7799                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7800                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7801                 rm $TMP/t57a.dump
7802         done
7803 }
7804 run_test 57a "verify MDS filesystem created with large inodes =="
7805
7806 test_57b() {
7807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7808         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7809                 skip_env "ldiskfs only test"
7810         fi
7811         remote_mds_nodsh && skip "remote MDS with nodsh"
7812
7813         local dir=$DIR/$tdir
7814         local filecount=100
7815         local file1=$dir/f1
7816         local fileN=$dir/f$filecount
7817
7818         rm -rf $dir || error "removing $dir"
7819         test_mkdir -c1 $dir
7820         local mdtidx=$($LFS getstripe -m $dir)
7821         local mdtname=MDT$(printf %04x $mdtidx)
7822         local facet=mds$((mdtidx + 1))
7823
7824         echo "mcreating $filecount files"
7825         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7826
7827         # verify that files do not have EAs yet
7828         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7829                 error "$file1 has an EA"
7830         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7831                 error "$fileN has an EA"
7832
7833         sync
7834         sleep 1
7835         df $dir  #make sure we get new statfs data
7836         local mdsfree=$(do_facet $facet \
7837                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7838         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7839         local file
7840
7841         echo "opening files to create objects/EAs"
7842         for file in $(seq -f $dir/f%g 1 $filecount); do
7843                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7844                         error "opening $file"
7845         done
7846
7847         # verify that files have EAs now
7848         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7849         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7850
7851         sleep 1  #make sure we get new statfs data
7852         df $dir
7853         local mdsfree2=$(do_facet $facet \
7854                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7855         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7856
7857         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7858                 if [ "$mdsfree" != "$mdsfree2" ]; then
7859                         error "MDC before $mdcfree != after $mdcfree2"
7860                 else
7861                         echo "MDC before $mdcfree != after $mdcfree2"
7862                         echo "unable to confirm if MDS has large inodes"
7863                 fi
7864         fi
7865         rm -rf $dir
7866 }
7867 run_test 57b "default LOV EAs are stored inside large inodes ==="
7868
7869 test_58() {
7870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7871         [ -z "$(which wiretest 2>/dev/null)" ] &&
7872                         skip_env "could not find wiretest"
7873
7874         wiretest
7875 }
7876 run_test 58 "verify cross-platform wire constants =============="
7877
7878 test_59() {
7879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7880
7881         echo "touch 130 files"
7882         createmany -o $DIR/f59- 130
7883         echo "rm 130 files"
7884         unlinkmany $DIR/f59- 130
7885         sync
7886         # wait for commitment of removal
7887         wait_delete_completed
7888 }
7889 run_test 59 "verify cancellation of llog records async ========="
7890
7891 TEST60_HEAD="test_60 run $RANDOM"
7892 test_60a() {
7893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7894         remote_mgs_nodsh && skip "remote MGS with nodsh"
7895         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7896                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7897                         skip_env "missing subtest run-llog.sh"
7898
7899         log "$TEST60_HEAD - from kernel mode"
7900         do_facet mgs "$LCTL dk > /dev/null"
7901         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7902         do_facet mgs $LCTL dk > $TMP/$tfile
7903
7904         # LU-6388: test llog_reader
7905         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7906         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7907         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7908                         skip_env "missing llog_reader"
7909         local fstype=$(facet_fstype mgs)
7910         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7911                 skip_env "Only for ldiskfs or zfs type mgs"
7912
7913         local mntpt=$(facet_mntpt mgs)
7914         local mgsdev=$(mgsdevname 1)
7915         local fid_list
7916         local fid
7917         local rec_list
7918         local rec
7919         local rec_type
7920         local obj_file
7921         local path
7922         local seq
7923         local oid
7924         local pass=true
7925
7926         #get fid and record list
7927         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7928                 tail -n 4))
7929         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7930                 tail -n 4))
7931         #remount mgs as ldiskfs or zfs type
7932         stop mgs || error "stop mgs failed"
7933         mount_fstype mgs || error "remount mgs failed"
7934         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7935                 fid=${fid_list[i]}
7936                 rec=${rec_list[i]}
7937                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7938                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7939                 oid=$((16#$oid))
7940
7941                 case $fstype in
7942                         ldiskfs )
7943                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7944                         zfs )
7945                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7946                 esac
7947                 echo "obj_file is $obj_file"
7948                 do_facet mgs $llog_reader $obj_file
7949
7950                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7951                         awk '{ print $3 }' | sed -e "s/^type=//g")
7952                 if [ $rec_type != $rec ]; then
7953                         echo "FAILED test_60a wrong record type $rec_type," \
7954                               "should be $rec"
7955                         pass=false
7956                         break
7957                 fi
7958
7959                 #check obj path if record type is LLOG_LOGID_MAGIC
7960                 if [ "$rec" == "1064553b" ]; then
7961                         path=$(do_facet mgs $llog_reader $obj_file |
7962                                 grep "path=" | awk '{ print $NF }' |
7963                                 sed -e "s/^path=//g")
7964                         if [ $obj_file != $mntpt/$path ]; then
7965                                 echo "FAILED test_60a wrong obj path" \
7966                                       "$montpt/$path, should be $obj_file"
7967                                 pass=false
7968                                 break
7969                         fi
7970                 fi
7971         done
7972         rm -f $TMP/$tfile
7973         #restart mgs before "error", otherwise it will block the next test
7974         stop mgs || error "stop mgs failed"
7975         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7976         $pass || error "test failed, see FAILED test_60a messages for specifics"
7977 }
7978 run_test 60a "llog_test run from kernel module and test llog_reader"
7979
7980 test_60b() { # bug 6411
7981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7982
7983         dmesg > $DIR/$tfile
7984         LLOG_COUNT=$(do_facet mgs dmesg |
7985                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7986                           /llog_[a-z]*.c:[0-9]/ {
7987                                 if (marker)
7988                                         from_marker++
7989                                 from_begin++
7990                           }
7991                           END {
7992                                 if (marker)
7993                                         print from_marker
7994                                 else
7995                                         print from_begin
7996                           }")
7997
7998         [[ $LLOG_COUNT -gt 120 ]] &&
7999                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8000 }
8001 run_test 60b "limit repeated messages from CERROR/CWARN"
8002
8003 test_60c() {
8004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8005
8006         echo "create 5000 files"
8007         createmany -o $DIR/f60c- 5000
8008 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8009         lctl set_param fail_loc=0x80000137
8010         unlinkmany $DIR/f60c- 5000
8011         lctl set_param fail_loc=0
8012 }
8013 run_test 60c "unlink file when mds full"
8014
8015 test_60d() {
8016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8017
8018         SAVEPRINTK=$(lctl get_param -n printk)
8019         # verify "lctl mark" is even working"
8020         MESSAGE="test message ID $RANDOM $$"
8021         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8022         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8023
8024         lctl set_param printk=0 || error "set lnet.printk failed"
8025         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8026         MESSAGE="new test message ID $RANDOM $$"
8027         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8028         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8029         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8030
8031         lctl set_param -n printk="$SAVEPRINTK"
8032 }
8033 run_test 60d "test printk console message masking"
8034
8035 test_60e() {
8036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8037         remote_mds_nodsh && skip "remote MDS with nodsh"
8038
8039         touch $DIR/$tfile
8040 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8041         do_facet mds1 lctl set_param fail_loc=0x15b
8042         rm $DIR/$tfile
8043 }
8044 run_test 60e "no space while new llog is being created"
8045
8046 test_60f() {
8047         local old_path=$($LCTL get_param -n debug_path)
8048
8049         stack_trap "$LCTL set_param debug_path=$old_path"
8050         stack_trap "rm -f $TMP/$tfile*"
8051         rm -f $TMP/$tfile* 2> /dev/null
8052         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8053         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8054         test_mkdir $DIR/$tdir
8055         # retry in case the open is cached and not released
8056         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8057                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8058                 sleep 0.1
8059         done
8060         ls $TMP/$tfile*
8061         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8062 }
8063 run_test 60f "change debug_path works"
8064
8065 test_60g() {
8066         local pid
8067         local i
8068
8069         test_mkdir -c $MDSCOUNT $DIR/$tdir
8070
8071         (
8072                 local index=0
8073                 while true; do
8074                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8075                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8076                                 2>/dev/null
8077                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8078                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8079                         index=$((index + 1))
8080                 done
8081         ) &
8082
8083         pid=$!
8084
8085         for i in {0..100}; do
8086                 # define OBD_FAIL_OSD_TXN_START    0x19a
8087                 local index=$((i % MDSCOUNT + 1))
8088
8089                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8090                         > /dev/null
8091                 sleep 0.01
8092         done
8093
8094         kill -9 $pid
8095
8096         for i in $(seq $MDSCOUNT); do
8097                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8098         done
8099
8100         mkdir $DIR/$tdir/new || error "mkdir failed"
8101         rmdir $DIR/$tdir/new || error "rmdir failed"
8102
8103         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8104                 -t namespace
8105         for i in $(seq $MDSCOUNT); do
8106                 wait_update_facet mds$i "$LCTL get_param -n \
8107                         mdd.$(facet_svc mds$i).lfsck_namespace |
8108                         awk '/^status/ { print \\\$2 }'" "completed"
8109         done
8110
8111         ls -R $DIR/$tdir || error "ls failed"
8112         rm -rf $DIR/$tdir || error "rmdir failed"
8113 }
8114 run_test 60g "transaction abort won't cause MDT hung"
8115
8116 test_60h() {
8117         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8118                 skip "Need MDS version at least 2.12.52"
8119         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8120
8121         local f
8122
8123         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8124         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8125         for fail_loc in 0x80000188 0x80000189; do
8126                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8127                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8128                         error "mkdir $dir-$fail_loc failed"
8129                 for i in {0..10}; do
8130                         # create may fail on missing stripe
8131                         echo $i > $DIR/$tdir-$fail_loc/$i
8132                 done
8133                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8134                         error "getdirstripe $tdir-$fail_loc failed"
8135                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8136                         error "migrate $tdir-$fail_loc failed"
8137                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8138                         error "getdirstripe $tdir-$fail_loc failed"
8139                 pushd $DIR/$tdir-$fail_loc
8140                 for f in *; do
8141                         echo $f | cmp $f - || error "$f data mismatch"
8142                 done
8143                 popd
8144                 rm -rf $DIR/$tdir-$fail_loc
8145         done
8146 }
8147 run_test 60h "striped directory with missing stripes can be accessed"
8148
8149 test_61a() {
8150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8151
8152         f="$DIR/f61"
8153         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8154         cancel_lru_locks osc
8155         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8156         sync
8157 }
8158 run_test 61a "mmap() writes don't make sync hang ================"
8159
8160 test_61b() {
8161         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8162 }
8163 run_test 61b "mmap() of unstriped file is successful"
8164
8165 # bug 2330 - insufficient obd_match error checking causes LBUG
8166 test_62() {
8167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8168
8169         f="$DIR/f62"
8170         echo foo > $f
8171         cancel_lru_locks osc
8172         lctl set_param fail_loc=0x405
8173         cat $f && error "cat succeeded, expect -EIO"
8174         lctl set_param fail_loc=0
8175 }
8176 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8177 # match every page all of the time.
8178 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8179
8180 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8181 # Though this test is irrelevant anymore, it helped to reveal some
8182 # other grant bugs (LU-4482), let's keep it.
8183 test_63a() {   # was test_63
8184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8185
8186         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8187
8188         for i in `seq 10` ; do
8189                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8190                 sleep 5
8191                 kill $!
8192                 sleep 1
8193         done
8194
8195         rm -f $DIR/f63 || true
8196 }
8197 run_test 63a "Verify oig_wait interruption does not crash ======="
8198
8199 # bug 2248 - async write errors didn't return to application on sync
8200 # bug 3677 - async write errors left page locked
8201 test_63b() {
8202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8203
8204         debugsave
8205         lctl set_param debug=-1
8206
8207         # ensure we have a grant to do async writes
8208         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8209         rm $DIR/$tfile
8210
8211         sync    # sync lest earlier test intercept the fail_loc
8212
8213         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8214         lctl set_param fail_loc=0x80000406
8215         $MULTIOP $DIR/$tfile Owy && \
8216                 error "sync didn't return ENOMEM"
8217         sync; sleep 2; sync     # do a real sync this time to flush page
8218         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8219                 error "locked page left in cache after async error" || true
8220         debugrestore
8221 }
8222 run_test 63b "async write errors should be returned to fsync ==="
8223
8224 test_64a () {
8225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8226
8227         lfs df $DIR
8228         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8229 }
8230 run_test 64a "verify filter grant calculations (in kernel) ====="
8231
8232 test_64b () {
8233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8234
8235         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8236 }
8237 run_test 64b "check out-of-space detection on client"
8238
8239 test_64c() {
8240         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8241 }
8242 run_test 64c "verify grant shrink"
8243
8244 import_param() {
8245         local tgt=$1
8246         local param=$2
8247
8248         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8249 }
8250
8251 # this does exactly what osc_request.c:osc_announce_cached() does in
8252 # order to calculate max amount of grants to ask from server
8253 want_grant() {
8254         local tgt=$1
8255
8256         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8257         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8258
8259         ((rpc_in_flight++));
8260         nrpages=$((nrpages * rpc_in_flight))
8261
8262         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8263
8264         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8265
8266         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8267         local undirty=$((nrpages * PAGE_SIZE))
8268
8269         local max_extent_pages
8270         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8271         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8272         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8273         local grant_extent_tax
8274         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8275
8276         undirty=$((undirty + nrextents * grant_extent_tax))
8277
8278         echo $undirty
8279 }
8280
8281 # this is size of unit for grant allocation. It should be equal to
8282 # what tgt_grant.c:tgt_grant_chunk() calculates
8283 grant_chunk() {
8284         local tgt=$1
8285         local max_brw_size
8286         local grant_extent_tax
8287
8288         max_brw_size=$(import_param $tgt max_brw_size)
8289
8290         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8291
8292         echo $(((max_brw_size + grant_extent_tax) * 2))
8293 }
8294
8295 test_64d() {
8296         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8297                 skip "OST < 2.10.55 doesn't limit grants enough"
8298
8299         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8300
8301         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8302                 skip "no grant_param connect flag"
8303
8304         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8305
8306         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8307         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8308
8309
8310         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8311         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8312
8313         $LFS setstripe $DIR/$tfile -i 0 -c 1
8314         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8315         ddpid=$!
8316
8317         while kill -0 $ddpid; do
8318                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8319
8320                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8321                         kill $ddpid
8322                         error "cur_grant $cur_grant > $max_cur_granted"
8323                 fi
8324
8325                 sleep 1
8326         done
8327 }
8328 run_test 64d "check grant limit exceed"
8329
8330 check_grants() {
8331         local tgt=$1
8332         local expected=$2
8333         local msg=$3
8334         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8335
8336         ((cur_grants == expected)) ||
8337                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8338 }
8339
8340 round_up_p2() {
8341         echo $((($1 + $2 - 1) & ~($2 - 1)))
8342 }
8343
8344 test_64e() {
8345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8346         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8347                 skip "Need OSS version at least 2.11.56"
8348
8349         # Remount client to reset grant
8350         remount_client $MOUNT || error "failed to remount client"
8351         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8352
8353         local init_grants=$(import_param $osc_tgt initial_grant)
8354
8355         check_grants $osc_tgt $init_grants "init grants"
8356
8357         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8358         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8359         local gbs=$(import_param $osc_tgt grant_block_size)
8360
8361         # write random number of bytes from max_brw_size / 4 to max_brw_size
8362         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8363         # align for direct io
8364         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8365         # round to grant consumption unit
8366         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8367
8368         local grants=$((wb_round_up + extent_tax))
8369
8370         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8371
8372         # define OBD_FAIL_TGT_NO_GRANT 0x725
8373         # make the server not grant more back
8374         do_facet ost1 $LCTL set_param fail_loc=0x725
8375         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8376
8377         do_facet ost1 $LCTL set_param fail_loc=0
8378
8379         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8380
8381         rm -f $DIR/$tfile || error "rm failed"
8382
8383         # Remount client to reset grant
8384         remount_client $MOUNT || error "failed to remount client"
8385         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8386
8387         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8388
8389         # define OBD_FAIL_TGT_NO_GRANT 0x725
8390         # make the server not grant more back
8391         do_facet ost1 $LCTL set_param fail_loc=0x725
8392         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8393         do_facet ost1 $LCTL set_param fail_loc=0
8394
8395         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8396 }
8397 run_test 64e "check grant consumption (no grant allocation)"
8398
8399 test_64f() {
8400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8401
8402         # Remount client to reset grant
8403         remount_client $MOUNT || error "failed to remount client"
8404         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8405
8406         local init_grants=$(import_param $osc_tgt initial_grant)
8407         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8408         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8409         local gbs=$(import_param $osc_tgt grant_block_size)
8410         local chunk=$(grant_chunk $osc_tgt)
8411
8412         # write random number of bytes from max_brw_size / 4 to max_brw_size
8413         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8414         # align for direct io
8415         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8416         # round to grant consumption unit
8417         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8418
8419         local grants=$((wb_round_up + extent_tax))
8420
8421         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8422         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8423                 error "error writing to $DIR/$tfile"
8424
8425         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8426                 "direct io with grant allocation"
8427
8428         rm -f $DIR/$tfile || error "rm failed"
8429
8430         # Remount client to reset grant
8431         remount_client $MOUNT || error "failed to remount client"
8432         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8433
8434         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8435
8436         local cmd="oO_WRONLY:w${write_bytes}_yc"
8437
8438         $MULTIOP $DIR/$tfile $cmd &
8439         MULTIPID=$!
8440         sleep 1
8441
8442         check_grants $osc_tgt $((init_grants - grants)) \
8443                 "buffered io, not write rpc"
8444
8445         kill -USR1 $MULTIPID
8446         wait
8447
8448         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8449                 "buffered io, one RPC"
8450 }
8451 run_test 64f "check grant consumption (with grant allocation)"
8452
8453 # bug 1414 - set/get directories' stripe info
8454 test_65a() {
8455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8456
8457         test_mkdir $DIR/$tdir
8458         touch $DIR/$tdir/f1
8459         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8460 }
8461 run_test 65a "directory with no stripe info"
8462
8463 test_65b() {
8464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8465
8466         test_mkdir $DIR/$tdir
8467         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8468
8469         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8470                                                 error "setstripe"
8471         touch $DIR/$tdir/f2
8472         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8473 }
8474 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8475
8476 test_65c() {
8477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8478         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8479
8480         test_mkdir $DIR/$tdir
8481         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8482
8483         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8484                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8485         touch $DIR/$tdir/f3
8486         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8487 }
8488 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8489
8490 test_65d() {
8491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8492
8493         test_mkdir $DIR/$tdir
8494         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8495         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8496
8497         if [[ $STRIPECOUNT -le 0 ]]; then
8498                 sc=1
8499         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8500                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8501                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8502         else
8503                 sc=$(($STRIPECOUNT - 1))
8504         fi
8505         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8506         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8507         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8508                 error "lverify failed"
8509 }
8510 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8511
8512 test_65e() {
8513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8514
8515         test_mkdir $DIR/$tdir
8516
8517         $LFS setstripe $DIR/$tdir || error "setstripe"
8518         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8519                                         error "no stripe info failed"
8520         touch $DIR/$tdir/f6
8521         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8522 }
8523 run_test 65e "directory setstripe defaults"
8524
8525 test_65f() {
8526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8527
8528         test_mkdir $DIR/${tdir}f
8529         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8530                 error "setstripe succeeded" || true
8531 }
8532 run_test 65f "dir setstripe permission (should return error) ==="
8533
8534 test_65g() {
8535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8536
8537         test_mkdir $DIR/$tdir
8538         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8539
8540         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8541                 error "setstripe -S failed"
8542         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8543         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8544                 error "delete default stripe failed"
8545 }
8546 run_test 65g "directory setstripe -d"
8547
8548 test_65h() {
8549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8550
8551         test_mkdir $DIR/$tdir
8552         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8553
8554         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8555                 error "setstripe -S failed"
8556         test_mkdir $DIR/$tdir/dd1
8557         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8558                 error "stripe info inherit failed"
8559 }
8560 run_test 65h "directory stripe info inherit ===================="
8561
8562 test_65i() {
8563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8564
8565         save_layout_restore_at_exit $MOUNT
8566
8567         # bug6367: set non-default striping on root directory
8568         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8569
8570         # bug12836: getstripe on -1 default directory striping
8571         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8572
8573         # bug12836: getstripe -v on -1 default directory striping
8574         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8575
8576         # bug12836: new find on -1 default directory striping
8577         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8578 }
8579 run_test 65i "various tests to set root directory striping"
8580
8581 test_65j() { # bug6367
8582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8583
8584         sync; sleep 1
8585
8586         # if we aren't already remounting for each test, do so for this test
8587         if [ "$I_MOUNTED" = "yes" ]; then
8588                 cleanup || error "failed to unmount"
8589                 setup
8590         fi
8591
8592         save_layout_restore_at_exit $MOUNT
8593
8594         $LFS setstripe -d $MOUNT || error "setstripe failed"
8595 }
8596 run_test 65j "set default striping on root directory (bug 6367)="
8597
8598 cleanup_65k() {
8599         rm -rf $DIR/$tdir
8600         wait_delete_completed
8601         do_facet $SINGLEMDS "lctl set_param -n \
8602                 osp.$ost*MDT0000.max_create_count=$max_count"
8603         do_facet $SINGLEMDS "lctl set_param -n \
8604                 osp.$ost*MDT0000.create_count=$count"
8605         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8606         echo $INACTIVE_OSC "is Activate"
8607
8608         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8609 }
8610
8611 test_65k() { # bug11679
8612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8613         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8614         remote_mds_nodsh && skip "remote MDS with nodsh"
8615
8616         local disable_precreate=true
8617         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8618                 disable_precreate=false
8619
8620         echo "Check OST status: "
8621         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8622                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8623
8624         for OSC in $MDS_OSCS; do
8625                 echo $OSC "is active"
8626                 do_facet $SINGLEMDS lctl --device %$OSC activate
8627         done
8628
8629         for INACTIVE_OSC in $MDS_OSCS; do
8630                 local ost=$(osc_to_ost $INACTIVE_OSC)
8631                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8632                                lov.*md*.target_obd |
8633                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8634
8635                 mkdir -p $DIR/$tdir
8636                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8637                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8638
8639                 echo "Deactivate: " $INACTIVE_OSC
8640                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8641
8642                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8643                               osp.$ost*MDT0000.create_count")
8644                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8645                                   osp.$ost*MDT0000.max_create_count")
8646                 $disable_precreate &&
8647                         do_facet $SINGLEMDS "lctl set_param -n \
8648                                 osp.$ost*MDT0000.max_create_count=0"
8649
8650                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8651                         [ -f $DIR/$tdir/$idx ] && continue
8652                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8653                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8654                                 { cleanup_65k;
8655                                   error "setstripe $idx should succeed"; }
8656                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8657                 done
8658                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8659                 rmdir $DIR/$tdir
8660
8661                 do_facet $SINGLEMDS "lctl set_param -n \
8662                         osp.$ost*MDT0000.max_create_count=$max_count"
8663                 do_facet $SINGLEMDS "lctl set_param -n \
8664                         osp.$ost*MDT0000.create_count=$count"
8665                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8666                 echo $INACTIVE_OSC "is Activate"
8667
8668                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8669         done
8670 }
8671 run_test 65k "validate manual striping works properly with deactivated OSCs"
8672
8673 test_65l() { # bug 12836
8674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8675
8676         test_mkdir -p $DIR/$tdir/test_dir
8677         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8678         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8679 }
8680 run_test 65l "lfs find on -1 stripe dir ========================"
8681
8682 test_65m() {
8683         local layout=$(save_layout $MOUNT)
8684         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8685                 restore_layout $MOUNT $layout
8686                 error "setstripe should fail by non-root users"
8687         }
8688         true
8689 }
8690 run_test 65m "normal user can't set filesystem default stripe"
8691
8692 test_65n() {
8693         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8694         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8695                 skip "Need MDS version at least 2.12.50"
8696         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8697
8698         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8699         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8700         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8701
8702         local root_layout=$(save_layout $MOUNT)
8703         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8704
8705         # new subdirectory under root directory should not inherit
8706         # the default layout from root
8707         local dir1=$MOUNT/$tdir-1
8708         mkdir $dir1 || error "mkdir $dir1 failed"
8709         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8710                 error "$dir1 shouldn't have LOV EA"
8711
8712         # delete the default layout on root directory
8713         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8714
8715         local dir2=$MOUNT/$tdir-2
8716         mkdir $dir2 || error "mkdir $dir2 failed"
8717         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8718                 error "$dir2 shouldn't have LOV EA"
8719
8720         # set a new striping pattern on root directory
8721         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8722         local new_def_stripe_size=$((def_stripe_size * 2))
8723         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8724                 error "set stripe size on $MOUNT failed"
8725
8726         # new file created in $dir2 should inherit the new stripe size from
8727         # the filesystem default
8728         local file2=$dir2/$tfile-2
8729         touch $file2 || error "touch $file2 failed"
8730
8731         local file2_stripe_size=$($LFS getstripe -S $file2)
8732         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8733         {
8734                 echo "file2_stripe_size: '$file2_stripe_size'"
8735                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8736                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8737         }
8738
8739         local dir3=$MOUNT/$tdir-3
8740         mkdir $dir3 || error "mkdir $dir3 failed"
8741         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8742         # the root layout, which is the actual default layout that will be used
8743         # when new files are created in $dir3.
8744         local dir3_layout=$(get_layout_param $dir3)
8745         local root_dir_layout=$(get_layout_param $MOUNT)
8746         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8747         {
8748                 echo "dir3_layout: '$dir3_layout'"
8749                 echo "root_dir_layout: '$root_dir_layout'"
8750                 error "$dir3 should show the default layout from $MOUNT"
8751         }
8752
8753         # set OST pool on root directory
8754         local pool=$TESTNAME
8755         pool_add $pool || error "add $pool failed"
8756         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8757                 error "add targets to $pool failed"
8758
8759         $LFS setstripe -p $pool $MOUNT ||
8760                 error "set OST pool on $MOUNT failed"
8761
8762         # new file created in $dir3 should inherit the pool from
8763         # the filesystem default
8764         local file3=$dir3/$tfile-3
8765         touch $file3 || error "touch $file3 failed"
8766
8767         local file3_pool=$($LFS getstripe -p $file3)
8768         [[ "$file3_pool" = "$pool" ]] ||
8769                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8770
8771         local dir4=$MOUNT/$tdir-4
8772         mkdir $dir4 || error "mkdir $dir4 failed"
8773         local dir4_layout=$(get_layout_param $dir4)
8774         root_dir_layout=$(get_layout_param $MOUNT)
8775         echo "$LFS getstripe -d $dir4"
8776         $LFS getstripe -d $dir4
8777         echo "$LFS getstripe -d $MOUNT"
8778         $LFS getstripe -d $MOUNT
8779         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8780         {
8781                 echo "dir4_layout: '$dir4_layout'"
8782                 echo "root_dir_layout: '$root_dir_layout'"
8783                 error "$dir4 should show the default layout from $MOUNT"
8784         }
8785
8786         # new file created in $dir4 should inherit the pool from
8787         # the filesystem default
8788         local file4=$dir4/$tfile-4
8789         touch $file4 || error "touch $file4 failed"
8790
8791         local file4_pool=$($LFS getstripe -p $file4)
8792         [[ "$file4_pool" = "$pool" ]] ||
8793                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8794
8795         # new subdirectory under non-root directory should inherit
8796         # the default layout from its parent directory
8797         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8798                 error "set directory layout on $dir4 failed"
8799
8800         local dir5=$dir4/$tdir-5
8801         mkdir $dir5 || error "mkdir $dir5 failed"
8802
8803         dir4_layout=$(get_layout_param $dir4)
8804         local dir5_layout=$(get_layout_param $dir5)
8805         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8806         {
8807                 echo "dir4_layout: '$dir4_layout'"
8808                 echo "dir5_layout: '$dir5_layout'"
8809                 error "$dir5 should inherit the default layout from $dir4"
8810         }
8811
8812         # though subdir under ROOT doesn't inherit default layout, but
8813         # its sub dir/file should be created with default layout.
8814         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8815         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8816                 skip "Need MDS version at least 2.12.59"
8817
8818         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8819         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8820         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8821
8822         if [ $default_lmv_hash == "none" ]; then
8823                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8824         else
8825                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8826                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8827         fi
8828
8829         $LFS setdirstripe -D -c 2 $MOUNT ||
8830                 error "setdirstripe -D -c 2 failed"
8831         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8832         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8833         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8834 }
8835 run_test 65n "don't inherit default layout from root for new subdirectories"
8836
8837 # bug 2543 - update blocks count on client
8838 test_66() {
8839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8840
8841         COUNT=${COUNT:-8}
8842         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8843         sync; sync_all_data; sync; sync_all_data
8844         cancel_lru_locks osc
8845         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8846         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8847 }
8848 run_test 66 "update inode blocks count on client ==============="
8849
8850 meminfo() {
8851         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8852 }
8853
8854 swap_used() {
8855         swapon -s | awk '($1 == "'$1'") { print $4 }'
8856 }
8857
8858 # bug5265, obdfilter oa2dentry return -ENOENT
8859 # #define OBD_FAIL_SRV_ENOENT 0x217
8860 test_69() {
8861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8862         remote_ost_nodsh && skip "remote OST with nodsh"
8863
8864         f="$DIR/$tfile"
8865         $LFS setstripe -c 1 -i 0 $f
8866
8867         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8868
8869         do_facet ost1 lctl set_param fail_loc=0x217
8870         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8871         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8872
8873         do_facet ost1 lctl set_param fail_loc=0
8874         $DIRECTIO write $f 0 2 || error "write error"
8875
8876         cancel_lru_locks osc
8877         $DIRECTIO read $f 0 1 || error "read error"
8878
8879         do_facet ost1 lctl set_param fail_loc=0x217
8880         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8881
8882         do_facet ost1 lctl set_param fail_loc=0
8883         rm -f $f
8884 }
8885 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8886
8887 test_71() {
8888         test_mkdir $DIR/$tdir
8889         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8890         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8891 }
8892 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8893
8894 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8896         [ "$RUNAS_ID" = "$UID" ] &&
8897                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8898         # Check that testing environment is properly set up. Skip if not
8899         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8900                 skip_env "User $RUNAS_ID does not exist - skipping"
8901
8902         touch $DIR/$tfile
8903         chmod 777 $DIR/$tfile
8904         chmod ug+s $DIR/$tfile
8905         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8906                 error "$RUNAS dd $DIR/$tfile failed"
8907         # See if we are still setuid/sgid
8908         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8909                 error "S/gid is not dropped on write"
8910         # Now test that MDS is updated too
8911         cancel_lru_locks mdc
8912         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8913                 error "S/gid is not dropped on MDS"
8914         rm -f $DIR/$tfile
8915 }
8916 run_test 72a "Test that remove suid works properly (bug5695) ===="
8917
8918 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8919         local perm
8920
8921         [ "$RUNAS_ID" = "$UID" ] &&
8922                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8923         [ "$RUNAS_ID" -eq 0 ] &&
8924                 skip_env "RUNAS_ID = 0 -- skipping"
8925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8926         # Check that testing environment is properly set up. Skip if not
8927         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8928                 skip_env "User $RUNAS_ID does not exist - skipping"
8929
8930         touch $DIR/${tfile}-f{g,u}
8931         test_mkdir $DIR/${tfile}-dg
8932         test_mkdir $DIR/${tfile}-du
8933         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8934         chmod g+s $DIR/${tfile}-{f,d}g
8935         chmod u+s $DIR/${tfile}-{f,d}u
8936         for perm in 777 2777 4777; do
8937                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8938                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8939                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8940                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8941         done
8942         true
8943 }
8944 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8945
8946 # bug 3462 - multiple simultaneous MDC requests
8947 test_73() {
8948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8949
8950         test_mkdir $DIR/d73-1
8951         test_mkdir $DIR/d73-2
8952         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8953         pid1=$!
8954
8955         lctl set_param fail_loc=0x80000129
8956         $MULTIOP $DIR/d73-1/f73-2 Oc &
8957         sleep 1
8958         lctl set_param fail_loc=0
8959
8960         $MULTIOP $DIR/d73-2/f73-3 Oc &
8961         pid3=$!
8962
8963         kill -USR1 $pid1
8964         wait $pid1 || return 1
8965
8966         sleep 25
8967
8968         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8969         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8970         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8971
8972         rm -rf $DIR/d73-*
8973 }
8974 run_test 73 "multiple MDC requests (should not deadlock)"
8975
8976 test_74a() { # bug 6149, 6184
8977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8978
8979         touch $DIR/f74a
8980         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8981         #
8982         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8983         # will spin in a tight reconnection loop
8984         $LCTL set_param fail_loc=0x8000030e
8985         # get any lock that won't be difficult - lookup works.
8986         ls $DIR/f74a
8987         $LCTL set_param fail_loc=0
8988         rm -f $DIR/f74a
8989         true
8990 }
8991 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8992
8993 test_74b() { # bug 13310
8994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8995
8996         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8997         #
8998         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8999         # will spin in a tight reconnection loop
9000         $LCTL set_param fail_loc=0x8000030e
9001         # get a "difficult" lock
9002         touch $DIR/f74b
9003         $LCTL set_param fail_loc=0
9004         rm -f $DIR/f74b
9005         true
9006 }
9007 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9008
9009 test_74c() {
9010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9011
9012         #define OBD_FAIL_LDLM_NEW_LOCK
9013         $LCTL set_param fail_loc=0x319
9014         touch $DIR/$tfile && error "touch successful"
9015         $LCTL set_param fail_loc=0
9016         true
9017 }
9018 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9019
9020 slab_lic=/sys/kernel/slab/lustre_inode_cache
9021 num_objects() {
9022         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9023         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9024                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9025 }
9026
9027 test_76a() { # Now for b=20433, added originally in b=1443
9028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9029
9030         cancel_lru_locks osc
9031         # there may be some slab objects cached per core
9032         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9033         local before=$(num_objects)
9034         local count=$((512 * cpus))
9035         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9036         local margin=$((count / 10))
9037         if [[ -f $slab_lic/aliases ]]; then
9038                 local aliases=$(cat $slab_lic/aliases)
9039                 (( aliases > 0 )) && margin=$((margin * aliases))
9040         fi
9041
9042         echo "before slab objects: $before"
9043         for i in $(seq $count); do
9044                 touch $DIR/$tfile
9045                 rm -f $DIR/$tfile
9046         done
9047         cancel_lru_locks osc
9048         local after=$(num_objects)
9049         echo "created: $count, after slab objects: $after"
9050         # shared slab counts are not very accurate, allow significant margin
9051         # the main goal is that the cache growth is not permanently > $count
9052         while (( after > before + margin )); do
9053                 sleep 1
9054                 after=$(num_objects)
9055                 wait=$((wait + 1))
9056                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9057                 if (( wait > 60 )); then
9058                         error "inode slab grew from $before+$margin to $after"
9059                 fi
9060         done
9061 }
9062 run_test 76a "confirm clients recycle inodes properly ===="
9063
9064 test_76b() {
9065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9066         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9067
9068         local count=512
9069         local before=$(num_objects)
9070
9071         for i in $(seq $count); do
9072                 mkdir $DIR/$tdir
9073                 rmdir $DIR/$tdir
9074         done
9075
9076         local after=$(num_objects)
9077         local wait=0
9078
9079         while (( after > before )); do
9080                 sleep 1
9081                 after=$(num_objects)
9082                 wait=$((wait + 1))
9083                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9084                 if (( wait > 60 )); then
9085                         error "inode slab grew from $before to $after"
9086                 fi
9087         done
9088
9089         echo "slab objects before: $before, after: $after"
9090 }
9091 run_test 76b "confirm clients recycle directory inodes properly ===="
9092
9093 export ORIG_CSUM=""
9094 set_checksums()
9095 {
9096         # Note: in sptlrpc modes which enable its own bulk checksum, the
9097         # original crc32_le bulk checksum will be automatically disabled,
9098         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9099         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9100         # In this case set_checksums() will not be no-op, because sptlrpc
9101         # bulk checksum will be enabled all through the test.
9102
9103         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9104         lctl set_param -n osc.*.checksums $1
9105         return 0
9106 }
9107
9108 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9109                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9110 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9111                              tr -d [] | head -n1)}
9112 set_checksum_type()
9113 {
9114         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9115         rc=$?
9116         log "set checksum type to $1, rc = $rc"
9117         return $rc
9118 }
9119
9120 get_osc_checksum_type()
9121 {
9122         # arugment 1: OST name, like OST0000
9123         ost=$1
9124         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9125                         sed 's/.*\[\(.*\)\].*/\1/g')
9126         rc=$?
9127         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9128         echo $checksum_type
9129 }
9130
9131 F77_TMP=$TMP/f77-temp
9132 F77SZ=8
9133 setup_f77() {
9134         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9135                 error "error writing to $F77_TMP"
9136 }
9137
9138 test_77a() { # bug 10889
9139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9140         $GSS && skip_env "could not run with gss"
9141
9142         [ ! -f $F77_TMP ] && setup_f77
9143         set_checksums 1
9144         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9145         set_checksums 0
9146         rm -f $DIR/$tfile
9147 }
9148 run_test 77a "normal checksum read/write operation"
9149
9150 test_77b() { # bug 10889
9151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9152         $GSS && skip_env "could not run with gss"
9153
9154         [ ! -f $F77_TMP ] && setup_f77
9155         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9156         $LCTL set_param fail_loc=0x80000409
9157         set_checksums 1
9158
9159         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9160                 error "dd error: $?"
9161         $LCTL set_param fail_loc=0
9162
9163         for algo in $CKSUM_TYPES; do
9164                 cancel_lru_locks osc
9165                 set_checksum_type $algo
9166                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9167                 $LCTL set_param fail_loc=0x80000408
9168                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9169                 $LCTL set_param fail_loc=0
9170         done
9171         set_checksums 0
9172         set_checksum_type $ORIG_CSUM_TYPE
9173         rm -f $DIR/$tfile
9174 }
9175 run_test 77b "checksum error on client write, read"
9176
9177 cleanup_77c() {
9178         trap 0
9179         set_checksums 0
9180         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9181         $check_ost &&
9182                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9183         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9184         $check_ost && [ -n "$ost_file_prefix" ] &&
9185                 do_facet ost1 rm -f ${ost_file_prefix}\*
9186 }
9187
9188 test_77c() {
9189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9190         $GSS && skip_env "could not run with gss"
9191         remote_ost_nodsh && skip "remote OST with nodsh"
9192
9193         local bad1
9194         local osc_file_prefix
9195         local osc_file
9196         local check_ost=false
9197         local ost_file_prefix
9198         local ost_file
9199         local orig_cksum
9200         local dump_cksum
9201         local fid
9202
9203         # ensure corruption will occur on first OSS/OST
9204         $LFS setstripe -i 0 $DIR/$tfile
9205
9206         [ ! -f $F77_TMP ] && setup_f77
9207         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9208                 error "dd write error: $?"
9209         fid=$($LFS path2fid $DIR/$tfile)
9210
9211         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9212         then
9213                 check_ost=true
9214                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9215                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9216         else
9217                 echo "OSS do not support bulk pages dump upon error"
9218         fi
9219
9220         osc_file_prefix=$($LCTL get_param -n debug_path)
9221         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9222
9223         trap cleanup_77c EXIT
9224
9225         set_checksums 1
9226         # enable bulk pages dump upon error on Client
9227         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9228         # enable bulk pages dump upon error on OSS
9229         $check_ost &&
9230                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9231
9232         # flush Client cache to allow next read to reach OSS
9233         cancel_lru_locks osc
9234
9235         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9236         $LCTL set_param fail_loc=0x80000408
9237         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9238         $LCTL set_param fail_loc=0
9239
9240         rm -f $DIR/$tfile
9241
9242         # check cksum dump on Client
9243         osc_file=$(ls ${osc_file_prefix}*)
9244         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9245         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9246         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9247         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9248         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9249                      cksum)
9250         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9251         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9252                 error "dump content does not match on Client"
9253
9254         $check_ost || skip "No need to check cksum dump on OSS"
9255
9256         # check cksum dump on OSS
9257         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9258         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9259         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9260         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9261         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9262                 error "dump content does not match on OSS"
9263
9264         cleanup_77c
9265 }
9266 run_test 77c "checksum error on client read with debug"
9267
9268 test_77d() { # bug 10889
9269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9270         $GSS && skip_env "could not run with gss"
9271
9272         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9273         $LCTL set_param fail_loc=0x80000409
9274         set_checksums 1
9275         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9276                 error "direct write: rc=$?"
9277         $LCTL set_param fail_loc=0
9278         set_checksums 0
9279
9280         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9281         $LCTL set_param fail_loc=0x80000408
9282         set_checksums 1
9283         cancel_lru_locks osc
9284         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9285                 error "direct read: rc=$?"
9286         $LCTL set_param fail_loc=0
9287         set_checksums 0
9288 }
9289 run_test 77d "checksum error on OST direct write, read"
9290
9291 test_77f() { # bug 10889
9292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9293         $GSS && skip_env "could not run with gss"
9294
9295         set_checksums 1
9296         for algo in $CKSUM_TYPES; do
9297                 cancel_lru_locks osc
9298                 set_checksum_type $algo
9299                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9300                 $LCTL set_param fail_loc=0x409
9301                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9302                         error "direct write succeeded"
9303                 $LCTL set_param fail_loc=0
9304         done
9305         set_checksum_type $ORIG_CSUM_TYPE
9306         set_checksums 0
9307 }
9308 run_test 77f "repeat checksum error on write (expect error)"
9309
9310 test_77g() { # bug 10889
9311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9312         $GSS && skip_env "could not run with gss"
9313         remote_ost_nodsh && skip "remote OST with nodsh"
9314
9315         [ ! -f $F77_TMP ] && setup_f77
9316
9317         local file=$DIR/$tfile
9318         stack_trap "rm -f $file" EXIT
9319
9320         $LFS setstripe -c 1 -i 0 $file
9321         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9322         do_facet ost1 lctl set_param fail_loc=0x8000021a
9323         set_checksums 1
9324         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9325                 error "write error: rc=$?"
9326         do_facet ost1 lctl set_param fail_loc=0
9327         set_checksums 0
9328
9329         cancel_lru_locks osc
9330         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9331         do_facet ost1 lctl set_param fail_loc=0x8000021b
9332         set_checksums 1
9333         cmp $F77_TMP $file || error "file compare failed"
9334         do_facet ost1 lctl set_param fail_loc=0
9335         set_checksums 0
9336 }
9337 run_test 77g "checksum error on OST write, read"
9338
9339 test_77k() { # LU-10906
9340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9341         $GSS && skip_env "could not run with gss"
9342
9343         local cksum_param="osc.$FSNAME*.checksums"
9344         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9345         local checksum
9346         local i
9347
9348         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9349         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9350         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9351
9352         for i in 0 1; do
9353                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9354                         error "failed to set checksum=$i on MGS"
9355                 wait_update $HOSTNAME "$get_checksum" $i
9356                 #remount
9357                 echo "remount client, checksum should be $i"
9358                 remount_client $MOUNT || error "failed to remount client"
9359                 checksum=$(eval $get_checksum)
9360                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9361         done
9362         # remove persistent param to avoid races with checksum mountopt below
9363         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9364                 error "failed to delete checksum on MGS"
9365
9366         for opt in "checksum" "nochecksum"; do
9367                 #remount with mount option
9368                 echo "remount client with option $opt, checksum should be $i"
9369                 umount_client $MOUNT || error "failed to umount client"
9370                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9371                         error "failed to mount client with option '$opt'"
9372                 checksum=$(eval $get_checksum)
9373                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9374                 i=$((i - 1))
9375         done
9376
9377         remount_client $MOUNT || error "failed to remount client"
9378 }
9379 run_test 77k "enable/disable checksum correctly"
9380
9381 test_77l() {
9382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9383         $GSS && skip_env "could not run with gss"
9384
9385         set_checksums 1
9386         stack_trap "set_checksums $ORIG_CSUM" EXIT
9387         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9388
9389         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9390
9391         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9392         for algo in $CKSUM_TYPES; do
9393                 set_checksum_type $algo || error "fail to set checksum type $algo"
9394                 osc_algo=$(get_osc_checksum_type OST0000)
9395                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9396
9397                 # no locks, no reqs to let the connection idle
9398                 cancel_lru_locks osc
9399                 lru_resize_disable osc
9400                 wait_osc_import_state client ost1 IDLE
9401
9402                 # ensure ost1 is connected
9403                 stat $DIR/$tfile >/dev/null || error "can't stat"
9404                 wait_osc_import_state client ost1 FULL
9405
9406                 osc_algo=$(get_osc_checksum_type OST0000)
9407                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9408         done
9409         return 0
9410 }
9411 run_test 77l "preferred checksum type is remembered after reconnected"
9412
9413 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9414 rm -f $F77_TMP
9415 unset F77_TMP
9416
9417 cleanup_test_78() {
9418         trap 0
9419         rm -f $DIR/$tfile
9420 }
9421
9422 test_78() { # bug 10901
9423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9424         remote_ost || skip_env "local OST"
9425
9426         NSEQ=5
9427         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9428         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9429         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9430         echo "MemTotal: $MEMTOTAL"
9431
9432         # reserve 256MB of memory for the kernel and other running processes,
9433         # and then take 1/2 of the remaining memory for the read/write buffers.
9434         if [ $MEMTOTAL -gt 512 ] ;then
9435                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9436         else
9437                 # for those poor memory-starved high-end clusters...
9438                 MEMTOTAL=$((MEMTOTAL / 2))
9439         fi
9440         echo "Mem to use for directio: $MEMTOTAL"
9441
9442         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9443         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9444         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9445         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9446                 head -n1)
9447         echo "Smallest OST: $SMALLESTOST"
9448         [[ $SMALLESTOST -lt 10240 ]] &&
9449                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9450
9451         trap cleanup_test_78 EXIT
9452
9453         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9454                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9455
9456         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9457         echo "File size: $F78SIZE"
9458         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9459         for i in $(seq 1 $NSEQ); do
9460                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9461                 echo directIO rdwr round $i of $NSEQ
9462                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9463         done
9464
9465         cleanup_test_78
9466 }
9467 run_test 78 "handle large O_DIRECT writes correctly ============"
9468
9469 test_79() { # bug 12743
9470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9471
9472         wait_delete_completed
9473
9474         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9475         BKFREE=$(calc_osc_kbytes kbytesfree)
9476         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9477
9478         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9479         DFTOTAL=`echo $STRING | cut -d, -f1`
9480         DFUSED=`echo $STRING  | cut -d, -f2`
9481         DFAVAIL=`echo $STRING | cut -d, -f3`
9482         DFFREE=$(($DFTOTAL - $DFUSED))
9483
9484         ALLOWANCE=$((64 * $OSTCOUNT))
9485
9486         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9487            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9488                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9489         fi
9490         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9491            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9492                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9493         fi
9494         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9495            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9496                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9497         fi
9498 }
9499 run_test 79 "df report consistency check ======================="
9500
9501 test_80() { # bug 10718
9502         remote_ost_nodsh && skip "remote OST with nodsh"
9503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9504
9505         # relax strong synchronous semantics for slow backends like ZFS
9506         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9507                 local soc="obdfilter.*.sync_lock_cancel"
9508                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9509
9510                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9511                 if [ -z "$save" ]; then
9512                         soc="obdfilter.*.sync_on_lock_cancel"
9513                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9514                 fi
9515
9516                 if [ "$save" != "never" ]; then
9517                         local hosts=$(comma_list $(osts_nodes))
9518
9519                         do_nodes $hosts $LCTL set_param $soc=never
9520                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9521                 fi
9522         fi
9523
9524         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9525         sync; sleep 1; sync
9526         local before=$(date +%s)
9527         cancel_lru_locks osc
9528         local after=$(date +%s)
9529         local diff=$((after - before))
9530         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9531
9532         rm -f $DIR/$tfile
9533 }
9534 run_test 80 "Page eviction is equally fast at high offsets too"
9535
9536 test_81a() { # LU-456
9537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9538         remote_ost_nodsh && skip "remote OST with nodsh"
9539
9540         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9541         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9542         do_facet ost1 lctl set_param fail_loc=0x80000228
9543
9544         # write should trigger a retry and success
9545         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9546         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9547         RC=$?
9548         if [ $RC -ne 0 ] ; then
9549                 error "write should success, but failed for $RC"
9550         fi
9551 }
9552 run_test 81a "OST should retry write when get -ENOSPC ==============="
9553
9554 test_81b() { # LU-456
9555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9556         remote_ost_nodsh && skip "remote OST with nodsh"
9557
9558         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9559         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9560         do_facet ost1 lctl set_param fail_loc=0x228
9561
9562         # write should retry several times and return -ENOSPC finally
9563         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9564         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9565         RC=$?
9566         ENOSPC=28
9567         if [ $RC -ne $ENOSPC ] ; then
9568                 error "dd should fail for -ENOSPC, but succeed."
9569         fi
9570 }
9571 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9572
9573 test_99() {
9574         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9575
9576         test_mkdir $DIR/$tdir.cvsroot
9577         chown $RUNAS_ID $DIR/$tdir.cvsroot
9578
9579         cd $TMP
9580         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9581
9582         cd /etc/init.d
9583         # some versions of cvs import exit(1) when asked to import links or
9584         # files they can't read.  ignore those files.
9585         local toignore=$(find . -type l -printf '-I %f\n' -o \
9586                          ! -perm /4 -printf '-I %f\n')
9587         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9588                 $tdir.reposname vtag rtag
9589
9590         cd $DIR
9591         test_mkdir $DIR/$tdir.reposname
9592         chown $RUNAS_ID $DIR/$tdir.reposname
9593         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9594
9595         cd $DIR/$tdir.reposname
9596         $RUNAS touch foo99
9597         $RUNAS cvs add -m 'addmsg' foo99
9598         $RUNAS cvs update
9599         $RUNAS cvs commit -m 'nomsg' foo99
9600         rm -fr $DIR/$tdir.cvsroot
9601 }
9602 run_test 99 "cvs strange file/directory operations"
9603
9604 test_100() {
9605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9606         [[ "$NETTYPE" =~ tcp ]] ||
9607                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9608         remote_ost_nodsh && skip "remote OST with nodsh"
9609         remote_mds_nodsh && skip "remote MDS with nodsh"
9610         remote_servers ||
9611                 skip "useless for local single node setup"
9612
9613         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9614                 [ "$PROT" != "tcp" ] && continue
9615                 RPORT=$(echo $REMOTE | cut -d: -f2)
9616                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9617
9618                 rc=0
9619                 LPORT=`echo $LOCAL | cut -d: -f2`
9620                 if [ $LPORT -ge 1024 ]; then
9621                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9622                         netstat -tna
9623                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9624                 fi
9625         done
9626         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9627 }
9628 run_test 100 "check local port using privileged port ==========="
9629
9630 function get_named_value()
9631 {
9632     local tag=$1
9633
9634     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9635 }
9636
9637 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9638                    awk '/^max_cached_mb/ { print $2 }')
9639
9640 cleanup_101a() {
9641         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9642         trap 0
9643 }
9644
9645 test_101a() {
9646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9647
9648         local s
9649         local discard
9650         local nreads=10000
9651         local cache_limit=32
9652
9653         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9654         trap cleanup_101a EXIT
9655         $LCTL set_param -n llite.*.read_ahead_stats=0
9656         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9657
9658         #
9659         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9660         #
9661         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9662         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9663
9664         discard=0
9665         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9666                    get_named_value 'read.but.discarded'); do
9667                         discard=$(($discard + $s))
9668         done
9669         cleanup_101a
9670
9671         $LCTL get_param osc.*-osc*.rpc_stats
9672         $LCTL get_param llite.*.read_ahead_stats
9673
9674         # Discard is generally zero, but sometimes a few random reads line up
9675         # and trigger larger readahead, which is wasted & leads to discards.
9676         if [[ $(($discard)) -gt $nreads ]]; then
9677                 error "too many ($discard) discarded pages"
9678         fi
9679         rm -f $DIR/$tfile || true
9680 }
9681 run_test 101a "check read-ahead for random reads"
9682
9683 setup_test101bc() {
9684         test_mkdir $DIR/$tdir
9685         local ssize=$1
9686         local FILE_LENGTH=$2
9687         STRIPE_OFFSET=0
9688
9689         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9690
9691         local list=$(comma_list $(osts_nodes))
9692         set_osd_param $list '' read_cache_enable 0
9693         set_osd_param $list '' writethrough_cache_enable 0
9694
9695         trap cleanup_test101bc EXIT
9696         # prepare the read-ahead file
9697         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9698
9699         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9700                                 count=$FILE_SIZE_MB 2> /dev/null
9701
9702 }
9703
9704 cleanup_test101bc() {
9705         trap 0
9706         rm -rf $DIR/$tdir
9707         rm -f $DIR/$tfile
9708
9709         local list=$(comma_list $(osts_nodes))
9710         set_osd_param $list '' read_cache_enable 1
9711         set_osd_param $list '' writethrough_cache_enable 1
9712 }
9713
9714 calc_total() {
9715         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9716 }
9717
9718 ra_check_101() {
9719         local READ_SIZE=$1
9720         local STRIPE_SIZE=$2
9721         local FILE_LENGTH=$3
9722         local RA_INC=1048576
9723         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9724         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9725                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9726         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9727                   get_named_value 'read.but.discarded' | calc_total)
9728         if [[ $DISCARD -gt $discard_limit ]]; then
9729                 $LCTL get_param llite.*.read_ahead_stats
9730                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9731         else
9732                 echo "Read-ahead success for size ${READ_SIZE}"
9733         fi
9734 }
9735
9736 test_101b() {
9737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9738         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9739
9740         local STRIPE_SIZE=1048576
9741         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9742
9743         if [ $SLOW == "yes" ]; then
9744                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9745         else
9746                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9747         fi
9748
9749         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9750
9751         # prepare the read-ahead file
9752         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9753         cancel_lru_locks osc
9754         for BIDX in 2 4 8 16 32 64 128 256
9755         do
9756                 local BSIZE=$((BIDX*4096))
9757                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9758                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9759                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9760                 $LCTL set_param -n llite.*.read_ahead_stats=0
9761                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9762                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9763                 cancel_lru_locks osc
9764                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9765         done
9766         cleanup_test101bc
9767         true
9768 }
9769 run_test 101b "check stride-io mode read-ahead ================="
9770
9771 test_101c() {
9772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9773
9774         local STRIPE_SIZE=1048576
9775         local FILE_LENGTH=$((STRIPE_SIZE*100))
9776         local nreads=10000
9777         local rsize=65536
9778         local osc_rpc_stats
9779
9780         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9781
9782         cancel_lru_locks osc
9783         $LCTL set_param osc.*.rpc_stats=0
9784         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9785         $LCTL get_param osc.*.rpc_stats
9786         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9787                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9788                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9789                 local size
9790
9791                 if [ $lines -le 20 ]; then
9792                         echo "continue debug"
9793                         continue
9794                 fi
9795                 for size in 1 2 4 8; do
9796                         local rpc=$(echo "$stats" |
9797                                     awk '($1 == "'$size':") {print $2; exit; }')
9798                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9799                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9800                 done
9801                 echo "$osc_rpc_stats check passed!"
9802         done
9803         cleanup_test101bc
9804         true
9805 }
9806 run_test 101c "check stripe_size aligned read-ahead"
9807
9808 test_101d() {
9809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9810
9811         local file=$DIR/$tfile
9812         local sz_MB=${FILESIZE_101d:-80}
9813         local ra_MB=${READAHEAD_MB:-40}
9814
9815         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9816         [ $free_MB -lt $sz_MB ] &&
9817                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9818
9819         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9820         $LFS setstripe -c -1 $file || error "setstripe failed"
9821
9822         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9823         echo Cancel LRU locks on lustre client to flush the client cache
9824         cancel_lru_locks osc
9825
9826         echo Disable read-ahead
9827         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9828         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9829         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
9830         $LCTL get_param -n llite.*.max_read_ahead_mb
9831
9832         echo "Reading the test file $file with read-ahead disabled"
9833         local sz_KB=$((sz_MB * 1024 / 4))
9834         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9835         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9836         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9837                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9838
9839         echo "Cancel LRU locks on lustre client to flush the client cache"
9840         cancel_lru_locks osc
9841         echo Enable read-ahead with ${ra_MB}MB
9842         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9843
9844         echo "Reading the test file $file with read-ahead enabled"
9845         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9846                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9847
9848         echo "read-ahead disabled time read $raOFF"
9849         echo "read-ahead enabled time read $raON"
9850
9851         rm -f $file
9852         wait_delete_completed
9853
9854         # use awk for this check instead of bash because it handles decimals
9855         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9856                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9857 }
9858 run_test 101d "file read with and without read-ahead enabled"
9859
9860 test_101e() {
9861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9862
9863         local file=$DIR/$tfile
9864         local size_KB=500  #KB
9865         local count=100
9866         local bsize=1024
9867
9868         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9869         local need_KB=$((count * size_KB))
9870         [[ $free_KB -le $need_KB ]] &&
9871                 skip_env "Need free space $need_KB, have $free_KB"
9872
9873         echo "Creating $count ${size_KB}K test files"
9874         for ((i = 0; i < $count; i++)); do
9875                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9876         done
9877
9878         echo "Cancel LRU locks on lustre client to flush the client cache"
9879         cancel_lru_locks $OSC
9880
9881         echo "Reset readahead stats"
9882         $LCTL set_param -n llite.*.read_ahead_stats=0
9883
9884         for ((i = 0; i < $count; i++)); do
9885                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9886         done
9887
9888         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9889                      get_named_value 'misses' | calc_total)
9890
9891         for ((i = 0; i < $count; i++)); do
9892                 rm -rf $file.$i 2>/dev/null
9893         done
9894
9895         #10000 means 20% reads are missing in readahead
9896         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9897 }
9898 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9899
9900 test_101f() {
9901         which iozone || skip_env "no iozone installed"
9902
9903         local old_debug=$($LCTL get_param debug)
9904         old_debug=${old_debug#*=}
9905         $LCTL set_param debug="reada mmap"
9906
9907         # create a test file
9908         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9909
9910         echo Cancel LRU locks on lustre client to flush the client cache
9911         cancel_lru_locks osc
9912
9913         echo Reset readahead stats
9914         $LCTL set_param -n llite.*.read_ahead_stats=0
9915
9916         echo mmap read the file with small block size
9917         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9918                 > /dev/null 2>&1
9919
9920         echo checking missing pages
9921         $LCTL get_param llite.*.read_ahead_stats
9922         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9923                         get_named_value 'misses' | calc_total)
9924
9925         $LCTL set_param debug="$old_debug"
9926         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9927         rm -f $DIR/$tfile
9928 }
9929 run_test 101f "check mmap read performance"
9930
9931 test_101g_brw_size_test() {
9932         local mb=$1
9933         local pages=$((mb * 1048576 / PAGE_SIZE))
9934         local file=$DIR/$tfile
9935
9936         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9937                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9938         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9939                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9940                         return 2
9941         done
9942
9943         stack_trap "rm -f $file" EXIT
9944         $LCTL set_param -n osc.*.rpc_stats=0
9945
9946         # 10 RPCs should be enough for the test
9947         local count=10
9948         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9949                 { error "dd write ${mb} MB blocks failed"; return 3; }
9950         cancel_lru_locks osc
9951         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9952                 { error "dd write ${mb} MB blocks failed"; return 4; }
9953
9954         # calculate number of full-sized read and write RPCs
9955         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9956                 sed -n '/pages per rpc/,/^$/p' |
9957                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9958                 END { print reads,writes }'))
9959         # allow one extra full-sized read RPC for async readahead
9960         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9961                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9962         [[ ${rpcs[1]} == $count ]] ||
9963                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9964 }
9965
9966 test_101g() {
9967         remote_ost_nodsh && skip "remote OST with nodsh"
9968
9969         local rpcs
9970         local osts=$(get_facets OST)
9971         local list=$(comma_list $(osts_nodes))
9972         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9973         local brw_size="obdfilter.*.brw_size"
9974
9975         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9976
9977         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9978
9979         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9980                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9981                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9982            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9983                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9984                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9985
9986                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9987                         suffix="M"
9988
9989                 if [[ $orig_mb -lt 16 ]]; then
9990                         save_lustre_params $osts "$brw_size" > $p
9991                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9992                                 error "set 16MB RPC size failed"
9993
9994                         echo "remount client to enable new RPC size"
9995                         remount_client $MOUNT || error "remount_client failed"
9996                 fi
9997
9998                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9999                 # should be able to set brw_size=12, but no rpc_stats for that
10000                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10001         fi
10002
10003         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10004
10005         if [[ $orig_mb -lt 16 ]]; then
10006                 restore_lustre_params < $p
10007                 remount_client $MOUNT || error "remount_client restore failed"
10008         fi
10009
10010         rm -f $p $DIR/$tfile
10011 }
10012 run_test 101g "Big bulk(4/16 MiB) readahead"
10013
10014 test_101h() {
10015         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10016
10017         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10018                 error "dd 70M file failed"
10019         echo Cancel LRU locks on lustre client to flush the client cache
10020         cancel_lru_locks osc
10021
10022         echo "Reset readahead stats"
10023         $LCTL set_param -n llite.*.read_ahead_stats 0
10024
10025         echo "Read 10M of data but cross 64M bundary"
10026         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10027         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10028                      get_named_value 'misses' | calc_total)
10029         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10030         rm -f $p $DIR/$tfile
10031 }
10032 run_test 101h "Readahead should cover current read window"
10033
10034 test_101i() {
10035         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10036                 error "dd 10M file failed"
10037
10038         local max_per_file_mb=$($LCTL get_param -n \
10039                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10040         cancel_lru_locks osc
10041         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10042         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10043                 error "set max_read_ahead_per_file_mb to 1 failed"
10044
10045         echo "Reset readahead stats"
10046         $LCTL set_param llite.*.read_ahead_stats=0
10047
10048         dd if=$DIR/$tfile of=/dev/null bs=2M
10049
10050         $LCTL get_param llite.*.read_ahead_stats
10051         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10052                      awk '/misses/ { print $2 }')
10053         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10054         rm -f $DIR/$tfile
10055 }
10056 run_test 101i "allow current readahead to exceed reservation"
10057
10058 test_101j() {
10059         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10060                 error "setstripe $DIR/$tfile failed"
10061         local file_size=$((1048576 * 16))
10062         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10063         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10064
10065         echo Disable read-ahead
10066         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10067
10068         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10069         for blk in $PAGE_SIZE 1048576 $file_size; do
10070                 cancel_lru_locks osc
10071                 echo "Reset readahead stats"
10072                 $LCTL set_param -n llite.*.read_ahead_stats=0
10073                 local count=$(($file_size / $blk))
10074                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10075                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10076                              get_named_value 'failed.to.fast.read' | calc_total)
10077                 $LCTL get_param -n llite.*.read_ahead_stats
10078                 [ $miss -eq $count ] || error "expected $count got $miss"
10079         done
10080
10081         rm -f $p $DIR/$tfile
10082 }
10083 run_test 101j "A complete read block should be submitted when no RA"
10084
10085 setup_test102() {
10086         test_mkdir $DIR/$tdir
10087         chown $RUNAS_ID $DIR/$tdir
10088         STRIPE_SIZE=65536
10089         STRIPE_OFFSET=1
10090         STRIPE_COUNT=$OSTCOUNT
10091         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10092
10093         trap cleanup_test102 EXIT
10094         cd $DIR
10095         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10096         cd $DIR/$tdir
10097         for num in 1 2 3 4; do
10098                 for count in $(seq 1 $STRIPE_COUNT); do
10099                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10100                                 local size=`expr $STRIPE_SIZE \* $num`
10101                                 local file=file"$num-$idx-$count"
10102                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10103                         done
10104                 done
10105         done
10106
10107         cd $DIR
10108         $1 tar cf $TMP/f102.tar $tdir --xattrs
10109 }
10110
10111 cleanup_test102() {
10112         trap 0
10113         rm -f $TMP/f102.tar
10114         rm -rf $DIR/d0.sanity/d102
10115 }
10116
10117 test_102a() {
10118         [ "$UID" != 0 ] && skip "must run as root"
10119         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10120                 skip_env "must have user_xattr"
10121
10122         [ -z "$(which setfattr 2>/dev/null)" ] &&
10123                 skip_env "could not find setfattr"
10124
10125         local testfile=$DIR/$tfile
10126
10127         touch $testfile
10128         echo "set/get xattr..."
10129         setfattr -n trusted.name1 -v value1 $testfile ||
10130                 error "setfattr -n trusted.name1=value1 $testfile failed"
10131         getfattr -n trusted.name1 $testfile 2> /dev/null |
10132           grep "trusted.name1=.value1" ||
10133                 error "$testfile missing trusted.name1=value1"
10134
10135         setfattr -n user.author1 -v author1 $testfile ||
10136                 error "setfattr -n user.author1=author1 $testfile failed"
10137         getfattr -n user.author1 $testfile 2> /dev/null |
10138           grep "user.author1=.author1" ||
10139                 error "$testfile missing trusted.author1=author1"
10140
10141         echo "listxattr..."
10142         setfattr -n trusted.name2 -v value2 $testfile ||
10143                 error "$testfile unable to set trusted.name2"
10144         setfattr -n trusted.name3 -v value3 $testfile ||
10145                 error "$testfile unable to set trusted.name3"
10146         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10147             grep "trusted.name" | wc -l) -eq 3 ] ||
10148                 error "$testfile missing 3 trusted.name xattrs"
10149
10150         setfattr -n user.author2 -v author2 $testfile ||
10151                 error "$testfile unable to set user.author2"
10152         setfattr -n user.author3 -v author3 $testfile ||
10153                 error "$testfile unable to set user.author3"
10154         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10155             grep "user.author" | wc -l) -eq 3 ] ||
10156                 error "$testfile missing 3 user.author xattrs"
10157
10158         echo "remove xattr..."
10159         setfattr -x trusted.name1 $testfile ||
10160                 error "$testfile error deleting trusted.name1"
10161         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10162                 error "$testfile did not delete trusted.name1 xattr"
10163
10164         setfattr -x user.author1 $testfile ||
10165                 error "$testfile error deleting user.author1"
10166         echo "set lustre special xattr ..."
10167         $LFS setstripe -c1 $testfile
10168         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10169                 awk -F "=" '/trusted.lov/ { print $2 }' )
10170         setfattr -n "trusted.lov" -v $lovea $testfile ||
10171                 error "$testfile doesn't ignore setting trusted.lov again"
10172         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10173                 error "$testfile allow setting invalid trusted.lov"
10174         rm -f $testfile
10175 }
10176 run_test 102a "user xattr test =================================="
10177
10178 check_102b_layout() {
10179         local layout="$*"
10180         local testfile=$DIR/$tfile
10181
10182         echo "test layout '$layout'"
10183         $LFS setstripe $layout $testfile || error "setstripe failed"
10184         $LFS getstripe -y $testfile
10185
10186         echo "get/set/list trusted.lov xattr ..." # b=10930
10187         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10188         [[ "$value" =~ "trusted.lov" ]] ||
10189                 error "can't get trusted.lov from $testfile"
10190         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10191                 error "getstripe failed"
10192
10193         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10194
10195         value=$(cut -d= -f2 <<<$value)
10196         # LU-13168: truncated xattr should fail if short lov_user_md header
10197         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10198                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10199         for len in $lens; do
10200                 echo "setfattr $len $testfile.2"
10201                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10202                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10203         done
10204         local stripe_size=$($LFS getstripe -S $testfile.2)
10205         local stripe_count=$($LFS getstripe -c $testfile.2)
10206         [[ $stripe_size -eq 65536 ]] ||
10207                 error "stripe size $stripe_size != 65536"
10208         [[ $stripe_count -eq $stripe_count_orig ]] ||
10209                 error "stripe count $stripe_count != $stripe_count_orig"
10210         rm $testfile $testfile.2
10211 }
10212
10213 test_102b() {
10214         [ -z "$(which setfattr 2>/dev/null)" ] &&
10215                 skip_env "could not find setfattr"
10216         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10217
10218         # check plain layout
10219         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10220
10221         # and also check composite layout
10222         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10223
10224 }
10225 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10226
10227 test_102c() {
10228         [ -z "$(which setfattr 2>/dev/null)" ] &&
10229                 skip_env "could not find setfattr"
10230         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10231
10232         # b10930: get/set/list lustre.lov xattr
10233         echo "get/set/list lustre.lov xattr ..."
10234         test_mkdir $DIR/$tdir
10235         chown $RUNAS_ID $DIR/$tdir
10236         local testfile=$DIR/$tdir/$tfile
10237         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10238                 error "setstripe failed"
10239         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10240                 error "getstripe failed"
10241         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10242         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10243
10244         local testfile2=${testfile}2
10245         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10246                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10247
10248         $RUNAS $MCREATE $testfile2
10249         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10250         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10251         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10252         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10253         [ $stripe_count -eq $STRIPECOUNT ] ||
10254                 error "stripe count $stripe_count != $STRIPECOUNT"
10255 }
10256 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10257
10258 compare_stripe_info1() {
10259         local stripe_index_all_zero=true
10260
10261         for num in 1 2 3 4; do
10262                 for count in $(seq 1 $STRIPE_COUNT); do
10263                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10264                                 local size=$((STRIPE_SIZE * num))
10265                                 local file=file"$num-$offset-$count"
10266                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10267                                 [[ $stripe_size -ne $size ]] &&
10268                                     error "$file: size $stripe_size != $size"
10269                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10270                                 # allow fewer stripes to be created, ORI-601
10271                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10272                                     error "$file: count $stripe_count != $count"
10273                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10274                                 [[ $stripe_index -ne 0 ]] &&
10275                                         stripe_index_all_zero=false
10276                         done
10277                 done
10278         done
10279         $stripe_index_all_zero &&
10280                 error "all files are being extracted starting from OST index 0"
10281         return 0
10282 }
10283
10284 have_xattrs_include() {
10285         tar --help | grep -q xattrs-include &&
10286                 echo --xattrs-include="lustre.*"
10287 }
10288
10289 test_102d() {
10290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10291         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10292
10293         XINC=$(have_xattrs_include)
10294         setup_test102
10295         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10296         cd $DIR/$tdir/$tdir
10297         compare_stripe_info1
10298 }
10299 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10300
10301 test_102f() {
10302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10303         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10304
10305         XINC=$(have_xattrs_include)
10306         setup_test102
10307         test_mkdir $DIR/$tdir.restore
10308         cd $DIR
10309         tar cf - --xattrs $tdir | tar xf - \
10310                 -C $DIR/$tdir.restore --xattrs $XINC
10311         cd $DIR/$tdir.restore/$tdir
10312         compare_stripe_info1
10313 }
10314 run_test 102f "tar copy files, not keep osts"
10315
10316 grow_xattr() {
10317         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10318                 skip "must have user_xattr"
10319         [ -z "$(which setfattr 2>/dev/null)" ] &&
10320                 skip_env "could not find setfattr"
10321         [ -z "$(which getfattr 2>/dev/null)" ] &&
10322                 skip_env "could not find getfattr"
10323
10324         local xsize=${1:-1024}  # in bytes
10325         local file=$DIR/$tfile
10326         local value="$(generate_string $xsize)"
10327         local xbig=trusted.big
10328         local toobig=$2
10329
10330         touch $file
10331         log "save $xbig on $file"
10332         if [ -z "$toobig" ]
10333         then
10334                 setfattr -n $xbig -v $value $file ||
10335                         error "saving $xbig on $file failed"
10336         else
10337                 setfattr -n $xbig -v $value $file &&
10338                         error "saving $xbig on $file succeeded"
10339                 return 0
10340         fi
10341
10342         local orig=$(get_xattr_value $xbig $file)
10343         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10344
10345         local xsml=trusted.sml
10346         log "save $xsml on $file"
10347         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10348
10349         local new=$(get_xattr_value $xbig $file)
10350         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10351
10352         log "grow $xsml on $file"
10353         setfattr -n $xsml -v "$value" $file ||
10354                 error "growing $xsml on $file failed"
10355
10356         new=$(get_xattr_value $xbig $file)
10357         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10358         log "$xbig still valid after growing $xsml"
10359
10360         rm -f $file
10361 }
10362
10363 test_102h() { # bug 15777
10364         grow_xattr 1024
10365 }
10366 run_test 102h "grow xattr from inside inode to external block"
10367
10368 test_102ha() {
10369         large_xattr_enabled || skip_env "ea_inode feature disabled"
10370
10371         echo "setting xattr of max xattr size: $(max_xattr_size)"
10372         grow_xattr $(max_xattr_size)
10373
10374         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10375         echo "This should fail:"
10376         grow_xattr $(($(max_xattr_size) + 10)) 1
10377 }
10378 run_test 102ha "grow xattr from inside inode to external inode"
10379
10380 test_102i() { # bug 17038
10381         [ -z "$(which getfattr 2>/dev/null)" ] &&
10382                 skip "could not find getfattr"
10383
10384         touch $DIR/$tfile
10385         ln -s $DIR/$tfile $DIR/${tfile}link
10386         getfattr -n trusted.lov $DIR/$tfile ||
10387                 error "lgetxattr on $DIR/$tfile failed"
10388         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10389                 grep -i "no such attr" ||
10390                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10391         rm -f $DIR/$tfile $DIR/${tfile}link
10392 }
10393 run_test 102i "lgetxattr test on symbolic link ============"
10394
10395 test_102j() {
10396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10397         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10398
10399         XINC=$(have_xattrs_include)
10400         setup_test102 "$RUNAS"
10401         chown $RUNAS_ID $DIR/$tdir
10402         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10403         cd $DIR/$tdir/$tdir
10404         compare_stripe_info1 "$RUNAS"
10405 }
10406 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10407
10408 test_102k() {
10409         [ -z "$(which setfattr 2>/dev/null)" ] &&
10410                 skip "could not find setfattr"
10411
10412         touch $DIR/$tfile
10413         # b22187 just check that does not crash for regular file.
10414         setfattr -n trusted.lov $DIR/$tfile
10415         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10416         local test_kdir=$DIR/$tdir
10417         test_mkdir $test_kdir
10418         local default_size=$($LFS getstripe -S $test_kdir)
10419         local default_count=$($LFS getstripe -c $test_kdir)
10420         local default_offset=$($LFS getstripe -i $test_kdir)
10421         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10422                 error 'dir setstripe failed'
10423         setfattr -n trusted.lov $test_kdir
10424         local stripe_size=$($LFS getstripe -S $test_kdir)
10425         local stripe_count=$($LFS getstripe -c $test_kdir)
10426         local stripe_offset=$($LFS getstripe -i $test_kdir)
10427         [ $stripe_size -eq $default_size ] ||
10428                 error "stripe size $stripe_size != $default_size"
10429         [ $stripe_count -eq $default_count ] ||
10430                 error "stripe count $stripe_count != $default_count"
10431         [ $stripe_offset -eq $default_offset ] ||
10432                 error "stripe offset $stripe_offset != $default_offset"
10433         rm -rf $DIR/$tfile $test_kdir
10434 }
10435 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10436
10437 test_102l() {
10438         [ -z "$(which getfattr 2>/dev/null)" ] &&
10439                 skip "could not find getfattr"
10440
10441         # LU-532 trusted. xattr is invisible to non-root
10442         local testfile=$DIR/$tfile
10443
10444         touch $testfile
10445
10446         echo "listxattr as user..."
10447         chown $RUNAS_ID $testfile
10448         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10449             grep -q "trusted" &&
10450                 error "$testfile trusted xattrs are user visible"
10451
10452         return 0;
10453 }
10454 run_test 102l "listxattr size test =================================="
10455
10456 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10457         local path=$DIR/$tfile
10458         touch $path
10459
10460         listxattr_size_check $path || error "listattr_size_check $path failed"
10461 }
10462 run_test 102m "Ensure listxattr fails on small bufffer ========"
10463
10464 cleanup_test102
10465
10466 getxattr() { # getxattr path name
10467         # Return the base64 encoding of the value of xattr name on path.
10468         local path=$1
10469         local name=$2
10470
10471         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10472         # file: $path
10473         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10474         #
10475         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10476
10477         getfattr --absolute-names --encoding=base64 --name=$name $path |
10478                 awk -F= -v name=$name '$1 == name {
10479                         print substr($0, index($0, "=") + 1);
10480         }'
10481 }
10482
10483 test_102n() { # LU-4101 mdt: protect internal xattrs
10484         [ -z "$(which setfattr 2>/dev/null)" ] &&
10485                 skip "could not find setfattr"
10486         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10487         then
10488                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10489         fi
10490
10491         local file0=$DIR/$tfile.0
10492         local file1=$DIR/$tfile.1
10493         local xattr0=$TMP/$tfile.0
10494         local xattr1=$TMP/$tfile.1
10495         local namelist="lov lma lmv link fid version som hsm"
10496         local name
10497         local value
10498
10499         rm -rf $file0 $file1 $xattr0 $xattr1
10500         touch $file0 $file1
10501
10502         # Get 'before' xattrs of $file1.
10503         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10504
10505         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10506                 namelist+=" lfsck_namespace"
10507         for name in $namelist; do
10508                 # Try to copy xattr from $file0 to $file1.
10509                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10510
10511                 setfattr --name=trusted.$name --value="$value" $file1 ||
10512                         error "setxattr 'trusted.$name' failed"
10513
10514                 # Try to set a garbage xattr.
10515                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10516
10517                 if [[ x$name == "xlov" ]]; then
10518                         setfattr --name=trusted.lov --value="$value" $file1 &&
10519                         error "setxattr invalid 'trusted.lov' success"
10520                 else
10521                         setfattr --name=trusted.$name --value="$value" $file1 ||
10522                                 error "setxattr invalid 'trusted.$name' failed"
10523                 fi
10524
10525                 # Try to remove the xattr from $file1. We don't care if this
10526                 # appears to succeed or fail, we just don't want there to be
10527                 # any changes or crashes.
10528                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10529         done
10530
10531         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10532         then
10533                 name="lfsck_ns"
10534                 # Try to copy xattr from $file0 to $file1.
10535                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10536
10537                 setfattr --name=trusted.$name --value="$value" $file1 ||
10538                         error "setxattr 'trusted.$name' failed"
10539
10540                 # Try to set a garbage xattr.
10541                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10542
10543                 setfattr --name=trusted.$name --value="$value" $file1 ||
10544                         error "setxattr 'trusted.$name' failed"
10545
10546                 # Try to remove the xattr from $file1. We don't care if this
10547                 # appears to succeed or fail, we just don't want there to be
10548                 # any changes or crashes.
10549                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10550         fi
10551
10552         # Get 'after' xattrs of file1.
10553         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10554
10555         if ! diff $xattr0 $xattr1; then
10556                 error "before and after xattrs of '$file1' differ"
10557         fi
10558
10559         rm -rf $file0 $file1 $xattr0 $xattr1
10560
10561         return 0
10562 }
10563 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10564
10565 test_102p() { # LU-4703 setxattr did not check ownership
10566         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10567                 skip "MDS needs to be at least 2.5.56"
10568
10569         local testfile=$DIR/$tfile
10570
10571         touch $testfile
10572
10573         echo "setfacl as user..."
10574         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10575         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10576
10577         echo "setfattr as user..."
10578         setfacl -m "u:$RUNAS_ID:---" $testfile
10579         $RUNAS setfattr -x system.posix_acl_access $testfile
10580         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10581 }
10582 run_test 102p "check setxattr(2) correctly fails without permission"
10583
10584 test_102q() {
10585         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10586                 skip "MDS needs to be at least 2.6.92"
10587
10588         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10589 }
10590 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10591
10592 test_102r() {
10593         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10594                 skip "MDS needs to be at least 2.6.93"
10595
10596         touch $DIR/$tfile || error "touch"
10597         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10598         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10599         rm $DIR/$tfile || error "rm"
10600
10601         #normal directory
10602         mkdir -p $DIR/$tdir || error "mkdir"
10603         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10604         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10605         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10606                 error "$testfile error deleting user.author1"
10607         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10608                 grep "user.$(basename $tdir)" &&
10609                 error "$tdir did not delete user.$(basename $tdir)"
10610         rmdir $DIR/$tdir || error "rmdir"
10611
10612         #striped directory
10613         test_mkdir $DIR/$tdir
10614         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10615         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10616         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10617                 error "$testfile error deleting user.author1"
10618         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10619                 grep "user.$(basename $tdir)" &&
10620                 error "$tdir did not delete user.$(basename $tdir)"
10621         rmdir $DIR/$tdir || error "rm striped dir"
10622 }
10623 run_test 102r "set EAs with empty values"
10624
10625 test_102s() {
10626         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10627                 skip "MDS needs to be at least 2.11.52"
10628
10629         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10630
10631         save_lustre_params client "llite.*.xattr_cache" > $save
10632
10633         for cache in 0 1; do
10634                 lctl set_param llite.*.xattr_cache=$cache
10635
10636                 rm -f $DIR/$tfile
10637                 touch $DIR/$tfile || error "touch"
10638                 for prefix in lustre security system trusted user; do
10639                         # Note getxattr() may fail with 'Operation not
10640                         # supported' or 'No such attribute' depending
10641                         # on prefix and cache.
10642                         getfattr -n $prefix.n102s $DIR/$tfile &&
10643                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10644                 done
10645         done
10646
10647         restore_lustre_params < $save
10648 }
10649 run_test 102s "getting nonexistent xattrs should fail"
10650
10651 test_102t() {
10652         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10653                 skip "MDS needs to be at least 2.11.52"
10654
10655         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10656
10657         save_lustre_params client "llite.*.xattr_cache" > $save
10658
10659         for cache in 0 1; do
10660                 lctl set_param llite.*.xattr_cache=$cache
10661
10662                 for buf_size in 0 256; do
10663                         rm -f $DIR/$tfile
10664                         touch $DIR/$tfile || error "touch"
10665                         setfattr -n user.multiop $DIR/$tfile
10666                         $MULTIOP $DIR/$tfile oa$buf_size ||
10667                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10668                 done
10669         done
10670
10671         restore_lustre_params < $save
10672 }
10673 run_test 102t "zero length xattr values handled correctly"
10674
10675 run_acl_subtest()
10676 {
10677     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10678     return $?
10679 }
10680
10681 test_103a() {
10682         [ "$UID" != 0 ] && skip "must run as root"
10683         $GSS && skip_env "could not run under gss"
10684         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10685                 skip_env "must have acl enabled"
10686         [ -z "$(which setfacl 2>/dev/null)" ] &&
10687                 skip_env "could not find setfacl"
10688         remote_mds_nodsh && skip "remote MDS with nodsh"
10689
10690         gpasswd -a daemon bin                           # LU-5641
10691         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10692
10693         declare -a identity_old
10694
10695         for num in $(seq $MDSCOUNT); do
10696                 switch_identity $num true || identity_old[$num]=$?
10697         done
10698
10699         SAVE_UMASK=$(umask)
10700         umask 0022
10701         mkdir -p $DIR/$tdir
10702         cd $DIR/$tdir
10703
10704         echo "performing cp ..."
10705         run_acl_subtest cp || error "run_acl_subtest cp failed"
10706         echo "performing getfacl-noacl..."
10707         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10708         echo "performing misc..."
10709         run_acl_subtest misc || error  "misc test failed"
10710         echo "performing permissions..."
10711         run_acl_subtest permissions || error "permissions failed"
10712         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10713         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10714                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10715                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10716         then
10717                 echo "performing permissions xattr..."
10718                 run_acl_subtest permissions_xattr ||
10719                         error "permissions_xattr failed"
10720         fi
10721         echo "performing setfacl..."
10722         run_acl_subtest setfacl || error  "setfacl test failed"
10723
10724         # inheritance test got from HP
10725         echo "performing inheritance..."
10726         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10727         chmod +x make-tree || error "chmod +x failed"
10728         run_acl_subtest inheritance || error "inheritance test failed"
10729         rm -f make-tree
10730
10731         echo "LU-974 ignore umask when acl is enabled..."
10732         run_acl_subtest 974 || error "LU-974 umask test failed"
10733         if [ $MDSCOUNT -ge 2 ]; then
10734                 run_acl_subtest 974_remote ||
10735                         error "LU-974 umask test failed under remote dir"
10736         fi
10737
10738         echo "LU-2561 newly created file is same size as directory..."
10739         if [ "$mds1_FSTYPE" != "zfs" ]; then
10740                 run_acl_subtest 2561 || error "LU-2561 test failed"
10741         else
10742                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10743         fi
10744
10745         run_acl_subtest 4924 || error "LU-4924 test failed"
10746
10747         cd $SAVE_PWD
10748         umask $SAVE_UMASK
10749
10750         for num in $(seq $MDSCOUNT); do
10751                 if [ "${identity_old[$num]}" = 1 ]; then
10752                         switch_identity $num false || identity_old[$num]=$?
10753                 fi
10754         done
10755 }
10756 run_test 103a "acl test"
10757
10758 test_103b() {
10759         declare -a pids
10760         local U
10761
10762         for U in {0..511}; do
10763                 {
10764                 local O=$(printf "%04o" $U)
10765
10766                 umask $(printf "%04o" $((511 ^ $O)))
10767                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10768                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10769
10770                 (( $S == ($O & 0666) )) ||
10771                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10772
10773                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10774                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10775                 (( $S == ($O & 0666) )) ||
10776                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10777
10778                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10779                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10780                 (( $S == ($O & 0666) )) ||
10781                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10782                 rm -f $DIR/$tfile.[smp]$0
10783                 } &
10784                 local pid=$!
10785
10786                 # limit the concurrently running threads to 64. LU-11878
10787                 local idx=$((U % 64))
10788                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10789                 pids[idx]=$pid
10790         done
10791         wait
10792 }
10793 run_test 103b "umask lfs setstripe"
10794
10795 test_103c() {
10796         mkdir -p $DIR/$tdir
10797         cp -rp $DIR/$tdir $DIR/$tdir.bak
10798
10799         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10800                 error "$DIR/$tdir shouldn't contain default ACL"
10801         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10802                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10803         true
10804 }
10805 run_test 103c "'cp -rp' won't set empty acl"
10806
10807 test_103e() {
10808         local numacl
10809         local fileacl
10810         local saved_debug=$($LCTL get_param -n debug)
10811
10812         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
10813                 skip "MDS needs to be at least 2.14.0"
10814
10815         large_xattr_enabled || skip_env "ea_inode feature disabled"
10816
10817         mkdir -p $DIR/$tdir
10818         # add big LOV EA to cause reply buffer overflow earlier
10819         $LFS setstripe -C 1000 $DIR/$tdir
10820         lctl set_param mdc.*-mdc*.stats=clear
10821
10822         $LCTL set_param debug=0
10823         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
10824         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
10825
10826         # add a large number of default ACLs (expect 8000+ for 2.13+)
10827         for U in {2..7000}; do
10828                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
10829                         error "Able to add just $U default ACLs"
10830         done
10831         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10832         echo "$numacl default ACLs created"
10833
10834         stat $DIR/$tdir || error "Cannot stat directory"
10835         # check file creation
10836         touch $DIR/$tdir/$tfile ||
10837                 error "failed to create $tfile with $numacl default ACLs"
10838         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
10839         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10840         echo "$fileacl ACLs were inherited"
10841         (( $fileacl == $numacl )) ||
10842                 error "Not all default ACLs were inherited: $numacl != $fileacl"
10843         # check that new ACLs creation adds new ACLs to inherited ACLs
10844         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
10845                 error "Cannot set new ACL"
10846         numacl=$((numacl + 1))
10847         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10848         (( $fileacl == $numacl )) ||
10849                 error "failed to add new ACL: $fileacl != $numacl as expected"
10850         # adds more ACLs to a file to reach their maximum at 8000+
10851         numacl=0
10852         for U in {20000..25000}; do
10853                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
10854                 numacl=$((numacl + 1))
10855         done
10856         echo "Added $numacl more ACLs to the file"
10857         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10858         echo "Total $fileacl ACLs in file"
10859         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
10860         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
10861         rmdir $DIR/$tdir || error "Cannot remove directory"
10862 }
10863 run_test 103e "inheritance of big amount of default ACLs"
10864
10865 test_104a() {
10866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10867
10868         touch $DIR/$tfile
10869         lfs df || error "lfs df failed"
10870         lfs df -ih || error "lfs df -ih failed"
10871         lfs df -h $DIR || error "lfs df -h $DIR failed"
10872         lfs df -i $DIR || error "lfs df -i $DIR failed"
10873         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10874         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10875
10876         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10877         lctl --device %$OSC deactivate
10878         lfs df || error "lfs df with deactivated OSC failed"
10879         lctl --device %$OSC activate
10880         # wait the osc back to normal
10881         wait_osc_import_ready client ost
10882
10883         lfs df || error "lfs df with reactivated OSC failed"
10884         rm -f $DIR/$tfile
10885 }
10886 run_test 104a "lfs df [-ih] [path] test ========================="
10887
10888 test_104b() {
10889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10890         [ $RUNAS_ID -eq $UID ] &&
10891                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10892
10893         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10894                         grep "Permission denied" | wc -l)))
10895         if [ $denied_cnt -ne 0 ]; then
10896                 error "lfs check servers test failed"
10897         fi
10898 }
10899 run_test 104b "$RUNAS lfs check servers test ===================="
10900
10901 test_105a() {
10902         # doesn't work on 2.4 kernels
10903         touch $DIR/$tfile
10904         if $(flock_is_enabled); then
10905                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10906         else
10907                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10908         fi
10909         rm -f $DIR/$tfile
10910 }
10911 run_test 105a "flock when mounted without -o flock test ========"
10912
10913 test_105b() {
10914         touch $DIR/$tfile
10915         if $(flock_is_enabled); then
10916                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10917         else
10918                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10919         fi
10920         rm -f $DIR/$tfile
10921 }
10922 run_test 105b "fcntl when mounted without -o flock test ========"
10923
10924 test_105c() {
10925         touch $DIR/$tfile
10926         if $(flock_is_enabled); then
10927                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10928         else
10929                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10930         fi
10931         rm -f $DIR/$tfile
10932 }
10933 run_test 105c "lockf when mounted without -o flock test"
10934
10935 test_105d() { # bug 15924
10936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10937
10938         test_mkdir $DIR/$tdir
10939         flock_is_enabled || skip_env "mount w/o flock enabled"
10940         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10941         $LCTL set_param fail_loc=0x80000315
10942         flocks_test 2 $DIR/$tdir
10943 }
10944 run_test 105d "flock race (should not freeze) ========"
10945
10946 test_105e() { # bug 22660 && 22040
10947         flock_is_enabled || skip_env "mount w/o flock enabled"
10948
10949         touch $DIR/$tfile
10950         flocks_test 3 $DIR/$tfile
10951 }
10952 run_test 105e "Two conflicting flocks from same process"
10953
10954 test_106() { #bug 10921
10955         test_mkdir $DIR/$tdir
10956         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10957         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10958 }
10959 run_test 106 "attempt exec of dir followed by chown of that dir"
10960
10961 test_107() {
10962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10963
10964         CDIR=`pwd`
10965         local file=core
10966
10967         cd $DIR
10968         rm -f $file
10969
10970         local save_pattern=$(sysctl -n kernel.core_pattern)
10971         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10972         sysctl -w kernel.core_pattern=$file
10973         sysctl -w kernel.core_uses_pid=0
10974
10975         ulimit -c unlimited
10976         sleep 60 &
10977         SLEEPPID=$!
10978
10979         sleep 1
10980
10981         kill -s 11 $SLEEPPID
10982         wait $SLEEPPID
10983         if [ -e $file ]; then
10984                 size=`stat -c%s $file`
10985                 [ $size -eq 0 ] && error "Fail to create core file $file"
10986         else
10987                 error "Fail to create core file $file"
10988         fi
10989         rm -f $file
10990         sysctl -w kernel.core_pattern=$save_pattern
10991         sysctl -w kernel.core_uses_pid=$save_uses_pid
10992         cd $CDIR
10993 }
10994 run_test 107 "Coredump on SIG"
10995
10996 test_110() {
10997         test_mkdir $DIR/$tdir
10998         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10999         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11000                 error "mkdir with 256 char should fail, but did not"
11001         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11002                 error "create with 255 char failed"
11003         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11004                 error "create with 256 char should fail, but did not"
11005
11006         ls -l $DIR/$tdir
11007         rm -rf $DIR/$tdir
11008 }
11009 run_test 110 "filename length checking"
11010
11011 #
11012 # Purpose: To verify dynamic thread (OSS) creation.
11013 #
11014 test_115() {
11015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11016         remote_ost_nodsh && skip "remote OST with nodsh"
11017
11018         # Lustre does not stop service threads once they are started.
11019         # Reset number of running threads to default.
11020         stopall
11021         setupall
11022
11023         local OSTIO_pre
11024         local save_params="$TMP/sanity-$TESTNAME.parameters"
11025
11026         # Get ll_ost_io count before I/O
11027         OSTIO_pre=$(do_facet ost1 \
11028                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11029         # Exit if lustre is not running (ll_ost_io not running).
11030         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11031
11032         echo "Starting with $OSTIO_pre threads"
11033         local thread_max=$((OSTIO_pre * 2))
11034         local rpc_in_flight=$((thread_max * 2))
11035         # Number of I/O Process proposed to be started.
11036         local nfiles
11037         local facets=$(get_facets OST)
11038
11039         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11040         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11041
11042         # Set in_flight to $rpc_in_flight
11043         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11044                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11045         nfiles=${rpc_in_flight}
11046         # Set ost thread_max to $thread_max
11047         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11048
11049         # 5 Minutes should be sufficient for max number of OSS
11050         # threads(thread_max) to be created.
11051         local timeout=300
11052
11053         # Start I/O.
11054         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11055         test_mkdir $DIR/$tdir
11056         for i in $(seq $nfiles); do
11057                 local file=$DIR/$tdir/${tfile}-$i
11058                 $LFS setstripe -c -1 -i 0 $file
11059                 ($WTL $file $timeout)&
11060         done
11061
11062         # I/O Started - Wait for thread_started to reach thread_max or report
11063         # error if thread_started is more than thread_max.
11064         echo "Waiting for thread_started to reach thread_max"
11065         local thread_started=0
11066         local end_time=$((SECONDS + timeout))
11067
11068         while [ $SECONDS -le $end_time ] ; do
11069                 echo -n "."
11070                 # Get ost i/o thread_started count.
11071                 thread_started=$(do_facet ost1 \
11072                         "$LCTL get_param \
11073                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11074                 # Break out if thread_started is equal/greater than thread_max
11075                 if [[ $thread_started -ge $thread_max ]]; then
11076                         echo ll_ost_io thread_started $thread_started, \
11077                                 equal/greater than thread_max $thread_max
11078                         break
11079                 fi
11080                 sleep 1
11081         done
11082
11083         # Cleanup - We have the numbers, Kill i/o jobs if running.
11084         jobcount=($(jobs -p))
11085         for i in $(seq 0 $((${#jobcount[@]}-1)))
11086         do
11087                 kill -9 ${jobcount[$i]}
11088                 if [ $? -ne 0 ] ; then
11089                         echo Warning: \
11090                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11091                 fi
11092         done
11093
11094         # Cleanup files left by WTL binary.
11095         for i in $(seq $nfiles); do
11096                 local file=$DIR/$tdir/${tfile}-$i
11097                 rm -rf $file
11098                 if [ $? -ne 0 ] ; then
11099                         echo "Warning: Failed to delete file $file"
11100                 fi
11101         done
11102
11103         restore_lustre_params <$save_params
11104         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11105
11106         # Error out if no new thread has started or Thread started is greater
11107         # than thread max.
11108         if [[ $thread_started -le $OSTIO_pre ||
11109                         $thread_started -gt $thread_max ]]; then
11110                 error "ll_ost_io: thread_started $thread_started" \
11111                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11112                       "No new thread started or thread started greater " \
11113                       "than thread_max."
11114         fi
11115 }
11116 run_test 115 "verify dynamic thread creation===================="
11117
11118 free_min_max () {
11119         wait_delete_completed
11120         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11121         echo "OST kbytes available: ${AVAIL[@]}"
11122         MAXV=${AVAIL[0]}
11123         MAXI=0
11124         MINV=${AVAIL[0]}
11125         MINI=0
11126         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11127                 #echo OST $i: ${AVAIL[i]}kb
11128                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11129                         MAXV=${AVAIL[i]}
11130                         MAXI=$i
11131                 fi
11132                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11133                         MINV=${AVAIL[i]}
11134                         MINI=$i
11135                 fi
11136         done
11137         echo "Min free space: OST $MINI: $MINV"
11138         echo "Max free space: OST $MAXI: $MAXV"
11139 }
11140
11141 test_116a() { # was previously test_116()
11142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11143         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11144         remote_mds_nodsh && skip "remote MDS with nodsh"
11145
11146         echo -n "Free space priority "
11147         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11148                 head -n1
11149         declare -a AVAIL
11150         free_min_max
11151
11152         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11153         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11154         trap simple_cleanup_common EXIT
11155
11156         # Check if we need to generate uneven OSTs
11157         test_mkdir -p $DIR/$tdir/OST${MINI}
11158         local FILL=$((MINV / 4))
11159         local DIFF=$((MAXV - MINV))
11160         local DIFF2=$((DIFF * 100 / MINV))
11161
11162         local threshold=$(do_facet $SINGLEMDS \
11163                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11164         threshold=${threshold%%%}
11165         echo -n "Check for uneven OSTs: "
11166         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11167
11168         if [[ $DIFF2 -gt $threshold ]]; then
11169                 echo "ok"
11170                 echo "Don't need to fill OST$MINI"
11171         else
11172                 # generate uneven OSTs. Write 2% over the QOS threshold value
11173                 echo "no"
11174                 DIFF=$((threshold - DIFF2 + 2))
11175                 DIFF2=$((MINV * DIFF / 100))
11176                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11177                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11178                         error "setstripe failed"
11179                 DIFF=$((DIFF2 / 2048))
11180                 i=0
11181                 while [ $i -lt $DIFF ]; do
11182                         i=$((i + 1))
11183                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11184                                 bs=2M count=1 2>/dev/null
11185                         echo -n .
11186                 done
11187                 echo .
11188                 sync
11189                 sleep_maxage
11190                 free_min_max
11191         fi
11192
11193         DIFF=$((MAXV - MINV))
11194         DIFF2=$((DIFF * 100 / MINV))
11195         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11196         if [ $DIFF2 -gt $threshold ]; then
11197                 echo "ok"
11198         else
11199                 echo "failed - QOS mode won't be used"
11200                 simple_cleanup_common
11201                 skip "QOS imbalance criteria not met"
11202         fi
11203
11204         MINI1=$MINI
11205         MINV1=$MINV
11206         MAXI1=$MAXI
11207         MAXV1=$MAXV
11208
11209         # now fill using QOS
11210         $LFS setstripe -c 1 $DIR/$tdir
11211         FILL=$((FILL / 200))
11212         if [ $FILL -gt 600 ]; then
11213                 FILL=600
11214         fi
11215         echo "writing $FILL files to QOS-assigned OSTs"
11216         i=0
11217         while [ $i -lt $FILL ]; do
11218                 i=$((i + 1))
11219                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11220                         count=1 2>/dev/null
11221                 echo -n .
11222         done
11223         echo "wrote $i 200k files"
11224         sync
11225         sleep_maxage
11226
11227         echo "Note: free space may not be updated, so measurements might be off"
11228         free_min_max
11229         DIFF2=$((MAXV - MINV))
11230         echo "free space delta: orig $DIFF final $DIFF2"
11231         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11232         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11233         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11234         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11235         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11236         if [[ $DIFF -gt 0 ]]; then
11237                 FILL=$((DIFF2 * 100 / DIFF - 100))
11238                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11239         fi
11240
11241         # Figure out which files were written where
11242         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11243                awk '/'$MINI1': / {print $2; exit}')
11244         echo $UUID
11245         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11246         echo "$MINC files created on smaller OST $MINI1"
11247         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11248                awk '/'$MAXI1': / {print $2; exit}')
11249         echo $UUID
11250         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11251         echo "$MAXC files created on larger OST $MAXI1"
11252         if [[ $MINC -gt 0 ]]; then
11253                 FILL=$((MAXC * 100 / MINC - 100))
11254                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11255         fi
11256         [[ $MAXC -gt $MINC ]] ||
11257                 error_ignore LU-9 "stripe QOS didn't balance free space"
11258         simple_cleanup_common
11259 }
11260 run_test 116a "stripe QOS: free space balance ==================="
11261
11262 test_116b() { # LU-2093
11263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11264         remote_mds_nodsh && skip "remote MDS with nodsh"
11265
11266 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11267         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11268                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11269         [ -z "$old_rr" ] && skip "no QOS"
11270         do_facet $SINGLEMDS lctl set_param \
11271                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11272         mkdir -p $DIR/$tdir
11273         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11274         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11275         do_facet $SINGLEMDS lctl set_param fail_loc=0
11276         rm -rf $DIR/$tdir
11277         do_facet $SINGLEMDS lctl set_param \
11278                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11279 }
11280 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11281
11282 test_117() # bug 10891
11283 {
11284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11285
11286         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11287         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11288         lctl set_param fail_loc=0x21e
11289         > $DIR/$tfile || error "truncate failed"
11290         lctl set_param fail_loc=0
11291         echo "Truncate succeeded."
11292         rm -f $DIR/$tfile
11293 }
11294 run_test 117 "verify osd extend =========="
11295
11296 NO_SLOW_RESENDCOUNT=4
11297 export OLD_RESENDCOUNT=""
11298 set_resend_count () {
11299         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11300         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11301         lctl set_param -n $PROC_RESENDCOUNT $1
11302         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11303 }
11304
11305 # for reduce test_118* time (b=14842)
11306 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11307
11308 # Reset async IO behavior after error case
11309 reset_async() {
11310         FILE=$DIR/reset_async
11311
11312         # Ensure all OSCs are cleared
11313         $LFS setstripe -c -1 $FILE
11314         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11315         sync
11316         rm $FILE
11317 }
11318
11319 test_118a() #bug 11710
11320 {
11321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11322
11323         reset_async
11324
11325         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11326         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11327         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11328
11329         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11330                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11331                 return 1;
11332         fi
11333         rm -f $DIR/$tfile
11334 }
11335 run_test 118a "verify O_SYNC works =========="
11336
11337 test_118b()
11338 {
11339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11340         remote_ost_nodsh && skip "remote OST with nodsh"
11341
11342         reset_async
11343
11344         #define OBD_FAIL_SRV_ENOENT 0x217
11345         set_nodes_failloc "$(osts_nodes)" 0x217
11346         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11347         RC=$?
11348         set_nodes_failloc "$(osts_nodes)" 0
11349         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11350         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11351                     grep -c writeback)
11352
11353         if [[ $RC -eq 0 ]]; then
11354                 error "Must return error due to dropped pages, rc=$RC"
11355                 return 1;
11356         fi
11357
11358         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11359                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11360                 return 1;
11361         fi
11362
11363         echo "Dirty pages not leaked on ENOENT"
11364
11365         # Due to the above error the OSC will issue all RPCs syncronously
11366         # until a subsequent RPC completes successfully without error.
11367         $MULTIOP $DIR/$tfile Ow4096yc
11368         rm -f $DIR/$tfile
11369
11370         return 0
11371 }
11372 run_test 118b "Reclaim dirty pages on fatal error =========="
11373
11374 test_118c()
11375 {
11376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11377
11378         # for 118c, restore the original resend count, LU-1940
11379         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11380                                 set_resend_count $OLD_RESENDCOUNT
11381         remote_ost_nodsh && skip "remote OST with nodsh"
11382
11383         reset_async
11384
11385         #define OBD_FAIL_OST_EROFS               0x216
11386         set_nodes_failloc "$(osts_nodes)" 0x216
11387
11388         # multiop should block due to fsync until pages are written
11389         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11390         MULTIPID=$!
11391         sleep 1
11392
11393         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11394                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11395         fi
11396
11397         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11398                     grep -c writeback)
11399         if [[ $WRITEBACK -eq 0 ]]; then
11400                 error "No page in writeback, writeback=$WRITEBACK"
11401         fi
11402
11403         set_nodes_failloc "$(osts_nodes)" 0
11404         wait $MULTIPID
11405         RC=$?
11406         if [[ $RC -ne 0 ]]; then
11407                 error "Multiop fsync failed, rc=$RC"
11408         fi
11409
11410         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11411         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11412                     grep -c writeback)
11413         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11414                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11415         fi
11416
11417         rm -f $DIR/$tfile
11418         echo "Dirty pages flushed via fsync on EROFS"
11419         return 0
11420 }
11421 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11422
11423 # continue to use small resend count to reduce test_118* time (b=14842)
11424 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11425
11426 test_118d()
11427 {
11428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11429         remote_ost_nodsh && skip "remote OST with nodsh"
11430
11431         reset_async
11432
11433         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11434         set_nodes_failloc "$(osts_nodes)" 0x214
11435         # multiop should block due to fsync until pages are written
11436         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11437         MULTIPID=$!
11438         sleep 1
11439
11440         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11441                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11442         fi
11443
11444         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11445                     grep -c writeback)
11446         if [[ $WRITEBACK -eq 0 ]]; then
11447                 error "No page in writeback, writeback=$WRITEBACK"
11448         fi
11449
11450         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11451         set_nodes_failloc "$(osts_nodes)" 0
11452
11453         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11454         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11455                     grep -c writeback)
11456         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11457                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11458         fi
11459
11460         rm -f $DIR/$tfile
11461         echo "Dirty pages gaurenteed flushed via fsync"
11462         return 0
11463 }
11464 run_test 118d "Fsync validation inject a delay of the bulk =========="
11465
11466 test_118f() {
11467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11468
11469         reset_async
11470
11471         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11472         lctl set_param fail_loc=0x8000040a
11473
11474         # Should simulate EINVAL error which is fatal
11475         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11476         RC=$?
11477         if [[ $RC -eq 0 ]]; then
11478                 error "Must return error due to dropped pages, rc=$RC"
11479         fi
11480
11481         lctl set_param fail_loc=0x0
11482
11483         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11484         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11485         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11486                     grep -c writeback)
11487         if [[ $LOCKED -ne 0 ]]; then
11488                 error "Locked pages remain in cache, locked=$LOCKED"
11489         fi
11490
11491         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11492                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11493         fi
11494
11495         rm -f $DIR/$tfile
11496         echo "No pages locked after fsync"
11497
11498         reset_async
11499         return 0
11500 }
11501 run_test 118f "Simulate unrecoverable OSC side error =========="
11502
11503 test_118g() {
11504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11505
11506         reset_async
11507
11508         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11509         lctl set_param fail_loc=0x406
11510
11511         # simulate local -ENOMEM
11512         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11513         RC=$?
11514
11515         lctl set_param fail_loc=0
11516         if [[ $RC -eq 0 ]]; then
11517                 error "Must return error due to dropped pages, rc=$RC"
11518         fi
11519
11520         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11521         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11522         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11523                         grep -c writeback)
11524         if [[ $LOCKED -ne 0 ]]; then
11525                 error "Locked pages remain in cache, locked=$LOCKED"
11526         fi
11527
11528         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11529                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11530         fi
11531
11532         rm -f $DIR/$tfile
11533         echo "No pages locked after fsync"
11534
11535         reset_async
11536         return 0
11537 }
11538 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11539
11540 test_118h() {
11541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11542         remote_ost_nodsh && skip "remote OST with nodsh"
11543
11544         reset_async
11545
11546         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11547         set_nodes_failloc "$(osts_nodes)" 0x20e
11548         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11549         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11550         RC=$?
11551
11552         set_nodes_failloc "$(osts_nodes)" 0
11553         if [[ $RC -eq 0 ]]; then
11554                 error "Must return error due to dropped pages, rc=$RC"
11555         fi
11556
11557         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11558         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11559         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11560                     grep -c writeback)
11561         if [[ $LOCKED -ne 0 ]]; then
11562                 error "Locked pages remain in cache, locked=$LOCKED"
11563         fi
11564
11565         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11566                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11567         fi
11568
11569         rm -f $DIR/$tfile
11570         echo "No pages locked after fsync"
11571
11572         return 0
11573 }
11574 run_test 118h "Verify timeout in handling recoverables errors  =========="
11575
11576 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11577
11578 test_118i() {
11579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11580         remote_ost_nodsh && skip "remote OST with nodsh"
11581
11582         reset_async
11583
11584         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11585         set_nodes_failloc "$(osts_nodes)" 0x20e
11586
11587         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11588         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11589         PID=$!
11590         sleep 5
11591         set_nodes_failloc "$(osts_nodes)" 0
11592
11593         wait $PID
11594         RC=$?
11595         if [[ $RC -ne 0 ]]; then
11596                 error "got error, but should be not, rc=$RC"
11597         fi
11598
11599         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11600         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11601         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11602         if [[ $LOCKED -ne 0 ]]; then
11603                 error "Locked pages remain in cache, locked=$LOCKED"
11604         fi
11605
11606         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11607                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11608         fi
11609
11610         rm -f $DIR/$tfile
11611         echo "No pages locked after fsync"
11612
11613         return 0
11614 }
11615 run_test 118i "Fix error before timeout in recoverable error  =========="
11616
11617 [ "$SLOW" = "no" ] && set_resend_count 4
11618
11619 test_118j() {
11620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11621         remote_ost_nodsh && skip "remote OST with nodsh"
11622
11623         reset_async
11624
11625         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11626         set_nodes_failloc "$(osts_nodes)" 0x220
11627
11628         # return -EIO from OST
11629         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11630         RC=$?
11631         set_nodes_failloc "$(osts_nodes)" 0x0
11632         if [[ $RC -eq 0 ]]; then
11633                 error "Must return error due to dropped pages, rc=$RC"
11634         fi
11635
11636         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11637         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11638         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11639         if [[ $LOCKED -ne 0 ]]; then
11640                 error "Locked pages remain in cache, locked=$LOCKED"
11641         fi
11642
11643         # in recoverable error on OST we want resend and stay until it finished
11644         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11645                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11646         fi
11647
11648         rm -f $DIR/$tfile
11649         echo "No pages locked after fsync"
11650
11651         return 0
11652 }
11653 run_test 118j "Simulate unrecoverable OST side error =========="
11654
11655 test_118k()
11656 {
11657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11658         remote_ost_nodsh && skip "remote OSTs with nodsh"
11659
11660         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11661         set_nodes_failloc "$(osts_nodes)" 0x20e
11662         test_mkdir $DIR/$tdir
11663
11664         for ((i=0;i<10;i++)); do
11665                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11666                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11667                 SLEEPPID=$!
11668                 sleep 0.500s
11669                 kill $SLEEPPID
11670                 wait $SLEEPPID
11671         done
11672
11673         set_nodes_failloc "$(osts_nodes)" 0
11674         rm -rf $DIR/$tdir
11675 }
11676 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11677
11678 test_118l() # LU-646
11679 {
11680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11681
11682         test_mkdir $DIR/$tdir
11683         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11684         rm -rf $DIR/$tdir
11685 }
11686 run_test 118l "fsync dir"
11687
11688 test_118m() # LU-3066
11689 {
11690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11691
11692         test_mkdir $DIR/$tdir
11693         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11694         rm -rf $DIR/$tdir
11695 }
11696 run_test 118m "fdatasync dir ========="
11697
11698 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11699
11700 test_118n()
11701 {
11702         local begin
11703         local end
11704
11705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11706         remote_ost_nodsh && skip "remote OSTs with nodsh"
11707
11708         # Sleep to avoid a cached response.
11709         #define OBD_STATFS_CACHE_SECONDS 1
11710         sleep 2
11711
11712         # Inject a 10 second delay in the OST_STATFS handler.
11713         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11714         set_nodes_failloc "$(osts_nodes)" 0x242
11715
11716         begin=$SECONDS
11717         stat --file-system $MOUNT > /dev/null
11718         end=$SECONDS
11719
11720         set_nodes_failloc "$(osts_nodes)" 0
11721
11722         if ((end - begin > 20)); then
11723             error "statfs took $((end - begin)) seconds, expected 10"
11724         fi
11725 }
11726 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11727
11728 test_119a() # bug 11737
11729 {
11730         BSIZE=$((512 * 1024))
11731         directio write $DIR/$tfile 0 1 $BSIZE
11732         # We ask to read two blocks, which is more than a file size.
11733         # directio will indicate an error when requested and actual
11734         # sizes aren't equeal (a normal situation in this case) and
11735         # print actual read amount.
11736         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11737         if [ "$NOB" != "$BSIZE" ]; then
11738                 error "read $NOB bytes instead of $BSIZE"
11739         fi
11740         rm -f $DIR/$tfile
11741 }
11742 run_test 119a "Short directIO read must return actual read amount"
11743
11744 test_119b() # bug 11737
11745 {
11746         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11747
11748         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11749         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11750         sync
11751         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11752                 error "direct read failed"
11753         rm -f $DIR/$tfile
11754 }
11755 run_test 119b "Sparse directIO read must return actual read amount"
11756
11757 test_119c() # bug 13099
11758 {
11759         BSIZE=1048576
11760         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11761         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11762         rm -f $DIR/$tfile
11763 }
11764 run_test 119c "Testing for direct read hitting hole"
11765
11766 test_119d() # bug 15950
11767 {
11768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11769
11770         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11771         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11772         BSIZE=1048576
11773         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11774         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11775         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11776         lctl set_param fail_loc=0x40d
11777         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11778         pid_dio=$!
11779         sleep 1
11780         cat $DIR/$tfile > /dev/null &
11781         lctl set_param fail_loc=0
11782         pid_reads=$!
11783         wait $pid_dio
11784         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11785         sleep 2
11786         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11787         error "the read rpcs have not completed in 2s"
11788         rm -f $DIR/$tfile
11789         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11790 }
11791 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11792
11793 test_120a() {
11794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11795         remote_mds_nodsh && skip "remote MDS with nodsh"
11796         test_mkdir -i0 -c1 $DIR/$tdir
11797         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11798                 skip_env "no early lock cancel on server"
11799
11800         lru_resize_disable mdc
11801         lru_resize_disable osc
11802         cancel_lru_locks mdc
11803         # asynchronous object destroy at MDT could cause bl ast to client
11804         cancel_lru_locks osc
11805
11806         stat $DIR/$tdir > /dev/null
11807         can1=$(do_facet mds1 \
11808                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11809                awk '/ldlm_cancel/ {print $2}')
11810         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11811                awk '/ldlm_bl_callback/ {print $2}')
11812         test_mkdir -i0 -c1 $DIR/$tdir/d1
11813         can2=$(do_facet mds1 \
11814                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11815                awk '/ldlm_cancel/ {print $2}')
11816         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11817                awk '/ldlm_bl_callback/ {print $2}')
11818         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11819         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11820         lru_resize_enable mdc
11821         lru_resize_enable osc
11822 }
11823 run_test 120a "Early Lock Cancel: mkdir test"
11824
11825 test_120b() {
11826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11827         remote_mds_nodsh && skip "remote MDS with nodsh"
11828         test_mkdir $DIR/$tdir
11829         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11830                 skip_env "no early lock cancel on server"
11831
11832         lru_resize_disable mdc
11833         lru_resize_disable osc
11834         cancel_lru_locks mdc
11835         stat $DIR/$tdir > /dev/null
11836         can1=$(do_facet $SINGLEMDS \
11837                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11838                awk '/ldlm_cancel/ {print $2}')
11839         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11840                awk '/ldlm_bl_callback/ {print $2}')
11841         touch $DIR/$tdir/f1
11842         can2=$(do_facet $SINGLEMDS \
11843                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11844                awk '/ldlm_cancel/ {print $2}')
11845         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11846                awk '/ldlm_bl_callback/ {print $2}')
11847         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11848         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11849         lru_resize_enable mdc
11850         lru_resize_enable osc
11851 }
11852 run_test 120b "Early Lock Cancel: create test"
11853
11854 test_120c() {
11855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11856         remote_mds_nodsh && skip "remote MDS with nodsh"
11857         test_mkdir -i0 -c1 $DIR/$tdir
11858         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11859                 skip "no early lock cancel on server"
11860
11861         lru_resize_disable mdc
11862         lru_resize_disable osc
11863         test_mkdir -i0 -c1 $DIR/$tdir/d1
11864         test_mkdir -i0 -c1 $DIR/$tdir/d2
11865         touch $DIR/$tdir/d1/f1
11866         cancel_lru_locks mdc
11867         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11868         can1=$(do_facet mds1 \
11869                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11870                awk '/ldlm_cancel/ {print $2}')
11871         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11872                awk '/ldlm_bl_callback/ {print $2}')
11873         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11874         can2=$(do_facet mds1 \
11875                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11876                awk '/ldlm_cancel/ {print $2}')
11877         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11878                awk '/ldlm_bl_callback/ {print $2}')
11879         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11880         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11881         lru_resize_enable mdc
11882         lru_resize_enable osc
11883 }
11884 run_test 120c "Early Lock Cancel: link test"
11885
11886 test_120d() {
11887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11888         remote_mds_nodsh && skip "remote MDS with nodsh"
11889         test_mkdir -i0 -c1 $DIR/$tdir
11890         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11891                 skip_env "no early lock cancel on server"
11892
11893         lru_resize_disable mdc
11894         lru_resize_disable osc
11895         touch $DIR/$tdir
11896         cancel_lru_locks mdc
11897         stat $DIR/$tdir > /dev/null
11898         can1=$(do_facet mds1 \
11899                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11900                awk '/ldlm_cancel/ {print $2}')
11901         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11902                awk '/ldlm_bl_callback/ {print $2}')
11903         chmod a+x $DIR/$tdir
11904         can2=$(do_facet mds1 \
11905                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11906                awk '/ldlm_cancel/ {print $2}')
11907         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11908                awk '/ldlm_bl_callback/ {print $2}')
11909         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11910         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11911         lru_resize_enable mdc
11912         lru_resize_enable osc
11913 }
11914 run_test 120d "Early Lock Cancel: setattr test"
11915
11916 test_120e() {
11917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11918         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11919                 skip_env "no early lock cancel on server"
11920         remote_mds_nodsh && skip "remote MDS with nodsh"
11921
11922         local dlmtrace_set=false
11923
11924         test_mkdir -i0 -c1 $DIR/$tdir
11925         lru_resize_disable mdc
11926         lru_resize_disable osc
11927         ! $LCTL get_param debug | grep -q dlmtrace &&
11928                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11929         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11930         cancel_lru_locks mdc
11931         cancel_lru_locks osc
11932         dd if=$DIR/$tdir/f1 of=/dev/null
11933         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11934         # XXX client can not do early lock cancel of OST lock
11935         # during unlink (LU-4206), so cancel osc lock now.
11936         sleep 2
11937         cancel_lru_locks osc
11938         can1=$(do_facet mds1 \
11939                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11940                awk '/ldlm_cancel/ {print $2}')
11941         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11942                awk '/ldlm_bl_callback/ {print $2}')
11943         unlink $DIR/$tdir/f1
11944         sleep 5
11945         can2=$(do_facet mds1 \
11946                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11947                awk '/ldlm_cancel/ {print $2}')
11948         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11949                awk '/ldlm_bl_callback/ {print $2}')
11950         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11951                 $LCTL dk $TMP/cancel.debug.txt
11952         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11953                 $LCTL dk $TMP/blocking.debug.txt
11954         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11955         lru_resize_enable mdc
11956         lru_resize_enable osc
11957 }
11958 run_test 120e "Early Lock Cancel: unlink test"
11959
11960 test_120f() {
11961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11962         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11963                 skip_env "no early lock cancel on server"
11964         remote_mds_nodsh && skip "remote MDS with nodsh"
11965
11966         test_mkdir -i0 -c1 $DIR/$tdir
11967         lru_resize_disable mdc
11968         lru_resize_disable osc
11969         test_mkdir -i0 -c1 $DIR/$tdir/d1
11970         test_mkdir -i0 -c1 $DIR/$tdir/d2
11971         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11972         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11973         cancel_lru_locks mdc
11974         cancel_lru_locks osc
11975         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11976         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11977         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11978         # XXX client can not do early lock cancel of OST lock
11979         # during rename (LU-4206), so cancel osc lock now.
11980         sleep 2
11981         cancel_lru_locks osc
11982         can1=$(do_facet mds1 \
11983                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11984                awk '/ldlm_cancel/ {print $2}')
11985         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11986                awk '/ldlm_bl_callback/ {print $2}')
11987         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11988         sleep 5
11989         can2=$(do_facet mds1 \
11990                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11991                awk '/ldlm_cancel/ {print $2}')
11992         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11993                awk '/ldlm_bl_callback/ {print $2}')
11994         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11995         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11996         lru_resize_enable mdc
11997         lru_resize_enable osc
11998 }
11999 run_test 120f "Early Lock Cancel: rename test"
12000
12001 test_120g() {
12002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12003         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12004                 skip_env "no early lock cancel on server"
12005         remote_mds_nodsh && skip "remote MDS with nodsh"
12006
12007         lru_resize_disable mdc
12008         lru_resize_disable osc
12009         count=10000
12010         echo create $count files
12011         test_mkdir $DIR/$tdir
12012         cancel_lru_locks mdc
12013         cancel_lru_locks osc
12014         t0=$(date +%s)
12015
12016         can0=$(do_facet $SINGLEMDS \
12017                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12018                awk '/ldlm_cancel/ {print $2}')
12019         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12020                awk '/ldlm_bl_callback/ {print $2}')
12021         createmany -o $DIR/$tdir/f $count
12022         sync
12023         can1=$(do_facet $SINGLEMDS \
12024                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12025                awk '/ldlm_cancel/ {print $2}')
12026         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12027                awk '/ldlm_bl_callback/ {print $2}')
12028         t1=$(date +%s)
12029         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12030         echo rm $count files
12031         rm -r $DIR/$tdir
12032         sync
12033         can2=$(do_facet $SINGLEMDS \
12034                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12035                awk '/ldlm_cancel/ {print $2}')
12036         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12037                awk '/ldlm_bl_callback/ {print $2}')
12038         t2=$(date +%s)
12039         echo total: $count removes in $((t2-t1))
12040         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12041         sleep 2
12042         # wait for commitment of removal
12043         lru_resize_enable mdc
12044         lru_resize_enable osc
12045 }
12046 run_test 120g "Early Lock Cancel: performance test"
12047
12048 test_121() { #bug #10589
12049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12050
12051         rm -rf $DIR/$tfile
12052         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12053 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12054         lctl set_param fail_loc=0x310
12055         cancel_lru_locks osc > /dev/null
12056         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12057         lctl set_param fail_loc=0
12058         [[ $reads -eq $writes ]] ||
12059                 error "read $reads blocks, must be $writes blocks"
12060 }
12061 run_test 121 "read cancel race ========="
12062
12063 test_123a_base() { # was test 123, statahead(bug 11401)
12064         local lsx="$1"
12065
12066         SLOWOK=0
12067         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12068                 log "testing UP system. Performance may be lower than expected."
12069                 SLOWOK=1
12070         fi
12071
12072         rm -rf $DIR/$tdir
12073         test_mkdir $DIR/$tdir
12074         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12075         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12076         MULT=10
12077         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12078                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12079
12080                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12081                 lctl set_param -n llite.*.statahead_max 0
12082                 lctl get_param llite.*.statahead_max
12083                 cancel_lru_locks mdc
12084                 cancel_lru_locks osc
12085                 stime=$(date +%s)
12086                 time $lsx $DIR/$tdir | wc -l
12087                 etime=$(date +%s)
12088                 delta=$((etime - stime))
12089                 log "$lsx $i files without statahead: $delta sec"
12090                 lctl set_param llite.*.statahead_max=$max
12091
12092                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12093                         grep "statahead wrong:" | awk '{print $3}')
12094                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12095                 cancel_lru_locks mdc
12096                 cancel_lru_locks osc
12097                 stime=$(date +%s)
12098                 time $lsx $DIR/$tdir | wc -l
12099                 etime=$(date +%s)
12100                 delta_sa=$((etime - stime))
12101                 log "$lsx $i files with statahead: $delta_sa sec"
12102                 lctl get_param -n llite.*.statahead_stats
12103                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12104                         grep "statahead wrong:" | awk '{print $3}')
12105
12106                 [[ $swrong -lt $ewrong ]] &&
12107                         log "statahead was stopped, maybe too many locks held!"
12108                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12109
12110                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12111                         max=$(lctl get_param -n llite.*.statahead_max |
12112                                 head -n 1)
12113                         lctl set_param -n llite.*.statahead_max 0
12114                         lctl get_param llite.*.statahead_max
12115                         cancel_lru_locks mdc
12116                         cancel_lru_locks osc
12117                         stime=$(date +%s)
12118                         time $lsx $DIR/$tdir | wc -l
12119                         etime=$(date +%s)
12120                         delta=$((etime - stime))
12121                         log "$lsx $i files again without statahead: $delta sec"
12122                         lctl set_param llite.*.statahead_max=$max
12123                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12124                                 if [  $SLOWOK -eq 0 ]; then
12125                                         error "$lsx $i files is slower with statahead!"
12126                                 else
12127                                         log "$lsx $i files is slower with statahead!"
12128                                 fi
12129                                 break
12130                         fi
12131                 fi
12132
12133                 [ $delta -gt 20 ] && break
12134                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12135                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12136         done
12137         log "$lsx done"
12138
12139         stime=$(date +%s)
12140         rm -r $DIR/$tdir
12141         sync
12142         etime=$(date +%s)
12143         delta=$((etime - stime))
12144         log "rm -r $DIR/$tdir/: $delta seconds"
12145         log "rm done"
12146         lctl get_param -n llite.*.statahead_stats
12147 }
12148
12149 test_123aa() {
12150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12151
12152         test_123a_base "ls -l"
12153 }
12154 run_test 123aa "verify statahead work"
12155
12156 test_123ab() {
12157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12158
12159         statx_supported || skip_env "Test must be statx() syscall supported"
12160
12161         test_123a_base "$STATX -l"
12162 }
12163 run_test 123ab "verify statahead work by using statx"
12164
12165 test_123ac() {
12166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12167
12168         statx_supported || skip_env "Test must be statx() syscall supported"
12169
12170         local rpcs_before
12171         local rpcs_after
12172         local agl_before
12173         local agl_after
12174
12175         cancel_lru_locks $OSC
12176         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12177         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12178                 awk '/agl.total:/ {print $3}')
12179         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12180         test_123a_base "$STATX --cached=always -D"
12181         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12182                 awk '/agl.total:/ {print $3}')
12183         [ $agl_before -eq $agl_after ] ||
12184                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12185         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12186         [ $rpcs_after -eq $rpcs_before ] ||
12187                 error "$STATX should not send glimpse RPCs to $OSC"
12188 }
12189 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12190
12191 test_123b () { # statahead(bug 15027)
12192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12193
12194         test_mkdir $DIR/$tdir
12195         createmany -o $DIR/$tdir/$tfile-%d 1000
12196
12197         cancel_lru_locks mdc
12198         cancel_lru_locks osc
12199
12200 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12201         lctl set_param fail_loc=0x80000803
12202         ls -lR $DIR/$tdir > /dev/null
12203         log "ls done"
12204         lctl set_param fail_loc=0x0
12205         lctl get_param -n llite.*.statahead_stats
12206         rm -r $DIR/$tdir
12207         sync
12208
12209 }
12210 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12211
12212 test_123c() {
12213         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12214
12215         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12216         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12217         touch $DIR/$tdir.1/{1..3}
12218         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12219
12220         remount_client $MOUNT
12221
12222         $MULTIOP $DIR/$tdir.0 Q
12223
12224         # let statahead to complete
12225         ls -l $DIR/$tdir.0 > /dev/null
12226
12227         testid=$(echo $TESTNAME | tr '_' ' ')
12228         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12229                 error "statahead warning" || true
12230 }
12231 run_test 123c "Can not initialize inode warning on DNE statahead"
12232
12233 test_124a() {
12234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12235         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12236                 skip_env "no lru resize on server"
12237
12238         local NR=2000
12239
12240         test_mkdir $DIR/$tdir
12241
12242         log "create $NR files at $DIR/$tdir"
12243         createmany -o $DIR/$tdir/f $NR ||
12244                 error "failed to create $NR files in $DIR/$tdir"
12245
12246         cancel_lru_locks mdc
12247         ls -l $DIR/$tdir > /dev/null
12248
12249         local NSDIR=""
12250         local LRU_SIZE=0
12251         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12252                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12253                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12254                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12255                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12256                         log "NSDIR=$NSDIR"
12257                         log "NS=$(basename $NSDIR)"
12258                         break
12259                 fi
12260         done
12261
12262         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12263                 skip "Not enough cached locks created!"
12264         fi
12265         log "LRU=$LRU_SIZE"
12266
12267         local SLEEP=30
12268
12269         # We know that lru resize allows one client to hold $LIMIT locks
12270         # for 10h. After that locks begin to be killed by client.
12271         local MAX_HRS=10
12272         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12273         log "LIMIT=$LIMIT"
12274         if [ $LIMIT -lt $LRU_SIZE ]; then
12275                 skip "Limit is too small $LIMIT"
12276         fi
12277
12278         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12279         # killing locks. Some time was spent for creating locks. This means
12280         # that up to the moment of sleep finish we must have killed some of
12281         # them (10-100 locks). This depends on how fast ther were created.
12282         # Many of them were touched in almost the same moment and thus will
12283         # be killed in groups.
12284         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12285
12286         # Use $LRU_SIZE_B here to take into account real number of locks
12287         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12288         local LRU_SIZE_B=$LRU_SIZE
12289         log "LVF=$LVF"
12290         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12291         log "OLD_LVF=$OLD_LVF"
12292         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12293
12294         # Let's make sure that we really have some margin. Client checks
12295         # cached locks every 10 sec.
12296         SLEEP=$((SLEEP+20))
12297         log "Sleep ${SLEEP} sec"
12298         local SEC=0
12299         while ((SEC<$SLEEP)); do
12300                 echo -n "..."
12301                 sleep 5
12302                 SEC=$((SEC+5))
12303                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12304                 echo -n "$LRU_SIZE"
12305         done
12306         echo ""
12307         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12308         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12309
12310         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12311                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12312                 unlinkmany $DIR/$tdir/f $NR
12313                 return
12314         }
12315
12316         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12317         log "unlink $NR files at $DIR/$tdir"
12318         unlinkmany $DIR/$tdir/f $NR
12319 }
12320 run_test 124a "lru resize ======================================="
12321
12322 get_max_pool_limit()
12323 {
12324         local limit=$($LCTL get_param \
12325                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12326         local max=0
12327         for l in $limit; do
12328                 if [[ $l -gt $max ]]; then
12329                         max=$l
12330                 fi
12331         done
12332         echo $max
12333 }
12334
12335 test_124b() {
12336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12337         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12338                 skip_env "no lru resize on server"
12339
12340         LIMIT=$(get_max_pool_limit)
12341
12342         NR=$(($(default_lru_size)*20))
12343         if [[ $NR -gt $LIMIT ]]; then
12344                 log "Limit lock number by $LIMIT locks"
12345                 NR=$LIMIT
12346         fi
12347
12348         IFree=$(mdsrate_inodes_available)
12349         if [ $IFree -lt $NR ]; then
12350                 log "Limit lock number by $IFree inodes"
12351                 NR=$IFree
12352         fi
12353
12354         lru_resize_disable mdc
12355         test_mkdir -p $DIR/$tdir/disable_lru_resize
12356
12357         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12358         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12359         cancel_lru_locks mdc
12360         stime=`date +%s`
12361         PID=""
12362         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12363         PID="$PID $!"
12364         sleep 2
12365         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12366         PID="$PID $!"
12367         sleep 2
12368         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12369         PID="$PID $!"
12370         wait $PID
12371         etime=`date +%s`
12372         nolruresize_delta=$((etime-stime))
12373         log "ls -la time: $nolruresize_delta seconds"
12374         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12375         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12376
12377         lru_resize_enable mdc
12378         test_mkdir -p $DIR/$tdir/enable_lru_resize
12379
12380         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12381         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12382         cancel_lru_locks mdc
12383         stime=`date +%s`
12384         PID=""
12385         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12386         PID="$PID $!"
12387         sleep 2
12388         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12389         PID="$PID $!"
12390         sleep 2
12391         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12392         PID="$PID $!"
12393         wait $PID
12394         etime=`date +%s`
12395         lruresize_delta=$((etime-stime))
12396         log "ls -la time: $lruresize_delta seconds"
12397         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12398
12399         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12400                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12401         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12402                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12403         else
12404                 log "lru resize performs the same with no lru resize"
12405         fi
12406         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12407 }
12408 run_test 124b "lru resize (performance test) ======================="
12409
12410 test_124c() {
12411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12412         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12413                 skip_env "no lru resize on server"
12414
12415         # cache ununsed locks on client
12416         local nr=100
12417         cancel_lru_locks mdc
12418         test_mkdir $DIR/$tdir
12419         createmany -o $DIR/$tdir/f $nr ||
12420                 error "failed to create $nr files in $DIR/$tdir"
12421         ls -l $DIR/$tdir > /dev/null
12422
12423         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12424         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12425         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12426         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12427         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12428
12429         # set lru_max_age to 1 sec
12430         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12431         echo "sleep $((recalc_p * 2)) seconds..."
12432         sleep $((recalc_p * 2))
12433
12434         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12435         # restore lru_max_age
12436         $LCTL set_param -n $nsdir.lru_max_age $max_age
12437         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12438         unlinkmany $DIR/$tdir/f $nr
12439 }
12440 run_test 124c "LRUR cancel very aged locks"
12441
12442 test_124d() {
12443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12444         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12445                 skip_env "no lru resize on server"
12446
12447         # cache ununsed locks on client
12448         local nr=100
12449
12450         lru_resize_disable mdc
12451         stack_trap "lru_resize_enable mdc" EXIT
12452
12453         cancel_lru_locks mdc
12454
12455         # asynchronous object destroy at MDT could cause bl ast to client
12456         test_mkdir $DIR/$tdir
12457         createmany -o $DIR/$tdir/f $nr ||
12458                 error "failed to create $nr files in $DIR/$tdir"
12459         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12460
12461         ls -l $DIR/$tdir > /dev/null
12462
12463         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12464         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12465         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12466         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12467
12468         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12469
12470         # set lru_max_age to 1 sec
12471         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12472         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12473
12474         echo "sleep $((recalc_p * 2)) seconds..."
12475         sleep $((recalc_p * 2))
12476
12477         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12478
12479         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12480 }
12481 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12482
12483 test_125() { # 13358
12484         $LCTL get_param -n llite.*.client_type | grep -q local ||
12485                 skip "must run as local client"
12486         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12487                 skip_env "must have acl enabled"
12488         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12489
12490         test_mkdir $DIR/$tdir
12491         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12492         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12493         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12494 }
12495 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12496
12497 test_126() { # bug 12829/13455
12498         $GSS && skip_env "must run as gss disabled"
12499         $LCTL get_param -n llite.*.client_type | grep -q local ||
12500                 skip "must run as local client"
12501         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12502
12503         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12504         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12505         rm -f $DIR/$tfile
12506         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12507 }
12508 run_test 126 "check that the fsgid provided by the client is taken into account"
12509
12510 test_127a() { # bug 15521
12511         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12512         local name count samp unit min max sum sumsq
12513
12514         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12515         echo "stats before reset"
12516         $LCTL get_param osc.*.stats
12517         $LCTL set_param osc.*.stats=0
12518         local fsize=$((2048 * 1024))
12519
12520         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12521         cancel_lru_locks osc
12522         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12523
12524         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12525         stack_trap "rm -f $TMP/$tfile.tmp"
12526         while read name count samp unit min max sum sumsq; do
12527                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12528                 [ ! $min ] && error "Missing min value for $name proc entry"
12529                 eval $name=$count || error "Wrong proc format"
12530
12531                 case $name in
12532                 read_bytes|write_bytes)
12533                         [[ "$unit" =~ "bytes" ]] ||
12534                                 error "unit is not 'bytes': $unit"
12535                         (( $min >= 4096 )) || error "min is too small: $min"
12536                         (( $min <= $fsize )) || error "min is too big: $min"
12537                         (( $max >= 4096 )) || error "max is too small: $max"
12538                         (( $max <= $fsize )) || error "max is too big: $max"
12539                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12540                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12541                                 error "sumsquare is too small: $sumsq"
12542                         (( $sumsq <= $fsize * $fsize )) ||
12543                                 error "sumsquare is too big: $sumsq"
12544                         ;;
12545                 ost_read|ost_write)
12546                         [[ "$unit" =~ "usec" ]] ||
12547                                 error "unit is not 'usec': $unit"
12548                         ;;
12549                 *)      ;;
12550                 esac
12551         done < $DIR/$tfile.tmp
12552
12553         #check that we actually got some stats
12554         [ "$read_bytes" ] || error "Missing read_bytes stats"
12555         [ "$write_bytes" ] || error "Missing write_bytes stats"
12556         [ "$read_bytes" != 0 ] || error "no read done"
12557         [ "$write_bytes" != 0 ] || error "no write done"
12558 }
12559 run_test 127a "verify the client stats are sane"
12560
12561 test_127b() { # bug LU-333
12562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12563         local name count samp unit min max sum sumsq
12564
12565         echo "stats before reset"
12566         $LCTL get_param llite.*.stats
12567         $LCTL set_param llite.*.stats=0
12568
12569         # perform 2 reads and writes so MAX is different from SUM.
12570         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12571         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12572         cancel_lru_locks osc
12573         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12574         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12575
12576         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12577         stack_trap "rm -f $TMP/$tfile.tmp"
12578         while read name count samp unit min max sum sumsq; do
12579                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12580                 eval $name=$count || error "Wrong proc format"
12581
12582                 case $name in
12583                 read_bytes|write_bytes)
12584                         [[ "$unit" =~ "bytes" ]] ||
12585                                 error "unit is not 'bytes': $unit"
12586                         (( $count == 2 )) || error "count is not 2: $count"
12587                         (( $min == $PAGE_SIZE )) ||
12588                                 error "min is not $PAGE_SIZE: $min"
12589                         (( $max == $PAGE_SIZE )) ||
12590                                 error "max is not $PAGE_SIZE: $max"
12591                         (( $sum == $PAGE_SIZE * 2 )) ||
12592                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12593                         ;;
12594                 read|write)
12595                         [[ "$unit" =~ "usec" ]] ||
12596                                 error "unit is not 'usec': $unit"
12597                         ;;
12598                 *)      ;;
12599                 esac
12600         done < $TMP/$tfile.tmp
12601
12602         #check that we actually got some stats
12603         [ "$read_bytes" ] || error "Missing read_bytes stats"
12604         [ "$write_bytes" ] || error "Missing write_bytes stats"
12605         [ "$read_bytes" != 0 ] || error "no read done"
12606         [ "$write_bytes" != 0 ] || error "no write done"
12607 }
12608 run_test 127b "verify the llite client stats are sane"
12609
12610 test_127c() { # LU-12394
12611         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12612         local size
12613         local bsize
12614         local reads
12615         local writes
12616         local count
12617
12618         $LCTL set_param llite.*.extents_stats=1
12619         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12620
12621         # Use two stripes so there is enough space in default config
12622         $LFS setstripe -c 2 $DIR/$tfile
12623
12624         # Extent stats start at 0-4K and go in power of two buckets
12625         # LL_HIST_START = 12 --> 2^12 = 4K
12626         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12627         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12628         # small configs
12629         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12630                 do
12631                 # Write and read, 2x each, second time at a non-zero offset
12632                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12633                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12634                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12635                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12636                 rm -f $DIR/$tfile
12637         done
12638
12639         $LCTL get_param llite.*.extents_stats
12640
12641         count=2
12642         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12643                 do
12644                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12645                                 grep -m 1 $bsize)
12646                 reads=$(echo $bucket | awk '{print $5}')
12647                 writes=$(echo $bucket | awk '{print $9}')
12648                 [ "$reads" -eq $count ] ||
12649                         error "$reads reads in < $bsize bucket, expect $count"
12650                 [ "$writes" -eq $count ] ||
12651                         error "$writes writes in < $bsize bucket, expect $count"
12652         done
12653
12654         # Test mmap write and read
12655         $LCTL set_param llite.*.extents_stats=c
12656         size=512
12657         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12658         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12659         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12660
12661         $LCTL get_param llite.*.extents_stats
12662
12663         count=$(((size*1024) / PAGE_SIZE))
12664
12665         bsize=$((2 * PAGE_SIZE / 1024))K
12666
12667         bucket=$($LCTL get_param -n llite.*.extents_stats |
12668                         grep -m 1 $bsize)
12669         reads=$(echo $bucket | awk '{print $5}')
12670         writes=$(echo $bucket | awk '{print $9}')
12671         # mmap writes fault in the page first, creating an additonal read
12672         [ "$reads" -eq $((2 * count)) ] ||
12673                 error "$reads reads in < $bsize bucket, expect $count"
12674         [ "$writes" -eq $count ] ||
12675                 error "$writes writes in < $bsize bucket, expect $count"
12676 }
12677 run_test 127c "test llite extent stats with regular & mmap i/o"
12678
12679 test_128() { # bug 15212
12680         touch $DIR/$tfile
12681         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12682                 find $DIR/$tfile
12683                 find $DIR/$tfile
12684         EOF
12685
12686         result=$(grep error $TMP/$tfile.log)
12687         rm -f $DIR/$tfile $TMP/$tfile.log
12688         [ -z "$result" ] ||
12689                 error "consecutive find's under interactive lfs failed"
12690 }
12691 run_test 128 "interactive lfs for 2 consecutive find's"
12692
12693 set_dir_limits () {
12694         local mntdev
12695         local canondev
12696         local node
12697
12698         local ldproc=/proc/fs/ldiskfs
12699         local facets=$(get_facets MDS)
12700
12701         for facet in ${facets//,/ }; do
12702                 canondev=$(ldiskfs_canon \
12703                            *.$(convert_facet2label $facet).mntdev $facet)
12704                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12705                         ldproc=/sys/fs/ldiskfs
12706                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12707                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12708         done
12709 }
12710
12711 check_mds_dmesg() {
12712         local facets=$(get_facets MDS)
12713         for facet in ${facets//,/ }; do
12714                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12715         done
12716         return 1
12717 }
12718
12719 test_129() {
12720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12721         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12722                 skip "Need MDS version with at least 2.5.56"
12723         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12724                 skip_env "ldiskfs only test"
12725         fi
12726         remote_mds_nodsh && skip "remote MDS with nodsh"
12727
12728         local ENOSPC=28
12729         local has_warning=false
12730
12731         rm -rf $DIR/$tdir
12732         mkdir -p $DIR/$tdir
12733
12734         # block size of mds1
12735         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12736         set_dir_limits $maxsize $((maxsize * 6 / 8))
12737         stack_trap "set_dir_limits 0 0"
12738         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12739         local dirsize=$(stat -c%s "$DIR/$tdir")
12740         local nfiles=0
12741         while (( $dirsize <= $maxsize )); do
12742                 $MCREATE $DIR/$tdir/file_base_$nfiles
12743                 rc=$?
12744                 # check two errors:
12745                 # ENOSPC for ext4 max_dir_size, which has been used since
12746                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12747                 if (( rc == ENOSPC )); then
12748                         set_dir_limits 0 0
12749                         echo "rc=$rc returned as expected after $nfiles files"
12750
12751                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12752                                 error "create failed w/o dir size limit"
12753
12754                         # messages may be rate limited if test is run repeatedly
12755                         check_mds_dmesg '"is approaching max"' ||
12756                                 echo "warning message should be output"
12757                         check_mds_dmesg '"has reached max"' ||
12758                                 echo "reached message should be output"
12759
12760                         dirsize=$(stat -c%s "$DIR/$tdir")
12761
12762                         [[ $dirsize -ge $maxsize ]] && return 0
12763                         error "dirsize $dirsize < $maxsize after $nfiles files"
12764                 elif (( rc != 0 )); then
12765                         break
12766                 fi
12767                 nfiles=$((nfiles + 1))
12768                 dirsize=$(stat -c%s "$DIR/$tdir")
12769         done
12770
12771         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12772 }
12773 run_test 129 "test directory size limit ========================"
12774
12775 OLDIFS="$IFS"
12776 cleanup_130() {
12777         trap 0
12778         IFS="$OLDIFS"
12779 }
12780
12781 test_130a() {
12782         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12783         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12784
12785         trap cleanup_130 EXIT RETURN
12786
12787         local fm_file=$DIR/$tfile
12788         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12789         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12790                 error "dd failed for $fm_file"
12791
12792         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12793         filefrag -ves $fm_file
12794         RC=$?
12795         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12796                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12797         [ $RC != 0 ] && error "filefrag $fm_file failed"
12798
12799         filefrag_op=$(filefrag -ve -k $fm_file |
12800                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12801         lun=$($LFS getstripe -i $fm_file)
12802
12803         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12804         IFS=$'\n'
12805         tot_len=0
12806         for line in $filefrag_op
12807         do
12808                 frag_lun=`echo $line | cut -d: -f5`
12809                 ext_len=`echo $line | cut -d: -f4`
12810                 if (( $frag_lun != $lun )); then
12811                         cleanup_130
12812                         error "FIEMAP on 1-stripe file($fm_file) failed"
12813                         return
12814                 fi
12815                 (( tot_len += ext_len ))
12816         done
12817
12818         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12819                 cleanup_130
12820                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12821                 return
12822         fi
12823
12824         cleanup_130
12825
12826         echo "FIEMAP on single striped file succeeded"
12827 }
12828 run_test 130a "FIEMAP (1-stripe file)"
12829
12830 test_130b() {
12831         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12832
12833         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12834         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12835
12836         trap cleanup_130 EXIT RETURN
12837
12838         local fm_file=$DIR/$tfile
12839         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12840                         error "setstripe on $fm_file"
12841         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12842                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12843
12844         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12845                 error "dd failed on $fm_file"
12846
12847         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12848         filefrag_op=$(filefrag -ve -k $fm_file |
12849                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12850
12851         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12852                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12853
12854         IFS=$'\n'
12855         tot_len=0
12856         num_luns=1
12857         for line in $filefrag_op
12858         do
12859                 frag_lun=$(echo $line | cut -d: -f5 |
12860                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12861                 ext_len=$(echo $line | cut -d: -f4)
12862                 if (( $frag_lun != $last_lun )); then
12863                         if (( tot_len != 1024 )); then
12864                                 cleanup_130
12865                                 error "FIEMAP on $fm_file failed; returned " \
12866                                 "len $tot_len for OST $last_lun instead of 1024"
12867                                 return
12868                         else
12869                                 (( num_luns += 1 ))
12870                                 tot_len=0
12871                         fi
12872                 fi
12873                 (( tot_len += ext_len ))
12874                 last_lun=$frag_lun
12875         done
12876         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12877                 cleanup_130
12878                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12879                         "luns or wrong len for OST $last_lun"
12880                 return
12881         fi
12882
12883         cleanup_130
12884
12885         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12886 }
12887 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12888
12889 test_130c() {
12890         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12891
12892         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12893         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12894
12895         trap cleanup_130 EXIT RETURN
12896
12897         local fm_file=$DIR/$tfile
12898         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12899         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12900                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12901
12902         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12903                         error "dd failed on $fm_file"
12904
12905         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12906         filefrag_op=$(filefrag -ve -k $fm_file |
12907                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12908
12909         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12910                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12911
12912         IFS=$'\n'
12913         tot_len=0
12914         num_luns=1
12915         for line in $filefrag_op
12916         do
12917                 frag_lun=$(echo $line | cut -d: -f5 |
12918                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12919                 ext_len=$(echo $line | cut -d: -f4)
12920                 if (( $frag_lun != $last_lun )); then
12921                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12922                         if (( logical != 512 )); then
12923                                 cleanup_130
12924                                 error "FIEMAP on $fm_file failed; returned " \
12925                                 "logical start for lun $logical instead of 512"
12926                                 return
12927                         fi
12928                         if (( tot_len != 512 )); then
12929                                 cleanup_130
12930                                 error "FIEMAP on $fm_file failed; returned " \
12931                                 "len $tot_len for OST $last_lun instead of 1024"
12932                                 return
12933                         else
12934                                 (( num_luns += 1 ))
12935                                 tot_len=0
12936                         fi
12937                 fi
12938                 (( tot_len += ext_len ))
12939                 last_lun=$frag_lun
12940         done
12941         if (( num_luns != 2 || tot_len != 512 )); then
12942                 cleanup_130
12943                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12944                         "luns or wrong len for OST $last_lun"
12945                 return
12946         fi
12947
12948         cleanup_130
12949
12950         echo "FIEMAP on 2-stripe file with hole succeeded"
12951 }
12952 run_test 130c "FIEMAP (2-stripe file with hole)"
12953
12954 test_130d() {
12955         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12956
12957         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12958         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12959
12960         trap cleanup_130 EXIT RETURN
12961
12962         local fm_file=$DIR/$tfile
12963         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12964                         error "setstripe on $fm_file"
12965         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12966                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12967
12968         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12969         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12970                 error "dd failed on $fm_file"
12971
12972         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12973         filefrag_op=$(filefrag -ve -k $fm_file |
12974                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12975
12976         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12977                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12978
12979         IFS=$'\n'
12980         tot_len=0
12981         num_luns=1
12982         for line in $filefrag_op
12983         do
12984                 frag_lun=$(echo $line | cut -d: -f5 |
12985                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12986                 ext_len=$(echo $line | cut -d: -f4)
12987                 if (( $frag_lun != $last_lun )); then
12988                         if (( tot_len != 1024 )); then
12989                                 cleanup_130
12990                                 error "FIEMAP on $fm_file failed; returned " \
12991                                 "len $tot_len for OST $last_lun instead of 1024"
12992                                 return
12993                         else
12994                                 (( num_luns += 1 ))
12995                                 tot_len=0
12996                         fi
12997                 fi
12998                 (( tot_len += ext_len ))
12999                 last_lun=$frag_lun
13000         done
13001         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13002                 cleanup_130
13003                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13004                         "luns or wrong len for OST $last_lun"
13005                 return
13006         fi
13007
13008         cleanup_130
13009
13010         echo "FIEMAP on N-stripe file succeeded"
13011 }
13012 run_test 130d "FIEMAP (N-stripe file)"
13013
13014 test_130e() {
13015         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13016
13017         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13018         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13019
13020         trap cleanup_130 EXIT RETURN
13021
13022         local fm_file=$DIR/$tfile
13023         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13024
13025         NUM_BLKS=512
13026         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13027         for ((i = 0; i < $NUM_BLKS; i++)); do
13028                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13029                         conv=notrunc > /dev/null 2>&1
13030         done
13031
13032         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13033         filefrag_op=$(filefrag -ve -k $fm_file |
13034                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13035
13036         last_lun=$(echo $filefrag_op | cut -d: -f5)
13037
13038         IFS=$'\n'
13039         tot_len=0
13040         num_luns=1
13041         for line in $filefrag_op; do
13042                 frag_lun=$(echo $line | cut -d: -f5)
13043                 ext_len=$(echo $line | cut -d: -f4)
13044                 if [[ "$frag_lun" != "$last_lun" ]]; then
13045                         if (( tot_len != $EXPECTED_LEN )); then
13046                                 cleanup_130
13047                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13048                         else
13049                                 (( num_luns += 1 ))
13050                                 tot_len=0
13051                         fi
13052                 fi
13053                 (( tot_len += ext_len ))
13054                 last_lun=$frag_lun
13055         done
13056         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13057                 cleanup_130
13058                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13059         fi
13060
13061         echo "FIEMAP with continuation calls succeeded"
13062 }
13063 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13064
13065 test_130f() {
13066         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13067         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13068
13069         local fm_file=$DIR/$tfile
13070         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13071                 error "multiop create with lov_delay_create on $fm_file"
13072
13073         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13074         filefrag_extents=$(filefrag -vek $fm_file |
13075                            awk '/extents? found/ { print $2 }')
13076         if [[ "$filefrag_extents" != "0" ]]; then
13077                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13078         fi
13079
13080         rm -f $fm_file
13081 }
13082 run_test 130f "FIEMAP (unstriped file)"
13083
13084 test_130g() {
13085         local file=$DIR/$tfile
13086         local nr=$((OSTCOUNT * 100))
13087
13088         $LFS setstripe -C $nr $file ||
13089                 error "failed to setstripe -C $nr $file"
13090
13091         dd if=/dev/zero of=$file count=$nr bs=1M
13092         sync
13093         nr=$($LFS getstripe -c $file)
13094
13095         local extents=$(filefrag -v $file |
13096                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13097
13098         echo "filefrag list $extents extents in file with stripecount $nr"
13099         if (( extents < nr )); then
13100                 $LFS getstripe $file
13101                 filefrag -v $file
13102                 error "filefrag printed $extents < $nr extents"
13103         fi
13104
13105         rm -f $file
13106 }
13107 run_test 130g "FIEMAP (overstripe file)"
13108
13109 # Test for writev/readv
13110 test_131a() {
13111         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13112                 error "writev test failed"
13113         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13114                 error "readv failed"
13115         rm -f $DIR/$tfile
13116 }
13117 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13118
13119 test_131b() {
13120         local fsize=$((524288 + 1048576 + 1572864))
13121         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13122                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13123                         error "append writev test failed"
13124
13125         ((fsize += 1572864 + 1048576))
13126         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13127                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13128                         error "append writev test failed"
13129         rm -f $DIR/$tfile
13130 }
13131 run_test 131b "test append writev"
13132
13133 test_131c() {
13134         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13135         error "NOT PASS"
13136 }
13137 run_test 131c "test read/write on file w/o objects"
13138
13139 test_131d() {
13140         rwv -f $DIR/$tfile -w -n 1 1572864
13141         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13142         if [ "$NOB" != 1572864 ]; then
13143                 error "Short read filed: read $NOB bytes instead of 1572864"
13144         fi
13145         rm -f $DIR/$tfile
13146 }
13147 run_test 131d "test short read"
13148
13149 test_131e() {
13150         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13151         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13152         error "read hitting hole failed"
13153         rm -f $DIR/$tfile
13154 }
13155 run_test 131e "test read hitting hole"
13156
13157 check_stats() {
13158         local facet=$1
13159         local op=$2
13160         local want=${3:-0}
13161         local res
13162
13163         case $facet in
13164         mds*) res=$(do_facet $facet \
13165                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13166                  ;;
13167         ost*) res=$(do_facet $facet \
13168                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13169                  ;;
13170         *) error "Wrong facet '$facet'" ;;
13171         esac
13172         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13173         # if the argument $3 is zero, it means any stat increment is ok.
13174         if [[ $want -gt 0 ]]; then
13175                 local count=$(echo $res | awk '{ print $2 }')
13176                 [[ $count -ne $want ]] &&
13177                         error "The $op counter on $facet is $count, not $want"
13178         fi
13179 }
13180
13181 test_133a() {
13182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13183         remote_ost_nodsh && skip "remote OST with nodsh"
13184         remote_mds_nodsh && skip "remote MDS with nodsh"
13185         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13186                 skip_env "MDS doesn't support rename stats"
13187
13188         local testdir=$DIR/${tdir}/stats_testdir
13189
13190         mkdir -p $DIR/${tdir}
13191
13192         # clear stats.
13193         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13194         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13195
13196         # verify mdt stats first.
13197         mkdir ${testdir} || error "mkdir failed"
13198         check_stats $SINGLEMDS "mkdir" 1
13199         touch ${testdir}/${tfile} || error "touch failed"
13200         check_stats $SINGLEMDS "open" 1
13201         check_stats $SINGLEMDS "close" 1
13202         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13203                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13204                 check_stats $SINGLEMDS "mknod" 2
13205         }
13206         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13207         check_stats $SINGLEMDS "unlink" 1
13208         rm -f ${testdir}/${tfile} || error "file remove failed"
13209         check_stats $SINGLEMDS "unlink" 2
13210
13211         # remove working dir and check mdt stats again.
13212         rmdir ${testdir} || error "rmdir failed"
13213         check_stats $SINGLEMDS "rmdir" 1
13214
13215         local testdir1=$DIR/${tdir}/stats_testdir1
13216         mkdir -p ${testdir}
13217         mkdir -p ${testdir1}
13218         touch ${testdir1}/test1
13219         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13220         check_stats $SINGLEMDS "crossdir_rename" 1
13221
13222         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13223         check_stats $SINGLEMDS "samedir_rename" 1
13224
13225         rm -rf $DIR/${tdir}
13226 }
13227 run_test 133a "Verifying MDT stats ========================================"
13228
13229 test_133b() {
13230         local res
13231
13232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13233         remote_ost_nodsh && skip "remote OST with nodsh"
13234         remote_mds_nodsh && skip "remote MDS with nodsh"
13235
13236         local testdir=$DIR/${tdir}/stats_testdir
13237
13238         mkdir -p ${testdir} || error "mkdir failed"
13239         touch ${testdir}/${tfile} || error "touch failed"
13240         cancel_lru_locks mdc
13241
13242         # clear stats.
13243         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13244         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13245
13246         # extra mdt stats verification.
13247         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13248         check_stats $SINGLEMDS "setattr" 1
13249         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13250         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13251         then            # LU-1740
13252                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13253                 check_stats $SINGLEMDS "getattr" 1
13254         fi
13255         rm -rf $DIR/${tdir}
13256
13257         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13258         # so the check below is not reliable
13259         [ $MDSCOUNT -eq 1 ] || return 0
13260
13261         # Sleep to avoid a cached response.
13262         #define OBD_STATFS_CACHE_SECONDS 1
13263         sleep 2
13264         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13265         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13266         $LFS df || error "lfs failed"
13267         check_stats $SINGLEMDS "statfs" 1
13268
13269         # check aggregated statfs (LU-10018)
13270         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13271                 return 0
13272         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13273                 return 0
13274         sleep 2
13275         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13276         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13277         df $DIR
13278         check_stats $SINGLEMDS "statfs" 1
13279
13280         # We want to check that the client didn't send OST_STATFS to
13281         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13282         # extra care is needed here.
13283         if remote_mds; then
13284                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13285                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13286
13287                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13288                 [ "$res" ] && error "OST got STATFS"
13289         fi
13290
13291         return 0
13292 }
13293 run_test 133b "Verifying extra MDT stats =================================="
13294
13295 test_133c() {
13296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13297         remote_ost_nodsh && skip "remote OST with nodsh"
13298         remote_mds_nodsh && skip "remote MDS with nodsh"
13299
13300         local testdir=$DIR/$tdir/stats_testdir
13301
13302         test_mkdir -p $testdir
13303
13304         # verify obdfilter stats.
13305         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13306         sync
13307         cancel_lru_locks osc
13308         wait_delete_completed
13309
13310         # clear stats.
13311         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13312         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13313
13314         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13315                 error "dd failed"
13316         sync
13317         cancel_lru_locks osc
13318         check_stats ost1 "write" 1
13319
13320         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13321         check_stats ost1 "read" 1
13322
13323         > $testdir/$tfile || error "truncate failed"
13324         check_stats ost1 "punch" 1
13325
13326         rm -f $testdir/$tfile || error "file remove failed"
13327         wait_delete_completed
13328         check_stats ost1 "destroy" 1
13329
13330         rm -rf $DIR/$tdir
13331 }
13332 run_test 133c "Verifying OST stats ========================================"
13333
13334 order_2() {
13335         local value=$1
13336         local orig=$value
13337         local order=1
13338
13339         while [ $value -ge 2 ]; do
13340                 order=$((order*2))
13341                 value=$((value/2))
13342         done
13343
13344         if [ $orig -gt $order ]; then
13345                 order=$((order*2))
13346         fi
13347         echo $order
13348 }
13349
13350 size_in_KMGT() {
13351     local value=$1
13352     local size=('K' 'M' 'G' 'T');
13353     local i=0
13354     local size_string=$value
13355
13356     while [ $value -ge 1024 ]; do
13357         if [ $i -gt 3 ]; then
13358             #T is the biggest unit we get here, if that is bigger,
13359             #just return XXXT
13360             size_string=${value}T
13361             break
13362         fi
13363         value=$((value >> 10))
13364         if [ $value -lt 1024 ]; then
13365             size_string=${value}${size[$i]}
13366             break
13367         fi
13368         i=$((i + 1))
13369     done
13370
13371     echo $size_string
13372 }
13373
13374 get_rename_size() {
13375         local size=$1
13376         local context=${2:-.}
13377         local sample=$(do_facet $SINGLEMDS $LCTL \
13378                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13379                 grep -A1 $context |
13380                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13381         echo $sample
13382 }
13383
13384 test_133d() {
13385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13386         remote_ost_nodsh && skip "remote OST with nodsh"
13387         remote_mds_nodsh && skip "remote MDS with nodsh"
13388         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13389                 skip_env "MDS doesn't support rename stats"
13390
13391         local testdir1=$DIR/${tdir}/stats_testdir1
13392         local testdir2=$DIR/${tdir}/stats_testdir2
13393         mkdir -p $DIR/${tdir}
13394
13395         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13396
13397         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13398         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13399
13400         createmany -o $testdir1/test 512 || error "createmany failed"
13401
13402         # check samedir rename size
13403         mv ${testdir1}/test0 ${testdir1}/test_0
13404
13405         local testdir1_size=$(ls -l $DIR/${tdir} |
13406                 awk '/stats_testdir1/ {print $5}')
13407         local testdir2_size=$(ls -l $DIR/${tdir} |
13408                 awk '/stats_testdir2/ {print $5}')
13409
13410         testdir1_size=$(order_2 $testdir1_size)
13411         testdir2_size=$(order_2 $testdir2_size)
13412
13413         testdir1_size=$(size_in_KMGT $testdir1_size)
13414         testdir2_size=$(size_in_KMGT $testdir2_size)
13415
13416         echo "source rename dir size: ${testdir1_size}"
13417         echo "target rename dir size: ${testdir2_size}"
13418
13419         local cmd="do_facet $SINGLEMDS $LCTL "
13420         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13421
13422         eval $cmd || error "$cmd failed"
13423         local samedir=$($cmd | grep 'same_dir')
13424         local same_sample=$(get_rename_size $testdir1_size)
13425         [ -z "$samedir" ] && error "samedir_rename_size count error"
13426         [[ $same_sample -eq 1 ]] ||
13427                 error "samedir_rename_size error $same_sample"
13428         echo "Check same dir rename stats success"
13429
13430         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13431
13432         # check crossdir rename size
13433         mv ${testdir1}/test_0 ${testdir2}/test_0
13434
13435         testdir1_size=$(ls -l $DIR/${tdir} |
13436                 awk '/stats_testdir1/ {print $5}')
13437         testdir2_size=$(ls -l $DIR/${tdir} |
13438                 awk '/stats_testdir2/ {print $5}')
13439
13440         testdir1_size=$(order_2 $testdir1_size)
13441         testdir2_size=$(order_2 $testdir2_size)
13442
13443         testdir1_size=$(size_in_KMGT $testdir1_size)
13444         testdir2_size=$(size_in_KMGT $testdir2_size)
13445
13446         echo "source rename dir size: ${testdir1_size}"
13447         echo "target rename dir size: ${testdir2_size}"
13448
13449         eval $cmd || error "$cmd failed"
13450         local crossdir=$($cmd | grep 'crossdir')
13451         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13452         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13453         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13454         [[ $src_sample -eq 1 ]] ||
13455                 error "crossdir_rename_size error $src_sample"
13456         [[ $tgt_sample -eq 1 ]] ||
13457                 error "crossdir_rename_size error $tgt_sample"
13458         echo "Check cross dir rename stats success"
13459         rm -rf $DIR/${tdir}
13460 }
13461 run_test 133d "Verifying rename_stats ========================================"
13462
13463 test_133e() {
13464         remote_mds_nodsh && skip "remote MDS with nodsh"
13465         remote_ost_nodsh && skip "remote OST with nodsh"
13466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13467
13468         local testdir=$DIR/${tdir}/stats_testdir
13469         local ctr f0 f1 bs=32768 count=42 sum
13470
13471         mkdir -p ${testdir} || error "mkdir failed"
13472
13473         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13474
13475         for ctr in {write,read}_bytes; do
13476                 sync
13477                 cancel_lru_locks osc
13478
13479                 do_facet ost1 $LCTL set_param -n \
13480                         "obdfilter.*.exports.clear=clear"
13481
13482                 if [ $ctr = write_bytes ]; then
13483                         f0=/dev/zero
13484                         f1=${testdir}/${tfile}
13485                 else
13486                         f0=${testdir}/${tfile}
13487                         f1=/dev/null
13488                 fi
13489
13490                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13491                         error "dd failed"
13492                 sync
13493                 cancel_lru_locks osc
13494
13495                 sum=$(do_facet ost1 $LCTL get_param \
13496                         "obdfilter.*.exports.*.stats" |
13497                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13498                                 $1 == ctr { sum += $7 }
13499                                 END { printf("%0.0f", sum) }')
13500
13501                 if ((sum != bs * count)); then
13502                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13503                 fi
13504         done
13505
13506         rm -rf $DIR/${tdir}
13507 }
13508 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13509
13510 test_133f() {
13511         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13512                 skip "too old lustre for get_param -R ($facet_ver)"
13513
13514         # verifying readability.
13515         $LCTL get_param -R '*' &> /dev/null
13516
13517         # Verifing writability with badarea_io.
13518         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13519                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13520                 error "client badarea_io failed"
13521
13522         # remount the FS in case writes/reads /proc break the FS
13523         cleanup || error "failed to unmount"
13524         setup || error "failed to setup"
13525 }
13526 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13527
13528 test_133g() {
13529         remote_mds_nodsh && skip "remote MDS with nodsh"
13530         remote_ost_nodsh && skip "remote OST with nodsh"
13531
13532         local facet
13533         for facet in mds1 ost1; do
13534                 local facet_ver=$(lustre_version_code $facet)
13535                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13536                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13537                 else
13538                         log "$facet: too old lustre for get_param -R"
13539                 fi
13540                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13541                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13542                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13543                                 xargs badarea_io" ||
13544                                         error "$facet badarea_io failed"
13545                 else
13546                         skip_noexit "$facet: too old lustre for get_param -R"
13547                 fi
13548         done
13549
13550         # remount the FS in case writes/reads /proc break the FS
13551         cleanup || error "failed to unmount"
13552         setup || error "failed to setup"
13553 }
13554 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13555
13556 test_133h() {
13557         remote_mds_nodsh && skip "remote MDS with nodsh"
13558         remote_ost_nodsh && skip "remote OST with nodsh"
13559         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13560                 skip "Need MDS version at least 2.9.54"
13561
13562         local facet
13563         for facet in client mds1 ost1; do
13564                 # Get the list of files that are missing the terminating newline
13565                 local plist=$(do_facet $facet
13566                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13567                 local ent
13568                 for ent in $plist; do
13569                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13570                                 awk -v FS='\v' -v RS='\v\v' \
13571                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13572                                         print FILENAME}'" 2>/dev/null)
13573                         [ -z $missing ] || {
13574                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13575                                 error "file does not end with newline: $facet-$ent"
13576                         }
13577                 done
13578         done
13579 }
13580 run_test 133h "Proc files should end with newlines"
13581
13582 test_134a() {
13583         remote_mds_nodsh && skip "remote MDS with nodsh"
13584         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13585                 skip "Need MDS version at least 2.7.54"
13586
13587         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13588         cancel_lru_locks mdc
13589
13590         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13591         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13592         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13593
13594         local nr=1000
13595         createmany -o $DIR/$tdir/f $nr ||
13596                 error "failed to create $nr files in $DIR/$tdir"
13597         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13598
13599         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13600         do_facet mds1 $LCTL set_param fail_loc=0x327
13601         do_facet mds1 $LCTL set_param fail_val=500
13602         touch $DIR/$tdir/m
13603
13604         echo "sleep 10 seconds ..."
13605         sleep 10
13606         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13607
13608         do_facet mds1 $LCTL set_param fail_loc=0
13609         do_facet mds1 $LCTL set_param fail_val=0
13610         [ $lck_cnt -lt $unused ] ||
13611                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13612
13613         rm $DIR/$tdir/m
13614         unlinkmany $DIR/$tdir/f $nr
13615 }
13616 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13617
13618 test_134b() {
13619         remote_mds_nodsh && skip "remote MDS with nodsh"
13620         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13621                 skip "Need MDS version at least 2.7.54"
13622
13623         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13624         cancel_lru_locks mdc
13625
13626         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13627                         ldlm.lock_reclaim_threshold_mb)
13628         # disable reclaim temporarily
13629         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13630
13631         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13632         do_facet mds1 $LCTL set_param fail_loc=0x328
13633         do_facet mds1 $LCTL set_param fail_val=500
13634
13635         $LCTL set_param debug=+trace
13636
13637         local nr=600
13638         createmany -o $DIR/$tdir/f $nr &
13639         local create_pid=$!
13640
13641         echo "Sleep $TIMEOUT seconds ..."
13642         sleep $TIMEOUT
13643         if ! ps -p $create_pid  > /dev/null 2>&1; then
13644                 do_facet mds1 $LCTL set_param fail_loc=0
13645                 do_facet mds1 $LCTL set_param fail_val=0
13646                 do_facet mds1 $LCTL set_param \
13647                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13648                 error "createmany finished incorrectly!"
13649         fi
13650         do_facet mds1 $LCTL set_param fail_loc=0
13651         do_facet mds1 $LCTL set_param fail_val=0
13652         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13653         wait $create_pid || return 1
13654
13655         unlinkmany $DIR/$tdir/f $nr
13656 }
13657 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13658
13659 test_135() {
13660         remote_mds_nodsh && skip "remote MDS with nodsh"
13661         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13662                 skip "Need MDS version at least 2.13.50"
13663         local fname
13664
13665         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13666
13667 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13668         #set only one record at plain llog
13669         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13670
13671         #fill already existed plain llog each 64767
13672         #wrapping whole catalog
13673         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13674
13675         createmany -o $DIR/$tdir/$tfile_ 64700
13676         for (( i = 0; i < 64700; i = i + 2 ))
13677         do
13678                 rm $DIR/$tdir/$tfile_$i &
13679                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13680                 local pid=$!
13681                 wait $pid
13682         done
13683
13684         #waiting osp synchronization
13685         wait_delete_completed
13686 }
13687 run_test 135 "Race catalog processing"
13688
13689 test_136() {
13690         remote_mds_nodsh && skip "remote MDS with nodsh"
13691         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13692                 skip "Need MDS version at least 2.13.50"
13693         local fname
13694
13695         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13696         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13697         #set only one record at plain llog
13698 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13699         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13700
13701         #fill already existed 2 plain llogs each 64767
13702         #wrapping whole catalog
13703         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13704         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13705         wait_delete_completed
13706
13707         createmany -o $DIR/$tdir/$tfile_ 10
13708         sleep 25
13709
13710         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13711         for (( i = 0; i < 10; i = i + 3 ))
13712         do
13713                 rm $DIR/$tdir/$tfile_$i &
13714                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13715                 local pid=$!
13716                 wait $pid
13717                 sleep 7
13718                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13719         done
13720
13721         #waiting osp synchronization
13722         wait_delete_completed
13723 }
13724 run_test 136 "Race catalog processing 2"
13725
13726 test_140() { #bug-17379
13727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13728
13729         test_mkdir $DIR/$tdir
13730         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13731         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13732
13733         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13734         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13735         local i=0
13736         while i=$((i + 1)); do
13737                 test_mkdir $i
13738                 cd $i || error "Changing to $i"
13739                 ln -s ../stat stat || error "Creating stat symlink"
13740                 # Read the symlink until ELOOP present,
13741                 # not LBUGing the system is considered success,
13742                 # we didn't overrun the stack.
13743                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13744                 if [ $ret -ne 0 ]; then
13745                         if [ $ret -eq 40 ]; then
13746                                 break  # -ELOOP
13747                         else
13748                                 error "Open stat symlink"
13749                                         return
13750                         fi
13751                 fi
13752         done
13753         i=$((i - 1))
13754         echo "The symlink depth = $i"
13755         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13756                 error "Invalid symlink depth"
13757
13758         # Test recursive symlink
13759         ln -s symlink_self symlink_self
13760         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13761         echo "open symlink_self returns $ret"
13762         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13763 }
13764 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13765
13766 test_150a() {
13767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13768
13769         local TF="$TMP/$tfile"
13770
13771         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13772         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13773         cp $TF $DIR/$tfile
13774         cancel_lru_locks $OSC
13775         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13776         remount_client $MOUNT
13777         df -P $MOUNT
13778         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13779
13780         $TRUNCATE $TF 6000
13781         $TRUNCATE $DIR/$tfile 6000
13782         cancel_lru_locks $OSC
13783         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13784
13785         echo "12345" >>$TF
13786         echo "12345" >>$DIR/$tfile
13787         cancel_lru_locks $OSC
13788         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13789
13790         echo "12345" >>$TF
13791         echo "12345" >>$DIR/$tfile
13792         cancel_lru_locks $OSC
13793         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13794 }
13795 run_test 150a "truncate/append tests"
13796
13797 test_150b() {
13798         check_set_fallocate_or_skip
13799
13800         touch $DIR/$tfile
13801         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13802         check_fallocate $DIR/$tfile || error "fallocate failed"
13803 }
13804 run_test 150b "Verify fallocate (prealloc) functionality"
13805
13806 test_150bb() {
13807         check_set_fallocate_or_skip
13808
13809         touch $DIR/$tfile
13810         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13811         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13812         > $DIR/$tfile
13813         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13814         # precomputed md5sum for 20MB of zeroes
13815         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13816         local sum=($(md5sum $DIR/$tfile))
13817
13818         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13819
13820         check_set_fallocate 1
13821
13822         > $DIR/$tfile
13823         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13824         sum=($(md5sum $DIR/$tfile))
13825
13826         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13827 }
13828 run_test 150bb "Verify fallocate modes both zero space"
13829
13830 test_150c() {
13831         check_set_fallocate_or_skip
13832
13833         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13834         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13835         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13836         sync; sync_all_data
13837         cancel_lru_locks $OSC
13838         sleep 5
13839         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13840         want=$((OSTCOUNT * 1048576))
13841
13842         # Must allocate all requested space, not more than 5% extra
13843         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13844                 error "bytes $bytes is not $want"
13845
13846         rm -f $DIR/$tfile
13847         # verify fallocate on PFL file
13848         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13849                 error "Create $DIR/$tfile failed"
13850         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13851                         error "fallocate failed"
13852         sync; sync_all_data
13853         cancel_lru_locks $OSC
13854         sleep 5
13855         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13856         local want=$((1024 * 1048576))
13857
13858         # Must allocate all requested space, not more than 5% extra
13859         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13860                 error "bytes $bytes is not $want"
13861 }
13862 run_test 150c "Verify fallocate Size and Blocks"
13863
13864 test_150d() {
13865         check_set_fallocate_or_skip
13866
13867         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13868         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13869         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13870         sync; sync_all_data
13871         cancel_lru_locks $OSC
13872         sleep 5
13873         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13874         local want=$((OSTCOUNT * 1048576))
13875
13876         # Must allocate all requested space, not more than 5% extra
13877         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13878                 error "bytes $bytes is not $want"
13879 }
13880 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13881
13882 test_150e() {
13883         check_set_fallocate_or_skip
13884
13885         echo "df before:"
13886         $LFS df
13887         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13888         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13889                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13890
13891         # Find OST with Minimum Size
13892         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13893                        sort -un | head -1)
13894
13895         # Get 100MB per OST of the available space to reduce run time
13896         # else 60% of the available space if we are running SLOW tests
13897         if [ $SLOW == "no" ]; then
13898                 local space=$((1024 * 100 * OSTCOUNT))
13899         else
13900                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
13901         fi
13902
13903         fallocate -l${space}k $DIR/$tfile ||
13904                 error "fallocate ${space}k $DIR/$tfile failed"
13905         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13906
13907         # get size immediately after fallocate. This should be correctly
13908         # updated
13909         local size=$(stat -c '%s' $DIR/$tfile)
13910         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13911
13912         # Sleep for a while for statfs to get updated. And not pull from cache.
13913         sleep 2
13914
13915         echo "df after fallocate:"
13916         $LFS df
13917
13918         (( size / 1024 == space )) || error "size $size != requested $space"
13919         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13920                 error "used $used < space $space"
13921
13922         rm $DIR/$tfile || error "rm failed"
13923         sync
13924         wait_delete_completed
13925
13926         echo "df after unlink:"
13927         $LFS df
13928 }
13929 run_test 150e "Verify 60% of available OST space consumed by fallocate"
13930
13931 test_150f() {
13932         local size
13933         local blocks
13934         local want_size_before=20480 # in bytes
13935         local want_blocks_before=40 # 512 sized blocks
13936         local want_blocks_after=24  # 512 sized blocks
13937         local length=$(((want_blocks_before - want_blocks_after) * 512))
13938
13939         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
13940                 skip "need at least 2.14.0 for fallocate punch"
13941
13942         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
13943                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
13944         fi
13945
13946         check_set_fallocate_or_skip
13947         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13948
13949         echo "Verify fallocate punch: Range within the file range"
13950         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
13951                 error "dd failed for bs 4096 and count 5"
13952
13953         # Call fallocate with punch range which is within the file range
13954         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
13955                 error "fallocate failed: offset 4096 and length $length"
13956         # client must see changes immediately after fallocate
13957         size=$(stat -c '%s' $DIR/$tfile)
13958         blocks=$(stat -c '%b' $DIR/$tfile)
13959
13960         # Verify punch worked.
13961         (( blocks == want_blocks_after )) ||
13962                 error "punch failed: blocks $blocks != $want_blocks_after"
13963
13964         (( size == want_size_before )) ||
13965                 error "punch failed: size $size != $want_size_before"
13966
13967         # Verify there is hole in file
13968         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
13969         # precomputed md5sum
13970         local expect="4a9a834a2db02452929c0a348273b4aa"
13971
13972         cksum=($(md5sum $DIR/$tfile))
13973         [[ "${cksum[0]}" == "$expect" ]] ||
13974                 error "unexpected MD5SUM after punch: ${cksum[0]}"
13975
13976         # Start second sub-case for fallocate punch.
13977         echo "Verify fallocate punch: Range overlapping and less than blocksize"
13978         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
13979                 error "dd failed for bs 4096 and count 5"
13980
13981         # Punch range less than block size will have no change in block count
13982         want_blocks_after=40  # 512 sized blocks
13983
13984         # Punch overlaps two blocks and less than blocksize
13985         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
13986                 error "fallocate failed: offset 4000 length 3000"
13987         size=$(stat -c '%s' $DIR/$tfile)
13988         blocks=$(stat -c '%b' $DIR/$tfile)
13989
13990         # Verify punch worked.
13991         (( blocks == want_blocks_after )) ||
13992                 error "punch failed: blocks $blocks != $want_blocks_after"
13993
13994         (( size == want_size_before )) ||
13995                 error "punch failed: size $size != $want_size_before"
13996
13997         # Verify if range is really zero'ed out. We expect Zeros.
13998         # precomputed md5sum
13999         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14000         cksum=($(md5sum $DIR/$tfile))
14001         [[ "${cksum[0]}" == "$expect" ]] ||
14002                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14003 }
14004 run_test 150f "Verify fallocate punch functionality"
14005
14006 test_150g() {
14007         local space
14008         local size
14009         local blocks
14010         local blocks_after
14011         local size_after
14012         local BS=4096 # Block size in bytes
14013
14014         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14015                 skip "need at least 2.14.0 for fallocate punch"
14016
14017         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14018                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14019         fi
14020
14021         check_set_fallocate_or_skip
14022         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14023
14024         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14025                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14026
14027         # Get 100MB per OST of the available space to reduce run time
14028         # else 60% of the available space if we are running SLOW tests
14029         if [ $SLOW == "no" ]; then
14030                 space=$((1024 * 100 * OSTCOUNT))
14031         else
14032                 # Find OST with Minimum Size
14033                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14034                         sort -un | head -1)
14035                 echo "min size OST: $space"
14036                 space=$(((space * 60)/100 * OSTCOUNT))
14037         fi
14038         # space in 1k units, round to 4k blocks
14039         local blkcount=$((space * 1024 / $BS))
14040
14041         echo "Verify fallocate punch: Very large Range"
14042         fallocate -l${space}k $DIR/$tfile ||
14043                 error "fallocate ${space}k $DIR/$tfile failed"
14044         # write 1M at the end, start and in the middle
14045         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14046                 error "dd failed: bs $BS count 256"
14047         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14048                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14049         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14050                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14051
14052         # Gather stats.
14053         size=$(stat -c '%s' $DIR/$tfile)
14054
14055         # gather punch length.
14056         local punch_size=$((size - (BS * 2)))
14057
14058         echo "punch_size = $punch_size"
14059         echo "size - punch_size: $((size - punch_size))"
14060         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14061
14062         # Call fallocate to punch all except 2 blocks. We leave the
14063         # first and the last block
14064         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14065         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14066                 error "fallocate failed: offset $BS length $punch_size"
14067
14068         size_after=$(stat -c '%s' $DIR/$tfile)
14069         blocks_after=$(stat -c '%b' $DIR/$tfile)
14070
14071         # Verify punch worked.
14072         # Size should be kept
14073         (( size == size_after )) ||
14074                 error "punch failed: size $size != $size_after"
14075
14076         # two 4k data blocks to remain plus possible 1 extra extent block
14077         (( blocks_after <= ((BS / 512) * 3) )) ||
14078                 error "too many blocks remains: $blocks_after"
14079
14080         # Verify that file has hole between the first and the last blocks
14081         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14082         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14083
14084         echo "Hole at [$hole_start, $hole_end)"
14085         (( hole_start == BS )) ||
14086                 error "no hole at offset $BS after punch"
14087
14088         (( hole_end == BS + punch_size )) ||
14089                 error "data at offset $hole_end < $((BS + punch_size))"
14090 }
14091 run_test 150g "Verify fallocate punch on large range"
14092
14093 #LU-2902 roc_hit was not able to read all values from lproc
14094 function roc_hit_init() {
14095         local list=$(comma_list $(osts_nodes))
14096         local dir=$DIR/$tdir-check
14097         local file=$dir/$tfile
14098         local BEFORE
14099         local AFTER
14100         local idx
14101
14102         test_mkdir $dir
14103         #use setstripe to do a write to every ost
14104         for i in $(seq 0 $((OSTCOUNT-1))); do
14105                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14106                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14107                 idx=$(printf %04x $i)
14108                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14109                         awk '$1 == "cache_access" {sum += $7}
14110                                 END { printf("%0.0f", sum) }')
14111
14112                 cancel_lru_locks osc
14113                 cat $file >/dev/null
14114
14115                 AFTER=$(get_osd_param $list *OST*$idx stats |
14116                         awk '$1 == "cache_access" {sum += $7}
14117                                 END { printf("%0.0f", sum) }')
14118
14119                 echo BEFORE:$BEFORE AFTER:$AFTER
14120                 if ! let "AFTER - BEFORE == 4"; then
14121                         rm -rf $dir
14122                         error "roc_hit is not safe to use"
14123                 fi
14124                 rm $file
14125         done
14126
14127         rm -rf $dir
14128 }
14129
14130 function roc_hit() {
14131         local list=$(comma_list $(osts_nodes))
14132         echo $(get_osd_param $list '' stats |
14133                 awk '$1 == "cache_hit" {sum += $7}
14134                         END { printf("%0.0f", sum) }')
14135 }
14136
14137 function set_cache() {
14138         local on=1
14139
14140         if [ "$2" == "off" ]; then
14141                 on=0;
14142         fi
14143         local list=$(comma_list $(osts_nodes))
14144         set_osd_param $list '' $1_cache_enable $on
14145
14146         cancel_lru_locks osc
14147 }
14148
14149 test_151() {
14150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14151         remote_ost_nodsh && skip "remote OST with nodsh"
14152
14153         local CPAGES=3
14154         local list=$(comma_list $(osts_nodes))
14155
14156         # check whether obdfilter is cache capable at all
14157         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14158                 skip "not cache-capable obdfilter"
14159         fi
14160
14161         # check cache is enabled on all obdfilters
14162         if get_osd_param $list '' read_cache_enable | grep 0; then
14163                 skip "oss cache is disabled"
14164         fi
14165
14166         set_osd_param $list '' writethrough_cache_enable 1
14167
14168         # check write cache is enabled on all obdfilters
14169         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14170                 skip "oss write cache is NOT enabled"
14171         fi
14172
14173         roc_hit_init
14174
14175         #define OBD_FAIL_OBD_NO_LRU  0x609
14176         do_nodes $list $LCTL set_param fail_loc=0x609
14177
14178         # pages should be in the case right after write
14179         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14180                 error "dd failed"
14181
14182         local BEFORE=$(roc_hit)
14183         cancel_lru_locks osc
14184         cat $DIR/$tfile >/dev/null
14185         local AFTER=$(roc_hit)
14186
14187         do_nodes $list $LCTL set_param fail_loc=0
14188
14189         if ! let "AFTER - BEFORE == CPAGES"; then
14190                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14191         fi
14192
14193         cancel_lru_locks osc
14194         # invalidates OST cache
14195         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14196         set_osd_param $list '' read_cache_enable 0
14197         cat $DIR/$tfile >/dev/null
14198
14199         # now data shouldn't be found in the cache
14200         BEFORE=$(roc_hit)
14201         cancel_lru_locks osc
14202         cat $DIR/$tfile >/dev/null
14203         AFTER=$(roc_hit)
14204         if let "AFTER - BEFORE != 0"; then
14205                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14206         fi
14207
14208         set_osd_param $list '' read_cache_enable 1
14209         rm -f $DIR/$tfile
14210 }
14211 run_test 151 "test cache on oss and controls ==============================="
14212
14213 test_152() {
14214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14215
14216         local TF="$TMP/$tfile"
14217
14218         # simulate ENOMEM during write
14219 #define OBD_FAIL_OST_NOMEM      0x226
14220         lctl set_param fail_loc=0x80000226
14221         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14222         cp $TF $DIR/$tfile
14223         sync || error "sync failed"
14224         lctl set_param fail_loc=0
14225
14226         # discard client's cache
14227         cancel_lru_locks osc
14228
14229         # simulate ENOMEM during read
14230         lctl set_param fail_loc=0x80000226
14231         cmp $TF $DIR/$tfile || error "cmp failed"
14232         lctl set_param fail_loc=0
14233
14234         rm -f $TF
14235 }
14236 run_test 152 "test read/write with enomem ============================"
14237
14238 test_153() {
14239         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14240 }
14241 run_test 153 "test if fdatasync does not crash ======================="
14242
14243 dot_lustre_fid_permission_check() {
14244         local fid=$1
14245         local ffid=$MOUNT/.lustre/fid/$fid
14246         local test_dir=$2
14247
14248         echo "stat fid $fid"
14249         stat $ffid > /dev/null || error "stat $ffid failed."
14250         echo "touch fid $fid"
14251         touch $ffid || error "touch $ffid failed."
14252         echo "write to fid $fid"
14253         cat /etc/hosts > $ffid || error "write $ffid failed."
14254         echo "read fid $fid"
14255         diff /etc/hosts $ffid || error "read $ffid failed."
14256         echo "append write to fid $fid"
14257         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14258         echo "rename fid $fid"
14259         mv $ffid $test_dir/$tfile.1 &&
14260                 error "rename $ffid to $tfile.1 should fail."
14261         touch $test_dir/$tfile.1
14262         mv $test_dir/$tfile.1 $ffid &&
14263                 error "rename $tfile.1 to $ffid should fail."
14264         rm -f $test_dir/$tfile.1
14265         echo "truncate fid $fid"
14266         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14267         echo "link fid $fid"
14268         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14269         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14270                 echo "setfacl fid $fid"
14271                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14272                 echo "getfacl fid $fid"
14273                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14274         fi
14275         echo "unlink fid $fid"
14276         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14277         echo "mknod fid $fid"
14278         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14279
14280         fid=[0xf00000400:0x1:0x0]
14281         ffid=$MOUNT/.lustre/fid/$fid
14282
14283         echo "stat non-exist fid $fid"
14284         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14285         echo "write to non-exist fid $fid"
14286         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14287         echo "link new fid $fid"
14288         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14289
14290         mkdir -p $test_dir/$tdir
14291         touch $test_dir/$tdir/$tfile
14292         fid=$($LFS path2fid $test_dir/$tdir)
14293         rc=$?
14294         [ $rc -ne 0 ] &&
14295                 error "error: could not get fid for $test_dir/$dir/$tfile."
14296
14297         ffid=$MOUNT/.lustre/fid/$fid
14298
14299         echo "ls $fid"
14300         ls $ffid > /dev/null || error "ls $ffid failed."
14301         echo "touch $fid/$tfile.1"
14302         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14303
14304         echo "touch $MOUNT/.lustre/fid/$tfile"
14305         touch $MOUNT/.lustre/fid/$tfile && \
14306                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14307
14308         echo "setxattr to $MOUNT/.lustre/fid"
14309         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14310
14311         echo "listxattr for $MOUNT/.lustre/fid"
14312         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14313
14314         echo "delxattr from $MOUNT/.lustre/fid"
14315         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14316
14317         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14318         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14319                 error "touch invalid fid should fail."
14320
14321         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14322         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14323                 error "touch non-normal fid should fail."
14324
14325         echo "rename $tdir to $MOUNT/.lustre/fid"
14326         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14327                 error "rename to $MOUNT/.lustre/fid should fail."
14328
14329         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14330         then            # LU-3547
14331                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14332                 local new_obf_mode=777
14333
14334                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14335                 chmod $new_obf_mode $DIR/.lustre/fid ||
14336                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14337
14338                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14339                 [ $obf_mode -eq $new_obf_mode ] ||
14340                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14341
14342                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14343                 chmod $old_obf_mode $DIR/.lustre/fid ||
14344                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14345         fi
14346
14347         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14348         fid=$($LFS path2fid $test_dir/$tfile-2)
14349
14350         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14351         then # LU-5424
14352                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14353                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14354                         error "create lov data thru .lustre failed"
14355         fi
14356         echo "cp /etc/passwd $test_dir/$tfile-2"
14357         cp /etc/passwd $test_dir/$tfile-2 ||
14358                 error "copy to $test_dir/$tfile-2 failed."
14359         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14360         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14361                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14362
14363         rm -rf $test_dir/tfile.lnk
14364         rm -rf $test_dir/$tfile-2
14365 }
14366
14367 test_154A() {
14368         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14369                 skip "Need MDS version at least 2.4.1"
14370
14371         local tf=$DIR/$tfile
14372         touch $tf
14373
14374         local fid=$($LFS path2fid $tf)
14375         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14376
14377         # check that we get the same pathname back
14378         local rootpath
14379         local found
14380         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14381                 echo "$rootpath $fid"
14382                 found=$($LFS fid2path $rootpath "$fid")
14383                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14384                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14385         done
14386
14387         # check wrong root path format
14388         rootpath=$MOUNT"_wrong"
14389         found=$($LFS fid2path $rootpath "$fid")
14390         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14391 }
14392 run_test 154A "lfs path2fid and fid2path basic checks"
14393
14394 test_154B() {
14395         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14396                 skip "Need MDS version at least 2.4.1"
14397
14398         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14399         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14400         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14401         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14402
14403         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14404         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14405
14406         # check that we get the same pathname
14407         echo "PFID: $PFID, name: $name"
14408         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14409         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14410         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14411                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14412
14413         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14414 }
14415 run_test 154B "verify the ll_decode_linkea tool"
14416
14417 test_154a() {
14418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14419         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14420         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14421                 skip "Need MDS version at least 2.2.51"
14422         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14423
14424         cp /etc/hosts $DIR/$tfile
14425
14426         fid=$($LFS path2fid $DIR/$tfile)
14427         rc=$?
14428         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14429
14430         dot_lustre_fid_permission_check "$fid" $DIR ||
14431                 error "dot lustre permission check $fid failed"
14432
14433         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14434
14435         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14436
14437         touch $MOUNT/.lustre/file &&
14438                 error "creation is not allowed under .lustre"
14439
14440         mkdir $MOUNT/.lustre/dir &&
14441                 error "mkdir is not allowed under .lustre"
14442
14443         rm -rf $DIR/$tfile
14444 }
14445 run_test 154a "Open-by-FID"
14446
14447 test_154b() {
14448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14449         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14450         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14451         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14452                 skip "Need MDS version at least 2.2.51"
14453
14454         local remote_dir=$DIR/$tdir/remote_dir
14455         local MDTIDX=1
14456         local rc=0
14457
14458         mkdir -p $DIR/$tdir
14459         $LFS mkdir -i $MDTIDX $remote_dir ||
14460                 error "create remote directory failed"
14461
14462         cp /etc/hosts $remote_dir/$tfile
14463
14464         fid=$($LFS path2fid $remote_dir/$tfile)
14465         rc=$?
14466         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14467
14468         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14469                 error "dot lustre permission check $fid failed"
14470         rm -rf $DIR/$tdir
14471 }
14472 run_test 154b "Open-by-FID for remote directory"
14473
14474 test_154c() {
14475         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14476                 skip "Need MDS version at least 2.4.1"
14477
14478         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14479         local FID1=$($LFS path2fid $DIR/$tfile.1)
14480         local FID2=$($LFS path2fid $DIR/$tfile.2)
14481         local FID3=$($LFS path2fid $DIR/$tfile.3)
14482
14483         local N=1
14484         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14485                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14486                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14487                 local want=FID$N
14488                 [ "$FID" = "${!want}" ] ||
14489                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14490                 N=$((N + 1))
14491         done
14492
14493         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14494         do
14495                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14496                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14497                 N=$((N + 1))
14498         done
14499 }
14500 run_test 154c "lfs path2fid and fid2path multiple arguments"
14501
14502 test_154d() {
14503         remote_mds_nodsh && skip "remote MDS with nodsh"
14504         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14505                 skip "Need MDS version at least 2.5.53"
14506
14507         if remote_mds; then
14508                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14509         else
14510                 nid="0@lo"
14511         fi
14512         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14513         local fd
14514         local cmd
14515
14516         rm -f $DIR/$tfile
14517         touch $DIR/$tfile
14518
14519         local fid=$($LFS path2fid $DIR/$tfile)
14520         # Open the file
14521         fd=$(free_fd)
14522         cmd="exec $fd<$DIR/$tfile"
14523         eval $cmd
14524         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14525         echo "$fid_list" | grep "$fid"
14526         rc=$?
14527
14528         cmd="exec $fd>/dev/null"
14529         eval $cmd
14530         if [ $rc -ne 0 ]; then
14531                 error "FID $fid not found in open files list $fid_list"
14532         fi
14533 }
14534 run_test 154d "Verify open file fid"
14535
14536 test_154e()
14537 {
14538         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14539                 skip "Need MDS version at least 2.6.50"
14540
14541         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14542                 error ".lustre returned by readdir"
14543         fi
14544 }
14545 run_test 154e ".lustre is not returned by readdir"
14546
14547 test_154f() {
14548         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14549
14550         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14551         test_mkdir -p -c1 $DIR/$tdir/d
14552         # test dirs inherit from its stripe
14553         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14554         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14555         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14556         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14557         touch $DIR/f
14558
14559         # get fid of parents
14560         local FID0=$($LFS path2fid $DIR/$tdir/d)
14561         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14562         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14563         local FID3=$($LFS path2fid $DIR)
14564
14565         # check that path2fid --parents returns expected <parent_fid>/name
14566         # 1) test for a directory (single parent)
14567         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14568         [ "$parent" == "$FID0/foo1" ] ||
14569                 error "expected parent: $FID0/foo1, got: $parent"
14570
14571         # 2) test for a file with nlink > 1 (multiple parents)
14572         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14573         echo "$parent" | grep -F "$FID1/$tfile" ||
14574                 error "$FID1/$tfile not returned in parent list"
14575         echo "$parent" | grep -F "$FID2/link" ||
14576                 error "$FID2/link not returned in parent list"
14577
14578         # 3) get parent by fid
14579         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14580         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14581         echo "$parent" | grep -F "$FID1/$tfile" ||
14582                 error "$FID1/$tfile not returned in parent list (by fid)"
14583         echo "$parent" | grep -F "$FID2/link" ||
14584                 error "$FID2/link not returned in parent list (by fid)"
14585
14586         # 4) test for entry in root directory
14587         parent=$($LFS path2fid --parents $DIR/f)
14588         echo "$parent" | grep -F "$FID3/f" ||
14589                 error "$FID3/f not returned in parent list"
14590
14591         # 5) test it on root directory
14592         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14593                 error "$MOUNT should not have parents"
14594
14595         # enable xattr caching and check that linkea is correctly updated
14596         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14597         save_lustre_params client "llite.*.xattr_cache" > $save
14598         lctl set_param llite.*.xattr_cache 1
14599
14600         # 6.1) linkea update on rename
14601         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14602
14603         # get parents by fid
14604         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14605         # foo1 should no longer be returned in parent list
14606         echo "$parent" | grep -F "$FID1" &&
14607                 error "$FID1 should no longer be in parent list"
14608         # the new path should appear
14609         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14610                 error "$FID2/$tfile.moved is not in parent list"
14611
14612         # 6.2) linkea update on unlink
14613         rm -f $DIR/$tdir/d/foo2/link
14614         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14615         # foo2/link should no longer be returned in parent list
14616         echo "$parent" | grep -F "$FID2/link" &&
14617                 error "$FID2/link should no longer be in parent list"
14618         true
14619
14620         rm -f $DIR/f
14621         restore_lustre_params < $save
14622         rm -f $save
14623 }
14624 run_test 154f "get parent fids by reading link ea"
14625
14626 test_154g()
14627 {
14628         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14629         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14630            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14631                 skip "Need MDS version at least 2.6.92"
14632
14633         mkdir -p $DIR/$tdir
14634         llapi_fid_test -d $DIR/$tdir
14635 }
14636 run_test 154g "various llapi FID tests"
14637
14638 test_155_small_load() {
14639     local temp=$TMP/$tfile
14640     local file=$DIR/$tfile
14641
14642     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14643         error "dd of=$temp bs=6096 count=1 failed"
14644     cp $temp $file
14645     cancel_lru_locks $OSC
14646     cmp $temp $file || error "$temp $file differ"
14647
14648     $TRUNCATE $temp 6000
14649     $TRUNCATE $file 6000
14650     cmp $temp $file || error "$temp $file differ (truncate1)"
14651
14652     echo "12345" >>$temp
14653     echo "12345" >>$file
14654     cmp $temp $file || error "$temp $file differ (append1)"
14655
14656     echo "12345" >>$temp
14657     echo "12345" >>$file
14658     cmp $temp $file || error "$temp $file differ (append2)"
14659
14660     rm -f $temp $file
14661     true
14662 }
14663
14664 test_155_big_load() {
14665         remote_ost_nodsh && skip "remote OST with nodsh"
14666
14667         local temp=$TMP/$tfile
14668         local file=$DIR/$tfile
14669
14670         free_min_max
14671         local cache_size=$(do_facet ost$((MAXI+1)) \
14672                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14673         local large_file_size=$((cache_size * 2))
14674
14675         echo "OSS cache size: $cache_size KB"
14676         echo "Large file size: $large_file_size KB"
14677
14678         [ $MAXV -le $large_file_size ] &&
14679                 skip_env "max available OST size needs > $large_file_size KB"
14680
14681         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14682
14683         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14684                 error "dd of=$temp bs=$large_file_size count=1k failed"
14685         cp $temp $file
14686         ls -lh $temp $file
14687         cancel_lru_locks osc
14688         cmp $temp $file || error "$temp $file differ"
14689
14690         rm -f $temp $file
14691         true
14692 }
14693
14694 save_writethrough() {
14695         local facets=$(get_facets OST)
14696
14697         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14698 }
14699
14700 test_155a() {
14701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14702
14703         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14704
14705         save_writethrough $p
14706
14707         set_cache read on
14708         set_cache writethrough on
14709         test_155_small_load
14710         restore_lustre_params < $p
14711         rm -f $p
14712 }
14713 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14714
14715 test_155b() {
14716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14717
14718         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14719
14720         save_writethrough $p
14721
14722         set_cache read on
14723         set_cache writethrough off
14724         test_155_small_load
14725         restore_lustre_params < $p
14726         rm -f $p
14727 }
14728 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14729
14730 test_155c() {
14731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14732
14733         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14734
14735         save_writethrough $p
14736
14737         set_cache read off
14738         set_cache writethrough on
14739         test_155_small_load
14740         restore_lustre_params < $p
14741         rm -f $p
14742 }
14743 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14744
14745 test_155d() {
14746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14747
14748         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14749
14750         save_writethrough $p
14751
14752         set_cache read off
14753         set_cache writethrough off
14754         test_155_small_load
14755         restore_lustre_params < $p
14756         rm -f $p
14757 }
14758 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14759
14760 test_155e() {
14761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14762
14763         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14764
14765         save_writethrough $p
14766
14767         set_cache read on
14768         set_cache writethrough on
14769         test_155_big_load
14770         restore_lustre_params < $p
14771         rm -f $p
14772 }
14773 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14774
14775 test_155f() {
14776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14777
14778         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14779
14780         save_writethrough $p
14781
14782         set_cache read on
14783         set_cache writethrough off
14784         test_155_big_load
14785         restore_lustre_params < $p
14786         rm -f $p
14787 }
14788 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14789
14790 test_155g() {
14791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14792
14793         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14794
14795         save_writethrough $p
14796
14797         set_cache read off
14798         set_cache writethrough on
14799         test_155_big_load
14800         restore_lustre_params < $p
14801         rm -f $p
14802 }
14803 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14804
14805 test_155h() {
14806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14807
14808         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14809
14810         save_writethrough $p
14811
14812         set_cache read off
14813         set_cache writethrough off
14814         test_155_big_load
14815         restore_lustre_params < $p
14816         rm -f $p
14817 }
14818 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14819
14820 test_156() {
14821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14822         remote_ost_nodsh && skip "remote OST with nodsh"
14823         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14824                 skip "stats not implemented on old servers"
14825         [ "$ost1_FSTYPE" = "zfs" ] &&
14826                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14827
14828         local CPAGES=3
14829         local BEFORE
14830         local AFTER
14831         local file="$DIR/$tfile"
14832         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14833
14834         save_writethrough $p
14835         roc_hit_init
14836
14837         log "Turn on read and write cache"
14838         set_cache read on
14839         set_cache writethrough on
14840
14841         log "Write data and read it back."
14842         log "Read should be satisfied from the cache."
14843         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14844         BEFORE=$(roc_hit)
14845         cancel_lru_locks osc
14846         cat $file >/dev/null
14847         AFTER=$(roc_hit)
14848         if ! let "AFTER - BEFORE == CPAGES"; then
14849                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14850         else
14851                 log "cache hits: before: $BEFORE, after: $AFTER"
14852         fi
14853
14854         log "Read again; it should be satisfied from the cache."
14855         BEFORE=$AFTER
14856         cancel_lru_locks osc
14857         cat $file >/dev/null
14858         AFTER=$(roc_hit)
14859         if ! let "AFTER - BEFORE == CPAGES"; then
14860                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14861         else
14862                 log "cache hits:: before: $BEFORE, after: $AFTER"
14863         fi
14864
14865         log "Turn off the read cache and turn on the write cache"
14866         set_cache read off
14867         set_cache writethrough on
14868
14869         log "Read again; it should be satisfied from the cache."
14870         BEFORE=$(roc_hit)
14871         cancel_lru_locks osc
14872         cat $file >/dev/null
14873         AFTER=$(roc_hit)
14874         if ! let "AFTER - BEFORE == CPAGES"; then
14875                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14876         else
14877                 log "cache hits:: before: $BEFORE, after: $AFTER"
14878         fi
14879
14880         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14881                 # > 2.12.56 uses pagecache if cached
14882                 log "Read again; it should not be satisfied from the cache."
14883                 BEFORE=$AFTER
14884                 cancel_lru_locks osc
14885                 cat $file >/dev/null
14886                 AFTER=$(roc_hit)
14887                 if ! let "AFTER - BEFORE == 0"; then
14888                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14889                 else
14890                         log "cache hits:: before: $BEFORE, after: $AFTER"
14891                 fi
14892         fi
14893
14894         log "Write data and read it back."
14895         log "Read should be satisfied from the cache."
14896         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14897         BEFORE=$(roc_hit)
14898         cancel_lru_locks osc
14899         cat $file >/dev/null
14900         AFTER=$(roc_hit)
14901         if ! let "AFTER - BEFORE == CPAGES"; then
14902                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14903         else
14904                 log "cache hits:: before: $BEFORE, after: $AFTER"
14905         fi
14906
14907         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14908                 # > 2.12.56 uses pagecache if cached
14909                 log "Read again; it should not be satisfied from the cache."
14910                 BEFORE=$AFTER
14911                 cancel_lru_locks osc
14912                 cat $file >/dev/null
14913                 AFTER=$(roc_hit)
14914                 if ! let "AFTER - BEFORE == 0"; then
14915                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14916                 else
14917                         log "cache hits:: before: $BEFORE, after: $AFTER"
14918                 fi
14919         fi
14920
14921         log "Turn off read and write cache"
14922         set_cache read off
14923         set_cache writethrough off
14924
14925         log "Write data and read it back"
14926         log "It should not be satisfied from the cache."
14927         rm -f $file
14928         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14929         cancel_lru_locks osc
14930         BEFORE=$(roc_hit)
14931         cat $file >/dev/null
14932         AFTER=$(roc_hit)
14933         if ! let "AFTER - BEFORE == 0"; then
14934                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14935         else
14936                 log "cache hits:: before: $BEFORE, after: $AFTER"
14937         fi
14938
14939         log "Turn on the read cache and turn off the write cache"
14940         set_cache read on
14941         set_cache writethrough off
14942
14943         log "Write data and read it back"
14944         log "It should not be satisfied from the cache."
14945         rm -f $file
14946         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14947         BEFORE=$(roc_hit)
14948         cancel_lru_locks osc
14949         cat $file >/dev/null
14950         AFTER=$(roc_hit)
14951         if ! let "AFTER - BEFORE == 0"; then
14952                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14953         else
14954                 log "cache hits:: before: $BEFORE, after: $AFTER"
14955         fi
14956
14957         log "Read again; it should be satisfied from the cache."
14958         BEFORE=$(roc_hit)
14959         cancel_lru_locks osc
14960         cat $file >/dev/null
14961         AFTER=$(roc_hit)
14962         if ! let "AFTER - BEFORE == CPAGES"; then
14963                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14964         else
14965                 log "cache hits:: before: $BEFORE, after: $AFTER"
14966         fi
14967
14968         restore_lustre_params < $p
14969         rm -f $p $file
14970 }
14971 run_test 156 "Verification of tunables"
14972
14973 test_160a() {
14974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14975         remote_mds_nodsh && skip "remote MDS with nodsh"
14976         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14977                 skip "Need MDS version at least 2.2.0"
14978
14979         changelog_register || error "changelog_register failed"
14980         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14981         changelog_users $SINGLEMDS | grep -q $cl_user ||
14982                 error "User $cl_user not found in changelog_users"
14983
14984         # change something
14985         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14986         changelog_clear 0 || error "changelog_clear failed"
14987         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14988         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14989         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14990         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14991         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14992         rm $DIR/$tdir/pics/desktop.jpg
14993
14994         changelog_dump | tail -10
14995
14996         echo "verifying changelog mask"
14997         changelog_chmask "-MKDIR"
14998         changelog_chmask "-CLOSE"
14999
15000         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15001         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15002
15003         changelog_chmask "+MKDIR"
15004         changelog_chmask "+CLOSE"
15005
15006         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15007         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15008
15009         changelog_dump | tail -10
15010         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15011         CLOSES=$(changelog_dump | grep -c "CLOSE")
15012         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15013         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15014
15015         # verify contents
15016         echo "verifying target fid"
15017         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15018         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15019         [ "$fidc" == "$fidf" ] ||
15020                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15021         echo "verifying parent fid"
15022         # The FID returned from the Changelog may be the directory shard on
15023         # a different MDT, and not the FID returned by path2fid on the parent.
15024         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15025         # since this is what will matter when recreating this file in the tree.
15026         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15027         local pathp=$($LFS fid2path $MOUNT "$fidp")
15028         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15029                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15030
15031         echo "getting records for $cl_user"
15032         changelog_users $SINGLEMDS
15033         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15034         local nclr=3
15035         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15036                 error "changelog_clear failed"
15037         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15038         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15039         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15040                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15041
15042         local min0_rec=$(changelog_users $SINGLEMDS |
15043                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15044         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15045                           awk '{ print $1; exit; }')
15046
15047         changelog_dump | tail -n 5
15048         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15049         [ $first_rec == $((min0_rec + 1)) ] ||
15050                 error "first index should be $min0_rec + 1 not $first_rec"
15051
15052         # LU-3446 changelog index reset on MDT restart
15053         local cur_rec1=$(changelog_users $SINGLEMDS |
15054                          awk '/^current.index:/ { print $NF }')
15055         changelog_clear 0 ||
15056                 error "clear all changelog records for $cl_user failed"
15057         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15058         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15059                 error "Fail to start $SINGLEMDS"
15060         local cur_rec2=$(changelog_users $SINGLEMDS |
15061                          awk '/^current.index:/ { print $NF }')
15062         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15063         [ $cur_rec1 == $cur_rec2 ] ||
15064                 error "current index should be $cur_rec1 not $cur_rec2"
15065
15066         echo "verifying users from this test are deregistered"
15067         changelog_deregister || error "changelog_deregister failed"
15068         changelog_users $SINGLEMDS | grep -q $cl_user &&
15069                 error "User '$cl_user' still in changelog_users"
15070
15071         # lctl get_param -n mdd.*.changelog_users
15072         # current index: 144
15073         # ID    index (idle seconds)
15074         # cl3   144 (2)
15075         if ! changelog_users $SINGLEMDS | grep "^cl"; then
15076                 # this is the normal case where all users were deregistered
15077                 # make sure no new records are added when no users are present
15078                 local last_rec1=$(changelog_users $SINGLEMDS |
15079                                   awk '/^current.index:/ { print $NF }')
15080                 touch $DIR/$tdir/chloe
15081                 local last_rec2=$(changelog_users $SINGLEMDS |
15082                                   awk '/^current.index:/ { print $NF }')
15083                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15084                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15085         else
15086                 # any changelog users must be leftovers from a previous test
15087                 changelog_users $SINGLEMDS
15088                 echo "other changelog users; can't verify off"
15089         fi
15090 }
15091 run_test 160a "changelog sanity"
15092
15093 test_160b() { # LU-3587
15094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15095         remote_mds_nodsh && skip "remote MDS with nodsh"
15096         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15097                 skip "Need MDS version at least 2.2.0"
15098
15099         changelog_register || error "changelog_register failed"
15100         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15101         changelog_users $SINGLEMDS | grep -q $cl_user ||
15102                 error "User '$cl_user' not found in changelog_users"
15103
15104         local longname1=$(str_repeat a 255)
15105         local longname2=$(str_repeat b 255)
15106
15107         cd $DIR
15108         echo "creating very long named file"
15109         touch $longname1 || error "create of '$longname1' failed"
15110         echo "renaming very long named file"
15111         mv $longname1 $longname2
15112
15113         changelog_dump | grep RENME | tail -n 5
15114         rm -f $longname2
15115 }
15116 run_test 160b "Verify that very long rename doesn't crash in changelog"
15117
15118 test_160c() {
15119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15120         remote_mds_nodsh && skip "remote MDS with nodsh"
15121
15122         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15123                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15124                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15125                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15126
15127         local rc=0
15128
15129         # Registration step
15130         changelog_register || error "changelog_register failed"
15131
15132         rm -rf $DIR/$tdir
15133         mkdir -p $DIR/$tdir
15134         $MCREATE $DIR/$tdir/foo_160c
15135         changelog_chmask "-TRUNC"
15136         $TRUNCATE $DIR/$tdir/foo_160c 200
15137         changelog_chmask "+TRUNC"
15138         $TRUNCATE $DIR/$tdir/foo_160c 199
15139         changelog_dump | tail -n 5
15140         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15141         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15142 }
15143 run_test 160c "verify that changelog log catch the truncate event"
15144
15145 test_160d() {
15146         remote_mds_nodsh && skip "remote MDS with nodsh"
15147         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15149         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15150                 skip "Need MDS version at least 2.7.60"
15151
15152         # Registration step
15153         changelog_register || error "changelog_register failed"
15154
15155         mkdir -p $DIR/$tdir/migrate_dir
15156         changelog_clear 0 || error "changelog_clear failed"
15157
15158         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15159         changelog_dump | tail -n 5
15160         local migrates=$(changelog_dump | grep -c "MIGRT")
15161         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15162 }
15163 run_test 160d "verify that changelog log catch the migrate event"
15164
15165 test_160e() {
15166         remote_mds_nodsh && skip "remote MDS with nodsh"
15167
15168         # Create a user
15169         changelog_register || error "changelog_register failed"
15170
15171         # Delete a future user (expect fail)
15172         local MDT0=$(facet_svc $SINGLEMDS)
15173         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15174         local rc=$?
15175
15176         if [ $rc -eq 0 ]; then
15177                 error "Deleted non-existant user cl77"
15178         elif [ $rc -ne 2 ]; then
15179                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15180         fi
15181
15182         # Clear to a bad index (1 billion should be safe)
15183         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15184         rc=$?
15185
15186         if [ $rc -eq 0 ]; then
15187                 error "Successfully cleared to invalid CL index"
15188         elif [ $rc -ne 22 ]; then
15189                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15190         fi
15191 }
15192 run_test 160e "changelog negative testing (should return errors)"
15193
15194 test_160f() {
15195         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15196         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15197                 skip "Need MDS version at least 2.10.56"
15198
15199         local mdts=$(comma_list $(mdts_nodes))
15200
15201         # Create a user
15202         changelog_register || error "first changelog_register failed"
15203         changelog_register || error "second changelog_register failed"
15204         local cl_users
15205         declare -A cl_user1
15206         declare -A cl_user2
15207         local user_rec1
15208         local user_rec2
15209         local i
15210
15211         # generate some changelog records to accumulate on each MDT
15212         # use all_char because created files should be evenly distributed
15213         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15214                 error "test_mkdir $tdir failed"
15215         log "$(date +%s): creating first files"
15216         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15217                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15218                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15219         done
15220
15221         # check changelogs have been generated
15222         local start=$SECONDS
15223         local idle_time=$((MDSCOUNT * 5 + 5))
15224         local nbcl=$(changelog_dump | wc -l)
15225         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15226
15227         for param in "changelog_max_idle_time=$idle_time" \
15228                      "changelog_gc=1" \
15229                      "changelog_min_gc_interval=2" \
15230                      "changelog_min_free_cat_entries=3"; do
15231                 local MDT0=$(facet_svc $SINGLEMDS)
15232                 local var="${param%=*}"
15233                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15234
15235                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15236                 do_nodes $mdts $LCTL set_param mdd.*.$param
15237         done
15238
15239         # force cl_user2 to be idle (1st part), but also cancel the
15240         # cl_user1 records so that it is not evicted later in the test.
15241         local sleep1=$((idle_time / 2))
15242         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15243         sleep $sleep1
15244
15245         # simulate changelog catalog almost full
15246         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15247         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15248
15249         for i in $(seq $MDSCOUNT); do
15250                 cl_users=(${CL_USERS[mds$i]})
15251                 cl_user1[mds$i]="${cl_users[0]}"
15252                 cl_user2[mds$i]="${cl_users[1]}"
15253
15254                 [ -n "${cl_user1[mds$i]}" ] ||
15255                         error "mds$i: no user registered"
15256                 [ -n "${cl_user2[mds$i]}" ] ||
15257                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15258
15259                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15260                 [ -n "$user_rec1" ] ||
15261                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15262                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15263                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15264                 [ -n "$user_rec2" ] ||
15265                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15266                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15267                      "$user_rec1 + 2 == $user_rec2"
15268                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15269                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15270                               "$user_rec1 + 2, but is $user_rec2"
15271                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15272                 [ -n "$user_rec2" ] ||
15273                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15274                 [ $user_rec1 == $user_rec2 ] ||
15275                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15276                               "$user_rec1, but is $user_rec2"
15277         done
15278
15279         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15280         local sleep2=$((idle_time - (SECONDS - start) + 1))
15281         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15282         sleep $sleep2
15283
15284         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15285         # cl_user1 should be OK because it recently processed records.
15286         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15287         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15288                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15289                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15290         done
15291
15292         # ensure gc thread is done
15293         for i in $(mdts_nodes); do
15294                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15295                         error "$i: GC-thread not done"
15296         done
15297
15298         local first_rec
15299         for (( i = 1; i <= MDSCOUNT; i++ )); do
15300                 # check cl_user1 still registered
15301                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15302                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15303                 # check cl_user2 unregistered
15304                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15305                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15306
15307                 # check changelogs are present and starting at $user_rec1 + 1
15308                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15309                 [ -n "$user_rec1" ] ||
15310                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15311                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15312                             awk '{ print $1; exit; }')
15313
15314                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15315                 [ $((user_rec1 + 1)) == $first_rec ] ||
15316                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15317         done
15318 }
15319 run_test 160f "changelog garbage collect (timestamped users)"
15320
15321 test_160g() {
15322         remote_mds_nodsh && skip "remote MDS with nodsh"
15323         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15324                 skip "Need MDS version at least 2.10.56"
15325
15326         local mdts=$(comma_list $(mdts_nodes))
15327
15328         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15329         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15330
15331         # Create a user
15332         changelog_register || error "first changelog_register failed"
15333         changelog_register || error "second changelog_register failed"
15334         local cl_users
15335         declare -A cl_user1
15336         declare -A cl_user2
15337         local user_rec1
15338         local user_rec2
15339         local i
15340
15341         # generate some changelog records to accumulate on each MDT
15342         # use all_char because created files should be evenly distributed
15343         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15344                 error "test_mkdir $tdir failed"
15345         for ((i = 0; i < MDSCOUNT; i++)); do
15346                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15347                         error "create $DIR/$tdir/d$i.1 failed"
15348         done
15349
15350         # check changelogs have been generated
15351         local nbcl=$(changelog_dump | wc -l)
15352         (( $nbcl > 0 )) || error "no changelogs found"
15353
15354         # reduce the max_idle_indexes value to make sure we exceed it
15355         for param in "changelog_max_idle_indexes=1" \
15356                      "changelog_gc=1" \
15357                      "changelog_min_gc_interval=2" \
15358                      "changelog_min_free_cat_entries=3"; do
15359                 local MDT0=$(facet_svc $SINGLEMDS)
15360                 local var="${param%=*}"
15361                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15362
15363                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15364                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15365                         error "unable to set mdd.*.$param"
15366         done
15367
15368         # simulate changelog catalog almost full
15369         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15370         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15371
15372         local start=$SECONDS
15373         for i in $(seq $MDSCOUNT); do
15374                 cl_users=(${CL_USERS[mds$i]})
15375                 cl_user1[mds$i]="${cl_users[0]}"
15376                 cl_user2[mds$i]="${cl_users[1]}"
15377
15378                 [ -n "${cl_user1[mds$i]}" ] ||
15379                         error "mds$i: no user registered"
15380                 [ -n "${cl_user2[mds$i]}" ] ||
15381                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15382
15383                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15384                 [ -n "$user_rec1" ] ||
15385                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15386                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15387                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15388                 [ -n "$user_rec2" ] ||
15389                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15390                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15391                      "$user_rec1 + 2 == $user_rec2"
15392                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15393                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15394                               "$user_rec1 + 2, but is $user_rec2"
15395                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15396                 [ -n "$user_rec2" ] ||
15397                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15398                 [ $user_rec1 == $user_rec2 ] ||
15399                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15400                               "$user_rec1, but is $user_rec2"
15401         done
15402
15403         # ensure we are past the previous changelog_min_gc_interval set above
15404         local sleep2=$((start + 2 - SECONDS))
15405         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15406
15407         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15408         # cl_user1 should be OK because it recently processed records.
15409         for ((i = 0; i < MDSCOUNT; i++)); do
15410                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15411                         error "create $DIR/$tdir/d$i.3 failed"
15412         done
15413
15414         # ensure gc thread is done
15415         for i in $(mdts_nodes); do
15416                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15417                         error "$i: GC-thread not done"
15418         done
15419
15420         local first_rec
15421         for (( i = 1; i <= MDSCOUNT; i++ )); do
15422                 # check cl_user1 still registered
15423                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15424                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15425                 # check cl_user2 unregistered
15426                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15427                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15428
15429                 # check changelogs are present and starting at $user_rec1 + 1
15430                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15431                 [ -n "$user_rec1" ] ||
15432                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15433                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15434                             awk '{ print $1; exit; }')
15435
15436                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15437                 [ $((user_rec1 + 1)) == $first_rec ] ||
15438                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15439         done
15440 }
15441 run_test 160g "changelog garbage collect (old users)"
15442
15443 test_160h() {
15444         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15445         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15446                 skip "Need MDS version at least 2.10.56"
15447
15448         local mdts=$(comma_list $(mdts_nodes))
15449
15450         # Create a user
15451         changelog_register || error "first changelog_register failed"
15452         changelog_register || error "second changelog_register failed"
15453         local cl_users
15454         declare -A cl_user1
15455         declare -A cl_user2
15456         local user_rec1
15457         local user_rec2
15458         local i
15459
15460         # generate some changelog records to accumulate on each MDT
15461         # use all_char because created files should be evenly distributed
15462         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15463                 error "test_mkdir $tdir failed"
15464         for ((i = 0; i < MDSCOUNT; i++)); do
15465                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15466                         error "create $DIR/$tdir/d$i.1 failed"
15467         done
15468
15469         # check changelogs have been generated
15470         local nbcl=$(changelog_dump | wc -l)
15471         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15472
15473         for param in "changelog_max_idle_time=10" \
15474                      "changelog_gc=1" \
15475                      "changelog_min_gc_interval=2"; do
15476                 local MDT0=$(facet_svc $SINGLEMDS)
15477                 local var="${param%=*}"
15478                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15479
15480                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15481                 do_nodes $mdts $LCTL set_param mdd.*.$param
15482         done
15483
15484         # force cl_user2 to be idle (1st part)
15485         sleep 9
15486
15487         for i in $(seq $MDSCOUNT); do
15488                 cl_users=(${CL_USERS[mds$i]})
15489                 cl_user1[mds$i]="${cl_users[0]}"
15490                 cl_user2[mds$i]="${cl_users[1]}"
15491
15492                 [ -n "${cl_user1[mds$i]}" ] ||
15493                         error "mds$i: no user registered"
15494                 [ -n "${cl_user2[mds$i]}" ] ||
15495                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15496
15497                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15498                 [ -n "$user_rec1" ] ||
15499                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15500                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15501                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15502                 [ -n "$user_rec2" ] ||
15503                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15504                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15505                      "$user_rec1 + 2 == $user_rec2"
15506                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15507                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15508                               "$user_rec1 + 2, but is $user_rec2"
15509                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15510                 [ -n "$user_rec2" ] ||
15511                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15512                 [ $user_rec1 == $user_rec2 ] ||
15513                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15514                               "$user_rec1, but is $user_rec2"
15515         done
15516
15517         # force cl_user2 to be idle (2nd part) and to reach
15518         # changelog_max_idle_time
15519         sleep 2
15520
15521         # force each GC-thread start and block then
15522         # one per MDT/MDD, set fail_val accordingly
15523         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15524         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15525
15526         # generate more changelogs to trigger fail_loc
15527         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15528                 error "create $DIR/$tdir/${tfile}bis failed"
15529
15530         # stop MDT to stop GC-thread, should be done in back-ground as it will
15531         # block waiting for the thread to be released and exit
15532         declare -A stop_pids
15533         for i in $(seq $MDSCOUNT); do
15534                 stop mds$i &
15535                 stop_pids[mds$i]=$!
15536         done
15537
15538         for i in $(mdts_nodes); do
15539                 local facet
15540                 local nb=0
15541                 local facets=$(facets_up_on_host $i)
15542
15543                 for facet in ${facets//,/ }; do
15544                         if [[ $facet == mds* ]]; then
15545                                 nb=$((nb + 1))
15546                         fi
15547                 done
15548                 # ensure each MDS's gc threads are still present and all in "R"
15549                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15550                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15551                         error "$i: expected $nb GC-thread"
15552                 wait_update $i \
15553                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15554                         "R" 20 ||
15555                         error "$i: GC-thread not found in R-state"
15556                 # check umounts of each MDT on MDS have reached kthread_stop()
15557                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15558                         error "$i: expected $nb umount"
15559                 wait_update $i \
15560                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15561                         error "$i: umount not found in D-state"
15562         done
15563
15564         # release all GC-threads
15565         do_nodes $mdts $LCTL set_param fail_loc=0
15566
15567         # wait for MDT stop to complete
15568         for i in $(seq $MDSCOUNT); do
15569                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15570         done
15571
15572         # XXX
15573         # may try to check if any orphan changelog records are present
15574         # via ldiskfs/zfs and llog_reader...
15575
15576         # re-start/mount MDTs
15577         for i in $(seq $MDSCOUNT); do
15578                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15579                         error "Fail to start mds$i"
15580         done
15581
15582         local first_rec
15583         for i in $(seq $MDSCOUNT); do
15584                 # check cl_user1 still registered
15585                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15586                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15587                 # check cl_user2 unregistered
15588                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15589                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15590
15591                 # check changelogs are present and starting at $user_rec1 + 1
15592                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15593                 [ -n "$user_rec1" ] ||
15594                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15595                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15596                             awk '{ print $1; exit; }')
15597
15598                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15599                 [ $((user_rec1 + 1)) == $first_rec ] ||
15600                         error "mds$i: first index should be $user_rec1 + 1, " \
15601                               "but is $first_rec"
15602         done
15603 }
15604 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15605               "during mount"
15606
15607 test_160i() {
15608
15609         local mdts=$(comma_list $(mdts_nodes))
15610
15611         changelog_register || error "first changelog_register failed"
15612
15613         # generate some changelog records to accumulate on each MDT
15614         # use all_char because created files should be evenly distributed
15615         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15616                 error "test_mkdir $tdir failed"
15617         for ((i = 0; i < MDSCOUNT; i++)); do
15618                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15619                         error "create $DIR/$tdir/d$i.1 failed"
15620         done
15621
15622         # check changelogs have been generated
15623         local nbcl=$(changelog_dump | wc -l)
15624         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15625
15626         # simulate race between register and unregister
15627         # XXX as fail_loc is set per-MDS, with DNE configs the race
15628         # simulation will only occur for one MDT per MDS and for the
15629         # others the normal race scenario will take place
15630         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15631         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15632         do_nodes $mdts $LCTL set_param fail_val=1
15633
15634         # unregister 1st user
15635         changelog_deregister &
15636         local pid1=$!
15637         # wait some time for deregister work to reach race rdv
15638         sleep 2
15639         # register 2nd user
15640         changelog_register || error "2nd user register failed"
15641
15642         wait $pid1 || error "1st user deregister failed"
15643
15644         local i
15645         local last_rec
15646         declare -A LAST_REC
15647         for i in $(seq $MDSCOUNT); do
15648                 if changelog_users mds$i | grep "^cl"; then
15649                         # make sure new records are added with one user present
15650                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15651                                           awk '/^current.index:/ { print $NF }')
15652                 else
15653                         error "mds$i has no user registered"
15654                 fi
15655         done
15656
15657         # generate more changelog records to accumulate on each MDT
15658         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15659                 error "create $DIR/$tdir/${tfile}bis failed"
15660
15661         for i in $(seq $MDSCOUNT); do
15662                 last_rec=$(changelog_users $SINGLEMDS |
15663                            awk '/^current.index:/ { print $NF }')
15664                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15665                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15666                         error "changelogs are off on mds$i"
15667         done
15668 }
15669 run_test 160i "changelog user register/unregister race"
15670
15671 test_160j() {
15672         remote_mds_nodsh && skip "remote MDS with nodsh"
15673         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15674                 skip "Need MDS version at least 2.12.56"
15675
15676         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15677         stack_trap "umount $MOUNT2" EXIT
15678
15679         changelog_register || error "first changelog_register failed"
15680         stack_trap "changelog_deregister" EXIT
15681
15682         # generate some changelog
15683         # use all_char because created files should be evenly distributed
15684         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15685                 error "mkdir $tdir failed"
15686         for ((i = 0; i < MDSCOUNT; i++)); do
15687                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15688                         error "create $DIR/$tdir/d$i.1 failed"
15689         done
15690
15691         # open the changelog device
15692         exec 3>/dev/changelog-$FSNAME-MDT0000
15693         stack_trap "exec 3>&-" EXIT
15694         exec 4</dev/changelog-$FSNAME-MDT0000
15695         stack_trap "exec 4<&-" EXIT
15696
15697         # umount the first lustre mount
15698         umount $MOUNT
15699         stack_trap "mount_client $MOUNT" EXIT
15700
15701         # read changelog, which may or may not fail, but should not crash
15702         cat <&4 >/dev/null
15703
15704         # clear changelog
15705         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15706         changelog_users $SINGLEMDS | grep -q $cl_user ||
15707                 error "User $cl_user not found in changelog_users"
15708
15709         printf 'clear:'$cl_user':0' >&3
15710 }
15711 run_test 160j "client can be umounted while its chanangelog is being used"
15712
15713 test_160k() {
15714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15715         remote_mds_nodsh && skip "remote MDS with nodsh"
15716
15717         mkdir -p $DIR/$tdir/1/1
15718
15719         changelog_register || error "changelog_register failed"
15720         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15721
15722         changelog_users $SINGLEMDS | grep -q $cl_user ||
15723                 error "User '$cl_user' not found in changelog_users"
15724 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15725         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15726         rmdir $DIR/$tdir/1/1 & sleep 1
15727         mkdir $DIR/$tdir/2
15728         touch $DIR/$tdir/2/2
15729         rm -rf $DIR/$tdir/2
15730
15731         wait
15732         sleep 4
15733
15734         changelog_dump | grep rmdir || error "rmdir not recorded"
15735 }
15736 run_test 160k "Verify that changelog records are not lost"
15737
15738 # Verifies that a file passed as a parameter has recently had an operation
15739 # performed on it that has generated an MTIME changelog which contains the
15740 # correct parent FID. As files might reside on a different MDT from the
15741 # parent directory in DNE configurations, the FIDs are translated to paths
15742 # before being compared, which should be identical
15743 compare_mtime_changelog() {
15744         local file="${1}"
15745         local mdtidx
15746         local mtime
15747         local cl_fid
15748         local pdir
15749         local dir
15750
15751         mdtidx=$($LFS getstripe --mdt-index $file)
15752         mdtidx=$(printf "%04x" $mdtidx)
15753
15754         # Obtain the parent FID from the MTIME changelog
15755         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15756         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15757
15758         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15759         [ -z "$cl_fid" ] && error "parent FID not present"
15760
15761         # Verify that the path for the parent FID is the same as the path for
15762         # the test directory
15763         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15764
15765         dir=$(dirname $1)
15766
15767         [[ "${pdir%/}" == "$dir" ]] ||
15768                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15769 }
15770
15771 test_160l() {
15772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15773
15774         remote_mds_nodsh && skip "remote MDS with nodsh"
15775         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15776                 skip "Need MDS version at least 2.13.55"
15777
15778         local cl_user
15779
15780         changelog_register || error "changelog_register failed"
15781         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15782
15783         changelog_users $SINGLEMDS | grep -q $cl_user ||
15784                 error "User '$cl_user' not found in changelog_users"
15785
15786         # Clear some types so that MTIME changelogs are generated
15787         changelog_chmask "-CREAT"
15788         changelog_chmask "-CLOSE"
15789
15790         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15791
15792         # Test CL_MTIME during setattr
15793         touch $DIR/$tdir/$tfile
15794         compare_mtime_changelog $DIR/$tdir/$tfile
15795
15796         # Test CL_MTIME during close
15797         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15798         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15799 }
15800 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15801
15802 test_160m() {
15803         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15804         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
15805                 skip "Need MDS version at least 2.14.51"
15806         local cl_users
15807         local cl_user1
15808         local cl_user2
15809         local pid1
15810
15811         # Create a user
15812         changelog_register || error "first changelog_register failed"
15813         changelog_register || error "second changelog_register failed"
15814
15815         cl_users=(${CL_USERS[mds1]})
15816         cl_user1="${cl_users[0]}"
15817         cl_user2="${cl_users[1]}"
15818         # generate some changelog records to accumulate on MDT0
15819         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
15820         createmany -m $DIR/$tdir/$tfile 50 ||
15821                 error "create $DIR/$tdir/$tfile failed"
15822         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
15823         rm -f $DIR/$tdir
15824
15825         # check changelogs have been generated
15826         local nbcl=$(changelog_dump | wc -l)
15827         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15828
15829 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
15830         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
15831
15832         __changelog_clear mds1 $cl_user1 +10
15833         __changelog_clear mds1 $cl_user2 0 &
15834         pid1=$!
15835         sleep 2
15836         __changelog_clear mds1 $cl_user1 0 ||
15837                 error "fail to cancel record for $cl_user1"
15838         wait $pid1
15839         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
15840 }
15841 run_test 160m "Changelog clear race"
15842
15843
15844 test_161a() {
15845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15846
15847         test_mkdir -c1 $DIR/$tdir
15848         cp /etc/hosts $DIR/$tdir/$tfile
15849         test_mkdir -c1 $DIR/$tdir/foo1
15850         test_mkdir -c1 $DIR/$tdir/foo2
15851         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15852         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15853         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15854         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15855         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15856         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15857                 $LFS fid2path $DIR $FID
15858                 error "bad link ea"
15859         fi
15860         # middle
15861         rm $DIR/$tdir/foo2/zachary
15862         # last
15863         rm $DIR/$tdir/foo2/thor
15864         # first
15865         rm $DIR/$tdir/$tfile
15866         # rename
15867         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15868         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15869                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15870         rm $DIR/$tdir/foo2/maggie
15871
15872         # overflow the EA
15873         local longname=$tfile.avg_len_is_thirty_two_
15874         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15875                 error_noexit 'failed to unlink many hardlinks'" EXIT
15876         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15877                 error "failed to hardlink many files"
15878         links=$($LFS fid2path $DIR $FID | wc -l)
15879         echo -n "${links}/1000 links in link EA"
15880         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15881 }
15882 run_test 161a "link ea sanity"
15883
15884 test_161b() {
15885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15886         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15887
15888         local MDTIDX=1
15889         local remote_dir=$DIR/$tdir/remote_dir
15890
15891         mkdir -p $DIR/$tdir
15892         $LFS mkdir -i $MDTIDX $remote_dir ||
15893                 error "create remote directory failed"
15894
15895         cp /etc/hosts $remote_dir/$tfile
15896         mkdir -p $remote_dir/foo1
15897         mkdir -p $remote_dir/foo2
15898         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15899         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15900         ln $remote_dir/$tfile $remote_dir/foo1/luna
15901         ln $remote_dir/$tfile $remote_dir/foo2/thor
15902
15903         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15904                      tr -d ']')
15905         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15906                 $LFS fid2path $DIR $FID
15907                 error "bad link ea"
15908         fi
15909         # middle
15910         rm $remote_dir/foo2/zachary
15911         # last
15912         rm $remote_dir/foo2/thor
15913         # first
15914         rm $remote_dir/$tfile
15915         # rename
15916         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15917         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15918         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15919                 $LFS fid2path $DIR $FID
15920                 error "bad link rename"
15921         fi
15922         rm $remote_dir/foo2/maggie
15923
15924         # overflow the EA
15925         local longname=filename_avg_len_is_thirty_two_
15926         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15927                 error "failed to hardlink many files"
15928         links=$($LFS fid2path $DIR $FID | wc -l)
15929         echo -n "${links}/1000 links in link EA"
15930         [[ ${links} -gt 60 ]] ||
15931                 error "expected at least 60 links in link EA"
15932         unlinkmany $remote_dir/foo2/$longname 1000 ||
15933         error "failed to unlink many hardlinks"
15934 }
15935 run_test 161b "link ea sanity under remote directory"
15936
15937 test_161c() {
15938         remote_mds_nodsh && skip "remote MDS with nodsh"
15939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15940         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15941                 skip "Need MDS version at least 2.1.5"
15942
15943         # define CLF_RENAME_LAST 0x0001
15944         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15945         changelog_register || error "changelog_register failed"
15946
15947         rm -rf $DIR/$tdir
15948         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15949         touch $DIR/$tdir/foo_161c
15950         touch $DIR/$tdir/bar_161c
15951         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15952         changelog_dump | grep RENME | tail -n 5
15953         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15954         changelog_clear 0 || error "changelog_clear failed"
15955         if [ x$flags != "x0x1" ]; then
15956                 error "flag $flags is not 0x1"
15957         fi
15958
15959         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15960         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15961         touch $DIR/$tdir/foo_161c
15962         touch $DIR/$tdir/bar_161c
15963         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15964         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15965         changelog_dump | grep RENME | tail -n 5
15966         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15967         changelog_clear 0 || error "changelog_clear failed"
15968         if [ x$flags != "x0x0" ]; then
15969                 error "flag $flags is not 0x0"
15970         fi
15971         echo "rename overwrite a target having nlink > 1," \
15972                 "changelog record has flags of $flags"
15973
15974         # rename doesn't overwrite a target (changelog flag 0x0)
15975         touch $DIR/$tdir/foo_161c
15976         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15977         changelog_dump | grep RENME | tail -n 5
15978         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15979         changelog_clear 0 || error "changelog_clear failed"
15980         if [ x$flags != "x0x0" ]; then
15981                 error "flag $flags is not 0x0"
15982         fi
15983         echo "rename doesn't overwrite a target," \
15984                 "changelog record has flags of $flags"
15985
15986         # define CLF_UNLINK_LAST 0x0001
15987         # unlink a file having nlink = 1 (changelog flag 0x1)
15988         rm -f $DIR/$tdir/foo2_161c
15989         changelog_dump | grep UNLNK | tail -n 5
15990         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15991         changelog_clear 0 || error "changelog_clear failed"
15992         if [ x$flags != "x0x1" ]; then
15993                 error "flag $flags is not 0x1"
15994         fi
15995         echo "unlink a file having nlink = 1," \
15996                 "changelog record has flags of $flags"
15997
15998         # unlink a file having nlink > 1 (changelog flag 0x0)
15999         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16000         rm -f $DIR/$tdir/foobar_161c
16001         changelog_dump | grep UNLNK | tail -n 5
16002         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16003         changelog_clear 0 || error "changelog_clear failed"
16004         if [ x$flags != "x0x0" ]; then
16005                 error "flag $flags is not 0x0"
16006         fi
16007         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16008 }
16009 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16010
16011 test_161d() {
16012         remote_mds_nodsh && skip "remote MDS with nodsh"
16013         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16014
16015         local pid
16016         local fid
16017
16018         changelog_register || error "changelog_register failed"
16019
16020         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16021         # interfer with $MOUNT/.lustre/fid/ access
16022         mkdir $DIR/$tdir
16023         [[ $? -eq 0 ]] || error "mkdir failed"
16024
16025         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16026         $LCTL set_param fail_loc=0x8000140c
16027         # 5s pause
16028         $LCTL set_param fail_val=5
16029
16030         # create file
16031         echo foofoo > $DIR/$tdir/$tfile &
16032         pid=$!
16033
16034         # wait for create to be delayed
16035         sleep 2
16036
16037         ps -p $pid
16038         [[ $? -eq 0 ]] || error "create should be blocked"
16039
16040         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16041         stack_trap "rm -f $tempfile"
16042         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16043         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16044         # some delay may occur during ChangeLog publishing and file read just
16045         # above, that could allow file write to happen finally
16046         [[ -s $tempfile ]] && echo "file should be empty"
16047
16048         $LCTL set_param fail_loc=0
16049
16050         wait $pid
16051         [[ $? -eq 0 ]] || error "create failed"
16052 }
16053 run_test 161d "create with concurrent .lustre/fid access"
16054
16055 check_path() {
16056         local expected="$1"
16057         shift
16058         local fid="$2"
16059
16060         local path
16061         path=$($LFS fid2path "$@")
16062         local rc=$?
16063
16064         if [ $rc -ne 0 ]; then
16065                 error "path looked up of '$expected' failed: rc=$rc"
16066         elif [ "$path" != "$expected" ]; then
16067                 error "path looked up '$path' instead of '$expected'"
16068         else
16069                 echo "FID '$fid' resolves to path '$path' as expected"
16070         fi
16071 }
16072
16073 test_162a() { # was test_162
16074         test_mkdir -p -c1 $DIR/$tdir/d2
16075         touch $DIR/$tdir/d2/$tfile
16076         touch $DIR/$tdir/d2/x1
16077         touch $DIR/$tdir/d2/x2
16078         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16079         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16080         # regular file
16081         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16082         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16083
16084         # softlink
16085         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16086         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16087         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16088
16089         # softlink to wrong file
16090         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16091         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16092         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16093
16094         # hardlink
16095         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16096         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16097         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16098         # fid2path dir/fsname should both work
16099         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16100         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16101
16102         # hardlink count: check that there are 2 links
16103         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16104         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16105
16106         # hardlink indexing: remove the first link
16107         rm $DIR/$tdir/d2/p/q/r/hlink
16108         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16109 }
16110 run_test 162a "path lookup sanity"
16111
16112 test_162b() {
16113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16114         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16115
16116         mkdir $DIR/$tdir
16117         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16118                                 error "create striped dir failed"
16119
16120         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16121                                         tail -n 1 | awk '{print $2}')
16122         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16123
16124         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16125         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16126
16127         # regular file
16128         for ((i=0;i<5;i++)); do
16129                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16130                         error "get fid for f$i failed"
16131                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16132
16133                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16134                         error "get fid for d$i failed"
16135                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16136         done
16137
16138         return 0
16139 }
16140 run_test 162b "striped directory path lookup sanity"
16141
16142 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16143 test_162c() {
16144         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16145                 skip "Need MDS version at least 2.7.51"
16146
16147         local lpath=$tdir.local
16148         local rpath=$tdir.remote
16149
16150         test_mkdir $DIR/$lpath
16151         test_mkdir $DIR/$rpath
16152
16153         for ((i = 0; i <= 101; i++)); do
16154                 lpath="$lpath/$i"
16155                 mkdir $DIR/$lpath
16156                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16157                         error "get fid for local directory $DIR/$lpath failed"
16158                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16159
16160                 rpath="$rpath/$i"
16161                 test_mkdir $DIR/$rpath
16162                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16163                         error "get fid for remote directory $DIR/$rpath failed"
16164                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16165         done
16166
16167         return 0
16168 }
16169 run_test 162c "fid2path works with paths 100 or more directories deep"
16170
16171 oalr_event_count() {
16172         local event="${1}"
16173         local trace="${2}"
16174
16175         awk -v name="${FSNAME}-OST0000" \
16176             -v event="${event}" \
16177             '$1 == "TRACE" && $2 == event && $3 == name' \
16178             "${trace}" |
16179         wc -l
16180 }
16181
16182 oalr_expect_event_count() {
16183         local event="${1}"
16184         local trace="${2}"
16185         local expect="${3}"
16186         local count
16187
16188         count=$(oalr_event_count "${event}" "${trace}")
16189         if ((count == expect)); then
16190                 return 0
16191         fi
16192
16193         error_noexit "${event} event count was '${count}', expected ${expect}"
16194         cat "${trace}" >&2
16195         exit 1
16196 }
16197
16198 cleanup_165() {
16199         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16200         stop ost1
16201         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16202 }
16203
16204 setup_165() {
16205         sync # Flush previous IOs so we can count log entries.
16206         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16207         stack_trap cleanup_165 EXIT
16208 }
16209
16210 test_165a() {
16211         local trace="/tmp/${tfile}.trace"
16212         local rc
16213         local count
16214
16215         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16216                 skip "OFD access log unsupported"
16217
16218         setup_165
16219         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16220         sleep 5
16221
16222         do_facet ost1 ofd_access_log_reader --list
16223         stop ost1
16224
16225         do_facet ost1 killall -TERM ofd_access_log_reader
16226         wait
16227         rc=$?
16228
16229         if ((rc != 0)); then
16230                 error "ofd_access_log_reader exited with rc = '${rc}'"
16231         fi
16232
16233         # Parse trace file for discovery events:
16234         oalr_expect_event_count alr_log_add "${trace}" 1
16235         oalr_expect_event_count alr_log_eof "${trace}" 1
16236         oalr_expect_event_count alr_log_free "${trace}" 1
16237 }
16238 run_test 165a "ofd access log discovery"
16239
16240 test_165b() {
16241         local trace="/tmp/${tfile}.trace"
16242         local file="${DIR}/${tfile}"
16243         local pfid1
16244         local pfid2
16245         local -a entry
16246         local rc
16247         local count
16248         local size
16249         local flags
16250
16251         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16252                 skip "OFD access log unsupported"
16253
16254         setup_165
16255         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16256         sleep 5
16257
16258         do_facet ost1 ofd_access_log_reader --list
16259
16260         lfs setstripe -c 1 -i 0 "${file}"
16261         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16262                 error "cannot create '${file}'"
16263
16264         sleep 5
16265         do_facet ost1 killall -TERM ofd_access_log_reader
16266         wait
16267         rc=$?
16268
16269         if ((rc != 0)); then
16270                 error "ofd_access_log_reader exited with rc = '${rc}'"
16271         fi
16272
16273         oalr_expect_event_count alr_log_entry "${trace}" 1
16274
16275         pfid1=$($LFS path2fid "${file}")
16276
16277         # 1     2             3   4    5     6   7    8    9     10
16278         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16279         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16280
16281         echo "entry = '${entry[*]}'" >&2
16282
16283         pfid2=${entry[4]}
16284         if [[ "${pfid1}" != "${pfid2}" ]]; then
16285                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16286         fi
16287
16288         size=${entry[8]}
16289         if ((size != 1048576)); then
16290                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16291         fi
16292
16293         flags=${entry[10]}
16294         if [[ "${flags}" != "w" ]]; then
16295                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16296         fi
16297
16298         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16299         sleep 5
16300
16301         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16302                 error "cannot read '${file}'"
16303         sleep 5
16304
16305         do_facet ost1 killall -TERM ofd_access_log_reader
16306         wait
16307         rc=$?
16308
16309         if ((rc != 0)); then
16310                 error "ofd_access_log_reader exited with rc = '${rc}'"
16311         fi
16312
16313         oalr_expect_event_count alr_log_entry "${trace}" 1
16314
16315         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16316         echo "entry = '${entry[*]}'" >&2
16317
16318         pfid2=${entry[4]}
16319         if [[ "${pfid1}" != "${pfid2}" ]]; then
16320                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16321         fi
16322
16323         size=${entry[8]}
16324         if ((size != 524288)); then
16325                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16326         fi
16327
16328         flags=${entry[10]}
16329         if [[ "${flags}" != "r" ]]; then
16330                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16331         fi
16332 }
16333 run_test 165b "ofd access log entries are produced and consumed"
16334
16335 test_165c() {
16336         local trace="/tmp/${tfile}.trace"
16337         local file="${DIR}/${tdir}/${tfile}"
16338
16339         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16340                 skip "OFD access log unsupported"
16341
16342         test_mkdir "${DIR}/${tdir}"
16343
16344         setup_165
16345         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16346         sleep 5
16347
16348         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16349
16350         # 4096 / 64 = 64. Create twice as many entries.
16351         for ((i = 0; i < 128; i++)); do
16352                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16353                         error "cannot create file"
16354         done
16355
16356         sync
16357
16358         do_facet ost1 killall -TERM ofd_access_log_reader
16359         wait
16360         rc=$?
16361         if ((rc != 0)); then
16362                 error "ofd_access_log_reader exited with rc = '${rc}'"
16363         fi
16364
16365         unlinkmany  "${file}-%d" 128
16366 }
16367 run_test 165c "full ofd access logs do not block IOs"
16368
16369 oal_get_read_count() {
16370         local stats="$1"
16371
16372         # STATS lustre-OST0001 alr_read_count 1
16373
16374         do_facet ost1 cat "${stats}" |
16375         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16376              END { print count; }'
16377 }
16378
16379 oal_expect_read_count() {
16380         local stats="$1"
16381         local count
16382         local expect="$2"
16383
16384         # Ask ofd_access_log_reader to write stats.
16385         do_facet ost1 killall -USR1 ofd_access_log_reader
16386
16387         # Allow some time for things to happen.
16388         sleep 1
16389
16390         count=$(oal_get_read_count "${stats}")
16391         if ((count == expect)); then
16392                 return 0
16393         fi
16394
16395         error_noexit "bad read count, got ${count}, expected ${expect}"
16396         do_facet ost1 cat "${stats}" >&2
16397         exit 1
16398 }
16399
16400 test_165d() {
16401         local stats="/tmp/${tfile}.stats"
16402         local file="${DIR}/${tdir}/${tfile}"
16403         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16404
16405         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16406                 skip "OFD access log unsupported"
16407
16408         test_mkdir "${DIR}/${tdir}"
16409
16410         setup_165
16411         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16412         sleep 5
16413
16414         lfs setstripe -c 1 -i 0 "${file}"
16415
16416         do_facet ost1 lctl set_param "${param}=rw"
16417         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16418                 error "cannot create '${file}'"
16419         oal_expect_read_count "${stats}" 1
16420
16421         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16422                 error "cannot read '${file}'"
16423         oal_expect_read_count "${stats}" 2
16424
16425         do_facet ost1 lctl set_param "${param}=r"
16426         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16427                 error "cannot create '${file}'"
16428         oal_expect_read_count "${stats}" 2
16429
16430         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16431                 error "cannot read '${file}'"
16432         oal_expect_read_count "${stats}" 3
16433
16434         do_facet ost1 lctl set_param "${param}=w"
16435         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16436                 error "cannot create '${file}'"
16437         oal_expect_read_count "${stats}" 4
16438
16439         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16440                 error "cannot read '${file}'"
16441         oal_expect_read_count "${stats}" 4
16442
16443         do_facet ost1 lctl set_param "${param}=0"
16444         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16445                 error "cannot create '${file}'"
16446         oal_expect_read_count "${stats}" 4
16447
16448         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16449                 error "cannot read '${file}'"
16450         oal_expect_read_count "${stats}" 4
16451
16452         do_facet ost1 killall -TERM ofd_access_log_reader
16453         wait
16454         rc=$?
16455         if ((rc != 0)); then
16456                 error "ofd_access_log_reader exited with rc = '${rc}'"
16457         fi
16458 }
16459 run_test 165d "ofd_access_log mask works"
16460
16461 test_165e() {
16462         local stats="/tmp/${tfile}.stats"
16463         local file0="${DIR}/${tdir}-0/${tfile}"
16464         local file1="${DIR}/${tdir}-1/${tfile}"
16465
16466         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16467                 skip "OFD access log unsupported"
16468
16469         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16470
16471         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16472         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16473
16474         lfs setstripe -c 1 -i 0 "${file0}"
16475         lfs setstripe -c 1 -i 0 "${file1}"
16476
16477         setup_165
16478         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16479         sleep 5
16480
16481         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16482                 error "cannot create '${file0}'"
16483         sync
16484         oal_expect_read_count "${stats}" 0
16485
16486         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16487                 error "cannot create '${file1}'"
16488         sync
16489         oal_expect_read_count "${stats}" 1
16490
16491         do_facet ost1 killall -TERM ofd_access_log_reader
16492         wait
16493         rc=$?
16494         if ((rc != 0)); then
16495                 error "ofd_access_log_reader exited with rc = '${rc}'"
16496         fi
16497 }
16498 run_test 165e "ofd_access_log MDT index filter works"
16499
16500 test_165f() {
16501         local trace="/tmp/${tfile}.trace"
16502         local rc
16503         local count
16504
16505         setup_165
16506         do_facet ost1 timeout 60 ofd_access_log_reader \
16507                 --exit-on-close --debug=- --trace=- > "${trace}" &
16508         sleep 5
16509         stop ost1
16510
16511         wait
16512         rc=$?
16513
16514         if ((rc != 0)); then
16515                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16516                 cat "${trace}"
16517                 exit 1
16518         fi
16519 }
16520 run_test 165f "ofd_access_log_reader --exit-on-close works"
16521
16522 test_169() {
16523         # do directio so as not to populate the page cache
16524         log "creating a 10 Mb file"
16525         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16526                 error "multiop failed while creating a file"
16527         log "starting reads"
16528         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16529         log "truncating the file"
16530         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16531                 error "multiop failed while truncating the file"
16532         log "killing dd"
16533         kill %+ || true # reads might have finished
16534         echo "wait until dd is finished"
16535         wait
16536         log "removing the temporary file"
16537         rm -rf $DIR/$tfile || error "tmp file removal failed"
16538 }
16539 run_test 169 "parallel read and truncate should not deadlock"
16540
16541 test_170() {
16542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16543
16544         $LCTL clear     # bug 18514
16545         $LCTL debug_daemon start $TMP/${tfile}_log_good
16546         touch $DIR/$tfile
16547         $LCTL debug_daemon stop
16548         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16549                 error "sed failed to read log_good"
16550
16551         $LCTL debug_daemon start $TMP/${tfile}_log_good
16552         rm -rf $DIR/$tfile
16553         $LCTL debug_daemon stop
16554
16555         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16556                error "lctl df log_bad failed"
16557
16558         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16559         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16560
16561         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16562         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16563
16564         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16565                 error "bad_line good_line1 good_line2 are empty"
16566
16567         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16568         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16569         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16570
16571         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16572         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16573         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16574
16575         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16576                 error "bad_line_new good_line_new are empty"
16577
16578         local expected_good=$((good_line1 + good_line2*2))
16579
16580         rm -f $TMP/${tfile}*
16581         # LU-231, short malformed line may not be counted into bad lines
16582         if [ $bad_line -ne $bad_line_new ] &&
16583                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16584                 error "expected $bad_line bad lines, but got $bad_line_new"
16585                 return 1
16586         fi
16587
16588         if [ $expected_good -ne $good_line_new ]; then
16589                 error "expected $expected_good good lines, but got $good_line_new"
16590                 return 2
16591         fi
16592         true
16593 }
16594 run_test 170 "test lctl df to handle corrupted log ====================="
16595
16596 test_171() { # bug20592
16597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16598
16599         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16600         $LCTL set_param fail_loc=0x50e
16601         $LCTL set_param fail_val=3000
16602         multiop_bg_pause $DIR/$tfile O_s || true
16603         local MULTIPID=$!
16604         kill -USR1 $MULTIPID
16605         # cause log dump
16606         sleep 3
16607         wait $MULTIPID
16608         if dmesg | grep "recursive fault"; then
16609                 error "caught a recursive fault"
16610         fi
16611         $LCTL set_param fail_loc=0
16612         true
16613 }
16614 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16615
16616 # it would be good to share it with obdfilter-survey/iokit-libecho code
16617 setup_obdecho_osc () {
16618         local rc=0
16619         local ost_nid=$1
16620         local obdfilter_name=$2
16621         echo "Creating new osc for $obdfilter_name on $ost_nid"
16622         # make sure we can find loopback nid
16623         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16624
16625         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16626                            ${obdfilter_name}_osc_UUID || rc=2; }
16627         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16628                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16629         return $rc
16630 }
16631
16632 cleanup_obdecho_osc () {
16633         local obdfilter_name=$1
16634         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16635         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16636         return 0
16637 }
16638
16639 obdecho_test() {
16640         local OBD=$1
16641         local node=$2
16642         local pages=${3:-64}
16643         local rc=0
16644         local id
16645
16646         local count=10
16647         local obd_size=$(get_obd_size $node $OBD)
16648         local page_size=$(get_page_size $node)
16649         if [[ -n "$obd_size" ]]; then
16650                 local new_count=$((obd_size / (pages * page_size / 1024)))
16651                 [[ $new_count -ge $count ]] || count=$new_count
16652         fi
16653
16654         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16655         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16656                            rc=2; }
16657         if [ $rc -eq 0 ]; then
16658             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16659             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16660         fi
16661         echo "New object id is $id"
16662         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16663                            rc=4; }
16664         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16665                            "test_brw $count w v $pages $id" || rc=4; }
16666         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16667                            rc=4; }
16668         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16669                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16670         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16671                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16672         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16673         return $rc
16674 }
16675
16676 test_180a() {
16677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16678
16679         if ! [ -d /sys/fs/lustre/echo_client ] &&
16680            ! module_loaded obdecho; then
16681                 load_module obdecho/obdecho &&
16682                         stack_trap "rmmod obdecho" EXIT ||
16683                         error "unable to load obdecho on client"
16684         fi
16685
16686         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16687         local host=$($LCTL get_param -n osc.$osc.import |
16688                      awk '/current_connection:/ { print $2 }' )
16689         local target=$($LCTL get_param -n osc.$osc.import |
16690                        awk '/target:/ { print $2 }' )
16691         target=${target%_UUID}
16692
16693         if [ -n "$target" ]; then
16694                 setup_obdecho_osc $host $target &&
16695                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16696                         { error "obdecho setup failed with $?"; return; }
16697
16698                 obdecho_test ${target}_osc client ||
16699                         error "obdecho_test failed on ${target}_osc"
16700         else
16701                 $LCTL get_param osc.$osc.import
16702                 error "there is no osc.$osc.import target"
16703         fi
16704 }
16705 run_test 180a "test obdecho on osc"
16706
16707 test_180b() {
16708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16709         remote_ost_nodsh && skip "remote OST with nodsh"
16710
16711         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16712                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16713                 error "failed to load module obdecho"
16714
16715         local target=$(do_facet ost1 $LCTL dl |
16716                        awk '/obdfilter/ { print $4; exit; }')
16717
16718         if [ -n "$target" ]; then
16719                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16720         else
16721                 do_facet ost1 $LCTL dl
16722                 error "there is no obdfilter target on ost1"
16723         fi
16724 }
16725 run_test 180b "test obdecho directly on obdfilter"
16726
16727 test_180c() { # LU-2598
16728         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16729         remote_ost_nodsh && skip "remote OST with nodsh"
16730         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16731                 skip "Need MDS version at least 2.4.0"
16732
16733         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16734                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16735                 error "failed to load module obdecho"
16736
16737         local target=$(do_facet ost1 $LCTL dl |
16738                        awk '/obdfilter/ { print $4; exit; }')
16739
16740         if [ -n "$target" ]; then
16741                 local pages=16384 # 64MB bulk I/O RPC size
16742
16743                 obdecho_test "$target" ost1 "$pages" ||
16744                         error "obdecho_test with pages=$pages failed with $?"
16745         else
16746                 do_facet ost1 $LCTL dl
16747                 error "there is no obdfilter target on ost1"
16748         fi
16749 }
16750 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16751
16752 test_181() { # bug 22177
16753         test_mkdir $DIR/$tdir
16754         # create enough files to index the directory
16755         createmany -o $DIR/$tdir/foobar 4000
16756         # print attributes for debug purpose
16757         lsattr -d .
16758         # open dir
16759         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16760         MULTIPID=$!
16761         # remove the files & current working dir
16762         unlinkmany $DIR/$tdir/foobar 4000
16763         rmdir $DIR/$tdir
16764         kill -USR1 $MULTIPID
16765         wait $MULTIPID
16766         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16767         return 0
16768 }
16769 run_test 181 "Test open-unlinked dir ========================"
16770
16771 test_182() {
16772         local fcount=1000
16773         local tcount=10
16774
16775         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16776
16777         $LCTL set_param mdc.*.rpc_stats=clear
16778
16779         for (( i = 0; i < $tcount; i++ )) ; do
16780                 mkdir $DIR/$tdir/$i
16781         done
16782
16783         for (( i = 0; i < $tcount; i++ )) ; do
16784                 createmany -o $DIR/$tdir/$i/f- $fcount &
16785         done
16786         wait
16787
16788         for (( i = 0; i < $tcount; i++ )) ; do
16789                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16790         done
16791         wait
16792
16793         $LCTL get_param mdc.*.rpc_stats
16794
16795         rm -rf $DIR/$tdir
16796 }
16797 run_test 182 "Test parallel modify metadata operations ================"
16798
16799 test_183() { # LU-2275
16800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16801         remote_mds_nodsh && skip "remote MDS with nodsh"
16802         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16803                 skip "Need MDS version at least 2.3.56"
16804
16805         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16806         echo aaa > $DIR/$tdir/$tfile
16807
16808 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16809         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16810
16811         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16812         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16813
16814         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16815
16816         # Flush negative dentry cache
16817         touch $DIR/$tdir/$tfile
16818
16819         # We are not checking for any leaked references here, they'll
16820         # become evident next time we do cleanup with module unload.
16821         rm -rf $DIR/$tdir
16822 }
16823 run_test 183 "No crash or request leak in case of strange dispositions ========"
16824
16825 # test suite 184 is for LU-2016, LU-2017
16826 test_184a() {
16827         check_swap_layouts_support
16828
16829         dir0=$DIR/$tdir/$testnum
16830         test_mkdir -p -c1 $dir0
16831         ref1=/etc/passwd
16832         ref2=/etc/group
16833         file1=$dir0/f1
16834         file2=$dir0/f2
16835         $LFS setstripe -c1 $file1
16836         cp $ref1 $file1
16837         $LFS setstripe -c2 $file2
16838         cp $ref2 $file2
16839         gen1=$($LFS getstripe -g $file1)
16840         gen2=$($LFS getstripe -g $file2)
16841
16842         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16843         gen=$($LFS getstripe -g $file1)
16844         [[ $gen1 != $gen ]] ||
16845                 "Layout generation on $file1 does not change"
16846         gen=$($LFS getstripe -g $file2)
16847         [[ $gen2 != $gen ]] ||
16848                 "Layout generation on $file2 does not change"
16849
16850         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16851         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16852
16853         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16854 }
16855 run_test 184a "Basic layout swap"
16856
16857 test_184b() {
16858         check_swap_layouts_support
16859
16860         dir0=$DIR/$tdir/$testnum
16861         mkdir -p $dir0 || error "creating dir $dir0"
16862         file1=$dir0/f1
16863         file2=$dir0/f2
16864         file3=$dir0/f3
16865         dir1=$dir0/d1
16866         dir2=$dir0/d2
16867         mkdir $dir1 $dir2
16868         $LFS setstripe -c1 $file1
16869         $LFS setstripe -c2 $file2
16870         $LFS setstripe -c1 $file3
16871         chown $RUNAS_ID $file3
16872         gen1=$($LFS getstripe -g $file1)
16873         gen2=$($LFS getstripe -g $file2)
16874
16875         $LFS swap_layouts $dir1 $dir2 &&
16876                 error "swap of directories layouts should fail"
16877         $LFS swap_layouts $dir1 $file1 &&
16878                 error "swap of directory and file layouts should fail"
16879         $RUNAS $LFS swap_layouts $file1 $file2 &&
16880                 error "swap of file we cannot write should fail"
16881         $LFS swap_layouts $file1 $file3 &&
16882                 error "swap of file with different owner should fail"
16883         /bin/true # to clear error code
16884 }
16885 run_test 184b "Forbidden layout swap (will generate errors)"
16886
16887 test_184c() {
16888         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16889         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16890         check_swap_layouts_support
16891         check_swap_layout_no_dom $DIR
16892
16893         local dir0=$DIR/$tdir/$testnum
16894         mkdir -p $dir0 || error "creating dir $dir0"
16895
16896         local ref1=$dir0/ref1
16897         local ref2=$dir0/ref2
16898         local file1=$dir0/file1
16899         local file2=$dir0/file2
16900         # create a file large enough for the concurrent test
16901         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16902         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16903         echo "ref file size: ref1($(stat -c %s $ref1))," \
16904              "ref2($(stat -c %s $ref2))"
16905
16906         cp $ref2 $file2
16907         dd if=$ref1 of=$file1 bs=16k &
16908         local DD_PID=$!
16909
16910         # Make sure dd starts to copy file, but wait at most 5 seconds
16911         local loops=0
16912         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16913
16914         $LFS swap_layouts $file1 $file2
16915         local rc=$?
16916         wait $DD_PID
16917         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16918         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16919
16920         # how many bytes copied before swapping layout
16921         local copied=$(stat -c %s $file2)
16922         local remaining=$(stat -c %s $ref1)
16923         remaining=$((remaining - copied))
16924         echo "Copied $copied bytes before swapping layout..."
16925
16926         cmp -n $copied $file1 $ref2 | grep differ &&
16927                 error "Content mismatch [0, $copied) of ref2 and file1"
16928         cmp -n $copied $file2 $ref1 ||
16929                 error "Content mismatch [0, $copied) of ref1 and file2"
16930         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16931                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16932
16933         # clean up
16934         rm -f $ref1 $ref2 $file1 $file2
16935 }
16936 run_test 184c "Concurrent write and layout swap"
16937
16938 test_184d() {
16939         check_swap_layouts_support
16940         check_swap_layout_no_dom $DIR
16941         [ -z "$(which getfattr 2>/dev/null)" ] &&
16942                 skip_env "no getfattr command"
16943
16944         local file1=$DIR/$tdir/$tfile-1
16945         local file2=$DIR/$tdir/$tfile-2
16946         local file3=$DIR/$tdir/$tfile-3
16947         local lovea1
16948         local lovea2
16949
16950         mkdir -p $DIR/$tdir
16951         touch $file1 || error "create $file1 failed"
16952         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16953                 error "create $file2 failed"
16954         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16955                 error "create $file3 failed"
16956         lovea1=$(get_layout_param $file1)
16957
16958         $LFS swap_layouts $file2 $file3 ||
16959                 error "swap $file2 $file3 layouts failed"
16960         $LFS swap_layouts $file1 $file2 ||
16961                 error "swap $file1 $file2 layouts failed"
16962
16963         lovea2=$(get_layout_param $file2)
16964         echo "$lovea1"
16965         echo "$lovea2"
16966         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16967
16968         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16969         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16970 }
16971 run_test 184d "allow stripeless layouts swap"
16972
16973 test_184e() {
16974         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16975                 skip "Need MDS version at least 2.6.94"
16976         check_swap_layouts_support
16977         check_swap_layout_no_dom $DIR
16978         [ -z "$(which getfattr 2>/dev/null)" ] &&
16979                 skip_env "no getfattr command"
16980
16981         local file1=$DIR/$tdir/$tfile-1
16982         local file2=$DIR/$tdir/$tfile-2
16983         local file3=$DIR/$tdir/$tfile-3
16984         local lovea
16985
16986         mkdir -p $DIR/$tdir
16987         touch $file1 || error "create $file1 failed"
16988         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16989                 error "create $file2 failed"
16990         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16991                 error "create $file3 failed"
16992
16993         $LFS swap_layouts $file1 $file2 ||
16994                 error "swap $file1 $file2 layouts failed"
16995
16996         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16997         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16998
16999         echo 123 > $file1 || error "Should be able to write into $file1"
17000
17001         $LFS swap_layouts $file1 $file3 ||
17002                 error "swap $file1 $file3 layouts failed"
17003
17004         echo 123 > $file1 || error "Should be able to write into $file1"
17005
17006         rm -rf $file1 $file2 $file3
17007 }
17008 run_test 184e "Recreate layout after stripeless layout swaps"
17009
17010 test_184f() {
17011         # Create a file with name longer than sizeof(struct stat) ==
17012         # 144 to see if we can get chars from the file name to appear
17013         # in the returned striping. Note that 'f' == 0x66.
17014         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17015
17016         mkdir -p $DIR/$tdir
17017         mcreate $DIR/$tdir/$file
17018         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17019                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17020         fi
17021 }
17022 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17023
17024 test_185() { # LU-2441
17025         # LU-3553 - no volatile file support in old servers
17026         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17027                 skip "Need MDS version at least 2.3.60"
17028
17029         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17030         touch $DIR/$tdir/spoo
17031         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17032         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17033                 error "cannot create/write a volatile file"
17034         [ "$FILESET" == "" ] &&
17035         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17036                 error "FID is still valid after close"
17037
17038         multiop_bg_pause $DIR/$tdir vVw4096_c
17039         local multi_pid=$!
17040
17041         local OLD_IFS=$IFS
17042         IFS=":"
17043         local fidv=($fid)
17044         IFS=$OLD_IFS
17045         # assume that the next FID for this client is sequential, since stdout
17046         # is unfortunately eaten by multiop_bg_pause
17047         local n=$((${fidv[1]} + 1))
17048         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17049         if [ "$FILESET" == "" ]; then
17050                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17051                         error "FID is missing before close"
17052         fi
17053         kill -USR1 $multi_pid
17054         # 1 second delay, so if mtime change we will see it
17055         sleep 1
17056         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17057         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17058 }
17059 run_test 185 "Volatile file support"
17060
17061 function create_check_volatile() {
17062         local idx=$1
17063         local tgt
17064
17065         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17066         local PID=$!
17067         sleep 1
17068         local FID=$(cat /tmp/${tfile}.fid)
17069         [ "$FID" == "" ] && error "can't get FID for volatile"
17070         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17071         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17072         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17073         kill -USR1 $PID
17074         wait
17075         sleep 1
17076         cancel_lru_locks mdc # flush opencache
17077         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17078         return 0
17079 }
17080
17081 test_185a(){
17082         # LU-12516 - volatile creation via .lustre
17083         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17084                 skip "Need MDS version at least 2.3.55"
17085
17086         create_check_volatile 0
17087         [ $MDSCOUNT -lt 2 ] && return 0
17088
17089         # DNE case
17090         create_check_volatile 1
17091
17092         return 0
17093 }
17094 run_test 185a "Volatile file creation in .lustre/fid/"
17095
17096 test_187a() {
17097         remote_mds_nodsh && skip "remote MDS with nodsh"
17098         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17099                 skip "Need MDS version at least 2.3.0"
17100
17101         local dir0=$DIR/$tdir/$testnum
17102         mkdir -p $dir0 || error "creating dir $dir0"
17103
17104         local file=$dir0/file1
17105         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17106         local dv1=$($LFS data_version $file)
17107         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17108         local dv2=$($LFS data_version $file)
17109         [[ $dv1 != $dv2 ]] ||
17110                 error "data version did not change on write $dv1 == $dv2"
17111
17112         # clean up
17113         rm -f $file1
17114 }
17115 run_test 187a "Test data version change"
17116
17117 test_187b() {
17118         remote_mds_nodsh && skip "remote MDS with nodsh"
17119         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17120                 skip "Need MDS version at least 2.3.0"
17121
17122         local dir0=$DIR/$tdir/$testnum
17123         mkdir -p $dir0 || error "creating dir $dir0"
17124
17125         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17126         [[ ${DV[0]} != ${DV[1]} ]] ||
17127                 error "data version did not change on write"\
17128                       " ${DV[0]} == ${DV[1]}"
17129
17130         # clean up
17131         rm -f $file1
17132 }
17133 run_test 187b "Test data version change on volatile file"
17134
17135 test_200() {
17136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17137         remote_mgs_nodsh && skip "remote MGS with nodsh"
17138         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17139
17140         local POOL=${POOL:-cea1}
17141         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17142         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17143         # Pool OST targets
17144         local first_ost=0
17145         local last_ost=$(($OSTCOUNT - 1))
17146         local ost_step=2
17147         local ost_list=$(seq $first_ost $ost_step $last_ost)
17148         local ost_range="$first_ost $last_ost $ost_step"
17149         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17150         local file_dir=$POOL_ROOT/file_tst
17151         local subdir=$test_path/subdir
17152         local rc=0
17153
17154         while : ; do
17155                 # former test_200a test_200b
17156                 pool_add $POOL                          || { rc=$? ; break; }
17157                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17158                 # former test_200c test_200d
17159                 mkdir -p $test_path
17160                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17161                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17162                 mkdir -p $subdir
17163                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17164                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17165                                                         || { rc=$? ; break; }
17166                 # former test_200e test_200f
17167                 local files=$((OSTCOUNT*3))
17168                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17169                                                         || { rc=$? ; break; }
17170                 pool_create_files $POOL $file_dir $files "$ost_list" \
17171                                                         || { rc=$? ; break; }
17172                 # former test_200g test_200h
17173                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17174                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17175
17176                 # former test_201a test_201b test_201c
17177                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17178
17179                 local f=$test_path/$tfile
17180                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17181                 pool_remove $POOL $f                    || { rc=$? ; break; }
17182                 break
17183         done
17184
17185         destroy_test_pools
17186
17187         return $rc
17188 }
17189 run_test 200 "OST pools"
17190
17191 # usage: default_attr <count | size | offset>
17192 default_attr() {
17193         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17194 }
17195
17196 # usage: check_default_stripe_attr
17197 check_default_stripe_attr() {
17198         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17199         case $1 in
17200         --stripe-count|-c)
17201                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17202         --stripe-size|-S)
17203                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17204         --stripe-index|-i)
17205                 EXPECTED=-1;;
17206         *)
17207                 error "unknown getstripe attr '$1'"
17208         esac
17209
17210         [ $ACTUAL == $EXPECTED ] ||
17211                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17212 }
17213
17214 test_204a() {
17215         test_mkdir $DIR/$tdir
17216         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17217
17218         check_default_stripe_attr --stripe-count
17219         check_default_stripe_attr --stripe-size
17220         check_default_stripe_attr --stripe-index
17221 }
17222 run_test 204a "Print default stripe attributes"
17223
17224 test_204b() {
17225         test_mkdir $DIR/$tdir
17226         $LFS setstripe --stripe-count 1 $DIR/$tdir
17227
17228         check_default_stripe_attr --stripe-size
17229         check_default_stripe_attr --stripe-index
17230 }
17231 run_test 204b "Print default stripe size and offset"
17232
17233 test_204c() {
17234         test_mkdir $DIR/$tdir
17235         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17236
17237         check_default_stripe_attr --stripe-count
17238         check_default_stripe_attr --stripe-index
17239 }
17240 run_test 204c "Print default stripe count and offset"
17241
17242 test_204d() {
17243         test_mkdir $DIR/$tdir
17244         $LFS setstripe --stripe-index 0 $DIR/$tdir
17245
17246         check_default_stripe_attr --stripe-count
17247         check_default_stripe_attr --stripe-size
17248 }
17249 run_test 204d "Print default stripe count and size"
17250
17251 test_204e() {
17252         test_mkdir $DIR/$tdir
17253         $LFS setstripe -d $DIR/$tdir
17254
17255         check_default_stripe_attr --stripe-count --raw
17256         check_default_stripe_attr --stripe-size --raw
17257         check_default_stripe_attr --stripe-index --raw
17258 }
17259 run_test 204e "Print raw stripe attributes"
17260
17261 test_204f() {
17262         test_mkdir $DIR/$tdir
17263         $LFS setstripe --stripe-count 1 $DIR/$tdir
17264
17265         check_default_stripe_attr --stripe-size --raw
17266         check_default_stripe_attr --stripe-index --raw
17267 }
17268 run_test 204f "Print raw stripe size and offset"
17269
17270 test_204g() {
17271         test_mkdir $DIR/$tdir
17272         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17273
17274         check_default_stripe_attr --stripe-count --raw
17275         check_default_stripe_attr --stripe-index --raw
17276 }
17277 run_test 204g "Print raw stripe count and offset"
17278
17279 test_204h() {
17280         test_mkdir $DIR/$tdir
17281         $LFS setstripe --stripe-index 0 $DIR/$tdir
17282
17283         check_default_stripe_attr --stripe-count --raw
17284         check_default_stripe_attr --stripe-size --raw
17285 }
17286 run_test 204h "Print raw stripe count and size"
17287
17288 # Figure out which job scheduler is being used, if any,
17289 # or use a fake one
17290 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17291         JOBENV=SLURM_JOB_ID
17292 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17293         JOBENV=LSB_JOBID
17294 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17295         JOBENV=PBS_JOBID
17296 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17297         JOBENV=LOADL_STEP_ID
17298 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17299         JOBENV=JOB_ID
17300 else
17301         $LCTL list_param jobid_name > /dev/null 2>&1
17302         if [ $? -eq 0 ]; then
17303                 JOBENV=nodelocal
17304         else
17305                 JOBENV=FAKE_JOBID
17306         fi
17307 fi
17308 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17309
17310 verify_jobstats() {
17311         local cmd=($1)
17312         shift
17313         local facets="$@"
17314
17315 # we don't really need to clear the stats for this test to work, since each
17316 # command has a unique jobid, but it makes debugging easier if needed.
17317 #       for facet in $facets; do
17318 #               local dev=$(convert_facet2label $facet)
17319 #               # clear old jobstats
17320 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17321 #       done
17322
17323         # use a new JobID for each test, or we might see an old one
17324         [ "$JOBENV" = "FAKE_JOBID" ] &&
17325                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17326
17327         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17328
17329         [ "$JOBENV" = "nodelocal" ] && {
17330                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17331                 $LCTL set_param jobid_name=$FAKE_JOBID
17332                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17333         }
17334
17335         log "Test: ${cmd[*]}"
17336         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17337
17338         if [ $JOBENV = "FAKE_JOBID" ]; then
17339                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17340         else
17341                 ${cmd[*]}
17342         fi
17343
17344         # all files are created on OST0000
17345         for facet in $facets; do
17346                 local stats="*.$(convert_facet2label $facet).job_stats"
17347
17348                 # strip out libtool wrappers for in-tree executables
17349                 if [ $(do_facet $facet lctl get_param $stats |
17350                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17351                         do_facet $facet lctl get_param $stats
17352                         error "No jobstats for $JOBVAL found on $facet::$stats"
17353                 fi
17354         done
17355 }
17356
17357 jobstats_set() {
17358         local new_jobenv=$1
17359
17360         set_persistent_param_and_check client "jobid_var" \
17361                 "$FSNAME.sys.jobid_var" $new_jobenv
17362 }
17363
17364 test_205a() { # Job stats
17365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17366         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17367                 skip "Need MDS version with at least 2.7.1"
17368         remote_mgs_nodsh && skip "remote MGS with nodsh"
17369         remote_mds_nodsh && skip "remote MDS with nodsh"
17370         remote_ost_nodsh && skip "remote OST with nodsh"
17371         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17372                 skip "Server doesn't support jobstats"
17373         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17374
17375         local old_jobenv=$($LCTL get_param -n jobid_var)
17376         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17377
17378         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17379                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17380         else
17381                 stack_trap "do_facet mgs $PERM_CMD \
17382                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17383         fi
17384         changelog_register
17385
17386         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17387                                 mdt.*.job_cleanup_interval | head -n 1)
17388         local new_interval=5
17389         do_facet $SINGLEMDS \
17390                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17391         stack_trap "do_facet $SINGLEMDS \
17392                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17393         local start=$SECONDS
17394
17395         local cmd
17396         # mkdir
17397         cmd="mkdir $DIR/$tdir"
17398         verify_jobstats "$cmd" "$SINGLEMDS"
17399         # rmdir
17400         cmd="rmdir $DIR/$tdir"
17401         verify_jobstats "$cmd" "$SINGLEMDS"
17402         # mkdir on secondary MDT
17403         if [ $MDSCOUNT -gt 1 ]; then
17404                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17405                 verify_jobstats "$cmd" "mds2"
17406         fi
17407         # mknod
17408         cmd="mknod $DIR/$tfile c 1 3"
17409         verify_jobstats "$cmd" "$SINGLEMDS"
17410         # unlink
17411         cmd="rm -f $DIR/$tfile"
17412         verify_jobstats "$cmd" "$SINGLEMDS"
17413         # create all files on OST0000 so verify_jobstats can find OST stats
17414         # open & close
17415         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17416         verify_jobstats "$cmd" "$SINGLEMDS"
17417         # setattr
17418         cmd="touch $DIR/$tfile"
17419         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17420         # write
17421         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17422         verify_jobstats "$cmd" "ost1"
17423         # read
17424         cancel_lru_locks osc
17425         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17426         verify_jobstats "$cmd" "ost1"
17427         # truncate
17428         cmd="$TRUNCATE $DIR/$tfile 0"
17429         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17430         # rename
17431         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17432         verify_jobstats "$cmd" "$SINGLEMDS"
17433         # jobstats expiry - sleep until old stats should be expired
17434         local left=$((new_interval + 5 - (SECONDS - start)))
17435         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17436                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17437                         "0" $left
17438         cmd="mkdir $DIR/$tdir.expire"
17439         verify_jobstats "$cmd" "$SINGLEMDS"
17440         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17441             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17442
17443         # Ensure that jobid are present in changelog (if supported by MDS)
17444         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17445                 changelog_dump | tail -10
17446                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17447                 [ $jobids -eq 9 ] ||
17448                         error "Wrong changelog jobid count $jobids != 9"
17449
17450                 # LU-5862
17451                 JOBENV="disable"
17452                 jobstats_set $JOBENV
17453                 touch $DIR/$tfile
17454                 changelog_dump | grep $tfile
17455                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17456                 [ $jobids -eq 0 ] ||
17457                         error "Unexpected jobids when jobid_var=$JOBENV"
17458         fi
17459
17460         # test '%j' access to environment variable - if supported
17461         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17462                 JOBENV="JOBCOMPLEX"
17463                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17464
17465                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17466         fi
17467
17468         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17469                 JOBENV="JOBCOMPLEX"
17470                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17471
17472                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17473         fi
17474
17475         # test '%j' access to per-session jobid - if supported
17476         if lctl list_param jobid_this_session > /dev/null 2>&1
17477         then
17478                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17479                 lctl set_param jobid_this_session=$USER
17480
17481                 JOBENV="JOBCOMPLEX"
17482                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17483
17484                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17485         fi
17486 }
17487 run_test 205a "Verify job stats"
17488
17489 # LU-13117, LU-13597
17490 test_205b() {
17491         job_stats="mdt.*.job_stats"
17492         $LCTL set_param $job_stats=clear
17493         # Setting jobid_var to USER might not be supported
17494         $LCTL set_param jobid_var=USER || true
17495         $LCTL set_param jobid_name="%e.%u"
17496         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17497         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17498                 grep "job_id:.*foolish" &&
17499                         error "Unexpected jobid found"
17500         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17501                 grep "open:.*min.*max.*sum" ||
17502                         error "wrong job_stats format found"
17503 }
17504 run_test 205b "Verify job stats jobid and output format"
17505
17506 # LU-13733
17507 test_205c() {
17508         $LCTL set_param llite.*.stats=0
17509         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17510         $LCTL get_param llite.*.stats
17511         $LCTL get_param llite.*.stats | grep \
17512                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17513                         error "wrong client stats format found"
17514 }
17515 run_test 205c "Verify client stats format"
17516
17517 # LU-1480, LU-1773 and LU-1657
17518 test_206() {
17519         mkdir -p $DIR/$tdir
17520         $LFS setstripe -c -1 $DIR/$tdir
17521 #define OBD_FAIL_LOV_INIT 0x1403
17522         $LCTL set_param fail_loc=0xa0001403
17523         $LCTL set_param fail_val=1
17524         touch $DIR/$tdir/$tfile || true
17525 }
17526 run_test 206 "fail lov_init_raid0() doesn't lbug"
17527
17528 test_207a() {
17529         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17530         local fsz=`stat -c %s $DIR/$tfile`
17531         cancel_lru_locks mdc
17532
17533         # do not return layout in getattr intent
17534 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17535         $LCTL set_param fail_loc=0x170
17536         local sz=`stat -c %s $DIR/$tfile`
17537
17538         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17539
17540         rm -rf $DIR/$tfile
17541 }
17542 run_test 207a "can refresh layout at glimpse"
17543
17544 test_207b() {
17545         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17546         local cksum=`md5sum $DIR/$tfile`
17547         local fsz=`stat -c %s $DIR/$tfile`
17548         cancel_lru_locks mdc
17549         cancel_lru_locks osc
17550
17551         # do not return layout in getattr intent
17552 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17553         $LCTL set_param fail_loc=0x171
17554
17555         # it will refresh layout after the file is opened but before read issues
17556         echo checksum is "$cksum"
17557         echo "$cksum" |md5sum -c --quiet || error "file differs"
17558
17559         rm -rf $DIR/$tfile
17560 }
17561 run_test 207b "can refresh layout at open"
17562
17563 test_208() {
17564         # FIXME: in this test suite, only RD lease is used. This is okay
17565         # for now as only exclusive open is supported. After generic lease
17566         # is done, this test suite should be revised. - Jinshan
17567
17568         remote_mds_nodsh && skip "remote MDS with nodsh"
17569         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17570                 skip "Need MDS version at least 2.4.52"
17571
17572         echo "==== test 1: verify get lease work"
17573         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17574
17575         echo "==== test 2: verify lease can be broken by upcoming open"
17576         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17577         local PID=$!
17578         sleep 1
17579
17580         $MULTIOP $DIR/$tfile oO_RDONLY:c
17581         kill -USR1 $PID && wait $PID || error "break lease error"
17582
17583         echo "==== test 3: verify lease can't be granted if an open already exists"
17584         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17585         local PID=$!
17586         sleep 1
17587
17588         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17589         kill -USR1 $PID && wait $PID || error "open file error"
17590
17591         echo "==== test 4: lease can sustain over recovery"
17592         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17593         PID=$!
17594         sleep 1
17595
17596         fail mds1
17597
17598         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17599
17600         echo "==== test 5: lease broken can't be regained by replay"
17601         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17602         PID=$!
17603         sleep 1
17604
17605         # open file to break lease and then recovery
17606         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17607         fail mds1
17608
17609         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17610
17611         rm -f $DIR/$tfile
17612 }
17613 run_test 208 "Exclusive open"
17614
17615 test_209() {
17616         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17617                 skip_env "must have disp_stripe"
17618
17619         touch $DIR/$tfile
17620         sync; sleep 5; sync;
17621
17622         echo 3 > /proc/sys/vm/drop_caches
17623         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17624                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17625         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17626
17627         # open/close 500 times
17628         for i in $(seq 500); do
17629                 cat $DIR/$tfile
17630         done
17631
17632         echo 3 > /proc/sys/vm/drop_caches
17633         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17634                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17635         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17636
17637         echo "before: $req_before, after: $req_after"
17638         [ $((req_after - req_before)) -ge 300 ] &&
17639                 error "open/close requests are not freed"
17640         return 0
17641 }
17642 run_test 209 "read-only open/close requests should be freed promptly"
17643
17644 test_210() {
17645         local pid
17646
17647         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17648         pid=$!
17649         sleep 1
17650
17651         $LFS getstripe $DIR/$tfile
17652         kill -USR1 $pid
17653         wait $pid || error "multiop failed"
17654
17655         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17656         pid=$!
17657         sleep 1
17658
17659         $LFS getstripe $DIR/$tfile
17660         kill -USR1 $pid
17661         wait $pid || error "multiop failed"
17662 }
17663 run_test 210 "lfs getstripe does not break leases"
17664
17665 test_212() {
17666         size=`date +%s`
17667         size=$((size % 8192 + 1))
17668         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17669         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17670         rm -f $DIR/f212 $DIR/f212.xyz
17671 }
17672 run_test 212 "Sendfile test ============================================"
17673
17674 test_213() {
17675         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17676         cancel_lru_locks osc
17677         lctl set_param fail_loc=0x8000040f
17678         # generate a read lock
17679         cat $DIR/$tfile > /dev/null
17680         # write to the file, it will try to cancel the above read lock.
17681         cat /etc/hosts >> $DIR/$tfile
17682 }
17683 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17684
17685 test_214() { # for bug 20133
17686         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17687         for (( i=0; i < 340; i++ )) ; do
17688                 touch $DIR/$tdir/d214c/a$i
17689         done
17690
17691         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17692         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17693         ls $DIR/d214c || error "ls $DIR/d214c failed"
17694         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17695         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17696 }
17697 run_test 214 "hash-indexed directory test - bug 20133"
17698
17699 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17700 create_lnet_proc_files() {
17701         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17702 }
17703
17704 # counterpart of create_lnet_proc_files
17705 remove_lnet_proc_files() {
17706         rm -f $TMP/lnet_$1.sys
17707 }
17708
17709 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17710 # 3rd arg as regexp for body
17711 check_lnet_proc_stats() {
17712         local l=$(cat "$TMP/lnet_$1" |wc -l)
17713         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17714
17715         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17716 }
17717
17718 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17719 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17720 # optional and can be regexp for 2nd line (lnet.routes case)
17721 check_lnet_proc_entry() {
17722         local blp=2          # blp stands for 'position of 1st line of body'
17723         [ -z "$5" ] || blp=3 # lnet.routes case
17724
17725         local l=$(cat "$TMP/lnet_$1" |wc -l)
17726         # subtracting one from $blp because the body can be empty
17727         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17728
17729         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17730                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17731
17732         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17733                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17734
17735         # bail out if any unexpected line happened
17736         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17737         [ "$?" != 0 ] || error "$2 misformatted"
17738 }
17739
17740 test_215() { # for bugs 18102, 21079, 21517
17741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17742
17743         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17744         local P='[1-9][0-9]*'           # positive numeric
17745         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17746         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17747         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17748         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17749
17750         local L1 # regexp for 1st line
17751         local L2 # regexp for 2nd line (optional)
17752         local BR # regexp for the rest (body)
17753
17754         # lnet.stats should look as 11 space-separated non-negative numerics
17755         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17756         create_lnet_proc_files "stats"
17757         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17758         remove_lnet_proc_files "stats"
17759
17760         # lnet.routes should look like this:
17761         # Routing disabled/enabled
17762         # net hops priority state router
17763         # where net is a string like tcp0, hops > 0, priority >= 0,
17764         # state is up/down,
17765         # router is a string like 192.168.1.1@tcp2
17766         L1="^Routing (disabled|enabled)$"
17767         L2="^net +hops +priority +state +router$"
17768         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17769         create_lnet_proc_files "routes"
17770         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17771         remove_lnet_proc_files "routes"
17772
17773         # lnet.routers should look like this:
17774         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17775         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17776         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17777         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17778         L1="^ref +rtr_ref +alive +router$"
17779         BR="^$P +$P +(up|down) +$NID$"
17780         create_lnet_proc_files "routers"
17781         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17782         remove_lnet_proc_files "routers"
17783
17784         # lnet.peers should look like this:
17785         # nid refs state last max rtr min tx min queue
17786         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17787         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17788         # numeric (0 or >0 or <0), queue >= 0.
17789         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17790         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17791         create_lnet_proc_files "peers"
17792         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17793         remove_lnet_proc_files "peers"
17794
17795         # lnet.buffers  should look like this:
17796         # pages count credits min
17797         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17798         L1="^pages +count +credits +min$"
17799         BR="^ +$N +$N +$I +$I$"
17800         create_lnet_proc_files "buffers"
17801         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17802         remove_lnet_proc_files "buffers"
17803
17804         # lnet.nis should look like this:
17805         # nid status alive refs peer rtr max tx min
17806         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17807         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17808         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17809         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17810         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17811         create_lnet_proc_files "nis"
17812         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17813         remove_lnet_proc_files "nis"
17814
17815         # can we successfully write to lnet.stats?
17816         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17817 }
17818 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17819
17820 test_216() { # bug 20317
17821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17822         remote_ost_nodsh && skip "remote OST with nodsh"
17823
17824         local node
17825         local facets=$(get_facets OST)
17826         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17827
17828         save_lustre_params client "osc.*.contention_seconds" > $p
17829         save_lustre_params $facets \
17830                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17831         save_lustre_params $facets \
17832                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17833         save_lustre_params $facets \
17834                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17835         clear_stats osc.*.osc_stats
17836
17837         # agressive lockless i/o settings
17838         do_nodes $(comma_list $(osts_nodes)) \
17839                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17840                         ldlm.namespaces.filter-*.contended_locks=0 \
17841                         ldlm.namespaces.filter-*.contention_seconds=60"
17842         lctl set_param -n osc.*.contention_seconds=60
17843
17844         $DIRECTIO write $DIR/$tfile 0 10 4096
17845         $CHECKSTAT -s 40960 $DIR/$tfile
17846
17847         # disable lockless i/o
17848         do_nodes $(comma_list $(osts_nodes)) \
17849                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17850                         ldlm.namespaces.filter-*.contended_locks=32 \
17851                         ldlm.namespaces.filter-*.contention_seconds=0"
17852         lctl set_param -n osc.*.contention_seconds=0
17853         clear_stats osc.*.osc_stats
17854
17855         dd if=/dev/zero of=$DIR/$tfile count=0
17856         $CHECKSTAT -s 0 $DIR/$tfile
17857
17858         restore_lustre_params <$p
17859         rm -f $p
17860         rm $DIR/$tfile
17861 }
17862 run_test 216 "check lockless direct write updates file size and kms correctly"
17863
17864 test_217() { # bug 22430
17865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17866
17867         local node
17868         local nid
17869
17870         for node in $(nodes_list); do
17871                 nid=$(host_nids_address $node $NETTYPE)
17872                 if [[ $nid = *-* ]] ; then
17873                         echo "lctl ping $(h2nettype $nid)"
17874                         lctl ping $(h2nettype $nid)
17875                 else
17876                         echo "skipping $node (no hyphen detected)"
17877                 fi
17878         done
17879 }
17880 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17881
17882 test_218() {
17883        # do directio so as not to populate the page cache
17884        log "creating a 10 Mb file"
17885        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17886        log "starting reads"
17887        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17888        log "truncating the file"
17889        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17890        log "killing dd"
17891        kill %+ || true # reads might have finished
17892        echo "wait until dd is finished"
17893        wait
17894        log "removing the temporary file"
17895        rm -rf $DIR/$tfile || error "tmp file removal failed"
17896 }
17897 run_test 218 "parallel read and truncate should not deadlock"
17898
17899 test_219() {
17900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17901
17902         # write one partial page
17903         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17904         # set no grant so vvp_io_commit_write will do sync write
17905         $LCTL set_param fail_loc=0x411
17906         # write a full page at the end of file
17907         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17908
17909         $LCTL set_param fail_loc=0
17910         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17911         $LCTL set_param fail_loc=0x411
17912         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17913
17914         # LU-4201
17915         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17916         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17917 }
17918 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17919
17920 test_220() { #LU-325
17921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17922         remote_ost_nodsh && skip "remote OST with nodsh"
17923         remote_mds_nodsh && skip "remote MDS with nodsh"
17924         remote_mgs_nodsh && skip "remote MGS with nodsh"
17925
17926         local OSTIDX=0
17927
17928         # create on MDT0000 so the last_id and next_id are correct
17929         mkdir $DIR/$tdir
17930         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17931         OST=${OST%_UUID}
17932
17933         # on the mdt's osc
17934         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17935         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17936                         osp.$mdtosc_proc1.prealloc_last_id)
17937         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17938                         osp.$mdtosc_proc1.prealloc_next_id)
17939
17940         $LFS df -i
17941
17942         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17943         #define OBD_FAIL_OST_ENOINO              0x229
17944         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17945         create_pool $FSNAME.$TESTNAME || return 1
17946         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17947
17948         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17949
17950         MDSOBJS=$((last_id - next_id))
17951         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17952
17953         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17954         echo "OST still has $count kbytes free"
17955
17956         echo "create $MDSOBJS files @next_id..."
17957         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17958
17959         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17960                         osp.$mdtosc_proc1.prealloc_last_id)
17961         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17962                         osp.$mdtosc_proc1.prealloc_next_id)
17963
17964         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17965         $LFS df -i
17966
17967         echo "cleanup..."
17968
17969         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17970         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17971
17972         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17973                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17974         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17975                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17976         echo "unlink $MDSOBJS files @$next_id..."
17977         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17978 }
17979 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17980
17981 test_221() {
17982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17983
17984         dd if=`which date` of=$MOUNT/date oflag=sync
17985         chmod +x $MOUNT/date
17986
17987         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17988         $LCTL set_param fail_loc=0x80001401
17989
17990         $MOUNT/date > /dev/null
17991         rm -f $MOUNT/date
17992 }
17993 run_test 221 "make sure fault and truncate race to not cause OOM"
17994
17995 test_222a () {
17996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17997
17998         rm -rf $DIR/$tdir
17999         test_mkdir $DIR/$tdir
18000         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18001         createmany -o $DIR/$tdir/$tfile 10
18002         cancel_lru_locks mdc
18003         cancel_lru_locks osc
18004         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18005         $LCTL set_param fail_loc=0x31a
18006         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18007         $LCTL set_param fail_loc=0
18008         rm -r $DIR/$tdir
18009 }
18010 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18011
18012 test_222b () {
18013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18014
18015         rm -rf $DIR/$tdir
18016         test_mkdir $DIR/$tdir
18017         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18018         createmany -o $DIR/$tdir/$tfile 10
18019         cancel_lru_locks mdc
18020         cancel_lru_locks osc
18021         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18022         $LCTL set_param fail_loc=0x31a
18023         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18024         $LCTL set_param fail_loc=0
18025 }
18026 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18027
18028 test_223 () {
18029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18030
18031         rm -rf $DIR/$tdir
18032         test_mkdir $DIR/$tdir
18033         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18034         createmany -o $DIR/$tdir/$tfile 10
18035         cancel_lru_locks mdc
18036         cancel_lru_locks osc
18037         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18038         $LCTL set_param fail_loc=0x31b
18039         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18040         $LCTL set_param fail_loc=0
18041         rm -r $DIR/$tdir
18042 }
18043 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18044
18045 test_224a() { # LU-1039, MRP-303
18046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18047
18048         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18049         $LCTL set_param fail_loc=0x508
18050         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18051         $LCTL set_param fail_loc=0
18052         df $DIR
18053 }
18054 run_test 224a "Don't panic on bulk IO failure"
18055
18056 test_224b() { # LU-1039, MRP-303
18057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18058
18059         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18060         cancel_lru_locks osc
18061         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18062         $LCTL set_param fail_loc=0x515
18063         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18064         $LCTL set_param fail_loc=0
18065         df $DIR
18066 }
18067 run_test 224b "Don't panic on bulk IO failure"
18068
18069 test_224c() { # LU-6441
18070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18071         remote_mds_nodsh && skip "remote MDS with nodsh"
18072
18073         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18074         save_writethrough $p
18075         set_cache writethrough on
18076
18077         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18078         local at_max=$($LCTL get_param -n at_max)
18079         local timeout=$($LCTL get_param -n timeout)
18080         local test_at="at_max"
18081         local param_at="$FSNAME.sys.at_max"
18082         local test_timeout="timeout"
18083         local param_timeout="$FSNAME.sys.timeout"
18084
18085         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18086
18087         set_persistent_param_and_check client "$test_at" "$param_at" 0
18088         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18089
18090         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18091         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18092         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18093         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18094         sync
18095         do_facet ost1 "$LCTL set_param fail_loc=0"
18096
18097         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18098         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18099                 $timeout
18100
18101         $LCTL set_param -n $pages_per_rpc
18102         restore_lustre_params < $p
18103         rm -f $p
18104 }
18105 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18106
18107 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18108 test_225a () {
18109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18110         if [ -z ${MDSSURVEY} ]; then
18111                 skip_env "mds-survey not found"
18112         fi
18113         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18114                 skip "Need MDS version at least 2.2.51"
18115
18116         local mds=$(facet_host $SINGLEMDS)
18117         local target=$(do_nodes $mds 'lctl dl' |
18118                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18119
18120         local cmd1="file_count=1000 thrhi=4"
18121         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18122         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18123         local cmd="$cmd1 $cmd2 $cmd3"
18124
18125         rm -f ${TMP}/mds_survey*
18126         echo + $cmd
18127         eval $cmd || error "mds-survey with zero-stripe failed"
18128         cat ${TMP}/mds_survey*
18129         rm -f ${TMP}/mds_survey*
18130 }
18131 run_test 225a "Metadata survey sanity with zero-stripe"
18132
18133 test_225b () {
18134         if [ -z ${MDSSURVEY} ]; then
18135                 skip_env "mds-survey not found"
18136         fi
18137         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18138                 skip "Need MDS version at least 2.2.51"
18139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18140         remote_mds_nodsh && skip "remote MDS with nodsh"
18141         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18142                 skip_env "Need to mount OST to test"
18143         fi
18144
18145         local mds=$(facet_host $SINGLEMDS)
18146         local target=$(do_nodes $mds 'lctl dl' |
18147                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18148
18149         local cmd1="file_count=1000 thrhi=4"
18150         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18151         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18152         local cmd="$cmd1 $cmd2 $cmd3"
18153
18154         rm -f ${TMP}/mds_survey*
18155         echo + $cmd
18156         eval $cmd || error "mds-survey with stripe_count failed"
18157         cat ${TMP}/mds_survey*
18158         rm -f ${TMP}/mds_survey*
18159 }
18160 run_test 225b "Metadata survey sanity with stripe_count = 1"
18161
18162 mcreate_path2fid () {
18163         local mode=$1
18164         local major=$2
18165         local minor=$3
18166         local name=$4
18167         local desc=$5
18168         local path=$DIR/$tdir/$name
18169         local fid
18170         local rc
18171         local fid_path
18172
18173         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18174                 error "cannot create $desc"
18175
18176         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18177         rc=$?
18178         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18179
18180         fid_path=$($LFS fid2path $MOUNT $fid)
18181         rc=$?
18182         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18183
18184         [ "$path" == "$fid_path" ] ||
18185                 error "fid2path returned $fid_path, expected $path"
18186
18187         echo "pass with $path and $fid"
18188 }
18189
18190 test_226a () {
18191         rm -rf $DIR/$tdir
18192         mkdir -p $DIR/$tdir
18193
18194         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18195         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18196         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18197         mcreate_path2fid 0040666 0 0 dir "directory"
18198         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18199         mcreate_path2fid 0100666 0 0 file "regular file"
18200         mcreate_path2fid 0120666 0 0 link "symbolic link"
18201         mcreate_path2fid 0140666 0 0 sock "socket"
18202 }
18203 run_test 226a "call path2fid and fid2path on files of all type"
18204
18205 test_226b () {
18206         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18207
18208         local MDTIDX=1
18209
18210         rm -rf $DIR/$tdir
18211         mkdir -p $DIR/$tdir
18212         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18213                 error "create remote directory failed"
18214         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18215         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18216                                 "character special file (null)"
18217         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18218                                 "character special file (no device)"
18219         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18220         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18221                                 "block special file (loop)"
18222         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18223         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18224         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18225 }
18226 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18227
18228 test_226c () {
18229         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18230         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18231                 skip "Need MDS version at least 2.13.55"
18232
18233         local submnt=/mnt/submnt
18234         local srcfile=/etc/passwd
18235         local dstfile=$submnt/passwd
18236         local path
18237         local fid
18238
18239         rm -rf $DIR/$tdir
18240         rm -rf $submnt
18241         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18242                 error "create remote directory failed"
18243         mkdir -p $submnt || error "create $submnt failed"
18244         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18245                 error "mount $submnt failed"
18246         stack_trap "umount $submnt" EXIT
18247
18248         cp $srcfile $dstfile
18249         fid=$($LFS path2fid $dstfile)
18250         path=$($LFS fid2path $submnt "$fid")
18251         [ "$path" = "$dstfile" ] ||
18252                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18253 }
18254 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18255
18256 # LU-1299 Executing or running ldd on a truncated executable does not
18257 # cause an out-of-memory condition.
18258 test_227() {
18259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18260         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18261
18262         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18263         chmod +x $MOUNT/date
18264
18265         $MOUNT/date > /dev/null
18266         ldd $MOUNT/date > /dev/null
18267         rm -f $MOUNT/date
18268 }
18269 run_test 227 "running truncated executable does not cause OOM"
18270
18271 # LU-1512 try to reuse idle OI blocks
18272 test_228a() {
18273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18274         remote_mds_nodsh && skip "remote MDS with nodsh"
18275         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18276
18277         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18278         local myDIR=$DIR/$tdir
18279
18280         mkdir -p $myDIR
18281         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18282         $LCTL set_param fail_loc=0x80001002
18283         createmany -o $myDIR/t- 10000
18284         $LCTL set_param fail_loc=0
18285         # The guard is current the largest FID holder
18286         touch $myDIR/guard
18287         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18288                     tr -d '[')
18289         local IDX=$(($SEQ % 64))
18290
18291         do_facet $SINGLEMDS sync
18292         # Make sure journal flushed.
18293         sleep 6
18294         local blk1=$(do_facet $SINGLEMDS \
18295                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18296                      grep Blockcount | awk '{print $4}')
18297
18298         # Remove old files, some OI blocks will become idle.
18299         unlinkmany $myDIR/t- 10000
18300         # Create new files, idle OI blocks should be reused.
18301         createmany -o $myDIR/t- 2000
18302         do_facet $SINGLEMDS sync
18303         # Make sure journal flushed.
18304         sleep 6
18305         local blk2=$(do_facet $SINGLEMDS \
18306                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18307                      grep Blockcount | awk '{print $4}')
18308
18309         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18310 }
18311 run_test 228a "try to reuse idle OI blocks"
18312
18313 test_228b() {
18314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18315         remote_mds_nodsh && skip "remote MDS with nodsh"
18316         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18317
18318         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18319         local myDIR=$DIR/$tdir
18320
18321         mkdir -p $myDIR
18322         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18323         $LCTL set_param fail_loc=0x80001002
18324         createmany -o $myDIR/t- 10000
18325         $LCTL set_param fail_loc=0
18326         # The guard is current the largest FID holder
18327         touch $myDIR/guard
18328         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18329                     tr -d '[')
18330         local IDX=$(($SEQ % 64))
18331
18332         do_facet $SINGLEMDS sync
18333         # Make sure journal flushed.
18334         sleep 6
18335         local blk1=$(do_facet $SINGLEMDS \
18336                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18337                      grep Blockcount | awk '{print $4}')
18338
18339         # Remove old files, some OI blocks will become idle.
18340         unlinkmany $myDIR/t- 10000
18341
18342         # stop the MDT
18343         stop $SINGLEMDS || error "Fail to stop MDT."
18344         # remount the MDT
18345         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18346
18347         df $MOUNT || error "Fail to df."
18348         # Create new files, idle OI blocks should be reused.
18349         createmany -o $myDIR/t- 2000
18350         do_facet $SINGLEMDS sync
18351         # Make sure journal flushed.
18352         sleep 6
18353         local blk2=$(do_facet $SINGLEMDS \
18354                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18355                      grep Blockcount | awk '{print $4}')
18356
18357         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18358 }
18359 run_test 228b "idle OI blocks can be reused after MDT restart"
18360
18361 #LU-1881
18362 test_228c() {
18363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18364         remote_mds_nodsh && skip "remote MDS with nodsh"
18365         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18366
18367         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18368         local myDIR=$DIR/$tdir
18369
18370         mkdir -p $myDIR
18371         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18372         $LCTL set_param fail_loc=0x80001002
18373         # 20000 files can guarantee there are index nodes in the OI file
18374         createmany -o $myDIR/t- 20000
18375         $LCTL set_param fail_loc=0
18376         # The guard is current the largest FID holder
18377         touch $myDIR/guard
18378         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18379                     tr -d '[')
18380         local IDX=$(($SEQ % 64))
18381
18382         do_facet $SINGLEMDS sync
18383         # Make sure journal flushed.
18384         sleep 6
18385         local blk1=$(do_facet $SINGLEMDS \
18386                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18387                      grep Blockcount | awk '{print $4}')
18388
18389         # Remove old files, some OI blocks will become idle.
18390         unlinkmany $myDIR/t- 20000
18391         rm -f $myDIR/guard
18392         # The OI file should become empty now
18393
18394         # Create new files, idle OI blocks should be reused.
18395         createmany -o $myDIR/t- 2000
18396         do_facet $SINGLEMDS sync
18397         # Make sure journal flushed.
18398         sleep 6
18399         local blk2=$(do_facet $SINGLEMDS \
18400                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18401                      grep Blockcount | awk '{print $4}')
18402
18403         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18404 }
18405 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18406
18407 test_229() { # LU-2482, LU-3448
18408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18409         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18410         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18411                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18412
18413         rm -f $DIR/$tfile
18414
18415         # Create a file with a released layout and stripe count 2.
18416         $MULTIOP $DIR/$tfile H2c ||
18417                 error "failed to create file with released layout"
18418
18419         $LFS getstripe -v $DIR/$tfile
18420
18421         local pattern=$($LFS getstripe -L $DIR/$tfile)
18422         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18423
18424         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18425                 error "getstripe"
18426         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18427         stat $DIR/$tfile || error "failed to stat released file"
18428
18429         chown $RUNAS_ID $DIR/$tfile ||
18430                 error "chown $RUNAS_ID $DIR/$tfile failed"
18431
18432         chgrp $RUNAS_ID $DIR/$tfile ||
18433                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18434
18435         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18436         rm $DIR/$tfile || error "failed to remove released file"
18437 }
18438 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18439
18440 test_230a() {
18441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18442         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18443         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18444                 skip "Need MDS version at least 2.11.52"
18445
18446         local MDTIDX=1
18447
18448         test_mkdir $DIR/$tdir
18449         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18450         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18451         [ $mdt_idx -ne 0 ] &&
18452                 error "create local directory on wrong MDT $mdt_idx"
18453
18454         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18455                         error "create remote directory failed"
18456         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18457         [ $mdt_idx -ne $MDTIDX ] &&
18458                 error "create remote directory on wrong MDT $mdt_idx"
18459
18460         createmany -o $DIR/$tdir/test_230/t- 10 ||
18461                 error "create files on remote directory failed"
18462         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18463         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18464         rm -r $DIR/$tdir || error "unlink remote directory failed"
18465 }
18466 run_test 230a "Create remote directory and files under the remote directory"
18467
18468 test_230b() {
18469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18470         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18471         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18472                 skip "Need MDS version at least 2.11.52"
18473
18474         local MDTIDX=1
18475         local mdt_index
18476         local i
18477         local file
18478         local pid
18479         local stripe_count
18480         local migrate_dir=$DIR/$tdir/migrate_dir
18481         local other_dir=$DIR/$tdir/other_dir
18482
18483         test_mkdir $DIR/$tdir
18484         test_mkdir -i0 -c1 $migrate_dir
18485         test_mkdir -i0 -c1 $other_dir
18486         for ((i=0; i<10; i++)); do
18487                 mkdir -p $migrate_dir/dir_${i}
18488                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18489                         error "create files under remote dir failed $i"
18490         done
18491
18492         cp /etc/passwd $migrate_dir/$tfile
18493         cp /etc/passwd $other_dir/$tfile
18494         chattr +SAD $migrate_dir
18495         chattr +SAD $migrate_dir/$tfile
18496
18497         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18498         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18499         local old_dir_mode=$(stat -c%f $migrate_dir)
18500         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18501
18502         mkdir -p $migrate_dir/dir_default_stripe2
18503         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18504         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18505
18506         mkdir -p $other_dir
18507         ln $migrate_dir/$tfile $other_dir/luna
18508         ln $migrate_dir/$tfile $migrate_dir/sofia
18509         ln $other_dir/$tfile $migrate_dir/david
18510         ln -s $migrate_dir/$tfile $other_dir/zachary
18511         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18512         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18513
18514         local len
18515         local lnktgt
18516
18517         # inline symlink
18518         for len in 58 59 60; do
18519                 lnktgt=$(str_repeat 'l' $len)
18520                 touch $migrate_dir/$lnktgt
18521                 ln -s $lnktgt $migrate_dir/${len}char_ln
18522         done
18523
18524         # PATH_MAX
18525         for len in 4094 4095; do
18526                 lnktgt=$(str_repeat 'l' $len)
18527                 ln -s $lnktgt $migrate_dir/${len}char_ln
18528         done
18529
18530         # NAME_MAX
18531         for len in 254 255; do
18532                 touch $migrate_dir/$(str_repeat 'l' $len)
18533         done
18534
18535         $LFS migrate -m $MDTIDX $migrate_dir ||
18536                 error "fails on migrating remote dir to MDT1"
18537
18538         echo "migratate to MDT1, then checking.."
18539         for ((i = 0; i < 10; i++)); do
18540                 for file in $(find $migrate_dir/dir_${i}); do
18541                         mdt_index=$($LFS getstripe -m $file)
18542                         # broken symlink getstripe will fail
18543                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18544                                 error "$file is not on MDT${MDTIDX}"
18545                 done
18546         done
18547
18548         # the multiple link file should still in MDT0
18549         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18550         [ $mdt_index == 0 ] ||
18551                 error "$file is not on MDT${MDTIDX}"
18552
18553         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18554         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18555                 error " expect $old_dir_flag get $new_dir_flag"
18556
18557         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18558         [ "$old_file_flag" = "$new_file_flag" ] ||
18559                 error " expect $old_file_flag get $new_file_flag"
18560
18561         local new_dir_mode=$(stat -c%f $migrate_dir)
18562         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18563                 error "expect mode $old_dir_mode get $new_dir_mode"
18564
18565         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18566         [ "$old_file_mode" = "$new_file_mode" ] ||
18567                 error "expect mode $old_file_mode get $new_file_mode"
18568
18569         diff /etc/passwd $migrate_dir/$tfile ||
18570                 error "$tfile different after migration"
18571
18572         diff /etc/passwd $other_dir/luna ||
18573                 error "luna different after migration"
18574
18575         diff /etc/passwd $migrate_dir/sofia ||
18576                 error "sofia different after migration"
18577
18578         diff /etc/passwd $migrate_dir/david ||
18579                 error "david different after migration"
18580
18581         diff /etc/passwd $other_dir/zachary ||
18582                 error "zachary different after migration"
18583
18584         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18585                 error "${tfile}_ln different after migration"
18586
18587         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18588                 error "${tfile}_ln_other different after migration"
18589
18590         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18591         [ $stripe_count = 2 ] ||
18592                 error "dir strpe_count $d != 2 after migration."
18593
18594         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18595         [ $stripe_count = 2 ] ||
18596                 error "file strpe_count $d != 2 after migration."
18597
18598         #migrate back to MDT0
18599         MDTIDX=0
18600
18601         $LFS migrate -m $MDTIDX $migrate_dir ||
18602                 error "fails on migrating remote dir to MDT0"
18603
18604         echo "migrate back to MDT0, checking.."
18605         for file in $(find $migrate_dir); do
18606                 mdt_index=$($LFS getstripe -m $file)
18607                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18608                         error "$file is not on MDT${MDTIDX}"
18609         done
18610
18611         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18612         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18613                 error " expect $old_dir_flag get $new_dir_flag"
18614
18615         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18616         [ "$old_file_flag" = "$new_file_flag" ] ||
18617                 error " expect $old_file_flag get $new_file_flag"
18618
18619         local new_dir_mode=$(stat -c%f $migrate_dir)
18620         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18621                 error "expect mode $old_dir_mode get $new_dir_mode"
18622
18623         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18624         [ "$old_file_mode" = "$new_file_mode" ] ||
18625                 error "expect mode $old_file_mode get $new_file_mode"
18626
18627         diff /etc/passwd ${migrate_dir}/$tfile ||
18628                 error "$tfile different after migration"
18629
18630         diff /etc/passwd ${other_dir}/luna ||
18631                 error "luna different after migration"
18632
18633         diff /etc/passwd ${migrate_dir}/sofia ||
18634                 error "sofia different after migration"
18635
18636         diff /etc/passwd ${other_dir}/zachary ||
18637                 error "zachary different after migration"
18638
18639         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18640                 error "${tfile}_ln different after migration"
18641
18642         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18643                 error "${tfile}_ln_other different after migration"
18644
18645         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18646         [ $stripe_count = 2 ] ||
18647                 error "dir strpe_count $d != 2 after migration."
18648
18649         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18650         [ $stripe_count = 2 ] ||
18651                 error "file strpe_count $d != 2 after migration."
18652
18653         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18654 }
18655 run_test 230b "migrate directory"
18656
18657 test_230c() {
18658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18659         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18660         remote_mds_nodsh && skip "remote MDS with nodsh"
18661         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18662                 skip "Need MDS version at least 2.11.52"
18663
18664         local MDTIDX=1
18665         local total=3
18666         local mdt_index
18667         local file
18668         local migrate_dir=$DIR/$tdir/migrate_dir
18669
18670         #If migrating directory fails in the middle, all entries of
18671         #the directory is still accessiable.
18672         test_mkdir $DIR/$tdir
18673         test_mkdir -i0 -c1 $migrate_dir
18674         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18675         stat $migrate_dir
18676         createmany -o $migrate_dir/f $total ||
18677                 error "create files under ${migrate_dir} failed"
18678
18679         # fail after migrating top dir, and this will fail only once, so the
18680         # first sub file migration will fail (currently f3), others succeed.
18681         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18682         do_facet mds1 lctl set_param fail_loc=0x1801
18683         local t=$(ls $migrate_dir | wc -l)
18684         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18685                 error "migrate should fail"
18686         local u=$(ls $migrate_dir | wc -l)
18687         [ "$u" == "$t" ] || error "$u != $t during migration"
18688
18689         # add new dir/file should succeed
18690         mkdir $migrate_dir/dir ||
18691                 error "mkdir failed under migrating directory"
18692         touch $migrate_dir/file ||
18693                 error "create file failed under migrating directory"
18694
18695         # add file with existing name should fail
18696         for file in $migrate_dir/f*; do
18697                 stat $file > /dev/null || error "stat $file failed"
18698                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18699                         error "open(O_CREAT|O_EXCL) $file should fail"
18700                 $MULTIOP $file m && error "create $file should fail"
18701                 touch $DIR/$tdir/remote_dir/$tfile ||
18702                         error "touch $tfile failed"
18703                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18704                         error "link $file should fail"
18705                 mdt_index=$($LFS getstripe -m $file)
18706                 if [ $mdt_index == 0 ]; then
18707                         # file failed to migrate is not allowed to rename to
18708                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18709                                 error "rename to $file should fail"
18710                 else
18711                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18712                                 error "rename to $file failed"
18713                 fi
18714                 echo hello >> $file || error "write $file failed"
18715         done
18716
18717         # resume migration with different options should fail
18718         $LFS migrate -m 0 $migrate_dir &&
18719                 error "migrate -m 0 $migrate_dir should fail"
18720
18721         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18722                 error "migrate -c 2 $migrate_dir should fail"
18723
18724         # resume migration should succeed
18725         $LFS migrate -m $MDTIDX $migrate_dir ||
18726                 error "migrate $migrate_dir failed"
18727
18728         echo "Finish migration, then checking.."
18729         for file in $(find $migrate_dir); do
18730                 mdt_index=$($LFS getstripe -m $file)
18731                 [ $mdt_index == $MDTIDX ] ||
18732                         error "$file is not on MDT${MDTIDX}"
18733         done
18734
18735         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18736 }
18737 run_test 230c "check directory accessiblity if migration failed"
18738
18739 test_230d() {
18740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18741         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18742         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18743                 skip "Need MDS version at least 2.11.52"
18744         # LU-11235
18745         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18746
18747         local migrate_dir=$DIR/$tdir/migrate_dir
18748         local old_index
18749         local new_index
18750         local old_count
18751         local new_count
18752         local new_hash
18753         local mdt_index
18754         local i
18755         local j
18756
18757         old_index=$((RANDOM % MDSCOUNT))
18758         old_count=$((MDSCOUNT - old_index))
18759         new_index=$((RANDOM % MDSCOUNT))
18760         new_count=$((MDSCOUNT - new_index))
18761         new_hash=1 # for all_char
18762
18763         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18764         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18765
18766         test_mkdir $DIR/$tdir
18767         test_mkdir -i $old_index -c $old_count $migrate_dir
18768
18769         for ((i=0; i<100; i++)); do
18770                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18771                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18772                         error "create files under remote dir failed $i"
18773         done
18774
18775         echo -n "Migrate from MDT$old_index "
18776         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18777         echo -n "to MDT$new_index"
18778         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18779         echo
18780
18781         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18782         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18783                 error "migrate remote dir error"
18784
18785         echo "Finish migration, then checking.."
18786         for file in $(find $migrate_dir); do
18787                 mdt_index=$($LFS getstripe -m $file)
18788                 if [ $mdt_index -lt $new_index ] ||
18789                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18790                         error "$file is on MDT$mdt_index"
18791                 fi
18792         done
18793
18794         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18795 }
18796 run_test 230d "check migrate big directory"
18797
18798 test_230e() {
18799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18800         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18801         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18802                 skip "Need MDS version at least 2.11.52"
18803
18804         local i
18805         local j
18806         local a_fid
18807         local b_fid
18808
18809         mkdir -p $DIR/$tdir
18810         mkdir $DIR/$tdir/migrate_dir
18811         mkdir $DIR/$tdir/other_dir
18812         touch $DIR/$tdir/migrate_dir/a
18813         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18814         ls $DIR/$tdir/other_dir
18815
18816         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18817                 error "migrate dir fails"
18818
18819         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18820         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18821
18822         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18823         [ $mdt_index == 0 ] || error "a is not on MDT0"
18824
18825         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18826                 error "migrate dir fails"
18827
18828         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18829         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18830
18831         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18832         [ $mdt_index == 1 ] || error "a is not on MDT1"
18833
18834         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18835         [ $mdt_index == 1 ] || error "b is not on MDT1"
18836
18837         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18838         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18839
18840         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18841
18842         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18843 }
18844 run_test 230e "migrate mulitple local link files"
18845
18846 test_230f() {
18847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18848         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18849         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18850                 skip "Need MDS version at least 2.11.52"
18851
18852         local a_fid
18853         local ln_fid
18854
18855         mkdir -p $DIR/$tdir
18856         mkdir $DIR/$tdir/migrate_dir
18857         $LFS mkdir -i1 $DIR/$tdir/other_dir
18858         touch $DIR/$tdir/migrate_dir/a
18859         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18860         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18861         ls $DIR/$tdir/other_dir
18862
18863         # a should be migrated to MDT1, since no other links on MDT0
18864         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18865                 error "#1 migrate dir fails"
18866         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18867         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18868         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18869         [ $mdt_index == 1 ] || error "a is not on MDT1"
18870
18871         # a should stay on MDT1, because it is a mulitple link file
18872         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18873                 error "#2 migrate dir fails"
18874         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18875         [ $mdt_index == 1 ] || error "a is not on MDT1"
18876
18877         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18878                 error "#3 migrate dir fails"
18879
18880         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18881         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18882         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18883
18884         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18885         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18886
18887         # a should be migrated to MDT0, since no other links on MDT1
18888         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18889                 error "#4 migrate dir fails"
18890         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18891         [ $mdt_index == 0 ] || error "a is not on MDT0"
18892
18893         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18894 }
18895 run_test 230f "migrate mulitple remote link files"
18896
18897 test_230g() {
18898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18899         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18900         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18901                 skip "Need MDS version at least 2.11.52"
18902
18903         mkdir -p $DIR/$tdir/migrate_dir
18904
18905         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18906                 error "migrating dir to non-exist MDT succeeds"
18907         true
18908 }
18909 run_test 230g "migrate dir to non-exist MDT"
18910
18911 test_230h() {
18912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18913         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18914         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18915                 skip "Need MDS version at least 2.11.52"
18916
18917         local mdt_index
18918
18919         mkdir -p $DIR/$tdir/migrate_dir
18920
18921         $LFS migrate -m1 $DIR &&
18922                 error "migrating mountpoint1 should fail"
18923
18924         $LFS migrate -m1 $DIR/$tdir/.. &&
18925                 error "migrating mountpoint2 should fail"
18926
18927         # same as mv
18928         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18929                 error "migrating $tdir/migrate_dir/.. should fail"
18930
18931         true
18932 }
18933 run_test 230h "migrate .. and root"
18934
18935 test_230i() {
18936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18937         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18938         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18939                 skip "Need MDS version at least 2.11.52"
18940
18941         mkdir -p $DIR/$tdir/migrate_dir
18942
18943         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18944                 error "migration fails with a tailing slash"
18945
18946         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18947                 error "migration fails with two tailing slashes"
18948 }
18949 run_test 230i "lfs migrate -m tolerates trailing slashes"
18950
18951 test_230j() {
18952         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18953         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18954                 skip "Need MDS version at least 2.11.52"
18955
18956         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18957         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18958                 error "create $tfile failed"
18959         cat /etc/passwd > $DIR/$tdir/$tfile
18960
18961         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18962
18963         cmp /etc/passwd $DIR/$tdir/$tfile ||
18964                 error "DoM file mismatch after migration"
18965 }
18966 run_test 230j "DoM file data not changed after dir migration"
18967
18968 test_230k() {
18969         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18970         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18971                 skip "Need MDS version at least 2.11.56"
18972
18973         local total=20
18974         local files_on_starting_mdt=0
18975
18976         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18977         $LFS getdirstripe $DIR/$tdir
18978         for i in $(seq $total); do
18979                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18980                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18981                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18982         done
18983
18984         echo "$files_on_starting_mdt files on MDT0"
18985
18986         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18987         $LFS getdirstripe $DIR/$tdir
18988
18989         files_on_starting_mdt=0
18990         for i in $(seq $total); do
18991                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18992                         error "file $tfile.$i mismatch after migration"
18993                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18994                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18995         done
18996
18997         echo "$files_on_starting_mdt files on MDT1 after migration"
18998         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18999
19000         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19001         $LFS getdirstripe $DIR/$tdir
19002
19003         files_on_starting_mdt=0
19004         for i in $(seq $total); do
19005                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19006                         error "file $tfile.$i mismatch after 2nd migration"
19007                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19008                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19009         done
19010
19011         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19012         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19013
19014         true
19015 }
19016 run_test 230k "file data not changed after dir migration"
19017
19018 test_230l() {
19019         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19020         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19021                 skip "Need MDS version at least 2.11.56"
19022
19023         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19024         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19025                 error "create files under remote dir failed $i"
19026         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19027 }
19028 run_test 230l "readdir between MDTs won't crash"
19029
19030 test_230m() {
19031         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19032         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19033                 skip "Need MDS version at least 2.11.56"
19034
19035         local MDTIDX=1
19036         local mig_dir=$DIR/$tdir/migrate_dir
19037         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19038         local shortstr="b"
19039         local val
19040
19041         echo "Creating files and dirs with xattrs"
19042         test_mkdir $DIR/$tdir
19043         test_mkdir -i0 -c1 $mig_dir
19044         mkdir $mig_dir/dir
19045         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19046                 error "cannot set xattr attr1 on dir"
19047         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19048                 error "cannot set xattr attr2 on dir"
19049         touch $mig_dir/dir/f0
19050         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19051                 error "cannot set xattr attr1 on file"
19052         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19053                 error "cannot set xattr attr2 on file"
19054         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19055         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19056         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19057         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19058         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19059         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19060         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19061         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19062         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19063
19064         echo "Migrating to MDT1"
19065         $LFS migrate -m $MDTIDX $mig_dir ||
19066                 error "fails on migrating dir to MDT1"
19067
19068         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19069         echo "Checking xattrs"
19070         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19071         [ "$val" = $longstr ] ||
19072                 error "expecting xattr1 $longstr on dir, found $val"
19073         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19074         [ "$val" = $shortstr ] ||
19075                 error "expecting xattr2 $shortstr on dir, found $val"
19076         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19077         [ "$val" = $longstr ] ||
19078                 error "expecting xattr1 $longstr on file, found $val"
19079         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19080         [ "$val" = $shortstr ] ||
19081                 error "expecting xattr2 $shortstr on file, found $val"
19082 }
19083 run_test 230m "xattrs not changed after dir migration"
19084
19085 test_230n() {
19086         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19087         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19088                 skip "Need MDS version at least 2.13.53"
19089
19090         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19091         cat /etc/hosts > $DIR/$tdir/$tfile
19092         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19093         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19094
19095         cmp /etc/hosts $DIR/$tdir/$tfile ||
19096                 error "File data mismatch after migration"
19097 }
19098 run_test 230n "Dir migration with mirrored file"
19099
19100 test_230o() {
19101         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19102         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19103                 skip "Need MDS version at least 2.13.52"
19104
19105         local mdts=$(comma_list $(mdts_nodes))
19106         local timeout=100
19107         local restripe_status
19108         local delta
19109         local i
19110
19111         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19112
19113         # in case "crush" hash type is not set
19114         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19115
19116         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19117                            mdt.*MDT0000.enable_dir_restripe)
19118         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19119         stack_trap "do_nodes $mdts $LCTL set_param \
19120                     mdt.*.enable_dir_restripe=$restripe_status"
19121
19122         mkdir $DIR/$tdir
19123         createmany -m $DIR/$tdir/f 100 ||
19124                 error "create files under remote dir failed $i"
19125         createmany -d $DIR/$tdir/d 100 ||
19126                 error "create dirs under remote dir failed $i"
19127
19128         for i in $(seq 2 $MDSCOUNT); do
19129                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19130                 $LFS setdirstripe -c $i $DIR/$tdir ||
19131                         error "split -c $i $tdir failed"
19132                 wait_update $HOSTNAME \
19133                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19134                         error "dir split not finished"
19135                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19136                         awk '/migrate/ {sum += $2} END { print sum }')
19137                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19138                 # delta is around total_files/stripe_count
19139                 (( $delta < 200 / (i - 1) + 4 )) ||
19140                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19141         done
19142 }
19143 run_test 230o "dir split"
19144
19145 test_230p() {
19146         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19147         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19148                 skip "Need MDS version at least 2.13.52"
19149
19150         local mdts=$(comma_list $(mdts_nodes))
19151         local timeout=100
19152         local restripe_status
19153         local delta
19154         local i
19155
19156         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19157
19158         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19159
19160         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19161                            mdt.*MDT0000.enable_dir_restripe)
19162         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19163         stack_trap "do_nodes $mdts $LCTL set_param \
19164                     mdt.*.enable_dir_restripe=$restripe_status"
19165
19166         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19167         createmany -m $DIR/$tdir/f 100 ||
19168                 error "create files under remote dir failed $i"
19169         createmany -d $DIR/$tdir/d 100 ||
19170                 error "create dirs under remote dir failed $i"
19171
19172         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19173                 local mdt_hash="crush"
19174
19175                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19176                 $LFS setdirstripe -c $i $DIR/$tdir ||
19177                         error "split -c $i $tdir failed"
19178                 [ $i -eq 1 ] && mdt_hash="none"
19179                 wait_update $HOSTNAME \
19180                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19181                         error "dir merge not finished"
19182                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19183                         awk '/migrate/ {sum += $2} END { print sum }')
19184                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19185                 # delta is around total_files/stripe_count
19186                 (( $delta < 200 / i + 4 )) ||
19187                         error "$delta files migrated >= $((200 / i + 4))"
19188         done
19189 }
19190 run_test 230p "dir merge"
19191
19192 test_230q() {
19193         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19194         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19195                 skip "Need MDS version at least 2.13.52"
19196
19197         local mdts=$(comma_list $(mdts_nodes))
19198         local saved_threshold=$(do_facet mds1 \
19199                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19200         local saved_delta=$(do_facet mds1 \
19201                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19202         local threshold=100
19203         local delta=2
19204         local total=0
19205         local stripe_count=0
19206         local stripe_index
19207         local nr_files
19208         local create
19209
19210         # test with fewer files on ZFS
19211         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19212
19213         stack_trap "do_nodes $mdts $LCTL set_param \
19214                     mdt.*.dir_split_count=$saved_threshold"
19215         stack_trap "do_nodes $mdts $LCTL set_param \
19216                     mdt.*.dir_split_delta=$saved_delta"
19217         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19218         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19219         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19220         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19221         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19222         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19223
19224         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19225         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19226
19227         create=$((threshold * 3 / 2))
19228         while [ $stripe_count -lt $MDSCOUNT ]; do
19229                 createmany -m $DIR/$tdir/f $total $create ||
19230                         error "create sub files failed"
19231                 stat $DIR/$tdir > /dev/null
19232                 total=$((total + create))
19233                 stripe_count=$((stripe_count + delta))
19234                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19235
19236                 wait_update $HOSTNAME \
19237                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19238                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19239
19240                 wait_update $HOSTNAME \
19241                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19242                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19243
19244                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19245                 echo "$nr_files/$total files on MDT$stripe_index after split"
19246                 # allow 10% margin of imbalance with crush hash
19247                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19248                         error "$nr_files files on MDT$stripe_index after split"
19249
19250                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19251                 [ $nr_files -eq $total ] ||
19252                         error "total sub files $nr_files != $total"
19253         done
19254 }
19255 run_test 230q "dir auto split"
19256
19257 test_230r() {
19258         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19259         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19260         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19261                 skip "Need MDS version at least 2.13.54"
19262
19263         # maximum amount of local locks:
19264         # parent striped dir - 2 locks
19265         # new stripe in parent to migrate to - 1 lock
19266         # source and target - 2 locks
19267         # Total 5 locks for regular file
19268         mkdir -p $DIR/$tdir
19269         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19270         touch $DIR/$tdir/dir1/eee
19271
19272         # create 4 hardlink for 4 more locks
19273         # Total: 9 locks > RS_MAX_LOCKS (8)
19274         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19275         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19276         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19277         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19278         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19279         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19280         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19281         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19282
19283         cancel_lru_locks mdc
19284
19285         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19286                 error "migrate dir fails"
19287
19288         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19289 }
19290 run_test 230r "migrate with too many local locks"
19291
19292 test_230s() {
19293         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19294                 skip "Need MDS version at least 2.13.57"
19295
19296         local mdts=$(comma_list $(mdts_nodes))
19297         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19298                                 mdt.*MDT0000.enable_dir_restripe)
19299
19300         stack_trap "do_nodes $mdts $LCTL set_param \
19301                     mdt.*.enable_dir_restripe=$restripe_status"
19302
19303         local st
19304         for st in 0 1; do
19305                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19306                 test_mkdir $DIR/$tdir
19307                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19308                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19309                 rmdir $DIR/$tdir
19310         done
19311 }
19312 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19313
19314 test_231a()
19315 {
19316         # For simplicity this test assumes that max_pages_per_rpc
19317         # is the same across all OSCs
19318         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19319         local bulk_size=$((max_pages * PAGE_SIZE))
19320         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19321                                        head -n 1)
19322
19323         mkdir -p $DIR/$tdir
19324         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19325                 error "failed to set stripe with -S ${brw_size}M option"
19326
19327         # clear the OSC stats
19328         $LCTL set_param osc.*.stats=0 &>/dev/null
19329         stop_writeback
19330
19331         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19332         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19333                 oflag=direct &>/dev/null || error "dd failed"
19334
19335         sync; sleep 1; sync # just to be safe
19336         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19337         if [ x$nrpcs != "x1" ]; then
19338                 $LCTL get_param osc.*.stats
19339                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19340         fi
19341
19342         start_writeback
19343         # Drop the OSC cache, otherwise we will read from it
19344         cancel_lru_locks osc
19345
19346         # clear the OSC stats
19347         $LCTL set_param osc.*.stats=0 &>/dev/null
19348
19349         # Client reads $bulk_size.
19350         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19351                 iflag=direct &>/dev/null || error "dd failed"
19352
19353         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19354         if [ x$nrpcs != "x1" ]; then
19355                 $LCTL get_param osc.*.stats
19356                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19357         fi
19358 }
19359 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19360
19361 test_231b() {
19362         mkdir -p $DIR/$tdir
19363         local i
19364         for i in {0..1023}; do
19365                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19366                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19367                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19368         done
19369         sync
19370 }
19371 run_test 231b "must not assert on fully utilized OST request buffer"
19372
19373 test_232a() {
19374         mkdir -p $DIR/$tdir
19375         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19376
19377         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19378         do_facet ost1 $LCTL set_param fail_loc=0x31c
19379
19380         # ignore dd failure
19381         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19382
19383         do_facet ost1 $LCTL set_param fail_loc=0
19384         umount_client $MOUNT || error "umount failed"
19385         mount_client $MOUNT || error "mount failed"
19386         stop ost1 || error "cannot stop ost1"
19387         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19388 }
19389 run_test 232a "failed lock should not block umount"
19390
19391 test_232b() {
19392         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19393                 skip "Need MDS version at least 2.10.58"
19394
19395         mkdir -p $DIR/$tdir
19396         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19397         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19398         sync
19399         cancel_lru_locks osc
19400
19401         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19402         do_facet ost1 $LCTL set_param fail_loc=0x31c
19403
19404         # ignore failure
19405         $LFS data_version $DIR/$tdir/$tfile || true
19406
19407         do_facet ost1 $LCTL set_param fail_loc=0
19408         umount_client $MOUNT || error "umount failed"
19409         mount_client $MOUNT || error "mount failed"
19410         stop ost1 || error "cannot stop ost1"
19411         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19412 }
19413 run_test 232b "failed data version lock should not block umount"
19414
19415 test_233a() {
19416         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19417                 skip "Need MDS version at least 2.3.64"
19418         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19419
19420         local fid=$($LFS path2fid $MOUNT)
19421
19422         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19423                 error "cannot access $MOUNT using its FID '$fid'"
19424 }
19425 run_test 233a "checking that OBF of the FS root succeeds"
19426
19427 test_233b() {
19428         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19429                 skip "Need MDS version at least 2.5.90"
19430         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19431
19432         local fid=$($LFS path2fid $MOUNT/.lustre)
19433
19434         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19435                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19436
19437         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19438         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19439                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19440 }
19441 run_test 233b "checking that OBF of the FS .lustre succeeds"
19442
19443 test_234() {
19444         local p="$TMP/sanityN-$TESTNAME.parameters"
19445         save_lustre_params client "llite.*.xattr_cache" > $p
19446         lctl set_param llite.*.xattr_cache 1 ||
19447                 skip_env "xattr cache is not supported"
19448
19449         mkdir -p $DIR/$tdir || error "mkdir failed"
19450         touch $DIR/$tdir/$tfile || error "touch failed"
19451         # OBD_FAIL_LLITE_XATTR_ENOMEM
19452         $LCTL set_param fail_loc=0x1405
19453         getfattr -n user.attr $DIR/$tdir/$tfile &&
19454                 error "getfattr should have failed with ENOMEM"
19455         $LCTL set_param fail_loc=0x0
19456         rm -rf $DIR/$tdir
19457
19458         restore_lustre_params < $p
19459         rm -f $p
19460 }
19461 run_test 234 "xattr cache should not crash on ENOMEM"
19462
19463 test_235() {
19464         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19465                 skip "Need MDS version at least 2.4.52"
19466
19467         flock_deadlock $DIR/$tfile
19468         local RC=$?
19469         case $RC in
19470                 0)
19471                 ;;
19472                 124) error "process hangs on a deadlock"
19473                 ;;
19474                 *) error "error executing flock_deadlock $DIR/$tfile"
19475                 ;;
19476         esac
19477 }
19478 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19479
19480 #LU-2935
19481 test_236() {
19482         check_swap_layouts_support
19483
19484         local ref1=/etc/passwd
19485         local ref2=/etc/group
19486         local file1=$DIR/$tdir/f1
19487         local file2=$DIR/$tdir/f2
19488
19489         test_mkdir -c1 $DIR/$tdir
19490         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19491         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19492         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19493         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19494         local fd=$(free_fd)
19495         local cmd="exec $fd<>$file2"
19496         eval $cmd
19497         rm $file2
19498         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19499                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19500         cmd="exec $fd>&-"
19501         eval $cmd
19502         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19503
19504         #cleanup
19505         rm -rf $DIR/$tdir
19506 }
19507 run_test 236 "Layout swap on open unlinked file"
19508
19509 # LU-4659 linkea consistency
19510 test_238() {
19511         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19512                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19513                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19514                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19515
19516         touch $DIR/$tfile
19517         ln $DIR/$tfile $DIR/$tfile.lnk
19518         touch $DIR/$tfile.new
19519         mv $DIR/$tfile.new $DIR/$tfile
19520         local fid1=$($LFS path2fid $DIR/$tfile)
19521         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19522         local path1=$($LFS fid2path $FSNAME "$fid1")
19523         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19524         local path2=$($LFS fid2path $FSNAME "$fid2")
19525         [ $tfile.lnk == $path2 ] ||
19526                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19527         rm -f $DIR/$tfile*
19528 }
19529 run_test 238 "Verify linkea consistency"
19530
19531 test_239A() { # was test_239
19532         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19533                 skip "Need MDS version at least 2.5.60"
19534
19535         local list=$(comma_list $(mdts_nodes))
19536
19537         mkdir -p $DIR/$tdir
19538         createmany -o $DIR/$tdir/f- 5000
19539         unlinkmany $DIR/$tdir/f- 5000
19540         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19541                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19542         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19543                         osp.*MDT*.sync_in_flight" | calc_sum)
19544         [ "$changes" -eq 0 ] || error "$changes not synced"
19545 }
19546 run_test 239A "osp_sync test"
19547
19548 test_239a() { #LU-5297
19549         remote_mds_nodsh && skip "remote MDS with nodsh"
19550
19551         touch $DIR/$tfile
19552         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19553         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19554         chgrp $RUNAS_GID $DIR/$tfile
19555         wait_delete_completed
19556 }
19557 run_test 239a "process invalid osp sync record correctly"
19558
19559 test_239b() { #LU-5297
19560         remote_mds_nodsh && skip "remote MDS with nodsh"
19561
19562         touch $DIR/$tfile1
19563         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19564         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19565         chgrp $RUNAS_GID $DIR/$tfile1
19566         wait_delete_completed
19567         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19568         touch $DIR/$tfile2
19569         chgrp $RUNAS_GID $DIR/$tfile2
19570         wait_delete_completed
19571 }
19572 run_test 239b "process osp sync record with ENOMEM error correctly"
19573
19574 test_240() {
19575         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19576         remote_mds_nodsh && skip "remote MDS with nodsh"
19577
19578         mkdir -p $DIR/$tdir
19579
19580         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19581                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19582         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19583                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19584
19585         umount_client $MOUNT || error "umount failed"
19586         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19587         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19588         mount_client $MOUNT || error "failed to mount client"
19589
19590         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19591         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19592 }
19593 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19594
19595 test_241_bio() {
19596         local count=$1
19597         local bsize=$2
19598
19599         for LOOP in $(seq $count); do
19600                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19601                 cancel_lru_locks $OSC || true
19602         done
19603 }
19604
19605 test_241_dio() {
19606         local count=$1
19607         local bsize=$2
19608
19609         for LOOP in $(seq $1); do
19610                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19611                         2>/dev/null
19612         done
19613 }
19614
19615 test_241a() { # was test_241
19616         local bsize=$PAGE_SIZE
19617
19618         (( bsize < 40960 )) && bsize=40960
19619         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19620         ls -la $DIR/$tfile
19621         cancel_lru_locks $OSC
19622         test_241_bio 1000 $bsize &
19623         PID=$!
19624         test_241_dio 1000 $bsize
19625         wait $PID
19626 }
19627 run_test 241a "bio vs dio"
19628
19629 test_241b() {
19630         local bsize=$PAGE_SIZE
19631
19632         (( bsize < 40960 )) && bsize=40960
19633         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19634         ls -la $DIR/$tfile
19635         test_241_dio 1000 $bsize &
19636         PID=$!
19637         test_241_dio 1000 $bsize
19638         wait $PID
19639 }
19640 run_test 241b "dio vs dio"
19641
19642 test_242() {
19643         remote_mds_nodsh && skip "remote MDS with nodsh"
19644
19645         mkdir -p $DIR/$tdir
19646         touch $DIR/$tdir/$tfile
19647
19648         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19649         do_facet mds1 lctl set_param fail_loc=0x105
19650         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19651
19652         do_facet mds1 lctl set_param fail_loc=0
19653         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19654 }
19655 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19656
19657 test_243()
19658 {
19659         test_mkdir $DIR/$tdir
19660         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19661 }
19662 run_test 243 "various group lock tests"
19663
19664 test_244a()
19665 {
19666         test_mkdir $DIR/$tdir
19667         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19668         sendfile_grouplock $DIR/$tdir/$tfile || \
19669                 error "sendfile+grouplock failed"
19670         rm -rf $DIR/$tdir
19671 }
19672 run_test 244a "sendfile with group lock tests"
19673
19674 test_244b()
19675 {
19676         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19677
19678         local threads=50
19679         local size=$((1024*1024))
19680
19681         test_mkdir $DIR/$tdir
19682         for i in $(seq 1 $threads); do
19683                 local file=$DIR/$tdir/file_$((i / 10))
19684                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19685                 local pids[$i]=$!
19686         done
19687         for i in $(seq 1 $threads); do
19688                 wait ${pids[$i]}
19689         done
19690 }
19691 run_test 244b "multi-threaded write with group lock"
19692
19693 test_245() {
19694         local flagname="multi_mod_rpcs"
19695         local connect_data_name="max_mod_rpcs"
19696         local out
19697
19698         # check if multiple modify RPCs flag is set
19699         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19700                 grep "connect_flags:")
19701         echo "$out"
19702
19703         echo "$out" | grep -qw $flagname
19704         if [ $? -ne 0 ]; then
19705                 echo "connect flag $flagname is not set"
19706                 return
19707         fi
19708
19709         # check if multiple modify RPCs data is set
19710         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19711         echo "$out"
19712
19713         echo "$out" | grep -qw $connect_data_name ||
19714                 error "import should have connect data $connect_data_name"
19715 }
19716 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19717
19718 cleanup_247() {
19719         local submount=$1
19720
19721         trap 0
19722         umount_client $submount
19723         rmdir $submount
19724 }
19725
19726 test_247a() {
19727         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19728                 grep -q subtree ||
19729                 skip_env "Fileset feature is not supported"
19730
19731         local submount=${MOUNT}_$tdir
19732
19733         mkdir $MOUNT/$tdir
19734         mkdir -p $submount || error "mkdir $submount failed"
19735         FILESET="$FILESET/$tdir" mount_client $submount ||
19736                 error "mount $submount failed"
19737         trap "cleanup_247 $submount" EXIT
19738         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19739         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19740                 error "read $MOUNT/$tdir/$tfile failed"
19741         cleanup_247 $submount
19742 }
19743 run_test 247a "mount subdir as fileset"
19744
19745 test_247b() {
19746         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19747                 skip_env "Fileset feature is not supported"
19748
19749         local submount=${MOUNT}_$tdir
19750
19751         rm -rf $MOUNT/$tdir
19752         mkdir -p $submount || error "mkdir $submount failed"
19753         SKIP_FILESET=1
19754         FILESET="$FILESET/$tdir" mount_client $submount &&
19755                 error "mount $submount should fail"
19756         rmdir $submount
19757 }
19758 run_test 247b "mount subdir that dose not exist"
19759
19760 test_247c() {
19761         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19762                 skip_env "Fileset feature is not supported"
19763
19764         local submount=${MOUNT}_$tdir
19765
19766         mkdir -p $MOUNT/$tdir/dir1
19767         mkdir -p $submount || error "mkdir $submount failed"
19768         trap "cleanup_247 $submount" EXIT
19769         FILESET="$FILESET/$tdir" mount_client $submount ||
19770                 error "mount $submount failed"
19771         local fid=$($LFS path2fid $MOUNT/)
19772         $LFS fid2path $submount $fid && error "fid2path should fail"
19773         cleanup_247 $submount
19774 }
19775 run_test 247c "running fid2path outside subdirectory root"
19776
19777 test_247d() {
19778         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19779                 skip "Fileset feature is not supported"
19780
19781         local submount=${MOUNT}_$tdir
19782
19783         mkdir -p $MOUNT/$tdir/dir1
19784         mkdir -p $submount || error "mkdir $submount failed"
19785         FILESET="$FILESET/$tdir" mount_client $submount ||
19786                 error "mount $submount failed"
19787         trap "cleanup_247 $submount" EXIT
19788
19789         local td=$submount/dir1
19790         local fid=$($LFS path2fid $td)
19791         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19792
19793         # check that we get the same pathname back
19794         local rootpath
19795         local found
19796         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19797                 echo "$rootpath $fid"
19798                 found=$($LFS fid2path $rootpath "$fid")
19799                 [ -n "found" ] || error "fid2path should succeed"
19800                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19801         done
19802         # check wrong root path format
19803         rootpath=$submount"_wrong"
19804         found=$($LFS fid2path $rootpath "$fid")
19805         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19806
19807         cleanup_247 $submount
19808 }
19809 run_test 247d "running fid2path inside subdirectory root"
19810
19811 # LU-8037
19812 test_247e() {
19813         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19814                 grep -q subtree ||
19815                 skip "Fileset feature is not supported"
19816
19817         local submount=${MOUNT}_$tdir
19818
19819         mkdir $MOUNT/$tdir
19820         mkdir -p $submount || error "mkdir $submount failed"
19821         FILESET="$FILESET/.." mount_client $submount &&
19822                 error "mount $submount should fail"
19823         rmdir $submount
19824 }
19825 run_test 247e "mount .. as fileset"
19826
19827 test_247f() {
19828         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19829         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19830                 skip "Need at least version 2.13.52"
19831         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
19832                 skip "Need at least version 2.14.50"
19833         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19834                 grep -q subtree ||
19835                 skip "Fileset feature is not supported"
19836
19837         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19838         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19839                 error "mkdir remote failed"
19840         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19841         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
19842                 error "mkdir striped failed"
19843         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19844
19845         local submount=${MOUNT}_$tdir
19846
19847         mkdir -p $submount || error "mkdir $submount failed"
19848         stack_trap "rmdir $submount"
19849
19850         local dir
19851         local stat
19852         local fileset=$FILESET
19853         local mdts=$(comma_list $(mdts_nodes))
19854
19855         stat=$(do_facet mds1 $LCTL get_param -n \
19856                 mdt.*MDT0000.enable_remote_subdir_mount)
19857         stack_trap "do_nodes $mdts $LCTL set_param \
19858                 mdt.*.enable_remote_subdir_mount=$stat"
19859
19860         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
19861         stack_trap "umount_client $submount"
19862         FILESET="$fileset/$tdir/remote" mount_client $submount &&
19863                 error "mount remote dir $dir should fail"
19864
19865         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
19866                 $tdir/striped/. ; do
19867                 FILESET="$fileset/$dir" mount_client $submount ||
19868                         error "mount $dir failed"
19869                 umount_client $submount
19870         done
19871
19872         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
19873         FILESET="$fileset/$tdir/remote" mount_client $submount ||
19874                 error "mount $tdir/remote failed"
19875 }
19876 run_test 247f "mount striped or remote directory as fileset"
19877
19878 test_247g() {
19879         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
19880         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
19881                 skip "Need at least version 2.14.50"
19882
19883         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
19884                 error "mkdir $tdir failed"
19885         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
19886
19887         local submount=${MOUNT}_$tdir
19888
19889         mkdir -p $submount || error "mkdir $submount failed"
19890         stack_trap "rmdir $submount"
19891
19892         FILESET="$fileset/$tdir" mount_client $submount ||
19893                 error "mount $dir failed"
19894         stack_trap "umount $submount"
19895
19896         local mdts=$(comma_list $(mdts_nodes))
19897
19898         local nrpcs
19899
19900         stat $submount > /dev/null
19901         cancel_lru_locks $MDC
19902         stat $submount > /dev/null
19903         stat $submount/$tfile > /dev/null
19904         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
19905         stat $submount/$tfile > /dev/null
19906         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
19907                 awk '/getattr/ {sum += $2} END {print sum}')
19908
19909         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
19910 }
19911 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
19912
19913 test_248a() {
19914         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19915         [ -z "$fast_read_sav" ] && skip "no fast read support"
19916
19917         # create a large file for fast read verification
19918         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19919
19920         # make sure the file is created correctly
19921         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19922                 { rm -f $DIR/$tfile; skip "file creation error"; }
19923
19924         echo "Test 1: verify that fast read is 4 times faster on cache read"
19925
19926         # small read with fast read enabled
19927         $LCTL set_param -n llite.*.fast_read=1
19928         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19929                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19930                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19931         # small read with fast read disabled
19932         $LCTL set_param -n llite.*.fast_read=0
19933         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19934                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19935                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19936
19937         # verify that fast read is 4 times faster for cache read
19938         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19939                 error_not_in_vm "fast read was not 4 times faster: " \
19940                            "$t_fast vs $t_slow"
19941
19942         echo "Test 2: verify the performance between big and small read"
19943         $LCTL set_param -n llite.*.fast_read=1
19944
19945         # 1k non-cache read
19946         cancel_lru_locks osc
19947         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19948                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19949                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19950
19951         # 1M non-cache read
19952         cancel_lru_locks osc
19953         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19954                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19955                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19956
19957         # verify that big IO is not 4 times faster than small IO
19958         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19959                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19960
19961         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19962         rm -f $DIR/$tfile
19963 }
19964 run_test 248a "fast read verification"
19965
19966 test_248b() {
19967         # Default short_io_bytes=16384, try both smaller and larger sizes.
19968         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19969         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19970         echo "bs=53248 count=113 normal buffered write"
19971         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19972                 error "dd of initial data file failed"
19973         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19974
19975         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19976         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19977                 error "dd with sync normal writes failed"
19978         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19979
19980         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19981         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19982                 error "dd with sync small writes failed"
19983         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19984
19985         cancel_lru_locks osc
19986
19987         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19988         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19989         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19990         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19991                 iflag=direct || error "dd with O_DIRECT small read failed"
19992         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19993         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19994                 error "compare $TMP/$tfile.1 failed"
19995
19996         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19997         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19998
19999         # just to see what the maximum tunable value is, and test parsing
20000         echo "test invalid parameter 2MB"
20001         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20002                 error "too-large short_io_bytes allowed"
20003         echo "test maximum parameter 512KB"
20004         # if we can set a larger short_io_bytes, run test regardless of version
20005         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20006                 # older clients may not allow setting it this large, that's OK
20007                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20008                         skip "Need at least client version 2.13.50"
20009                 error "medium short_io_bytes failed"
20010         fi
20011         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20012         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20013
20014         echo "test large parameter 64KB"
20015         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20016         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20017
20018         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20019         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20020                 error "dd with sync large writes failed"
20021         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20022
20023         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20024         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20025         num=$((113 * 4096 / PAGE_SIZE))
20026         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20027         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20028                 error "dd with O_DIRECT large writes failed"
20029         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20030                 error "compare $DIR/$tfile.3 failed"
20031
20032         cancel_lru_locks osc
20033
20034         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20035         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20036                 error "dd with O_DIRECT large read failed"
20037         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20038                 error "compare $TMP/$tfile.2 failed"
20039
20040         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20041         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20042                 error "dd with O_DIRECT large read failed"
20043         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20044                 error "compare $TMP/$tfile.3 failed"
20045 }
20046 run_test 248b "test short_io read and write for both small and large sizes"
20047
20048 test_249() { # LU-7890
20049         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20050                 skip "Need at least version 2.8.54"
20051
20052         rm -f $DIR/$tfile
20053         $LFS setstripe -c 1 $DIR/$tfile
20054         # Offset 2T == 4k * 512M
20055         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20056                 error "dd to 2T offset failed"
20057 }
20058 run_test 249 "Write above 2T file size"
20059
20060 test_250() {
20061         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20062          && skip "no 16TB file size limit on ZFS"
20063
20064         $LFS setstripe -c 1 $DIR/$tfile
20065         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20066         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20067         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20068         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20069                 conv=notrunc,fsync && error "append succeeded"
20070         return 0
20071 }
20072 run_test 250 "Write above 16T limit"
20073
20074 test_251() {
20075         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20076
20077         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20078         #Skip once - writing the first stripe will succeed
20079         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20080         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20081                 error "short write happened"
20082
20083         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20084         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20085                 error "short read happened"
20086
20087         rm -f $DIR/$tfile
20088 }
20089 run_test 251 "Handling short read and write correctly"
20090
20091 test_252() {
20092         remote_mds_nodsh && skip "remote MDS with nodsh"
20093         remote_ost_nodsh && skip "remote OST with nodsh"
20094         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20095                 skip_env "ldiskfs only test"
20096         fi
20097
20098         local tgt
20099         local dev
20100         local out
20101         local uuid
20102         local num
20103         local gen
20104
20105         # check lr_reader on OST0000
20106         tgt=ost1
20107         dev=$(facet_device $tgt)
20108         out=$(do_facet $tgt $LR_READER $dev)
20109         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20110         echo "$out"
20111         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20112         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20113                 error "Invalid uuid returned by $LR_READER on target $tgt"
20114         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20115
20116         # check lr_reader -c on MDT0000
20117         tgt=mds1
20118         dev=$(facet_device $tgt)
20119         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20120                 skip "$LR_READER does not support additional options"
20121         fi
20122         out=$(do_facet $tgt $LR_READER -c $dev)
20123         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20124         echo "$out"
20125         num=$(echo "$out" | grep -c "mdtlov")
20126         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20127                 error "Invalid number of mdtlov clients returned by $LR_READER"
20128         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20129
20130         # check lr_reader -cr on MDT0000
20131         out=$(do_facet $tgt $LR_READER -cr $dev)
20132         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20133         echo "$out"
20134         echo "$out" | grep -q "^reply_data:$" ||
20135                 error "$LR_READER should have returned 'reply_data' section"
20136         num=$(echo "$out" | grep -c "client_generation")
20137         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20138 }
20139 run_test 252 "check lr_reader tool"
20140
20141 test_253() {
20142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20143         remote_mds_nodsh && skip "remote MDS with nodsh"
20144         remote_mgs_nodsh && skip "remote MGS with nodsh"
20145
20146         local ostidx=0
20147         local rc=0
20148         local ost_name=$(ostname_from_index $ostidx)
20149
20150         # on the mdt's osc
20151         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20152         do_facet $SINGLEMDS $LCTL get_param -n \
20153                 osp.$mdtosc_proc1.reserved_mb_high ||
20154                 skip  "remote MDS does not support reserved_mb_high"
20155
20156         rm -rf $DIR/$tdir
20157         wait_mds_ost_sync
20158         wait_delete_completed
20159         mkdir $DIR/$tdir
20160
20161         pool_add $TESTNAME || error "Pool creation failed"
20162         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20163
20164         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20165                 error "Setstripe failed"
20166
20167         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20168
20169         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20170                     grep "watermarks")
20171         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20172
20173         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20174                         osp.$mdtosc_proc1.prealloc_status)
20175         echo "prealloc_status $oa_status"
20176
20177         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20178                 error "File creation should fail"
20179
20180         #object allocation was stopped, but we still able to append files
20181         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20182                 oflag=append || error "Append failed"
20183
20184         rm -f $DIR/$tdir/$tfile.0
20185
20186         # For this test, we want to delete the files we created to go out of
20187         # space but leave the watermark, so we remain nearly out of space
20188         ost_watermarks_enospc_delete_files $tfile $ostidx
20189
20190         wait_delete_completed
20191
20192         sleep_maxage
20193
20194         for i in $(seq 10 12); do
20195                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20196                         2>/dev/null || error "File creation failed after rm"
20197         done
20198
20199         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20200                         osp.$mdtosc_proc1.prealloc_status)
20201         echo "prealloc_status $oa_status"
20202
20203         if (( oa_status != 0 )); then
20204                 error "Object allocation still disable after rm"
20205         fi
20206 }
20207 run_test 253 "Check object allocation limit"
20208
20209 test_254() {
20210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20211         remote_mds_nodsh && skip "remote MDS with nodsh"
20212         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20213                 skip "MDS does not support changelog_size"
20214
20215         local cl_user
20216         local MDT0=$(facet_svc $SINGLEMDS)
20217
20218         changelog_register || error "changelog_register failed"
20219
20220         changelog_clear 0 || error "changelog_clear failed"
20221
20222         local size1=$(do_facet $SINGLEMDS \
20223                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20224         echo "Changelog size $size1"
20225
20226         rm -rf $DIR/$tdir
20227         $LFS mkdir -i 0 $DIR/$tdir
20228         # change something
20229         mkdir -p $DIR/$tdir/pics/2008/zachy
20230         touch $DIR/$tdir/pics/2008/zachy/timestamp
20231         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20232         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20233         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20234         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20235         rm $DIR/$tdir/pics/desktop.jpg
20236
20237         local size2=$(do_facet $SINGLEMDS \
20238                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20239         echo "Changelog size after work $size2"
20240
20241         (( $size2 > $size1 )) ||
20242                 error "new Changelog size=$size2 less than old size=$size1"
20243 }
20244 run_test 254 "Check changelog size"
20245
20246 ladvise_no_type()
20247 {
20248         local type=$1
20249         local file=$2
20250
20251         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20252                 awk -F: '{print $2}' | grep $type > /dev/null
20253         if [ $? -ne 0 ]; then
20254                 return 0
20255         fi
20256         return 1
20257 }
20258
20259 ladvise_no_ioctl()
20260 {
20261         local file=$1
20262
20263         lfs ladvise -a willread $file > /dev/null 2>&1
20264         if [ $? -eq 0 ]; then
20265                 return 1
20266         fi
20267
20268         lfs ladvise -a willread $file 2>&1 |
20269                 grep "Inappropriate ioctl for device" > /dev/null
20270         if [ $? -eq 0 ]; then
20271                 return 0
20272         fi
20273         return 1
20274 }
20275
20276 percent() {
20277         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20278 }
20279
20280 # run a random read IO workload
20281 # usage: random_read_iops <filename> <filesize> <iosize>
20282 random_read_iops() {
20283         local file=$1
20284         local fsize=$2
20285         local iosize=${3:-4096}
20286
20287         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20288                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20289 }
20290
20291 drop_file_oss_cache() {
20292         local file="$1"
20293         local nodes="$2"
20294
20295         $LFS ladvise -a dontneed $file 2>/dev/null ||
20296                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20297 }
20298
20299 ladvise_willread_performance()
20300 {
20301         local repeat=10
20302         local average_origin=0
20303         local average_cache=0
20304         local average_ladvise=0
20305
20306         for ((i = 1; i <= $repeat; i++)); do
20307                 echo "Iter $i/$repeat: reading without willread hint"
20308                 cancel_lru_locks osc
20309                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20310                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20311                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20312                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20313
20314                 cancel_lru_locks osc
20315                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20316                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20317                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20318
20319                 cancel_lru_locks osc
20320                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20321                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20322                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20323                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20324                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20325         done
20326         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20327         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20328         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20329
20330         speedup_cache=$(percent $average_cache $average_origin)
20331         speedup_ladvise=$(percent $average_ladvise $average_origin)
20332
20333         echo "Average uncached read: $average_origin"
20334         echo "Average speedup with OSS cached read: " \
20335                 "$average_cache = +$speedup_cache%"
20336         echo "Average speedup with ladvise willread: " \
20337                 "$average_ladvise = +$speedup_ladvise%"
20338
20339         local lowest_speedup=20
20340         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20341                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20342                         "got $average_cache%. Skipping ladvise willread check."
20343                 return 0
20344         fi
20345
20346         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20347         # it is still good to run until then to exercise 'ladvise willread'
20348         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20349                 [ "$ost1_FSTYPE" = "zfs" ] &&
20350                 echo "osd-zfs does not support dontneed or drop_caches" &&
20351                 return 0
20352
20353         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20354         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20355                 error_not_in_vm "Speedup with willread is less than " \
20356                         "$lowest_speedup%, got $average_ladvise%"
20357 }
20358
20359 test_255a() {
20360         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20361                 skip "lustre < 2.8.54 does not support ladvise "
20362         remote_ost_nodsh && skip "remote OST with nodsh"
20363
20364         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20365
20366         ladvise_no_type willread $DIR/$tfile &&
20367                 skip "willread ladvise is not supported"
20368
20369         ladvise_no_ioctl $DIR/$tfile &&
20370                 skip "ladvise ioctl is not supported"
20371
20372         local size_mb=100
20373         local size=$((size_mb * 1048576))
20374         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20375                 error "dd to $DIR/$tfile failed"
20376
20377         lfs ladvise -a willread $DIR/$tfile ||
20378                 error "Ladvise failed with no range argument"
20379
20380         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20381                 error "Ladvise failed with no -l or -e argument"
20382
20383         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20384                 error "Ladvise failed with only -e argument"
20385
20386         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20387                 error "Ladvise failed with only -l argument"
20388
20389         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20390                 error "End offset should not be smaller than start offset"
20391
20392         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20393                 error "End offset should not be equal to start offset"
20394
20395         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20396                 error "Ladvise failed with overflowing -s argument"
20397
20398         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20399                 error "Ladvise failed with overflowing -e argument"
20400
20401         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20402                 error "Ladvise failed with overflowing -l argument"
20403
20404         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20405                 error "Ladvise succeeded with conflicting -l and -e arguments"
20406
20407         echo "Synchronous ladvise should wait"
20408         local delay=4
20409 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20410         do_nodes $(comma_list $(osts_nodes)) \
20411                 $LCTL set_param fail_val=$delay fail_loc=0x237
20412
20413         local start_ts=$SECONDS
20414         lfs ladvise -a willread $DIR/$tfile ||
20415                 error "Ladvise failed with no range argument"
20416         local end_ts=$SECONDS
20417         local inteval_ts=$((end_ts - start_ts))
20418
20419         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20420                 error "Synchronous advice didn't wait reply"
20421         fi
20422
20423         echo "Asynchronous ladvise shouldn't wait"
20424         local start_ts=$SECONDS
20425         lfs ladvise -a willread -b $DIR/$tfile ||
20426                 error "Ladvise failed with no range argument"
20427         local end_ts=$SECONDS
20428         local inteval_ts=$((end_ts - start_ts))
20429
20430         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20431                 error "Asynchronous advice blocked"
20432         fi
20433
20434         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20435         ladvise_willread_performance
20436 }
20437 run_test 255a "check 'lfs ladvise -a willread'"
20438
20439 facet_meminfo() {
20440         local facet=$1
20441         local info=$2
20442
20443         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20444 }
20445
20446 test_255b() {
20447         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20448                 skip "lustre < 2.8.54 does not support ladvise "
20449         remote_ost_nodsh && skip "remote OST with nodsh"
20450
20451         lfs setstripe -c 1 -i 0 $DIR/$tfile
20452
20453         ladvise_no_type dontneed $DIR/$tfile &&
20454                 skip "dontneed ladvise is not supported"
20455
20456         ladvise_no_ioctl $DIR/$tfile &&
20457                 skip "ladvise ioctl is not supported"
20458
20459         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20460                 [ "$ost1_FSTYPE" = "zfs" ] &&
20461                 skip "zfs-osd does not support 'ladvise dontneed'"
20462
20463         local size_mb=100
20464         local size=$((size_mb * 1048576))
20465         # In order to prevent disturbance of other processes, only check 3/4
20466         # of the memory usage
20467         local kibibytes=$((size_mb * 1024 * 3 / 4))
20468
20469         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20470                 error "dd to $DIR/$tfile failed"
20471
20472         #force write to complete before dropping OST cache & checking memory
20473         sync
20474
20475         local total=$(facet_meminfo ost1 MemTotal)
20476         echo "Total memory: $total KiB"
20477
20478         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20479         local before_read=$(facet_meminfo ost1 Cached)
20480         echo "Cache used before read: $before_read KiB"
20481
20482         lfs ladvise -a willread $DIR/$tfile ||
20483                 error "Ladvise willread failed"
20484         local after_read=$(facet_meminfo ost1 Cached)
20485         echo "Cache used after read: $after_read KiB"
20486
20487         lfs ladvise -a dontneed $DIR/$tfile ||
20488                 error "Ladvise dontneed again failed"
20489         local no_read=$(facet_meminfo ost1 Cached)
20490         echo "Cache used after dontneed ladvise: $no_read KiB"
20491
20492         if [ $total -lt $((before_read + kibibytes)) ]; then
20493                 echo "Memory is too small, abort checking"
20494                 return 0
20495         fi
20496
20497         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20498                 error "Ladvise willread should use more memory" \
20499                         "than $kibibytes KiB"
20500         fi
20501
20502         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20503                 error "Ladvise dontneed should release more memory" \
20504                         "than $kibibytes KiB"
20505         fi
20506 }
20507 run_test 255b "check 'lfs ladvise -a dontneed'"
20508
20509 test_255c() {
20510         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20511                 skip "lustre < 2.10.50 does not support lockahead"
20512
20513         local ost1_imp=$(get_osc_import_name client ost1)
20514         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20515                          cut -d'.' -f2)
20516         local count
20517         local new_count
20518         local difference
20519         local i
20520         local rc
20521
20522         test_mkdir -p $DIR/$tdir
20523         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20524
20525         #test 10 returns only success/failure
20526         i=10
20527         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20528         rc=$?
20529         if [ $rc -eq 255 ]; then
20530                 error "Ladvise test${i} failed, ${rc}"
20531         fi
20532
20533         #test 11 counts lock enqueue requests, all others count new locks
20534         i=11
20535         count=$(do_facet ost1 \
20536                 $LCTL get_param -n ost.OSS.ost.stats)
20537         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20538
20539         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20540         rc=$?
20541         if [ $rc -eq 255 ]; then
20542                 error "Ladvise test${i} failed, ${rc}"
20543         fi
20544
20545         new_count=$(do_facet ost1 \
20546                 $LCTL get_param -n ost.OSS.ost.stats)
20547         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20548                    awk '{ print $2 }')
20549
20550         difference="$((new_count - count))"
20551         if [ $difference -ne $rc ]; then
20552                 error "Ladvise test${i}, bad enqueue count, returned " \
20553                       "${rc}, actual ${difference}"
20554         fi
20555
20556         for i in $(seq 12 21); do
20557                 # If we do not do this, we run the risk of having too many
20558                 # locks and starting lock cancellation while we are checking
20559                 # lock counts.
20560                 cancel_lru_locks osc
20561
20562                 count=$($LCTL get_param -n \
20563                        ldlm.namespaces.$imp_name.lock_unused_count)
20564
20565                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20566                 rc=$?
20567                 if [ $rc -eq 255 ]; then
20568                         error "Ladvise test ${i} failed, ${rc}"
20569                 fi
20570
20571                 new_count=$($LCTL get_param -n \
20572                        ldlm.namespaces.$imp_name.lock_unused_count)
20573                 difference="$((new_count - count))"
20574
20575                 # Test 15 output is divided by 100 to map down to valid return
20576                 if [ $i -eq 15 ]; then
20577                         rc="$((rc * 100))"
20578                 fi
20579
20580                 if [ $difference -ne $rc ]; then
20581                         error "Ladvise test ${i}, bad lock count, returned " \
20582                               "${rc}, actual ${difference}"
20583                 fi
20584         done
20585
20586         #test 22 returns only success/failure
20587         i=22
20588         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20589         rc=$?
20590         if [ $rc -eq 255 ]; then
20591                 error "Ladvise test${i} failed, ${rc}"
20592         fi
20593 }
20594 run_test 255c "suite of ladvise lockahead tests"
20595
20596 test_256() {
20597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20598         remote_mds_nodsh && skip "remote MDS with nodsh"
20599         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20600         changelog_users $SINGLEMDS | grep "^cl" &&
20601                 skip "active changelog user"
20602
20603         local cl_user
20604         local cat_sl
20605         local mdt_dev
20606
20607         mdt_dev=$(mdsdevname 1)
20608         echo $mdt_dev
20609
20610         changelog_register || error "changelog_register failed"
20611
20612         rm -rf $DIR/$tdir
20613         mkdir -p $DIR/$tdir
20614
20615         changelog_clear 0 || error "changelog_clear failed"
20616
20617         # change something
20618         touch $DIR/$tdir/{1..10}
20619
20620         # stop the MDT
20621         stop $SINGLEMDS || error "Fail to stop MDT"
20622
20623         # remount the MDT
20624
20625         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20626
20627         #after mount new plainllog is used
20628         touch $DIR/$tdir/{11..19}
20629         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20630         stack_trap "rm -f $tmpfile"
20631         cat_sl=$(do_facet $SINGLEMDS "sync; \
20632                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20633                  llog_reader $tmpfile | grep -c type=1064553b")
20634         do_facet $SINGLEMDS llog_reader $tmpfile
20635
20636         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20637
20638         changelog_clear 0 || error "changelog_clear failed"
20639
20640         cat_sl=$(do_facet $SINGLEMDS "sync; \
20641                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20642                  llog_reader $tmpfile | grep -c type=1064553b")
20643
20644         if (( cat_sl == 2 )); then
20645                 error "Empty plain llog was not deleted from changelog catalog"
20646         elif (( cat_sl != 1 )); then
20647                 error "Active plain llog shouldn't be deleted from catalog"
20648         fi
20649 }
20650 run_test 256 "Check llog delete for empty and not full state"
20651
20652 test_257() {
20653         remote_mds_nodsh && skip "remote MDS with nodsh"
20654         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20655                 skip "Need MDS version at least 2.8.55"
20656
20657         test_mkdir $DIR/$tdir
20658
20659         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20660                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20661         stat $DIR/$tdir
20662
20663 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20664         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20665         local facet=mds$((mdtidx + 1))
20666         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20667         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20668
20669         stop $facet || error "stop MDS failed"
20670         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20671                 error "start MDS fail"
20672         wait_recovery_complete $facet
20673 }
20674 run_test 257 "xattr locks are not lost"
20675
20676 # Verify we take the i_mutex when security requires it
20677 test_258a() {
20678 #define OBD_FAIL_IMUTEX_SEC 0x141c
20679         $LCTL set_param fail_loc=0x141c
20680         touch $DIR/$tfile
20681         chmod u+s $DIR/$tfile
20682         chmod a+rwx $DIR/$tfile
20683         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20684         RC=$?
20685         if [ $RC -ne 0 ]; then
20686                 error "error, failed to take i_mutex, rc=$?"
20687         fi
20688         rm -f $DIR/$tfile
20689 }
20690 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20691
20692 # Verify we do NOT take the i_mutex in the normal case
20693 test_258b() {
20694 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20695         $LCTL set_param fail_loc=0x141d
20696         touch $DIR/$tfile
20697         chmod a+rwx $DIR
20698         chmod a+rw $DIR/$tfile
20699         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20700         RC=$?
20701         if [ $RC -ne 0 ]; then
20702                 error "error, took i_mutex unnecessarily, rc=$?"
20703         fi
20704         rm -f $DIR/$tfile
20705
20706 }
20707 run_test 258b "verify i_mutex security behavior"
20708
20709 test_259() {
20710         local file=$DIR/$tfile
20711         local before
20712         local after
20713
20714         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20715
20716         stack_trap "rm -f $file" EXIT
20717
20718         wait_delete_completed
20719         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20720         echo "before: $before"
20721
20722         $LFS setstripe -i 0 -c 1 $file
20723         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20724         sync_all_data
20725         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20726         echo "after write: $after"
20727
20728 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20729         do_facet ost1 $LCTL set_param fail_loc=0x2301
20730         $TRUNCATE $file 0
20731         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20732         echo "after truncate: $after"
20733
20734         stop ost1
20735         do_facet ost1 $LCTL set_param fail_loc=0
20736         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20737         sleep 2
20738         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20739         echo "after restart: $after"
20740         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20741                 error "missing truncate?"
20742
20743         return 0
20744 }
20745 run_test 259 "crash at delayed truncate"
20746
20747 test_260() {
20748 #define OBD_FAIL_MDC_CLOSE               0x806
20749         $LCTL set_param fail_loc=0x80000806
20750         touch $DIR/$tfile
20751
20752 }
20753 run_test 260 "Check mdc_close fail"
20754
20755 ### Data-on-MDT sanity tests ###
20756 test_270a() {
20757         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20758                 skip "Need MDS version at least 2.10.55 for DoM"
20759
20760         # create DoM file
20761         local dom=$DIR/$tdir/dom_file
20762         local tmp=$DIR/$tdir/tmp_file
20763
20764         mkdir -p $DIR/$tdir
20765
20766         # basic checks for DoM component creation
20767         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20768                 error "Can set MDT layout to non-first entry"
20769
20770         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20771                 error "Can define multiple entries as MDT layout"
20772
20773         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20774
20775         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20776         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20777         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20778
20779         local mdtidx=$($LFS getstripe -m $dom)
20780         local mdtname=MDT$(printf %04x $mdtidx)
20781         local facet=mds$((mdtidx + 1))
20782         local space_check=1
20783
20784         # Skip free space checks with ZFS
20785         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20786
20787         # write
20788         sync
20789         local size_tmp=$((65536 * 3))
20790         local mdtfree1=$(do_facet $facet \
20791                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20792
20793         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20794         # check also direct IO along write
20795         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20796         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20797         sync
20798         cmp $tmp $dom || error "file data is different"
20799         [ $(stat -c%s $dom) == $size_tmp ] ||
20800                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20801         if [ $space_check == 1 ]; then
20802                 local mdtfree2=$(do_facet $facet \
20803                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20804
20805                 # increase in usage from by $size_tmp
20806                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20807                         error "MDT free space wrong after write: " \
20808                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20809         fi
20810
20811         # truncate
20812         local size_dom=10000
20813
20814         $TRUNCATE $dom $size_dom
20815         [ $(stat -c%s $dom) == $size_dom ] ||
20816                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20817         if [ $space_check == 1 ]; then
20818                 mdtfree1=$(do_facet $facet \
20819                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20820                 # decrease in usage from $size_tmp to new $size_dom
20821                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20822                   $(((size_tmp - size_dom) / 1024)) ] ||
20823                         error "MDT free space is wrong after truncate: " \
20824                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20825         fi
20826
20827         # append
20828         cat $tmp >> $dom
20829         sync
20830         size_dom=$((size_dom + size_tmp))
20831         [ $(stat -c%s $dom) == $size_dom ] ||
20832                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20833         if [ $space_check == 1 ]; then
20834                 mdtfree2=$(do_facet $facet \
20835                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20836                 # increase in usage by $size_tmp from previous
20837                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20838                         error "MDT free space is wrong after append: " \
20839                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20840         fi
20841
20842         # delete
20843         rm $dom
20844         if [ $space_check == 1 ]; then
20845                 mdtfree1=$(do_facet $facet \
20846                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20847                 # decrease in usage by $size_dom from previous
20848                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20849                         error "MDT free space is wrong after removal: " \
20850                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20851         fi
20852
20853         # combined striping
20854         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20855                 error "Can't create DoM + OST striping"
20856
20857         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20858         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20859         # check also direct IO along write
20860         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20861         sync
20862         cmp $tmp $dom || error "file data is different"
20863         [ $(stat -c%s $dom) == $size_tmp ] ||
20864                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20865         rm $dom $tmp
20866
20867         return 0
20868 }
20869 run_test 270a "DoM: basic functionality tests"
20870
20871 test_270b() {
20872         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20873                 skip "Need MDS version at least 2.10.55"
20874
20875         local dom=$DIR/$tdir/dom_file
20876         local max_size=1048576
20877
20878         mkdir -p $DIR/$tdir
20879         $LFS setstripe -E $max_size -L mdt $dom
20880
20881         # truncate over the limit
20882         $TRUNCATE $dom $(($max_size + 1)) &&
20883                 error "successful truncate over the maximum size"
20884         # write over the limit
20885         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20886                 error "successful write over the maximum size"
20887         # append over the limit
20888         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20889         echo "12345" >> $dom && error "successful append over the maximum size"
20890         rm $dom
20891
20892         return 0
20893 }
20894 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20895
20896 test_270c() {
20897         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20898                 skip "Need MDS version at least 2.10.55"
20899
20900         mkdir -p $DIR/$tdir
20901         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20902
20903         # check files inherit DoM EA
20904         touch $DIR/$tdir/first
20905         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20906                 error "bad pattern"
20907         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20908                 error "bad stripe count"
20909         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20910                 error "bad stripe size"
20911
20912         # check directory inherits DoM EA and uses it as default
20913         mkdir $DIR/$tdir/subdir
20914         touch $DIR/$tdir/subdir/second
20915         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20916                 error "bad pattern in sub-directory"
20917         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20918                 error "bad stripe count in sub-directory"
20919         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20920                 error "bad stripe size in sub-directory"
20921         return 0
20922 }
20923 run_test 270c "DoM: DoM EA inheritance tests"
20924
20925 test_270d() {
20926         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20927                 skip "Need MDS version at least 2.10.55"
20928
20929         mkdir -p $DIR/$tdir
20930         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20931
20932         # inherit default DoM striping
20933         mkdir $DIR/$tdir/subdir
20934         touch $DIR/$tdir/subdir/f1
20935
20936         # change default directory striping
20937         $LFS setstripe -c 1 $DIR/$tdir/subdir
20938         touch $DIR/$tdir/subdir/f2
20939         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20940                 error "wrong default striping in file 2"
20941         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20942                 error "bad pattern in file 2"
20943         return 0
20944 }
20945 run_test 270d "DoM: change striping from DoM to RAID0"
20946
20947 test_270e() {
20948         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20949                 skip "Need MDS version at least 2.10.55"
20950
20951         mkdir -p $DIR/$tdir/dom
20952         mkdir -p $DIR/$tdir/norm
20953         DOMFILES=20
20954         NORMFILES=10
20955         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20956         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20957
20958         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20959         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20960
20961         # find DoM files by layout
20962         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20963         [ $NUM -eq  $DOMFILES ] ||
20964                 error "lfs find -L: found $NUM, expected $DOMFILES"
20965         echo "Test 1: lfs find 20 DOM files by layout: OK"
20966
20967         # there should be 1 dir with default DOM striping
20968         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20969         [ $NUM -eq  1 ] ||
20970                 error "lfs find -L: found $NUM, expected 1 dir"
20971         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20972
20973         # find DoM files by stripe size
20974         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20975         [ $NUM -eq  $DOMFILES ] ||
20976                 error "lfs find -S: found $NUM, expected $DOMFILES"
20977         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20978
20979         # find files by stripe offset except DoM files
20980         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20981         [ $NUM -eq  $NORMFILES ] ||
20982                 error "lfs find -i: found $NUM, expected $NORMFILES"
20983         echo "Test 5: lfs find no DOM files by stripe index: OK"
20984         return 0
20985 }
20986 run_test 270e "DoM: lfs find with DoM files test"
20987
20988 test_270f() {
20989         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20990                 skip "Need MDS version at least 2.10.55"
20991
20992         local mdtname=${FSNAME}-MDT0000-mdtlov
20993         local dom=$DIR/$tdir/dom_file
20994         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20995                                                 lod.$mdtname.dom_stripesize)
20996         local dom_limit=131072
20997
20998         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20999         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21000                                                 lod.$mdtname.dom_stripesize)
21001         [ ${dom_limit} -eq ${dom_current} ] ||
21002                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21003
21004         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21005         $LFS setstripe -d $DIR/$tdir
21006         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21007                 error "Can't set directory default striping"
21008
21009         # exceed maximum stripe size
21010         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21011                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21012         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21013                 error "Able to create DoM component size more than LOD limit"
21014
21015         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21016         dom_current=$(do_facet mds1 $LCTL get_param -n \
21017                                                 lod.$mdtname.dom_stripesize)
21018         [ 0 -eq ${dom_current} ] ||
21019                 error "Can't set zero DoM stripe limit"
21020         rm $dom
21021
21022         # attempt to create DoM file on server with disabled DoM should
21023         # remove DoM entry from layout and be succeed
21024         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21025                 error "Can't create DoM file (DoM is disabled)"
21026         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21027                 error "File has DoM component while DoM is disabled"
21028         rm $dom
21029
21030         # attempt to create DoM file with only DoM stripe should return error
21031         $LFS setstripe -E $dom_limit -L mdt $dom &&
21032                 error "Able to create DoM-only file while DoM is disabled"
21033
21034         # too low values to be aligned with smallest stripe size 64K
21035         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21036         dom_current=$(do_facet mds1 $LCTL get_param -n \
21037                                                 lod.$mdtname.dom_stripesize)
21038         [ 30000 -eq ${dom_current} ] &&
21039                 error "Can set too small DoM stripe limit"
21040
21041         # 64K is a minimal stripe size in Lustre, expect limit of that size
21042         [ 65536 -eq ${dom_current} ] ||
21043                 error "Limit is not set to 64K but ${dom_current}"
21044
21045         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21046         dom_current=$(do_facet mds1 $LCTL get_param -n \
21047                                                 lod.$mdtname.dom_stripesize)
21048         echo $dom_current
21049         [ 2147483648 -eq ${dom_current} ] &&
21050                 error "Can set too large DoM stripe limit"
21051
21052         do_facet mds1 $LCTL set_param -n \
21053                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21054         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21055                 error "Can't create DoM component size after limit change"
21056         do_facet mds1 $LCTL set_param -n \
21057                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21058         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21059                 error "Can't create DoM file after limit decrease"
21060         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21061                 error "Can create big DoM component after limit decrease"
21062         touch ${dom}_def ||
21063                 error "Can't create file with old default layout"
21064
21065         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21066         return 0
21067 }
21068 run_test 270f "DoM: maximum DoM stripe size checks"
21069
21070 test_270g() {
21071         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21072                 skip "Need MDS version at least 2.13.52"
21073         local dom=$DIR/$tdir/$tfile
21074
21075         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21076         local lodname=${FSNAME}-MDT0000-mdtlov
21077
21078         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21079         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21080         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21081         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21082
21083         local dom_limit=1024
21084         local dom_threshold="50%"
21085
21086         $LFS setstripe -d $DIR/$tdir
21087         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21088                 error "Can't set directory default striping"
21089
21090         do_facet mds1 $LCTL set_param -n \
21091                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21092         # set 0 threshold and create DOM file to change tunable stripesize
21093         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21094         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21095                 error "Failed to create $dom file"
21096         # now tunable dom_cur_stripesize should reach maximum
21097         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21098                                         lod.${lodname}.dom_stripesize_cur_kb)
21099         [[ $dom_current == $dom_limit ]] ||
21100                 error "Current DOM stripesize is not maximum"
21101         rm $dom
21102
21103         # set threshold for further tests
21104         do_facet mds1 $LCTL set_param -n \
21105                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21106         echo "DOM threshold is $dom_threshold free space"
21107         local dom_def
21108         local dom_set
21109         # Spoof bfree to exceed threshold
21110         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21111         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21112         for spfree in 40 20 0 15 30 55; do
21113                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21114                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21115                         error "Failed to create $dom file"
21116                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21117                                         lod.${lodname}.dom_stripesize_cur_kb)
21118                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21119                 [[ $dom_def != $dom_current ]] ||
21120                         error "Default stripe size was not changed"
21121                 if [[ $spfree > 0 ]] ; then
21122                         dom_set=$($LFS getstripe -S $dom)
21123                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21124                                 error "DOM component size is still old"
21125                 else
21126                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21127                                 error "DoM component is set with no free space"
21128                 fi
21129                 rm $dom
21130                 dom_current=$dom_def
21131         done
21132 }
21133 run_test 270g "DoM: default DoM stripe size depends on free space"
21134
21135 test_270h() {
21136         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21137                 skip "Need MDS version at least 2.13.53"
21138
21139         local mdtname=${FSNAME}-MDT0000-mdtlov
21140         local dom=$DIR/$tdir/$tfile
21141         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21142
21143         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21144         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21145
21146         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21147         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21148                 error "can't create OST file"
21149         # mirrored file with DOM entry in the second mirror
21150         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21151                 error "can't create mirror with DoM component"
21152
21153         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21154
21155         # DOM component in the middle and has other enries in the same mirror,
21156         # should succeed but lost DoM component
21157         $LFS setstripe --copy=${dom}_1 $dom ||
21158                 error "Can't create file from OST|DOM mirror layout"
21159         # check new file has no DoM layout after all
21160         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21161                 error "File has DoM component while DoM is disabled"
21162 }
21163 run_test 270h "DoM: DoM stripe removal when disabled on server"
21164
21165 test_271a() {
21166         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21167                 skip "Need MDS version at least 2.10.55"
21168
21169         local dom=$DIR/$tdir/dom
21170
21171         mkdir -p $DIR/$tdir
21172
21173         $LFS setstripe -E 1024K -L mdt $dom
21174
21175         lctl set_param -n mdc.*.stats=clear
21176         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21177         cat $dom > /dev/null
21178         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21179         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21180         ls $dom
21181         rm -f $dom
21182 }
21183 run_test 271a "DoM: data is cached for read after write"
21184
21185 test_271b() {
21186         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21187                 skip "Need MDS version at least 2.10.55"
21188
21189         local dom=$DIR/$tdir/dom
21190
21191         mkdir -p $DIR/$tdir
21192
21193         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21194
21195         lctl set_param -n mdc.*.stats=clear
21196         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21197         cancel_lru_locks mdc
21198         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21199         # second stat to check size is cached on client
21200         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21201         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21202         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21203         rm -f $dom
21204 }
21205 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21206
21207 test_271ba() {
21208         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21209                 skip "Need MDS version at least 2.10.55"
21210
21211         local dom=$DIR/$tdir/dom
21212
21213         mkdir -p $DIR/$tdir
21214
21215         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21216
21217         lctl set_param -n mdc.*.stats=clear
21218         lctl set_param -n osc.*.stats=clear
21219         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21220         cancel_lru_locks mdc
21221         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21222         # second stat to check size is cached on client
21223         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21224         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21225         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21226         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21227         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21228         rm -f $dom
21229 }
21230 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21231
21232
21233 get_mdc_stats() {
21234         local mdtidx=$1
21235         local param=$2
21236         local mdt=MDT$(printf %04x $mdtidx)
21237
21238         if [ -z $param ]; then
21239                 lctl get_param -n mdc.*$mdt*.stats
21240         else
21241                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21242         fi
21243 }
21244
21245 test_271c() {
21246         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21247                 skip "Need MDS version at least 2.10.55"
21248
21249         local dom=$DIR/$tdir/dom
21250
21251         mkdir -p $DIR/$tdir
21252
21253         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21254
21255         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21256         local facet=mds$((mdtidx + 1))
21257
21258         cancel_lru_locks mdc
21259         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21260         createmany -o $dom 1000
21261         lctl set_param -n mdc.*.stats=clear
21262         smalliomany -w $dom 1000 200
21263         get_mdc_stats $mdtidx
21264         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21265         # Each file has 1 open, 1 IO enqueues, total 2000
21266         # but now we have also +1 getxattr for security.capability, total 3000
21267         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21268         unlinkmany $dom 1000
21269
21270         cancel_lru_locks mdc
21271         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21272         createmany -o $dom 1000
21273         lctl set_param -n mdc.*.stats=clear
21274         smalliomany -w $dom 1000 200
21275         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21276         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21277         # for OPEN and IO lock.
21278         [ $((enq - enq_2)) -ge 1000 ] ||
21279                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21280         unlinkmany $dom 1000
21281         return 0
21282 }
21283 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21284
21285 cleanup_271def_tests() {
21286         trap 0
21287         rm -f $1
21288 }
21289
21290 test_271d() {
21291         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21292                 skip "Need MDS version at least 2.10.57"
21293
21294         local dom=$DIR/$tdir/dom
21295         local tmp=$TMP/$tfile
21296         trap "cleanup_271def_tests $tmp" EXIT
21297
21298         mkdir -p $DIR/$tdir
21299
21300         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21301
21302         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21303
21304         cancel_lru_locks mdc
21305         dd if=/dev/urandom of=$tmp bs=1000 count=1
21306         dd if=$tmp of=$dom bs=1000 count=1
21307         cancel_lru_locks mdc
21308
21309         cat /etc/hosts >> $tmp
21310         lctl set_param -n mdc.*.stats=clear
21311
21312         # append data to the same file it should update local page
21313         echo "Append to the same page"
21314         cat /etc/hosts >> $dom
21315         local num=$(get_mdc_stats $mdtidx ost_read)
21316         local ra=$(get_mdc_stats $mdtidx req_active)
21317         local rw=$(get_mdc_stats $mdtidx req_waittime)
21318
21319         [ -z $num ] || error "$num READ RPC occured"
21320         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21321         echo "... DONE"
21322
21323         # compare content
21324         cmp $tmp $dom || error "file miscompare"
21325
21326         cancel_lru_locks mdc
21327         lctl set_param -n mdc.*.stats=clear
21328
21329         echo "Open and read file"
21330         cat $dom > /dev/null
21331         local num=$(get_mdc_stats $mdtidx ost_read)
21332         local ra=$(get_mdc_stats $mdtidx req_active)
21333         local rw=$(get_mdc_stats $mdtidx req_waittime)
21334
21335         [ -z $num ] || error "$num READ RPC occured"
21336         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21337         echo "... DONE"
21338
21339         # compare content
21340         cmp $tmp $dom || error "file miscompare"
21341
21342         return 0
21343 }
21344 run_test 271d "DoM: read on open (1K file in reply buffer)"
21345
21346 test_271f() {
21347         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21348                 skip "Need MDS version at least 2.10.57"
21349
21350         local dom=$DIR/$tdir/dom
21351         local tmp=$TMP/$tfile
21352         trap "cleanup_271def_tests $tmp" EXIT
21353
21354         mkdir -p $DIR/$tdir
21355
21356         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21357
21358         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21359
21360         cancel_lru_locks mdc
21361         dd if=/dev/urandom of=$tmp bs=265000 count=1
21362         dd if=$tmp of=$dom bs=265000 count=1
21363         cancel_lru_locks mdc
21364         cat /etc/hosts >> $tmp
21365         lctl set_param -n mdc.*.stats=clear
21366
21367         echo "Append to the same page"
21368         cat /etc/hosts >> $dom
21369         local num=$(get_mdc_stats $mdtidx ost_read)
21370         local ra=$(get_mdc_stats $mdtidx req_active)
21371         local rw=$(get_mdc_stats $mdtidx req_waittime)
21372
21373         [ -z $num ] || error "$num READ RPC occured"
21374         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21375         echo "... DONE"
21376
21377         # compare content
21378         cmp $tmp $dom || error "file miscompare"
21379
21380         cancel_lru_locks mdc
21381         lctl set_param -n mdc.*.stats=clear
21382
21383         echo "Open and read file"
21384         cat $dom > /dev/null
21385         local num=$(get_mdc_stats $mdtidx ost_read)
21386         local ra=$(get_mdc_stats $mdtidx req_active)
21387         local rw=$(get_mdc_stats $mdtidx req_waittime)
21388
21389         [ -z $num ] && num=0
21390         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21391         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21392         echo "... DONE"
21393
21394         # compare content
21395         cmp $tmp $dom || error "file miscompare"
21396
21397         return 0
21398 }
21399 run_test 271f "DoM: read on open (200K file and read tail)"
21400
21401 test_271g() {
21402         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21403                 skip "Skipping due to old client or server version"
21404
21405         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21406         # to get layout
21407         $CHECKSTAT -t file $DIR1/$tfile
21408
21409         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21410         MULTIOP_PID=$!
21411         sleep 1
21412         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21413         $LCTL set_param fail_loc=0x80000314
21414         rm $DIR1/$tfile || error "Unlink fails"
21415         RC=$?
21416         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21417         [ $RC -eq 0 ] || error "Failed write to stale object"
21418 }
21419 run_test 271g "Discard DoM data vs client flush race"
21420
21421 test_272a() {
21422         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21423                 skip "Need MDS version at least 2.11.50"
21424
21425         local dom=$DIR/$tdir/dom
21426         mkdir -p $DIR/$tdir
21427
21428         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21429         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21430                 error "failed to write data into $dom"
21431         local old_md5=$(md5sum $dom)
21432
21433         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21434                 error "failed to migrate to the same DoM component"
21435
21436         local new_md5=$(md5sum $dom)
21437
21438         [ "$old_md5" == "$new_md5" ] ||
21439                 error "md5sum differ: $old_md5, $new_md5"
21440
21441         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21442                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21443 }
21444 run_test 272a "DoM migration: new layout with the same DOM component"
21445
21446 test_272b() {
21447         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21448                 skip "Need MDS version at least 2.11.50"
21449
21450         local dom=$DIR/$tdir/dom
21451         mkdir -p $DIR/$tdir
21452         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21453
21454         local mdtidx=$($LFS getstripe -m $dom)
21455         local mdtname=MDT$(printf %04x $mdtidx)
21456         local facet=mds$((mdtidx + 1))
21457
21458         local mdtfree1=$(do_facet $facet \
21459                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21460         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21461                 error "failed to write data into $dom"
21462         local old_md5=$(md5sum $dom)
21463         cancel_lru_locks mdc
21464         local mdtfree1=$(do_facet $facet \
21465                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21466
21467         $LFS migrate -c2 $dom ||
21468                 error "failed to migrate to the new composite layout"
21469         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21470                 error "MDT stripe was not removed"
21471
21472         cancel_lru_locks mdc
21473         local new_md5=$(md5sum $dom)
21474         [ "$old_md5" == "$new_md5" ] ||
21475                 error "$old_md5 != $new_md5"
21476
21477         # Skip free space checks with ZFS
21478         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21479                 local mdtfree2=$(do_facet $facet \
21480                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21481                 [ $mdtfree2 -gt $mdtfree1 ] ||
21482                         error "MDT space is not freed after migration"
21483         fi
21484         return 0
21485 }
21486 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21487
21488 test_272c() {
21489         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21490                 skip "Need MDS version at least 2.11.50"
21491
21492         local dom=$DIR/$tdir/$tfile
21493         mkdir -p $DIR/$tdir
21494         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21495
21496         local mdtidx=$($LFS getstripe -m $dom)
21497         local mdtname=MDT$(printf %04x $mdtidx)
21498         local facet=mds$((mdtidx + 1))
21499
21500         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21501                 error "failed to write data into $dom"
21502         local old_md5=$(md5sum $dom)
21503         cancel_lru_locks mdc
21504         local mdtfree1=$(do_facet $facet \
21505                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21506
21507         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21508                 error "failed to migrate to the new composite layout"
21509         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21510                 error "MDT stripe was not removed"
21511
21512         cancel_lru_locks mdc
21513         local new_md5=$(md5sum $dom)
21514         [ "$old_md5" == "$new_md5" ] ||
21515                 error "$old_md5 != $new_md5"
21516
21517         # Skip free space checks with ZFS
21518         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21519                 local mdtfree2=$(do_facet $facet \
21520                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21521                 [ $mdtfree2 -gt $mdtfree1 ] ||
21522                         error "MDS space is not freed after migration"
21523         fi
21524         return 0
21525 }
21526 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21527
21528 test_272d() {
21529         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21530                 skip "Need MDS version at least 2.12.55"
21531
21532         local dom=$DIR/$tdir/$tfile
21533         mkdir -p $DIR/$tdir
21534         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21535
21536         local mdtidx=$($LFS getstripe -m $dom)
21537         local mdtname=MDT$(printf %04x $mdtidx)
21538         local facet=mds$((mdtidx + 1))
21539
21540         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21541                 error "failed to write data into $dom"
21542         local old_md5=$(md5sum $dom)
21543         cancel_lru_locks mdc
21544         local mdtfree1=$(do_facet $facet \
21545                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21546
21547         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21548                 error "failed mirroring to the new composite layout"
21549         $LFS mirror resync $dom ||
21550                 error "failed mirror resync"
21551         $LFS mirror split --mirror-id 1 -d $dom ||
21552                 error "failed mirror split"
21553
21554         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21555                 error "MDT stripe was not removed"
21556
21557         cancel_lru_locks mdc
21558         local new_md5=$(md5sum $dom)
21559         [ "$old_md5" == "$new_md5" ] ||
21560                 error "$old_md5 != $new_md5"
21561
21562         # Skip free space checks with ZFS
21563         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21564                 local mdtfree2=$(do_facet $facet \
21565                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21566                 [ $mdtfree2 -gt $mdtfree1 ] ||
21567                         error "MDS space is not freed after DOM mirror deletion"
21568         fi
21569         return 0
21570 }
21571 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21572
21573 test_272e() {
21574         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21575                 skip "Need MDS version at least 2.12.55"
21576
21577         local dom=$DIR/$tdir/$tfile
21578         mkdir -p $DIR/$tdir
21579         $LFS setstripe -c 2 $dom
21580
21581         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21582                 error "failed to write data into $dom"
21583         local old_md5=$(md5sum $dom)
21584         cancel_lru_locks mdc
21585
21586         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21587                 error "failed mirroring to the DOM layout"
21588         $LFS mirror resync $dom ||
21589                 error "failed mirror resync"
21590         $LFS mirror split --mirror-id 1 -d $dom ||
21591                 error "failed mirror split"
21592
21593         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21594                 error "MDT stripe was not removed"
21595
21596         cancel_lru_locks mdc
21597         local new_md5=$(md5sum $dom)
21598         [ "$old_md5" == "$new_md5" ] ||
21599                 error "$old_md5 != $new_md5"
21600
21601         return 0
21602 }
21603 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21604
21605 test_272f() {
21606         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21607                 skip "Need MDS version at least 2.12.55"
21608
21609         local dom=$DIR/$tdir/$tfile
21610         mkdir -p $DIR/$tdir
21611         $LFS setstripe -c 2 $dom
21612
21613         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21614                 error "failed to write data into $dom"
21615         local old_md5=$(md5sum $dom)
21616         cancel_lru_locks mdc
21617
21618         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21619                 error "failed migrating to the DOM file"
21620
21621         cancel_lru_locks mdc
21622         local new_md5=$(md5sum $dom)
21623         [ "$old_md5" != "$new_md5" ] &&
21624                 error "$old_md5 != $new_md5"
21625
21626         return 0
21627 }
21628 run_test 272f "DoM migration: OST-striped file to DOM file"
21629
21630 test_273a() {
21631         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21632                 skip "Need MDS version at least 2.11.50"
21633
21634         # Layout swap cannot be done if either file has DOM component,
21635         # this will never be supported, migration should be used instead
21636
21637         local dom=$DIR/$tdir/$tfile
21638         mkdir -p $DIR/$tdir
21639
21640         $LFS setstripe -c2 ${dom}_plain
21641         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21642         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21643                 error "can swap layout with DoM component"
21644         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21645                 error "can swap layout with DoM component"
21646
21647         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21648         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21649                 error "can swap layout with DoM component"
21650         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21651                 error "can swap layout with DoM component"
21652         return 0
21653 }
21654 run_test 273a "DoM: layout swapping should fail with DOM"
21655
21656 test_273b() {
21657         mkdir -p $DIR/$tdir
21658         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
21659
21660 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
21661         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
21662
21663         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
21664 }
21665 run_test 273b "DoM: race writeback and object destroy"
21666
21667 test_275() {
21668         remote_ost_nodsh && skip "remote OST with nodsh"
21669         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21670                 skip "Need OST version >= 2.10.57"
21671
21672         local file=$DIR/$tfile
21673         local oss
21674
21675         oss=$(comma_list $(osts_nodes))
21676
21677         dd if=/dev/urandom of=$file bs=1M count=2 ||
21678                 error "failed to create a file"
21679         cancel_lru_locks osc
21680
21681         #lock 1
21682         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21683                 error "failed to read a file"
21684
21685 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21686         $LCTL set_param fail_loc=0x8000031f
21687
21688         cancel_lru_locks osc &
21689         sleep 1
21690
21691 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21692         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21693         #IO takes another lock, but matches the PENDING one
21694         #and places it to the IO RPC
21695         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21696                 error "failed to read a file with PENDING lock"
21697 }
21698 run_test 275 "Read on a canceled duplicate lock"
21699
21700 test_276() {
21701         remote_ost_nodsh && skip "remote OST with nodsh"
21702         local pid
21703
21704         do_facet ost1 "(while true; do \
21705                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21706                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21707         pid=$!
21708
21709         for LOOP in $(seq 20); do
21710                 stop ost1
21711                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21712         done
21713         kill -9 $pid
21714         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21715                 rm $TMP/sanity_276_pid"
21716 }
21717 run_test 276 "Race between mount and obd_statfs"
21718
21719 test_277() {
21720         $LCTL set_param ldlm.namespaces.*.lru_size=0
21721         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21722         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21723                         grep ^used_mb | awk '{print $2}')
21724         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21725         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21726                 oflag=direct conv=notrunc
21727         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21728                         grep ^used_mb | awk '{print $2}')
21729         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21730 }
21731 run_test 277 "Direct IO shall drop page cache"
21732
21733 test_278() {
21734         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21735         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21736         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21737                 skip "needs the same host for mdt1 mdt2" && return
21738
21739         local pid1
21740         local pid2
21741
21742 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21743         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21744         stop mds2 &
21745         pid2=$!
21746
21747         stop mds1
21748
21749         echo "Starting MDTs"
21750         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21751         wait $pid2
21752 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21753 #will return NULL
21754         do_facet mds2 $LCTL set_param fail_loc=0
21755
21756         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21757         wait_recovery_complete mds2
21758 }
21759 run_test 278 "Race starting MDS between MDTs stop/start"
21760
21761 test_280() {
21762         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21763                 skip "Need MGS version at least 2.13.52"
21764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21765         combined_mgs_mds || skip "needs combined MGS/MDT"
21766
21767         umount_client $MOUNT
21768 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21769         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21770
21771         mount_client $MOUNT &
21772         sleep 1
21773         stop mgs || error "stop mgs failed"
21774         #for a race mgs would crash
21775         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21776         # make sure we unmount client before remounting
21777         wait
21778         umount_client $MOUNT
21779         mount_client $MOUNT || error "mount client failed"
21780 }
21781 run_test 280 "Race between MGS umount and client llog processing"
21782
21783 cleanup_test_300() {
21784         trap 0
21785         umask $SAVE_UMASK
21786 }
21787 test_striped_dir() {
21788         local mdt_index=$1
21789         local stripe_count
21790         local stripe_index
21791
21792         mkdir -p $DIR/$tdir
21793
21794         SAVE_UMASK=$(umask)
21795         trap cleanup_test_300 RETURN EXIT
21796
21797         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21798                                                 $DIR/$tdir/striped_dir ||
21799                 error "set striped dir error"
21800
21801         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21802         [ "$mode" = "755" ] || error "expect 755 got $mode"
21803
21804         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21805                 error "getdirstripe failed"
21806         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21807         if [ "$stripe_count" != "2" ]; then
21808                 error "1:stripe_count is $stripe_count, expect 2"
21809         fi
21810         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21811         if [ "$stripe_count" != "2" ]; then
21812                 error "2:stripe_count is $stripe_count, expect 2"
21813         fi
21814
21815         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21816         if [ "$stripe_index" != "$mdt_index" ]; then
21817                 error "stripe_index is $stripe_index, expect $mdt_index"
21818         fi
21819
21820         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21821                 error "nlink error after create striped dir"
21822
21823         mkdir $DIR/$tdir/striped_dir/a
21824         mkdir $DIR/$tdir/striped_dir/b
21825
21826         stat $DIR/$tdir/striped_dir/a ||
21827                 error "create dir under striped dir failed"
21828         stat $DIR/$tdir/striped_dir/b ||
21829                 error "create dir under striped dir failed"
21830
21831         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21832                 error "nlink error after mkdir"
21833
21834         rmdir $DIR/$tdir/striped_dir/a
21835         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21836                 error "nlink error after rmdir"
21837
21838         rmdir $DIR/$tdir/striped_dir/b
21839         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21840                 error "nlink error after rmdir"
21841
21842         chattr +i $DIR/$tdir/striped_dir
21843         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21844                 error "immutable flags not working under striped dir!"
21845         chattr -i $DIR/$tdir/striped_dir
21846
21847         rmdir $DIR/$tdir/striped_dir ||
21848                 error "rmdir striped dir error"
21849
21850         cleanup_test_300
21851
21852         true
21853 }
21854
21855 test_300a() {
21856         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21857                 skip "skipped for lustre < 2.7.0"
21858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21859         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21860
21861         test_striped_dir 0 || error "failed on striped dir on MDT0"
21862         test_striped_dir 1 || error "failed on striped dir on MDT0"
21863 }
21864 run_test 300a "basic striped dir sanity test"
21865
21866 test_300b() {
21867         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21868                 skip "skipped for lustre < 2.7.0"
21869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21870         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21871
21872         local i
21873         local mtime1
21874         local mtime2
21875         local mtime3
21876
21877         test_mkdir $DIR/$tdir || error "mkdir fail"
21878         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21879                 error "set striped dir error"
21880         for i in {0..9}; do
21881                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21882                 sleep 1
21883                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21884                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21885                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21886                 sleep 1
21887                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21888                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21889                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21890         done
21891         true
21892 }
21893 run_test 300b "check ctime/mtime for striped dir"
21894
21895 test_300c() {
21896         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21897                 skip "skipped for lustre < 2.7.0"
21898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21899         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21900
21901         local file_count
21902
21903         mkdir -p $DIR/$tdir
21904         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21905                 error "set striped dir error"
21906
21907         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21908                 error "chown striped dir failed"
21909
21910         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21911                 error "create 5k files failed"
21912
21913         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21914
21915         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21916
21917         rm -rf $DIR/$tdir
21918 }
21919 run_test 300c "chown && check ls under striped directory"
21920
21921 test_300d() {
21922         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21923                 skip "skipped for lustre < 2.7.0"
21924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21925         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21926
21927         local stripe_count
21928         local file
21929
21930         mkdir -p $DIR/$tdir
21931         $LFS setstripe -c 2 $DIR/$tdir
21932
21933         #local striped directory
21934         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21935                 error "set striped dir error"
21936         #look at the directories for debug purposes
21937         ls -l $DIR/$tdir
21938         $LFS getdirstripe $DIR/$tdir
21939         ls -l $DIR/$tdir/striped_dir
21940         $LFS getdirstripe $DIR/$tdir/striped_dir
21941         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21942                 error "create 10 files failed"
21943
21944         #remote striped directory
21945         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21946                 error "set striped dir error"
21947         #look at the directories for debug purposes
21948         ls -l $DIR/$tdir
21949         $LFS getdirstripe $DIR/$tdir
21950         ls -l $DIR/$tdir/remote_striped_dir
21951         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21952         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21953                 error "create 10 files failed"
21954
21955         for file in $(find $DIR/$tdir); do
21956                 stripe_count=$($LFS getstripe -c $file)
21957                 [ $stripe_count -eq 2 ] ||
21958                         error "wrong stripe $stripe_count for $file"
21959         done
21960
21961         rm -rf $DIR/$tdir
21962 }
21963 run_test 300d "check default stripe under striped directory"
21964
21965 test_300e() {
21966         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21967                 skip "Need MDS version at least 2.7.55"
21968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21969         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21970
21971         local stripe_count
21972         local file
21973
21974         mkdir -p $DIR/$tdir
21975
21976         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21977                 error "set striped dir error"
21978
21979         touch $DIR/$tdir/striped_dir/a
21980         touch $DIR/$tdir/striped_dir/b
21981         touch $DIR/$tdir/striped_dir/c
21982
21983         mkdir $DIR/$tdir/striped_dir/dir_a
21984         mkdir $DIR/$tdir/striped_dir/dir_b
21985         mkdir $DIR/$tdir/striped_dir/dir_c
21986
21987         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21988                 error "set striped adir under striped dir error"
21989
21990         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21991                 error "set striped bdir under striped dir error"
21992
21993         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21994                 error "set striped cdir under striped dir error"
21995
21996         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21997                 error "rename dir under striped dir fails"
21998
21999         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22000                 error "rename dir under different stripes fails"
22001
22002         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22003                 error "rename file under striped dir should succeed"
22004
22005         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22006                 error "rename dir under striped dir should succeed"
22007
22008         rm -rf $DIR/$tdir
22009 }
22010 run_test 300e "check rename under striped directory"
22011
22012 test_300f() {
22013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22014         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22015         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22016                 skip "Need MDS version at least 2.7.55"
22017
22018         local stripe_count
22019         local file
22020
22021         rm -rf $DIR/$tdir
22022         mkdir -p $DIR/$tdir
22023
22024         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22025                 error "set striped dir error"
22026
22027         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22028                 error "set striped dir error"
22029
22030         touch $DIR/$tdir/striped_dir/a
22031         mkdir $DIR/$tdir/striped_dir/dir_a
22032         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22033                 error "create striped dir under striped dir fails"
22034
22035         touch $DIR/$tdir/striped_dir1/b
22036         mkdir $DIR/$tdir/striped_dir1/dir_b
22037         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22038                 error "create striped dir under striped dir fails"
22039
22040         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22041                 error "rename dir under different striped dir should fail"
22042
22043         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22044                 error "rename striped dir under diff striped dir should fail"
22045
22046         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22047                 error "rename file under diff striped dirs fails"
22048
22049         rm -rf $DIR/$tdir
22050 }
22051 run_test 300f "check rename cross striped directory"
22052
22053 test_300_check_default_striped_dir()
22054 {
22055         local dirname=$1
22056         local default_count=$2
22057         local default_index=$3
22058         local stripe_count
22059         local stripe_index
22060         local dir_stripe_index
22061         local dir
22062
22063         echo "checking $dirname $default_count $default_index"
22064         $LFS setdirstripe -D -c $default_count -i $default_index \
22065                                 -H all_char $DIR/$tdir/$dirname ||
22066                 error "set default stripe on striped dir error"
22067         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22068         [ $stripe_count -eq $default_count ] ||
22069                 error "expect $default_count get $stripe_count for $dirname"
22070
22071         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22072         [ $stripe_index -eq $default_index ] ||
22073                 error "expect $default_index get $stripe_index for $dirname"
22074
22075         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22076                                                 error "create dirs failed"
22077
22078         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22079         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22080         for dir in $(find $DIR/$tdir/$dirname/*); do
22081                 stripe_count=$($LFS getdirstripe -c $dir)
22082                 (( $stripe_count == $default_count )) ||
22083                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22084                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22085                 error "stripe count $default_count != $stripe_count for $dir"
22086
22087                 stripe_index=$($LFS getdirstripe -i $dir)
22088                 [ $default_index -eq -1 ] ||
22089                         [ $stripe_index -eq $default_index ] ||
22090                         error "$stripe_index != $default_index for $dir"
22091
22092                 #check default stripe
22093                 stripe_count=$($LFS getdirstripe -D -c $dir)
22094                 [ $stripe_count -eq $default_count ] ||
22095                 error "default count $default_count != $stripe_count for $dir"
22096
22097                 stripe_index=$($LFS getdirstripe -D -i $dir)
22098                 [ $stripe_index -eq $default_index ] ||
22099                 error "default index $default_index != $stripe_index for $dir"
22100         done
22101         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22102 }
22103
22104 test_300g() {
22105         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22106         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22107                 skip "Need MDS version at least 2.7.55"
22108
22109         local dir
22110         local stripe_count
22111         local stripe_index
22112
22113         mkdir $DIR/$tdir
22114         mkdir $DIR/$tdir/normal_dir
22115
22116         #Checking when client cache stripe index
22117         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22118         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22119                 error "create striped_dir failed"
22120
22121         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22122                 error "create dir0 fails"
22123         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22124         [ $stripe_index -eq 0 ] ||
22125                 error "dir0 expect index 0 got $stripe_index"
22126
22127         mkdir $DIR/$tdir/striped_dir/dir1 ||
22128                 error "create dir1 fails"
22129         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22130         [ $stripe_index -eq 1 ] ||
22131                 error "dir1 expect index 1 got $stripe_index"
22132
22133         #check default stripe count/stripe index
22134         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22135         test_300_check_default_striped_dir normal_dir 1 0
22136         test_300_check_default_striped_dir normal_dir -1 1
22137         test_300_check_default_striped_dir normal_dir 2 -1
22138
22139         #delete default stripe information
22140         echo "delete default stripeEA"
22141         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22142                 error "set default stripe on striped dir error"
22143
22144         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22145         for dir in $(find $DIR/$tdir/normal_dir/*); do
22146                 stripe_count=$($LFS getdirstripe -c $dir)
22147                 [ $stripe_count -eq 0 ] ||
22148                         error "expect 1 get $stripe_count for $dir"
22149                 stripe_index=$($LFS getdirstripe -i $dir)
22150                 [ $stripe_index -eq 0 ] ||
22151                         error "expect 0 get $stripe_index for $dir"
22152         done
22153 }
22154 run_test 300g "check default striped directory for normal directory"
22155
22156 test_300h() {
22157         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22158         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22159                 skip "Need MDS version at least 2.7.55"
22160
22161         local dir
22162         local stripe_count
22163
22164         mkdir $DIR/$tdir
22165         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22166                 error "set striped dir error"
22167
22168         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22169         test_300_check_default_striped_dir striped_dir 1 0
22170         test_300_check_default_striped_dir striped_dir -1 1
22171         test_300_check_default_striped_dir striped_dir 2 -1
22172
22173         #delete default stripe information
22174         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22175                 error "set default stripe on striped dir error"
22176
22177         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22178         for dir in $(find $DIR/$tdir/striped_dir/*); do
22179                 stripe_count=$($LFS getdirstripe -c $dir)
22180                 [ $stripe_count -eq 0 ] ||
22181                         error "expect 1 get $stripe_count for $dir"
22182         done
22183 }
22184 run_test 300h "check default striped directory for striped directory"
22185
22186 test_300i() {
22187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22188         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22189         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22190                 skip "Need MDS version at least 2.7.55"
22191
22192         local stripe_count
22193         local file
22194
22195         mkdir $DIR/$tdir
22196
22197         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22198                 error "set striped dir error"
22199
22200         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22201                 error "create files under striped dir failed"
22202
22203         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22204                 error "set striped hashdir error"
22205
22206         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22207                 error "create dir0 under hash dir failed"
22208         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22209                 error "create dir1 under hash dir failed"
22210         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22211                 error "create dir2 under hash dir failed"
22212
22213         # unfortunately, we need to umount to clear dir layout cache for now
22214         # once we fully implement dir layout, we can drop this
22215         umount_client $MOUNT || error "umount failed"
22216         mount_client $MOUNT || error "mount failed"
22217
22218         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22219         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22220         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22221
22222         #set the stripe to be unknown hash type
22223         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22224         $LCTL set_param fail_loc=0x1901
22225         for ((i = 0; i < 10; i++)); do
22226                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22227                         error "stat f-$i failed"
22228                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22229         done
22230
22231         touch $DIR/$tdir/striped_dir/f0 &&
22232                 error "create under striped dir with unknown hash should fail"
22233
22234         $LCTL set_param fail_loc=0
22235
22236         umount_client $MOUNT || error "umount failed"
22237         mount_client $MOUNT || error "mount failed"
22238
22239         return 0
22240 }
22241 run_test 300i "client handle unknown hash type striped directory"
22242
22243 test_300j() {
22244         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22246         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22247                 skip "Need MDS version at least 2.7.55"
22248
22249         local stripe_count
22250         local file
22251
22252         mkdir $DIR/$tdir
22253
22254         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22255         $LCTL set_param fail_loc=0x1702
22256         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22257                 error "set striped dir error"
22258
22259         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22260                 error "create files under striped dir failed"
22261
22262         $LCTL set_param fail_loc=0
22263
22264         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22265
22266         return 0
22267 }
22268 run_test 300j "test large update record"
22269
22270 test_300k() {
22271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22272         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22273         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22274                 skip "Need MDS version at least 2.7.55"
22275
22276         # this test needs a huge transaction
22277         local kb
22278         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22279              osd*.$FSNAME-MDT0000.kbytestotal")
22280         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22281
22282         local stripe_count
22283         local file
22284
22285         mkdir $DIR/$tdir
22286
22287         #define OBD_FAIL_LARGE_STRIPE   0x1703
22288         $LCTL set_param fail_loc=0x1703
22289         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22290                 error "set striped dir error"
22291         $LCTL set_param fail_loc=0
22292
22293         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22294                 error "getstripeddir fails"
22295         rm -rf $DIR/$tdir/striped_dir ||
22296                 error "unlink striped dir fails"
22297
22298         return 0
22299 }
22300 run_test 300k "test large striped directory"
22301
22302 test_300l() {
22303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22304         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22305         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22306                 skip "Need MDS version at least 2.7.55"
22307
22308         local stripe_index
22309
22310         test_mkdir -p $DIR/$tdir/striped_dir
22311         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22312                         error "chown $RUNAS_ID failed"
22313         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22314                 error "set default striped dir failed"
22315
22316         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22317         $LCTL set_param fail_loc=0x80000158
22318         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22319
22320         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22321         [ $stripe_index -eq 1 ] ||
22322                 error "expect 1 get $stripe_index for $dir"
22323 }
22324 run_test 300l "non-root user to create dir under striped dir with stale layout"
22325
22326 test_300m() {
22327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22328         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22329         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22330                 skip "Need MDS version at least 2.7.55"
22331
22332         mkdir -p $DIR/$tdir/striped_dir
22333         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22334                 error "set default stripes dir error"
22335
22336         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22337
22338         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22339         [ $stripe_count -eq 0 ] ||
22340                         error "expect 0 get $stripe_count for a"
22341
22342         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22343                 error "set default stripes dir error"
22344
22345         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22346
22347         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22348         [ $stripe_count -eq 0 ] ||
22349                         error "expect 0 get $stripe_count for b"
22350
22351         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22352                 error "set default stripes dir error"
22353
22354         mkdir $DIR/$tdir/striped_dir/c &&
22355                 error "default stripe_index is invalid, mkdir c should fails"
22356
22357         rm -rf $DIR/$tdir || error "rmdir fails"
22358 }
22359 run_test 300m "setstriped directory on single MDT FS"
22360
22361 cleanup_300n() {
22362         local list=$(comma_list $(mdts_nodes))
22363
22364         trap 0
22365         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22366 }
22367
22368 test_300n() {
22369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22370         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22371         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22372                 skip "Need MDS version at least 2.7.55"
22373         remote_mds_nodsh && skip "remote MDS with nodsh"
22374
22375         local stripe_index
22376         local list=$(comma_list $(mdts_nodes))
22377
22378         trap cleanup_300n RETURN EXIT
22379         mkdir -p $DIR/$tdir
22380         chmod 777 $DIR/$tdir
22381         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22382                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22383                 error "create striped dir succeeds with gid=0"
22384
22385         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22386         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22387                 error "create striped dir fails with gid=-1"
22388
22389         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22390         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22391                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22392                 error "set default striped dir succeeds with gid=0"
22393
22394
22395         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22396         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22397                 error "set default striped dir fails with gid=-1"
22398
22399
22400         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22401         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22402                                         error "create test_dir fails"
22403         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22404                                         error "create test_dir1 fails"
22405         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22406                                         error "create test_dir2 fails"
22407         cleanup_300n
22408 }
22409 run_test 300n "non-root user to create dir under striped dir with default EA"
22410
22411 test_300o() {
22412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22413         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22414         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22415                 skip "Need MDS version at least 2.7.55"
22416
22417         local numfree1
22418         local numfree2
22419
22420         mkdir -p $DIR/$tdir
22421
22422         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22423         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22424         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22425                 skip "not enough free inodes $numfree1 $numfree2"
22426         fi
22427
22428         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22429         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22430         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22431                 skip "not enough free space $numfree1 $numfree2"
22432         fi
22433
22434         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22435                 error "setdirstripe fails"
22436
22437         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22438                 error "create dirs fails"
22439
22440         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22441         ls $DIR/$tdir/striped_dir > /dev/null ||
22442                 error "ls striped dir fails"
22443         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22444                 error "unlink big striped dir fails"
22445 }
22446 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22447
22448 test_300p() {
22449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22450         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22451         remote_mds_nodsh && skip "remote MDS with nodsh"
22452
22453         mkdir -p $DIR/$tdir
22454
22455         #define OBD_FAIL_OUT_ENOSPC     0x1704
22456         do_facet mds2 lctl set_param fail_loc=0x80001704
22457         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22458                  && error "create striped directory should fail"
22459
22460         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22461
22462         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22463         true
22464 }
22465 run_test 300p "create striped directory without space"
22466
22467 test_300q() {
22468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22469         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22470
22471         local fd=$(free_fd)
22472         local cmd="exec $fd<$tdir"
22473         cd $DIR
22474         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22475         eval $cmd
22476         cmd="exec $fd<&-"
22477         trap "eval $cmd" EXIT
22478         cd $tdir || error "cd $tdir fails"
22479         rmdir  ../$tdir || error "rmdir $tdir fails"
22480         mkdir local_dir && error "create dir succeeds"
22481         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22482         eval $cmd
22483         return 0
22484 }
22485 run_test 300q "create remote directory under orphan directory"
22486
22487 test_300r() {
22488         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22489                 skip "Need MDS version at least 2.7.55" && return
22490         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22491
22492         mkdir $DIR/$tdir
22493
22494         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22495                 error "set striped dir error"
22496
22497         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22498                 error "getstripeddir fails"
22499
22500         local stripe_count
22501         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22502                       awk '/lmv_stripe_count:/ { print $2 }')
22503
22504         [ $MDSCOUNT -ne $stripe_count ] &&
22505                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22506
22507         rm -rf $DIR/$tdir/striped_dir ||
22508                 error "unlink striped dir fails"
22509 }
22510 run_test 300r "test -1 striped directory"
22511
22512 test_300s_helper() {
22513         local count=$1
22514
22515         local stripe_dir=$DIR/$tdir/striped_dir.$count
22516
22517         $LFS mkdir -c $count $stripe_dir ||
22518                 error "lfs mkdir -c error"
22519
22520         $LFS getdirstripe $stripe_dir ||
22521                 error "lfs getdirstripe fails"
22522
22523         local stripe_count
22524         stripe_count=$($LFS getdirstripe $stripe_dir |
22525                       awk '/lmv_stripe_count:/ { print $2 }')
22526
22527         [ $count -ne $stripe_count ] &&
22528                 error_noexit "bad stripe count $stripe_count expected $count"
22529
22530         local dupe_stripes
22531         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22532                 awk '/0x/ {count[$1] += 1}; END {
22533                         for (idx in count) {
22534                                 if (count[idx]>1) {
22535                                         print "index " idx " count " count[idx]
22536                                 }
22537                         }
22538                 }')
22539
22540         if [[ -n "$dupe_stripes" ]] ; then
22541                 lfs getdirstripe $stripe_dir
22542                 error_noexit "Dupe MDT above: $dupe_stripes "
22543         fi
22544
22545         rm -rf $stripe_dir ||
22546                 error_noexit "unlink $stripe_dir fails"
22547 }
22548
22549 test_300s() {
22550         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22551                 skip "Need MDS version at least 2.7.55" && return
22552         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22553
22554         mkdir $DIR/$tdir
22555         for count in $(seq 2 $MDSCOUNT); do
22556                 test_300s_helper $count
22557         done
22558 }
22559 run_test 300s "test lfs mkdir -c without -i"
22560
22561
22562 prepare_remote_file() {
22563         mkdir $DIR/$tdir/src_dir ||
22564                 error "create remote source failed"
22565
22566         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22567                  error "cp to remote source failed"
22568         touch $DIR/$tdir/src_dir/a
22569
22570         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22571                 error "create remote target dir failed"
22572
22573         touch $DIR/$tdir/tgt_dir/b
22574
22575         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22576                 error "rename dir cross MDT failed!"
22577
22578         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22579                 error "src_child still exists after rename"
22580
22581         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22582                 error "missing file(a) after rename"
22583
22584         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22585                 error "diff after rename"
22586 }
22587
22588 test_310a() {
22589         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22591
22592         local remote_file=$DIR/$tdir/tgt_dir/b
22593
22594         mkdir -p $DIR/$tdir
22595
22596         prepare_remote_file || error "prepare remote file failed"
22597
22598         #open-unlink file
22599         $OPENUNLINK $remote_file $remote_file ||
22600                 error "openunlink $remote_file failed"
22601         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22602 }
22603 run_test 310a "open unlink remote file"
22604
22605 test_310b() {
22606         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22608
22609         local remote_file=$DIR/$tdir/tgt_dir/b
22610
22611         mkdir -p $DIR/$tdir
22612
22613         prepare_remote_file || error "prepare remote file failed"
22614
22615         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22616         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22617         $CHECKSTAT -t file $remote_file || error "check file failed"
22618 }
22619 run_test 310b "unlink remote file with multiple links while open"
22620
22621 test_310c() {
22622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22623         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22624
22625         local remote_file=$DIR/$tdir/tgt_dir/b
22626
22627         mkdir -p $DIR/$tdir
22628
22629         prepare_remote_file || error "prepare remote file failed"
22630
22631         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22632         multiop_bg_pause $remote_file O_uc ||
22633                         error "mulitop failed for remote file"
22634         MULTIPID=$!
22635         $MULTIOP $DIR/$tfile Ouc
22636         kill -USR1 $MULTIPID
22637         wait $MULTIPID
22638 }
22639 run_test 310c "open-unlink remote file with multiple links"
22640
22641 #LU-4825
22642 test_311() {
22643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22644         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22645         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22646                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22647         remote_mds_nodsh && skip "remote MDS with nodsh"
22648
22649         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22650         local mdts=$(comma_list $(mdts_nodes))
22651
22652         mkdir -p $DIR/$tdir
22653         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22654         createmany -o $DIR/$tdir/$tfile. 1000
22655
22656         # statfs data is not real time, let's just calculate it
22657         old_iused=$((old_iused + 1000))
22658
22659         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22660                         osp.*OST0000*MDT0000.create_count")
22661         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22662                                 osp.*OST0000*MDT0000.max_create_count")
22663         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22664
22665         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22666         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22667         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22668
22669         unlinkmany $DIR/$tdir/$tfile. 1000
22670
22671         do_nodes $mdts "$LCTL set_param -n \
22672                         osp.*OST0000*.max_create_count=$max_count"
22673         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22674                 do_nodes $mdts "$LCTL set_param -n \
22675                                 osp.*OST0000*.create_count=$count"
22676         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22677                         grep "=0" && error "create_count is zero"
22678
22679         local new_iused
22680         for i in $(seq 120); do
22681                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22682                 # system may be too busy to destroy all objs in time, use
22683                 # a somewhat small value to not fail autotest
22684                 [ $((old_iused - new_iused)) -gt 400 ] && break
22685                 sleep 1
22686         done
22687
22688         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22689         [ $((old_iused - new_iused)) -gt 400 ] ||
22690                 error "objs not destroyed after unlink"
22691 }
22692 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22693
22694 zfs_oid_to_objid()
22695 {
22696         local ost=$1
22697         local objid=$2
22698
22699         local vdevdir=$(dirname $(facet_vdevice $ost))
22700         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22701         local zfs_zapid=$(do_facet $ost $cmd |
22702                           grep -w "/O/0/d$((objid%32))" -C 5 |
22703                           awk '/Object/{getline; print $1}')
22704         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22705                           awk "/$objid = /"'{printf $3}')
22706
22707         echo $zfs_objid
22708 }
22709
22710 zfs_object_blksz() {
22711         local ost=$1
22712         local objid=$2
22713
22714         local vdevdir=$(dirname $(facet_vdevice $ost))
22715         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22716         local blksz=$(do_facet $ost $cmd $objid |
22717                       awk '/dblk/{getline; printf $4}')
22718
22719         case "${blksz: -1}" in
22720                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22721                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22722                 *) ;;
22723         esac
22724
22725         echo $blksz
22726 }
22727
22728 test_312() { # LU-4856
22729         remote_ost_nodsh && skip "remote OST with nodsh"
22730         [ "$ost1_FSTYPE" = "zfs" ] ||
22731                 skip_env "the test only applies to zfs"
22732
22733         local max_blksz=$(do_facet ost1 \
22734                           $ZFS get -p recordsize $(facet_device ost1) |
22735                           awk '!/VALUE/{print $3}')
22736
22737         # to make life a little bit easier
22738         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22739         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22740
22741         local tf=$DIR/$tdir/$tfile
22742         touch $tf
22743         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22744
22745         # Get ZFS object id
22746         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22747         # block size change by sequential overwrite
22748         local bs
22749
22750         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22751                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22752
22753                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22754                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22755         done
22756         rm -f $tf
22757
22758         # block size change by sequential append write
22759         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22760         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22761         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22762         local count
22763
22764         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22765                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22766                         oflag=sync conv=notrunc
22767
22768                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22769                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22770                         error "blksz error, actual $blksz, " \
22771                                 "expected: 2 * $count * $PAGE_SIZE"
22772         done
22773         rm -f $tf
22774
22775         # random write
22776         touch $tf
22777         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22778         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22779
22780         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22781         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22782         [ $blksz -eq $PAGE_SIZE ] ||
22783                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22784
22785         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22786         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22787         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22788
22789         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22790         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22791         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22792 }
22793 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22794
22795 test_313() {
22796         remote_ost_nodsh && skip "remote OST with nodsh"
22797
22798         local file=$DIR/$tfile
22799
22800         rm -f $file
22801         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22802
22803         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22804         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22805         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22806                 error "write should failed"
22807         do_facet ost1 "$LCTL set_param fail_loc=0"
22808         rm -f $file
22809 }
22810 run_test 313 "io should fail after last_rcvd update fail"
22811
22812 test_314() {
22813         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22814
22815         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22816         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22817         rm -f $DIR/$tfile
22818         wait_delete_completed
22819         do_facet ost1 "$LCTL set_param fail_loc=0"
22820 }
22821 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22822
22823 test_315() { # LU-618
22824         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22825
22826         local file=$DIR/$tfile
22827         rm -f $file
22828
22829         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22830                 error "multiop file write failed"
22831         $MULTIOP $file oO_RDONLY:r4063232_c &
22832         PID=$!
22833
22834         sleep 2
22835
22836         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22837         kill -USR1 $PID
22838
22839         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22840         rm -f $file
22841 }
22842 run_test 315 "read should be accounted"
22843
22844 test_316() {
22845         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22846         large_xattr_enabled || skip_env "ea_inode feature disabled"
22847
22848         rm -rf $DIR/$tdir/d
22849         mkdir -p $DIR/$tdir/d
22850         chown nobody $DIR/$tdir/d
22851         touch $DIR/$tdir/d/file
22852
22853         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22854 }
22855 run_test 316 "lfs mv"
22856
22857 test_317() {
22858         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22859                 skip "Need MDS version at least 2.11.53"
22860         if [ "$ost1_FSTYPE" == "zfs" ]; then
22861                 skip "LU-10370: no implementation for ZFS"
22862         fi
22863
22864         local trunc_sz
22865         local grant_blk_size
22866
22867         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22868                         awk '/grant_block_size:/ { print $2; exit; }')
22869         #
22870         # Create File of size 5M. Truncate it to below size's and verify
22871         # blocks count.
22872         #
22873         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22874                 error "Create file $DIR/$tfile failed"
22875         stack_trap "rm -f $DIR/$tfile" EXIT
22876
22877         for trunc_sz in 2097152 4097 4000 509 0; do
22878                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22879                         error "truncate $tfile to $trunc_sz failed"
22880                 local sz=$(stat --format=%s $DIR/$tfile)
22881                 local blk=$(stat --format=%b $DIR/$tfile)
22882                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22883                                      grant_blk_size) * 8))
22884
22885                 if [[ $blk -ne $trunc_blk ]]; then
22886                         $(which stat) $DIR/$tfile
22887                         error "Expected Block $trunc_blk got $blk for $tfile"
22888                 fi
22889
22890                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22891                         error "Expected Size $trunc_sz got $sz for $tfile"
22892         done
22893
22894         #
22895         # sparse file test
22896         # Create file with a hole and write actual two blocks. Block count
22897         # must be 16.
22898         #
22899         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22900                 conv=fsync || error "Create file : $DIR/$tfile"
22901
22902         # Calculate the final truncate size.
22903         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22904
22905         #
22906         # truncate to size $trunc_sz bytes. Strip the last block
22907         # The block count must drop to 8
22908         #
22909         $TRUNCATE $DIR/$tfile $trunc_sz ||
22910                 error "truncate $tfile to $trunc_sz failed"
22911
22912         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22913         sz=$(stat --format=%s $DIR/$tfile)
22914         blk=$(stat --format=%b $DIR/$tfile)
22915
22916         if [[ $blk -ne $trunc_bsz ]]; then
22917                 $(which stat) $DIR/$tfile
22918                 error "Expected Block $trunc_bsz got $blk for $tfile"
22919         fi
22920
22921         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22922                 error "Expected Size $trunc_sz got $sz for $tfile"
22923 }
22924 run_test 317 "Verify blocks get correctly update after truncate"
22925
22926 test_318() {
22927         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
22928         local old_max_active=$($LCTL get_param -n \
22929                             ${llite_name}.max_read_ahead_async_active \
22930                             2>/dev/null)
22931
22932         $LCTL set_param llite.*.max_read_ahead_async_active=256
22933         local max_active=$($LCTL get_param -n \
22934                            ${llite_name}.max_read_ahead_async_active \
22935                            2>/dev/null)
22936         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22937
22938         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22939                 error "set max_read_ahead_async_active should succeed"
22940
22941         $LCTL set_param llite.*.max_read_ahead_async_active=512
22942         max_active=$($LCTL get_param -n \
22943                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
22944         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22945
22946         # restore @max_active
22947         [ $old_max_active -ne 0 ] && $LCTL set_param \
22948                 llite.*.max_read_ahead_async_active=$old_max_active
22949
22950         local old_threshold=$($LCTL get_param -n \
22951                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
22952         local max_per_file_mb=$($LCTL get_param -n \
22953                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
22954
22955         local invalid=$(($max_per_file_mb + 1))
22956         $LCTL set_param \
22957                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22958                         && error "set $invalid should fail"
22959
22960         local valid=$(($invalid - 1))
22961         $LCTL set_param \
22962                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22963                         error "set $valid should succeed"
22964         local threshold=$($LCTL get_param -n \
22965                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
22966         [ $threshold -eq $valid ] || error \
22967                 "expect threshold $valid got $threshold"
22968         $LCTL set_param \
22969                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22970 }
22971 run_test 318 "Verify async readahead tunables"
22972
22973 test_319() {
22974         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22975
22976         local before=$(date +%s)
22977         local evict
22978         local mdir=$DIR/$tdir
22979         local file=$mdir/xxx
22980
22981         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22982         touch $file
22983
22984 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22985         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22986         $LFS mv -m1 $file &
22987
22988         sleep 1
22989         dd if=$file of=/dev/null
22990         wait
22991         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22992           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22993
22994         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22995 }
22996 run_test 319 "lost lease lock on migrate error"
22997
22998 test_398a() { # LU-4198
22999         local ost1_imp=$(get_osc_import_name client ost1)
23000         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23001                          cut -d'.' -f2)
23002
23003         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23004         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23005
23006         # request a new lock on client
23007         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23008
23009         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23010         local lock_count=$($LCTL get_param -n \
23011                            ldlm.namespaces.$imp_name.lru_size)
23012         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23013
23014         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23015
23016         # no lock cached, should use lockless IO and not enqueue new lock
23017         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23018         lock_count=$($LCTL get_param -n \
23019                      ldlm.namespaces.$imp_name.lru_size)
23020         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23021 }
23022 run_test 398a "direct IO should cancel lock otherwise lockless"
23023
23024 test_398b() { # LU-4198
23025         which fio || skip_env "no fio installed"
23026         $LFS setstripe -c -1 $DIR/$tfile
23027
23028         local size=12
23029         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23030
23031         local njobs=4
23032         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23033         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23034                 --numjobs=$njobs --fallocate=none \
23035                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23036                 --filename=$DIR/$tfile &
23037         bg_pid=$!
23038
23039         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23040         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23041                 --numjobs=$njobs --fallocate=none \
23042                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23043                 --filename=$DIR/$tfile || true
23044         wait $bg_pid
23045
23046         rm -rf $DIR/$tfile
23047 }
23048 run_test 398b "DIO and buffer IO race"
23049
23050 test_398c() { # LU-4198
23051         local ost1_imp=$(get_osc_import_name client ost1)
23052         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23053                          cut -d'.' -f2)
23054
23055         which fio || skip_env "no fio installed"
23056
23057         saved_debug=$($LCTL get_param -n debug)
23058         $LCTL set_param debug=0
23059
23060         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23061         ((size /= 1024)) # by megabytes
23062         ((size /= 2)) # write half of the OST at most
23063         [ $size -gt 40 ] && size=40 #reduce test time anyway
23064
23065         $LFS setstripe -c 1 $DIR/$tfile
23066
23067         # it seems like ldiskfs reserves more space than necessary if the
23068         # writing blocks are not mapped, so it extends the file firstly
23069         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23070         cancel_lru_locks osc
23071
23072         # clear and verify rpc_stats later
23073         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23074
23075         local njobs=4
23076         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23077         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23078                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23079                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23080                 --filename=$DIR/$tfile
23081         [ $? -eq 0 ] || error "fio write error"
23082
23083         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23084                 error "Locks were requested while doing AIO"
23085
23086         # get the percentage of 1-page I/O
23087         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23088                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23089                 awk '{print $7}')
23090         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23091
23092         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23093         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23094                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23095                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23096                 --filename=$DIR/$tfile
23097         [ $? -eq 0 ] || error "fio mixed read write error"
23098
23099         echo "AIO with large block size ${size}M"
23100         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23101                 --numjobs=1 --fallocate=none --ioengine=libaio \
23102                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23103                 --filename=$DIR/$tfile
23104         [ $? -eq 0 ] || error "fio large block size failed"
23105
23106         rm -rf $DIR/$tfile
23107         $LCTL set_param debug="$saved_debug"
23108 }
23109 run_test 398c "run fio to test AIO"
23110
23111 test_398d() { #  LU-13846
23112         test -f aiocp || skip_env "no aiocp installed"
23113         local aio_file=$DIR/aio_file
23114
23115         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23116
23117         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23118         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23119
23120         diff $DIR/$tfile $aio_file || "file diff after aiocp"
23121
23122         # make sure we don't crash and fail properly
23123         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23124                 error "aio not aligned with PAGE SIZE should fail"
23125
23126         rm -rf $DIR/$tfile $aio_file
23127 }
23128 run_test 398d "run aiocp to verify block size > stripe size"
23129
23130 test_398e() {
23131         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23132         touch $DIR/$tfile.new
23133         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23134 }
23135 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23136
23137 test_fake_rw() {
23138         local read_write=$1
23139         if [ "$read_write" = "write" ]; then
23140                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23141         elif [ "$read_write" = "read" ]; then
23142                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23143         else
23144                 error "argument error"
23145         fi
23146
23147         # turn off debug for performance testing
23148         local saved_debug=$($LCTL get_param -n debug)
23149         $LCTL set_param debug=0
23150
23151         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23152
23153         # get ost1 size - $FSNAME-OST0000
23154         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23155         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23156         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23157
23158         if [ "$read_write" = "read" ]; then
23159                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23160         fi
23161
23162         local start_time=$(date +%s.%N)
23163         $dd_cmd bs=1M count=$blocks oflag=sync ||
23164                 error "real dd $read_write error"
23165         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23166
23167         if [ "$read_write" = "write" ]; then
23168                 rm -f $DIR/$tfile
23169         fi
23170
23171         # define OBD_FAIL_OST_FAKE_RW           0x238
23172         do_facet ost1 $LCTL set_param fail_loc=0x238
23173
23174         local start_time=$(date +%s.%N)
23175         $dd_cmd bs=1M count=$blocks oflag=sync ||
23176                 error "fake dd $read_write error"
23177         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23178
23179         if [ "$read_write" = "write" ]; then
23180                 # verify file size
23181                 cancel_lru_locks osc
23182                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23183                         error "$tfile size not $blocks MB"
23184         fi
23185         do_facet ost1 $LCTL set_param fail_loc=0
23186
23187         echo "fake $read_write $duration_fake vs. normal $read_write" \
23188                 "$duration in seconds"
23189         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23190                 error_not_in_vm "fake write is slower"
23191
23192         $LCTL set_param -n debug="$saved_debug"
23193         rm -f $DIR/$tfile
23194 }
23195 test_399a() { # LU-7655 for OST fake write
23196         remote_ost_nodsh && skip "remote OST with nodsh"
23197
23198         test_fake_rw write
23199 }
23200 run_test 399a "fake write should not be slower than normal write"
23201
23202 test_399b() { # LU-8726 for OST fake read
23203         remote_ost_nodsh && skip "remote OST with nodsh"
23204         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23205                 skip_env "ldiskfs only test"
23206         fi
23207
23208         test_fake_rw read
23209 }
23210 run_test 399b "fake read should not be slower than normal read"
23211
23212 test_400a() { # LU-1606, was conf-sanity test_74
23213         if ! which $CC > /dev/null 2>&1; then
23214                 skip_env "$CC is not installed"
23215         fi
23216
23217         local extra_flags=''
23218         local out=$TMP/$tfile
23219         local prefix=/usr/include/lustre
23220         local prog
23221
23222         # Oleg removes c files in his test rig so test if any c files exist
23223         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23224                 skip_env "Needed c test files are missing"
23225
23226         if ! [[ -d $prefix ]]; then
23227                 # Assume we're running in tree and fixup the include path.
23228                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23229                 extra_flags+=" -L$LUSTRE/utils/.lib"
23230         fi
23231
23232         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23233                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
23234                         error "client api broken"
23235         done
23236         rm -f $out
23237 }
23238 run_test 400a "Lustre client api program can compile and link"
23239
23240 test_400b() { # LU-1606, LU-5011
23241         local header
23242         local out=$TMP/$tfile
23243         local prefix=/usr/include/linux/lustre
23244
23245         # We use a hard coded prefix so that this test will not fail
23246         # when run in tree. There are headers in lustre/include/lustre/
23247         # that are not packaged (like lustre_idl.h) and have more
23248         # complicated include dependencies (like config.h and lnet/types.h).
23249         # Since this test about correct packaging we just skip them when
23250         # they don't exist (see below) rather than try to fixup cppflags.
23251
23252         if ! which $CC > /dev/null 2>&1; then
23253                 skip_env "$CC is not installed"
23254         fi
23255
23256         for header in $prefix/*.h; do
23257                 if ! [[ -f "$header" ]]; then
23258                         continue
23259                 fi
23260
23261                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
23262                         continue # lustre_ioctl.h is internal header
23263                 fi
23264
23265                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
23266                         error "cannot compile '$header'"
23267         done
23268         rm -f $out
23269 }
23270 run_test 400b "packaged headers can be compiled"
23271
23272 test_401a() { #LU-7437
23273         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23274         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23275
23276         #count the number of parameters by "list_param -R"
23277         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23278         #count the number of parameters by listing proc files
23279         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23280         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23281         echo "proc_dirs='$proc_dirs'"
23282         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23283         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23284                       sort -u | wc -l)
23285
23286         [ $params -eq $procs ] ||
23287                 error "found $params parameters vs. $procs proc files"
23288
23289         # test the list_param -D option only returns directories
23290         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23291         #count the number of parameters by listing proc directories
23292         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23293                 sort -u | wc -l)
23294
23295         [ $params -eq $procs ] ||
23296                 error "found $params parameters vs. $procs proc files"
23297 }
23298 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23299
23300 test_401b() {
23301         # jobid_var may not allow arbitrary values, so use jobid_name
23302         # if available
23303         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23304                 local testname=jobid_name tmp='testing%p'
23305         else
23306                 local testname=jobid_var tmp=testing
23307         fi
23308
23309         local save=$($LCTL get_param -n $testname)
23310
23311         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23312                 error "no error returned when setting bad parameters"
23313
23314         local jobid_new=$($LCTL get_param -n foe $testname baz)
23315         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23316
23317         $LCTL set_param -n fog=bam $testname=$save bat=fog
23318         local jobid_old=$($LCTL get_param -n foe $testname bag)
23319         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23320 }
23321 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23322
23323 test_401c() {
23324         # jobid_var may not allow arbitrary values, so use jobid_name
23325         # if available
23326         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23327                 local testname=jobid_name
23328         else
23329                 local testname=jobid_var
23330         fi
23331
23332         local jobid_var_old=$($LCTL get_param -n $testname)
23333         local jobid_var_new
23334
23335         $LCTL set_param $testname= &&
23336                 error "no error returned for 'set_param a='"
23337
23338         jobid_var_new=$($LCTL get_param -n $testname)
23339         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23340                 error "$testname was changed by setting without value"
23341
23342         $LCTL set_param $testname &&
23343                 error "no error returned for 'set_param a'"
23344
23345         jobid_var_new=$($LCTL get_param -n $testname)
23346         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23347                 error "$testname was changed by setting without value"
23348 }
23349 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23350
23351 test_401d() {
23352         # jobid_var may not allow arbitrary values, so use jobid_name
23353         # if available
23354         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23355                 local testname=jobid_name new_value='foo=bar%p'
23356         else
23357                 local testname=jobid_var new_valuie=foo=bar
23358         fi
23359
23360         local jobid_var_old=$($LCTL get_param -n $testname)
23361         local jobid_var_new
23362
23363         $LCTL set_param $testname=$new_value ||
23364                 error "'set_param a=b' did not accept a value containing '='"
23365
23366         jobid_var_new=$($LCTL get_param -n $testname)
23367         [[ "$jobid_var_new" == "$new_value" ]] ||
23368                 error "'set_param a=b' failed on a value containing '='"
23369
23370         # Reset the $testname to test the other format
23371         $LCTL set_param $testname=$jobid_var_old
23372         jobid_var_new=$($LCTL get_param -n $testname)
23373         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23374                 error "failed to reset $testname"
23375
23376         $LCTL set_param $testname $new_value ||
23377                 error "'set_param a b' did not accept a value containing '='"
23378
23379         jobid_var_new=$($LCTL get_param -n $testname)
23380         [[ "$jobid_var_new" == "$new_value" ]] ||
23381                 error "'set_param a b' failed on a value containing '='"
23382
23383         $LCTL set_param $testname $jobid_var_old
23384         jobid_var_new=$($LCTL get_param -n $testname)
23385         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23386                 error "failed to reset $testname"
23387 }
23388 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23389
23390 test_402() {
23391         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23392         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23393                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23394         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23395                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23396                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23397         remote_mds_nodsh && skip "remote MDS with nodsh"
23398
23399         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23400 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23401         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23402         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23403                 echo "Touch failed - OK"
23404 }
23405 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23406
23407 test_403() {
23408         local file1=$DIR/$tfile.1
23409         local file2=$DIR/$tfile.2
23410         local tfile=$TMP/$tfile
23411
23412         rm -f $file1 $file2 $tfile
23413
23414         touch $file1
23415         ln $file1 $file2
23416
23417         # 30 sec OBD_TIMEOUT in ll_getattr()
23418         # right before populating st_nlink
23419         $LCTL set_param fail_loc=0x80001409
23420         stat -c %h $file1 > $tfile &
23421
23422         # create an alias, drop all locks and reclaim the dentry
23423         < $file2
23424         cancel_lru_locks mdc
23425         cancel_lru_locks osc
23426         sysctl -w vm.drop_caches=2
23427
23428         wait
23429
23430         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23431
23432         rm -f $tfile $file1 $file2
23433 }
23434 run_test 403 "i_nlink should not drop to zero due to aliasing"
23435
23436 test_404() { # LU-6601
23437         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23438                 skip "Need server version newer than 2.8.52"
23439         remote_mds_nodsh && skip "remote MDS with nodsh"
23440
23441         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23442                 awk '/osp .*-osc-MDT/ { print $4}')
23443
23444         local osp
23445         for osp in $mosps; do
23446                 echo "Deactivate: " $osp
23447                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23448                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23449                         awk -vp=$osp '$4 == p { print $2 }')
23450                 [ $stat = IN ] || {
23451                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23452                         error "deactivate error"
23453                 }
23454                 echo "Activate: " $osp
23455                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23456                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23457                         awk -vp=$osp '$4 == p { print $2 }')
23458                 [ $stat = UP ] || {
23459                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23460                         error "activate error"
23461                 }
23462         done
23463 }
23464 run_test 404 "validate manual {de}activated works properly for OSPs"
23465
23466 test_405() {
23467         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23468         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23469                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23470                         skip "Layout swap lock is not supported"
23471
23472         check_swap_layouts_support
23473         check_swap_layout_no_dom $DIR
23474
23475         test_mkdir $DIR/$tdir
23476         swap_lock_test -d $DIR/$tdir ||
23477                 error "One layout swap locked test failed"
23478 }
23479 run_test 405 "Various layout swap lock tests"
23480
23481 test_406() {
23482         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23483         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23484         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23486         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23487                 skip "Need MDS version at least 2.8.50"
23488
23489         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23490         local test_pool=$TESTNAME
23491
23492         pool_add $test_pool || error "pool_add failed"
23493         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23494                 error "pool_add_targets failed"
23495
23496         save_layout_restore_at_exit $MOUNT
23497
23498         # parent set default stripe count only, child will stripe from both
23499         # parent and fs default
23500         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23501                 error "setstripe $MOUNT failed"
23502         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23503         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23504         for i in $(seq 10); do
23505                 local f=$DIR/$tdir/$tfile.$i
23506                 touch $f || error "touch failed"
23507                 local count=$($LFS getstripe -c $f)
23508                 [ $count -eq $OSTCOUNT ] ||
23509                         error "$f stripe count $count != $OSTCOUNT"
23510                 local offset=$($LFS getstripe -i $f)
23511                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23512                 local size=$($LFS getstripe -S $f)
23513                 [ $size -eq $((def_stripe_size * 2)) ] ||
23514                         error "$f stripe size $size != $((def_stripe_size * 2))"
23515                 local pool=$($LFS getstripe -p $f)
23516                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23517         done
23518
23519         # change fs default striping, delete parent default striping, now child
23520         # will stripe from new fs default striping only
23521         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23522                 error "change $MOUNT default stripe failed"
23523         $LFS setstripe -c 0 $DIR/$tdir ||
23524                 error "delete $tdir default stripe failed"
23525         for i in $(seq 11 20); do
23526                 local f=$DIR/$tdir/$tfile.$i
23527                 touch $f || error "touch $f failed"
23528                 local count=$($LFS getstripe -c $f)
23529                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23530                 local offset=$($LFS getstripe -i $f)
23531                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23532                 local size=$($LFS getstripe -S $f)
23533                 [ $size -eq $def_stripe_size ] ||
23534                         error "$f stripe size $size != $def_stripe_size"
23535                 local pool=$($LFS getstripe -p $f)
23536                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23537         done
23538
23539         unlinkmany $DIR/$tdir/$tfile. 1 20
23540
23541         local f=$DIR/$tdir/$tfile
23542         pool_remove_all_targets $test_pool $f
23543         pool_remove $test_pool $f
23544 }
23545 run_test 406 "DNE support fs default striping"
23546
23547 test_407() {
23548         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23549         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23550                 skip "Need MDS version at least 2.8.55"
23551         remote_mds_nodsh && skip "remote MDS with nodsh"
23552
23553         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23554                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23555         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23556                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23557         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23558
23559         #define OBD_FAIL_DT_TXN_STOP    0x2019
23560         for idx in $(seq $MDSCOUNT); do
23561                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23562         done
23563         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23564         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23565                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23566         true
23567 }
23568 run_test 407 "transaction fail should cause operation fail"
23569
23570 test_408() {
23571         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23572
23573         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23574         lctl set_param fail_loc=0x8000040a
23575         # let ll_prepare_partial_page() fail
23576         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23577
23578         rm -f $DIR/$tfile
23579
23580         # create at least 100 unused inodes so that
23581         # shrink_icache_memory(0) should not return 0
23582         touch $DIR/$tfile-{0..100}
23583         rm -f $DIR/$tfile-{0..100}
23584         sync
23585
23586         echo 2 > /proc/sys/vm/drop_caches
23587 }
23588 run_test 408 "drop_caches should not hang due to page leaks"
23589
23590 test_409()
23591 {
23592         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23593
23594         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23595         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23596         touch $DIR/$tdir/guard || error "(2) Fail to create"
23597
23598         local PREFIX=$(str_repeat 'A' 128)
23599         echo "Create 1K hard links start at $(date)"
23600         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23601                 error "(3) Fail to hard link"
23602
23603         echo "Links count should be right although linkEA overflow"
23604         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23605         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23606         [ $linkcount -eq 1001 ] ||
23607                 error "(5) Unexpected hard links count: $linkcount"
23608
23609         echo "List all links start at $(date)"
23610         ls -l $DIR/$tdir/foo > /dev/null ||
23611                 error "(6) Fail to list $DIR/$tdir/foo"
23612
23613         echo "Unlink hard links start at $(date)"
23614         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23615                 error "(7) Fail to unlink"
23616         echo "Unlink hard links finished at $(date)"
23617 }
23618 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23619
23620 test_410()
23621 {
23622         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23623                 skip "Need client version at least 2.9.59"
23624         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23625                 skip "Need MODULES build"
23626
23627         # Create a file, and stat it from the kernel
23628         local testfile=$DIR/$tfile
23629         touch $testfile
23630
23631         local run_id=$RANDOM
23632         local my_ino=$(stat --format "%i" $testfile)
23633
23634         # Try to insert the module. This will always fail as the
23635         # module is designed to not be inserted.
23636         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23637             &> /dev/null
23638
23639         # Anything but success is a test failure
23640         dmesg | grep -q \
23641             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23642             error "no inode match"
23643 }
23644 run_test 410 "Test inode number returned from kernel thread"
23645
23646 cleanup_test411_cgroup() {
23647         trap 0
23648         rmdir "$1"
23649 }
23650
23651 test_411() {
23652         local cg_basedir=/sys/fs/cgroup/memory
23653         # LU-9966
23654         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23655                 skip "no setup for cgroup"
23656
23657         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23658                 error "test file creation failed"
23659         cancel_lru_locks osc
23660
23661         # Create a very small memory cgroup to force a slab allocation error
23662         local cgdir=$cg_basedir/osc_slab_alloc
23663         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23664         trap "cleanup_test411_cgroup $cgdir" EXIT
23665         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23666         echo 1M > $cgdir/memory.limit_in_bytes
23667
23668         # Should not LBUG, just be killed by oom-killer
23669         # dd will return 0 even allocation failure in some environment.
23670         # So don't check return value
23671         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23672         cleanup_test411_cgroup $cgdir
23673
23674         return 0
23675 }
23676 run_test 411 "Slab allocation error with cgroup does not LBUG"
23677
23678 test_412() {
23679         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23680         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23681                 skip "Need server version at least 2.10.55"
23682         fi
23683
23684         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23685                 error "mkdir failed"
23686         $LFS getdirstripe $DIR/$tdir
23687         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23688         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23689                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23690         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23691         [ $stripe_count -eq 2 ] ||
23692                 error "expect 2 get $stripe_count"
23693 }
23694 run_test 412 "mkdir on specific MDTs"
23695
23696 test_qos_mkdir() {
23697         local mkdir_cmd=$1
23698         local stripe_count=$2
23699         local mdts=$(comma_list $(mdts_nodes))
23700
23701         local testdir
23702         local lmv_qos_prio_free
23703         local lmv_qos_threshold_rr
23704         local lmv_qos_maxage
23705         local lod_qos_prio_free
23706         local lod_qos_threshold_rr
23707         local lod_qos_maxage
23708         local count
23709         local i
23710
23711         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23712         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23713         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23714                 head -n1)
23715         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23716         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23717         stack_trap "$LCTL set_param \
23718                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23719         stack_trap "$LCTL set_param \
23720                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23721         stack_trap "$LCTL set_param \
23722                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23723
23724         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23725                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23726         lod_qos_prio_free=${lod_qos_prio_free%%%}
23727         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23728                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23729         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23730         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23731                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23732         stack_trap "do_nodes $mdts $LCTL set_param \
23733                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23734         stack_trap "do_nodes $mdts $LCTL set_param \
23735                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23736                 EXIT
23737         stack_trap "do_nodes $mdts $LCTL set_param \
23738                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23739
23740         echo
23741         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23742
23743         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23744         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23745
23746         testdir=$DIR/$tdir-s$stripe_count/rr
23747
23748         for i in $(seq $((100 * MDSCOUNT))); do
23749                 eval $mkdir_cmd $testdir/subdir$i ||
23750                         error "$mkdir_cmd subdir$i failed"
23751         done
23752
23753         for i in $(seq $MDSCOUNT); do
23754                 count=$($LFS getdirstripe -i $testdir/* |
23755                                 grep ^$((i - 1))$ | wc -l)
23756                 echo "$count directories created on MDT$((i - 1))"
23757                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23758
23759                 if [ $stripe_count -gt 1 ]; then
23760                         count=$($LFS getdirstripe $testdir/* |
23761                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23762                         echo "$count stripes created on MDT$((i - 1))"
23763                         # deviation should < 5% of average
23764                         [ $count -lt $((95 * stripe_count)) ] ||
23765                         [ $count -gt $((105 * stripe_count)) ] &&
23766                                 error "stripes are not evenly distributed"
23767                 fi
23768         done
23769
23770         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23771         do_nodes $mdts $LCTL set_param \
23772                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23773
23774         echo
23775         echo "Check for uneven MDTs: "
23776
23777         local ffree
23778         local bavail
23779         local max
23780         local min
23781         local max_index
23782         local min_index
23783         local tmp
23784
23785         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23786         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23787         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23788
23789         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23790         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23791         max_index=0
23792         min_index=0
23793         for ((i = 1; i < ${#ffree[@]}; i++)); do
23794                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23795                 if [ $tmp -gt $max ]; then
23796                         max=$tmp
23797                         max_index=$i
23798                 fi
23799                 if [ $tmp -lt $min ]; then
23800                         min=$tmp
23801                         min_index=$i
23802                 fi
23803         done
23804
23805         [ ${ffree[min_index]} -eq 0 ] &&
23806                 skip "no free files in MDT$min_index"
23807         [ ${ffree[min_index]} -gt 100000000 ] &&
23808                 skip "too much free files in MDT$min_index"
23809
23810         # Check if we need to generate uneven MDTs
23811         local threshold=50
23812         local diff=$(((max - min) * 100 / min))
23813         local value="$(generate_string 1024)"
23814
23815         while [ $diff -lt $threshold ]; do
23816                 # generate uneven MDTs, create till $threshold% diff
23817                 echo -n "weight diff=$diff% must be > $threshold% ..."
23818                 count=$((${ffree[min_index]} / 10))
23819                 # 50 sec per 10000 files in vm
23820                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23821                         skip "$count files to create"
23822                 echo "Fill MDT$min_index with $count files"
23823                 [ -d $DIR/$tdir-MDT$min_index ] ||
23824                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23825                         error "mkdir $tdir-MDT$min_index failed"
23826                 for i in $(seq $count); do
23827                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23828                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23829                                 error "create f$j_$i failed"
23830                         setfattr -n user.413b -v $value \
23831                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23832                                 error "setfattr f$j_$i failed"
23833                 done
23834
23835                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23836                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23837                 max=$(((${ffree[max_index]} >> 8) * \
23838                         (${bavail[max_index]} * bsize >> 16)))
23839                 min=$(((${ffree[min_index]} >> 8) * \
23840                         (${bavail[min_index]} * bsize >> 16)))
23841                 diff=$(((max - min) * 100 / min))
23842         done
23843
23844         echo "MDT filesfree available: ${ffree[@]}"
23845         echo "MDT blocks available: ${bavail[@]}"
23846         echo "weight diff=$diff%"
23847
23848         echo
23849         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23850
23851         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23852         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23853         # decrease statfs age, so that it can be updated in time
23854         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23855         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23856
23857         sleep 1
23858
23859         testdir=$DIR/$tdir-s$stripe_count/qos
23860
23861         for i in $(seq $((100 * MDSCOUNT))); do
23862                 eval $mkdir_cmd $testdir/subdir$i ||
23863                         error "$mkdir_cmd subdir$i failed"
23864         done
23865
23866         for i in $(seq $MDSCOUNT); do
23867                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23868                         wc -l)
23869                 echo "$count directories created on MDT$((i - 1))"
23870
23871                 if [ $stripe_count -gt 1 ]; then
23872                         count=$($LFS getdirstripe $testdir/* |
23873                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23874                         echo "$count stripes created on MDT$((i - 1))"
23875                 fi
23876         done
23877
23878         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23879         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23880
23881         # D-value should > 10% of averge
23882         [ $((max - min)) -lt 10 ] &&
23883                 error "subdirs shouldn't be evenly distributed"
23884
23885         # ditto
23886         if [ $stripe_count -gt 1 ]; then
23887                 max=$($LFS getdirstripe $testdir/* |
23888                         grep -P "^\s+$max_index\t" | wc -l)
23889                 min=$($LFS getdirstripe $testdir/* |
23890                         grep -P "^\s+$min_index\t" | wc -l)
23891                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23892                         error "stripes shouldn't be evenly distributed"|| true
23893         fi
23894 }
23895
23896 test_413a() {
23897         [ $MDSCOUNT -lt 2 ] &&
23898                 skip "We need at least 2 MDTs for this test"
23899
23900         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23901                 skip "Need server version at least 2.12.52"
23902
23903         local stripe_count
23904
23905         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23906                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23907                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23908                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23909                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23910         done
23911 }
23912 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23913
23914 test_413b() {
23915         [ $MDSCOUNT -lt 2 ] &&
23916                 skip "We need at least 2 MDTs for this test"
23917
23918         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23919                 skip "Need server version at least 2.12.52"
23920
23921         local stripe_count
23922
23923         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23924                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23925                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23926                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23927                 $LFS setdirstripe -D -c $stripe_count \
23928                         $DIR/$tdir-s$stripe_count/rr ||
23929                         error "setdirstripe failed"
23930                 $LFS setdirstripe -D -c $stripe_count \
23931                         $DIR/$tdir-s$stripe_count/qos ||
23932                         error "setdirstripe failed"
23933                 test_qos_mkdir "mkdir" $stripe_count
23934         done
23935 }
23936 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23937
23938 test_414() {
23939 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23940         $LCTL set_param fail_loc=0x80000521
23941         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23942         rm -f $DIR/$tfile
23943 }
23944 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23945
23946 test_415() {
23947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23948         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23949                 skip "Need server version at least 2.11.52"
23950
23951         # LU-11102
23952         local total
23953         local setattr_pid
23954         local start_time
23955         local end_time
23956         local duration
23957
23958         total=500
23959         # this test may be slow on ZFS
23960         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23961
23962         # though this test is designed for striped directory, let's test normal
23963         # directory too since lock is always saved as CoS lock.
23964         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23965         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23966
23967         (
23968                 while true; do
23969                         touch $DIR/$tdir
23970                 done
23971         ) &
23972         setattr_pid=$!
23973
23974         start_time=$(date +%s)
23975         for i in $(seq $total); do
23976                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23977                         > /dev/null
23978         done
23979         end_time=$(date +%s)
23980         duration=$((end_time - start_time))
23981
23982         kill -9 $setattr_pid
23983
23984         echo "rename $total files took $duration sec"
23985         [ $duration -lt 100 ] || error "rename took $duration sec"
23986 }
23987 run_test 415 "lock revoke is not missing"
23988
23989 test_416() {
23990         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23991                 skip "Need server version at least 2.11.55"
23992
23993         # define OBD_FAIL_OSD_TXN_START    0x19a
23994         do_facet mds1 lctl set_param fail_loc=0x19a
23995
23996         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23997
23998         true
23999 }
24000 run_test 416 "transaction start failure won't cause system hung"
24001
24002 cleanup_417() {
24003         trap 0
24004         do_nodes $(comma_list $(mdts_nodes)) \
24005                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24006         do_nodes $(comma_list $(mdts_nodes)) \
24007                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24008         do_nodes $(comma_list $(mdts_nodes)) \
24009                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24010 }
24011
24012 test_417() {
24013         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24014         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24015                 skip "Need MDS version at least 2.11.56"
24016
24017         trap cleanup_417 RETURN EXIT
24018
24019         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24020         do_nodes $(comma_list $(mdts_nodes)) \
24021                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24022         $LFS migrate -m 0 $DIR/$tdir.1 &&
24023                 error "migrate dir $tdir.1 should fail"
24024
24025         do_nodes $(comma_list $(mdts_nodes)) \
24026                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24027         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24028                 error "create remote dir $tdir.2 should fail"
24029
24030         do_nodes $(comma_list $(mdts_nodes)) \
24031                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24032         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24033                 error "create striped dir $tdir.3 should fail"
24034         true
24035 }
24036 run_test 417 "disable remote dir, striped dir and dir migration"
24037
24038 # Checks that the outputs of df [-i] and lfs df [-i] match
24039 #
24040 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24041 check_lfs_df() {
24042         local dir=$2
24043         local inodes
24044         local df_out
24045         local lfs_df_out
24046         local count
24047         local passed=false
24048
24049         # blocks or inodes
24050         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24051
24052         for count in {1..100}; do
24053                 cancel_lru_locks
24054                 sync; sleep 0.2
24055
24056                 # read the lines of interest
24057                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24058                         error "df $inodes $dir | tail -n +2 failed"
24059                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24060                         error "lfs df $inodes $dir | grep summary: failed"
24061
24062                 # skip first substrings of each output as they are different
24063                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24064                 # compare the two outputs
24065                 passed=true
24066                 for i in {1..5}; do
24067                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24068                 done
24069                 $passed && break
24070         done
24071
24072         if ! $passed; then
24073                 df -P $inodes $dir
24074                 echo
24075                 lfs df $inodes $dir
24076                 error "df and lfs df $1 output mismatch: "      \
24077                       "df ${inodes}: ${df_out[*]}, "            \
24078                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24079         fi
24080 }
24081
24082 test_418() {
24083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24084
24085         local dir=$DIR/$tdir
24086         local numfiles=$((RANDOM % 4096 + 2))
24087         local numblocks=$((RANDOM % 256 + 1))
24088
24089         wait_delete_completed
24090         test_mkdir $dir
24091
24092         # check block output
24093         check_lfs_df blocks $dir
24094         # check inode output
24095         check_lfs_df inodes $dir
24096
24097         # create a single file and retest
24098         echo "Creating a single file and testing"
24099         createmany -o $dir/$tfile- 1 &>/dev/null ||
24100                 error "creating 1 file in $dir failed"
24101         check_lfs_df blocks $dir
24102         check_lfs_df inodes $dir
24103
24104         # create a random number of files
24105         echo "Creating $((numfiles - 1)) files and testing"
24106         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24107                 error "creating $((numfiles - 1)) files in $dir failed"
24108
24109         # write a random number of blocks to the first test file
24110         echo "Writing $numblocks 4K blocks and testing"
24111         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24112                 count=$numblocks &>/dev/null ||
24113                 error "dd to $dir/${tfile}-0 failed"
24114
24115         # retest
24116         check_lfs_df blocks $dir
24117         check_lfs_df inodes $dir
24118
24119         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24120                 error "unlinking $numfiles files in $dir failed"
24121 }
24122 run_test 418 "df and lfs df outputs match"
24123
24124 test_419()
24125 {
24126         local dir=$DIR/$tdir
24127
24128         mkdir -p $dir
24129         touch $dir/file
24130
24131         cancel_lru_locks mdc
24132
24133         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24134         $LCTL set_param fail_loc=0x1410
24135         cat $dir/file
24136         $LCTL set_param fail_loc=0
24137         rm -rf $dir
24138 }
24139 run_test 419 "Verify open file by name doesn't crash kernel"
24140
24141 test_420()
24142 {
24143         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24144                 skip "Need MDS version at least 2.12.53"
24145
24146         local SAVE_UMASK=$(umask)
24147         local dir=$DIR/$tdir
24148         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24149
24150         mkdir -p $dir
24151         umask 0000
24152         mkdir -m03777 $dir/testdir
24153         ls -dn $dir/testdir
24154         # Need to remove trailing '.' when SELinux is enabled
24155         local dirperms=$(ls -dn $dir/testdir |
24156                          awk '{ sub(/\.$/, "", $1); print $1}')
24157         [ $dirperms == "drwxrwsrwt" ] ||
24158                 error "incorrect perms on $dir/testdir"
24159
24160         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24161                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24162         ls -n $dir/testdir/testfile
24163         local fileperms=$(ls -n $dir/testdir/testfile |
24164                           awk '{ sub(/\.$/, "", $1); print $1}')
24165         [ $fileperms == "-rwxr-xr-x" ] ||
24166                 error "incorrect perms on $dir/testdir/testfile"
24167
24168         umask $SAVE_UMASK
24169 }
24170 run_test 420 "clear SGID bit on non-directories for non-members"
24171
24172 test_421a() {
24173         local cnt
24174         local fid1
24175         local fid2
24176
24177         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24178                 skip "Need MDS version at least 2.12.54"
24179
24180         test_mkdir $DIR/$tdir
24181         createmany -o $DIR/$tdir/f 3
24182         cnt=$(ls -1 $DIR/$tdir | wc -l)
24183         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24184
24185         fid1=$(lfs path2fid $DIR/$tdir/f1)
24186         fid2=$(lfs path2fid $DIR/$tdir/f2)
24187         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
24188
24189         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
24190         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
24191
24192         cnt=$(ls -1 $DIR/$tdir | wc -l)
24193         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24194
24195         rm -f $DIR/$tdir/f3 || error "can't remove f3"
24196         createmany -o $DIR/$tdir/f 3
24197         cnt=$(ls -1 $DIR/$tdir | wc -l)
24198         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24199
24200         fid1=$(lfs path2fid $DIR/$tdir/f1)
24201         fid2=$(lfs path2fid $DIR/$tdir/f2)
24202         echo "remove using fsname $FSNAME"
24203         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
24204
24205         cnt=$(ls -1 $DIR/$tdir | wc -l)
24206         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24207 }
24208 run_test 421a "simple rm by fid"
24209
24210 test_421b() {
24211         local cnt
24212         local FID1
24213         local FID2
24214
24215         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24216                 skip "Need MDS version at least 2.12.54"
24217
24218         test_mkdir $DIR/$tdir
24219         createmany -o $DIR/$tdir/f 3
24220         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
24221         MULTIPID=$!
24222
24223         FID1=$(lfs path2fid $DIR/$tdir/f1)
24224         FID2=$(lfs path2fid $DIR/$tdir/f2)
24225         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
24226
24227         kill -USR1 $MULTIPID
24228         wait
24229
24230         cnt=$(ls $DIR/$tdir | wc -l)
24231         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
24232 }
24233 run_test 421b "rm by fid on open file"
24234
24235 test_421c() {
24236         local cnt
24237         local FIDS
24238
24239         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24240                 skip "Need MDS version at least 2.12.54"
24241
24242         test_mkdir $DIR/$tdir
24243         createmany -o $DIR/$tdir/f 3
24244         touch $DIR/$tdir/$tfile
24245         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
24246         cnt=$(ls -1 $DIR/$tdir | wc -l)
24247         [ $cnt != 184 ] && error "unexpected #files: $cnt"
24248
24249         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
24250         $LFS rmfid $DIR $FID1 || error "rmfid failed"
24251
24252         cnt=$(ls $DIR/$tdir | wc -l)
24253         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
24254 }
24255 run_test 421c "rm by fid against hardlinked files"
24256
24257 test_421d() {
24258         local cnt
24259         local FIDS
24260
24261         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24262                 skip "Need MDS version at least 2.12.54"
24263
24264         test_mkdir $DIR/$tdir
24265         createmany -o $DIR/$tdir/f 4097
24266         cnt=$(ls -1 $DIR/$tdir | wc -l)
24267         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
24268
24269         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
24270         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24271
24272         cnt=$(ls $DIR/$tdir | wc -l)
24273         rm -rf $DIR/$tdir
24274         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24275 }
24276 run_test 421d "rmfid en masse"
24277
24278 test_421e() {
24279         local cnt
24280         local FID
24281
24282         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24283         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24284                 skip "Need MDS version at least 2.12.54"
24285
24286         mkdir -p $DIR/$tdir
24287         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24288         createmany -o $DIR/$tdir/striped_dir/f 512
24289         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24290         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24291
24292         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24293                 sed "s/[/][^:]*://g")
24294         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24295
24296         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24297         rm -rf $DIR/$tdir
24298         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24299 }
24300 run_test 421e "rmfid in DNE"
24301
24302 test_421f() {
24303         local cnt
24304         local FID
24305
24306         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24307                 skip "Need MDS version at least 2.12.54"
24308
24309         test_mkdir $DIR/$tdir
24310         touch $DIR/$tdir/f
24311         cnt=$(ls -1 $DIR/$tdir | wc -l)
24312         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24313
24314         FID=$(lfs path2fid $DIR/$tdir/f)
24315         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24316         # rmfid should fail
24317         cnt=$(ls -1 $DIR/$tdir | wc -l)
24318         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24319
24320         chmod a+rw $DIR/$tdir
24321         ls -la $DIR/$tdir
24322         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24323         # rmfid should fail
24324         cnt=$(ls -1 $DIR/$tdir | wc -l)
24325         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24326
24327         rm -f $DIR/$tdir/f
24328         $RUNAS touch $DIR/$tdir/f
24329         FID=$(lfs path2fid $DIR/$tdir/f)
24330         echo "rmfid as root"
24331         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24332         cnt=$(ls -1 $DIR/$tdir | wc -l)
24333         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24334
24335         rm -f $DIR/$tdir/f
24336         $RUNAS touch $DIR/$tdir/f
24337         cnt=$(ls -1 $DIR/$tdir | wc -l)
24338         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24339         FID=$(lfs path2fid $DIR/$tdir/f)
24340         # rmfid w/o user_fid2path mount option should fail
24341         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24342         cnt=$(ls -1 $DIR/$tdir | wc -l)
24343         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24344
24345         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24346         stack_trap "rmdir $tmpdir"
24347         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24348                 error "failed to mount client'"
24349         stack_trap "umount_client $tmpdir"
24350
24351         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24352         # rmfid should succeed
24353         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24354         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24355
24356         # rmfid shouldn't allow to remove files due to dir's permission
24357         chmod a+rwx $tmpdir/$tdir
24358         touch $tmpdir/$tdir/f
24359         ls -la $tmpdir/$tdir
24360         FID=$(lfs path2fid $tmpdir/$tdir/f)
24361         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24362         return 0
24363 }
24364 run_test 421f "rmfid checks permissions"
24365
24366 test_421g() {
24367         local cnt
24368         local FIDS
24369
24370         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24371         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24372                 skip "Need MDS version at least 2.12.54"
24373
24374         mkdir -p $DIR/$tdir
24375         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24376         createmany -o $DIR/$tdir/striped_dir/f 512
24377         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24378         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24379
24380         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24381                 sed "s/[/][^:]*://g")
24382
24383         rm -f $DIR/$tdir/striped_dir/f1*
24384         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24385         removed=$((512 - cnt))
24386
24387         # few files have been just removed, so we expect
24388         # rmfid to fail on their fids
24389         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24390         [ $removed != $errors ] && error "$errors != $removed"
24391
24392         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24393         rm -rf $DIR/$tdir
24394         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24395 }
24396 run_test 421g "rmfid to return errors properly"
24397
24398 test_422() {
24399         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24400         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24401         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24402         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24403         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24404
24405         local amc=$(at_max_get client)
24406         local amo=$(at_max_get mds1)
24407         local timeout=`lctl get_param -n timeout`
24408
24409         at_max_set 0 client
24410         at_max_set 0 mds1
24411
24412 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24413         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24414                         fail_val=$(((2*timeout + 10)*1000))
24415         touch $DIR/$tdir/d3/file &
24416         sleep 2
24417 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24418         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24419                         fail_val=$((2*timeout + 5))
24420         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24421         local pid=$!
24422         sleep 1
24423         kill -9 $pid
24424         sleep $((2 * timeout))
24425         echo kill $pid
24426         kill -9 $pid
24427         lctl mark touch
24428         touch $DIR/$tdir/d2/file3
24429         touch $DIR/$tdir/d2/file4
24430         touch $DIR/$tdir/d2/file5
24431
24432         wait
24433         at_max_set $amc client
24434         at_max_set $amo mds1
24435
24436         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24437         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24438                 error "Watchdog is always throttled"
24439 }
24440 run_test 422 "kill a process with RPC in progress"
24441
24442 stat_test() {
24443     df -h $MOUNT &
24444     df -h $MOUNT &
24445     df -h $MOUNT &
24446     df -h $MOUNT &
24447     df -h $MOUNT &
24448     df -h $MOUNT &
24449 }
24450
24451 test_423() {
24452     local _stats
24453     # ensure statfs cache is expired
24454     sleep 2;
24455
24456     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24457     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24458
24459     return 0
24460 }
24461 run_test 423 "statfs should return a right data"
24462
24463 test_424() {
24464 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24465         $LCTL set_param fail_loc=0x80000522
24466         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24467         rm -f $DIR/$tfile
24468 }
24469 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24470
24471 test_425() {
24472         test_mkdir -c -1 $DIR/$tdir
24473         $LFS setstripe -c -1 $DIR/$tdir
24474
24475         lru_resize_disable "" 100
24476         stack_trap "lru_resize_enable" EXIT
24477
24478         sleep 5
24479
24480         for i in $(seq $((MDSCOUNT * 125))); do
24481                 local t=$DIR/$tdir/$tfile_$i
24482
24483                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24484                         error_noexit "Create file $t"
24485         done
24486         stack_trap "rm -rf $DIR/$tdir" EXIT
24487
24488         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24489                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24490                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24491
24492                 [ $lock_count -le $lru_size ] ||
24493                         error "osc lock count $lock_count > lru size $lru_size"
24494         done
24495
24496         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24497                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24498                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24499
24500                 [ $lock_count -le $lru_size ] ||
24501                         error "mdc lock count $lock_count > lru size $lru_size"
24502         done
24503 }
24504 run_test 425 "lock count should not exceed lru size"
24505
24506 test_426() {
24507         splice-test -r $DIR/$tfile
24508         splice-test -rd $DIR/$tfile
24509         splice-test $DIR/$tfile
24510         splice-test -d $DIR/$tfile
24511 }
24512 run_test 426 "splice test on Lustre"
24513
24514 test_427() {
24515         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24516         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24517                 skip "Need MDS version at least 2.12.4"
24518         local log
24519
24520         mkdir $DIR/$tdir
24521         mkdir $DIR/$tdir/1
24522         mkdir $DIR/$tdir/2
24523         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24524         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24525
24526         $LFS getdirstripe $DIR/$tdir/1/dir
24527
24528         #first setfattr for creating updatelog
24529         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24530
24531 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24532         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24533         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24534         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24535
24536         sleep 2
24537         fail mds2
24538         wait_recovery_complete mds2 $((2*TIMEOUT))
24539
24540         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24541         echo $log | grep "get update log failed" &&
24542                 error "update log corruption is detected" || true
24543 }
24544 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24545
24546 test_428() {
24547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24548         local cache_limit=$CACHE_MAX
24549
24550         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
24551         $LCTL set_param -n llite.*.max_cached_mb=64
24552
24553         mkdir $DIR/$tdir
24554         $LFS setstripe -c 1 $DIR/$tdir
24555         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
24556         stack_trap "rm -f $DIR/$tdir/$tfile.*"
24557         #test write
24558         for f in $(seq 4); do
24559                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
24560         done
24561         wait
24562
24563         cancel_lru_locks osc
24564         # Test read
24565         for f in $(seq 4); do
24566                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
24567         done
24568         wait
24569 }
24570 run_test 428 "large block size IO should not hang"
24571
24572 lseek_test_430() {
24573         local offset
24574         local file=$1
24575
24576         # data at [200K, 400K)
24577         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24578                 error "256K->512K dd fails"
24579         # data at [2M, 3M)
24580         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24581                 error "2M->3M dd fails"
24582         # data at [4M, 5M)
24583         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24584                 error "4M->5M dd fails"
24585         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24586         # start at first component hole #1
24587         printf "Seeking hole from 1000 ... "
24588         offset=$(lseek_test -l 1000 $file)
24589         echo $offset
24590         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24591         printf "Seeking data from 1000 ... "
24592         offset=$(lseek_test -d 1000 $file)
24593         echo $offset
24594         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24595
24596         # start at first component data block
24597         printf "Seeking hole from 300000 ... "
24598         offset=$(lseek_test -l 300000 $file)
24599         echo $offset
24600         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24601         printf "Seeking data from 300000 ... "
24602         offset=$(lseek_test -d 300000 $file)
24603         echo $offset
24604         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24605
24606         # start at the first component but beyond end of object size
24607         printf "Seeking hole from 1000000 ... "
24608         offset=$(lseek_test -l 1000000 $file)
24609         echo $offset
24610         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24611         printf "Seeking data from 1000000 ... "
24612         offset=$(lseek_test -d 1000000 $file)
24613         echo $offset
24614         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24615
24616         # start at second component stripe 2 (empty file)
24617         printf "Seeking hole from 1500000 ... "
24618         offset=$(lseek_test -l 1500000 $file)
24619         echo $offset
24620         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
24621         printf "Seeking data from 1500000 ... "
24622         offset=$(lseek_test -d 1500000 $file)
24623         echo $offset
24624         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24625
24626         # start at second component stripe 1 (all data)
24627         printf "Seeking hole from 3000000 ... "
24628         offset=$(lseek_test -l 3000000 $file)
24629         echo $offset
24630         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
24631         printf "Seeking data from 3000000 ... "
24632         offset=$(lseek_test -d 3000000 $file)
24633         echo $offset
24634         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
24635
24636         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
24637                 error "2nd dd fails"
24638         echo "Add data block at 640K...1280K"
24639
24640         # start at before new data block, in hole
24641         printf "Seeking hole from 600000 ... "
24642         offset=$(lseek_test -l 600000 $file)
24643         echo $offset
24644         [[ $offset == 600000 ]] || error "offset $offset != 600000"
24645         printf "Seeking data from 600000 ... "
24646         offset=$(lseek_test -d 600000 $file)
24647         echo $offset
24648         [[ $offset == 655360 ]] || error "offset $offset != 655360"
24649
24650         # start at the first component new data block
24651         printf "Seeking hole from 1000000 ... "
24652         offset=$(lseek_test -l 1000000 $file)
24653         echo $offset
24654         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24655         printf "Seeking data from 1000000 ... "
24656         offset=$(lseek_test -d 1000000 $file)
24657         echo $offset
24658         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24659
24660         # start at second component stripe 2, new data
24661         printf "Seeking hole from 1200000 ... "
24662         offset=$(lseek_test -l 1200000 $file)
24663         echo $offset
24664         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24665         printf "Seeking data from 1200000 ... "
24666         offset=$(lseek_test -d 1200000 $file)
24667         echo $offset
24668         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
24669
24670         # start beyond file end
24671         printf "Using offset > filesize ... "
24672         lseek_test -l 4000000 $file && error "lseek should fail"
24673         printf "Using offset > filesize ... "
24674         lseek_test -d 4000000 $file && error "lseek should fail"
24675
24676         printf "Done\n\n"
24677 }
24678
24679 test_430a() {
24680         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
24681                 skip "MDT does not support SEEK_HOLE"
24682
24683         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24684                 skip "OST does not support SEEK_HOLE"
24685
24686         local file=$DIR/$tdir/$tfile
24687
24688         mkdir -p $DIR/$tdir
24689
24690         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
24691         # OST stripe #1 will have continuous data at [1M, 3M)
24692         # OST stripe #2 is empty
24693         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
24694         lseek_test_430 $file
24695         rm $file
24696         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
24697         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
24698         lseek_test_430 $file
24699         rm $file
24700         $LFS setstripe -c2 -S 512K $file
24701         echo "Two stripes, stripe size 512K"
24702         lseek_test_430 $file
24703         rm $file
24704         # FLR with stale mirror
24705         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
24706                        -N -c2 -S 1M $file
24707         echo "Mirrored file:"
24708         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
24709         echo "Plain 2 stripes 1M"
24710         lseek_test_430 $file
24711         rm $file
24712 }
24713 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
24714
24715 test_430b() {
24716         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24717                 skip "OST does not support SEEK_HOLE"
24718
24719         local offset
24720         local file=$DIR/$tdir/$tfile
24721
24722         mkdir -p $DIR/$tdir
24723         # Empty layout lseek should fail
24724         $MCREATE $file
24725         # seek from 0
24726         printf "Seeking hole from 0 ... "
24727         lseek_test -l 0 $file && error "lseek should fail"
24728         printf "Seeking data from 0 ... "
24729         lseek_test -d 0 $file && error "lseek should fail"
24730         rm $file
24731
24732         # 1M-hole file
24733         $LFS setstripe -E 1M -c2 -E eof $file
24734         $TRUNCATE $file 1048576
24735         printf "Seeking hole from 1000000 ... "
24736         offset=$(lseek_test -l 1000000 $file)
24737         echo $offset
24738         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24739         printf "Seeking data from 1000000 ... "
24740         lseek_test -d 1000000 $file && error "lseek should fail"
24741         rm $file
24742
24743         # full component followed by non-inited one
24744         $LFS setstripe -E 1M -c2 -E eof $file
24745         dd if=/dev/urandom of=$file bs=1M count=1
24746         printf "Seeking hole from 1000000 ... "
24747         offset=$(lseek_test -l 1000000 $file)
24748         echo $offset
24749         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24750         printf "Seeking hole from 1048576 ... "
24751         lseek_test -l 1048576 $file && error "lseek should fail"
24752         # init second component and truncate back
24753         echo "123" >> $file
24754         $TRUNCATE $file 1048576
24755         printf "Seeking hole from 1000000 ... "
24756         offset=$(lseek_test -l 1000000 $file)
24757         echo $offset
24758         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24759         printf "Seeking hole from 1048576 ... "
24760         lseek_test -l 1048576 $file && error "lseek should fail"
24761         # boundary checks for big values
24762         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
24763         offset=$(lseek_test -d 0 $file.10g)
24764         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
24765         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
24766         offset=$(lseek_test -d 0 $file.100g)
24767         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
24768         return 0
24769 }
24770 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
24771
24772 test_430c() {
24773         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24774                 skip "OST does not support SEEK_HOLE"
24775
24776         local file=$DIR/$tdir/$tfile
24777         local start
24778
24779         mkdir -p $DIR/$tdir
24780         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
24781
24782         # cp version 8.33+ prefers lseek over fiemap
24783         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
24784                 start=$SECONDS
24785                 time cp $file /dev/null
24786                 (( SECONDS - start < 5 )) ||
24787                         error "cp: too long runtime $((SECONDS - start))"
24788
24789         fi
24790         # tar version 1.29+ supports SEEK_HOLE/DATA
24791         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
24792                 start=$SECONDS
24793                 time tar cS $file - | cat > /dev/null
24794                 (( SECONDS - start < 5 )) ||
24795                         error "tar: too long runtime $((SECONDS - start))"
24796         fi
24797 }
24798 run_test 430c "lseek: external tools check"
24799
24800 test_431() { # LU-14187
24801         local file=$DIR/$tdir/$tfile
24802
24803         mkdir -p $DIR/$tdir
24804         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
24805         dd if=/dev/urandom of=$file bs=4k count=1
24806         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
24807         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
24808         #define OBD_FAIL_OST_RESTART_IO 0x251
24809         do_facet ost1 "$LCTL set_param fail_loc=0x251"
24810         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
24811         cp $file $file.0
24812         cancel_lru_locks
24813         sync_all_data
24814         echo 3 > /proc/sys/vm/drop_caches
24815         diff  $file $file.0 || error "data diff"
24816 }
24817 run_test 431 "Restart transaction for IO"
24818
24819 prep_801() {
24820         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24821         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24822                 skip "Need server version at least 2.9.55"
24823
24824         start_full_debug_logging
24825 }
24826
24827 post_801() {
24828         stop_full_debug_logging
24829 }
24830
24831 barrier_stat() {
24832         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24833                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24834                            awk '/The barrier for/ { print $7 }')
24835                 echo $st
24836         else
24837                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24838                 echo \'$st\'
24839         fi
24840 }
24841
24842 barrier_expired() {
24843         local expired
24844
24845         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24846                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24847                           awk '/will be expired/ { print $7 }')
24848         else
24849                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24850         fi
24851
24852         echo $expired
24853 }
24854
24855 test_801a() {
24856         prep_801
24857
24858         echo "Start barrier_freeze at: $(date)"
24859         #define OBD_FAIL_BARRIER_DELAY          0x2202
24860         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24861         # Do not reduce barrier time - See LU-11873
24862         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24863
24864         sleep 2
24865         local b_status=$(barrier_stat)
24866         echo "Got barrier status at: $(date)"
24867         [ "$b_status" = "'freezing_p1'" ] ||
24868                 error "(1) unexpected barrier status $b_status"
24869
24870         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24871         wait
24872         b_status=$(barrier_stat)
24873         [ "$b_status" = "'frozen'" ] ||
24874                 error "(2) unexpected barrier status $b_status"
24875
24876         local expired=$(barrier_expired)
24877         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24878         sleep $((expired + 3))
24879
24880         b_status=$(barrier_stat)
24881         [ "$b_status" = "'expired'" ] ||
24882                 error "(3) unexpected barrier status $b_status"
24883
24884         # Do not reduce barrier time - See LU-11873
24885         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24886                 error "(4) fail to freeze barrier"
24887
24888         b_status=$(barrier_stat)
24889         [ "$b_status" = "'frozen'" ] ||
24890                 error "(5) unexpected barrier status $b_status"
24891
24892         echo "Start barrier_thaw at: $(date)"
24893         #define OBD_FAIL_BARRIER_DELAY          0x2202
24894         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24895         do_facet mgs $LCTL barrier_thaw $FSNAME &
24896
24897         sleep 2
24898         b_status=$(barrier_stat)
24899         echo "Got barrier status at: $(date)"
24900         [ "$b_status" = "'thawing'" ] ||
24901                 error "(6) unexpected barrier status $b_status"
24902
24903         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24904         wait
24905         b_status=$(barrier_stat)
24906         [ "$b_status" = "'thawed'" ] ||
24907                 error "(7) unexpected barrier status $b_status"
24908
24909         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24910         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24911         do_facet mgs $LCTL barrier_freeze $FSNAME
24912
24913         b_status=$(barrier_stat)
24914         [ "$b_status" = "'failed'" ] ||
24915                 error "(8) unexpected barrier status $b_status"
24916
24917         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24918         do_facet mgs $LCTL barrier_thaw $FSNAME
24919
24920         post_801
24921 }
24922 run_test 801a "write barrier user interfaces and stat machine"
24923
24924 test_801b() {
24925         prep_801
24926
24927         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24928         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24929         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24930         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24931         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24932
24933         cancel_lru_locks mdc
24934
24935         # 180 seconds should be long enough
24936         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24937
24938         local b_status=$(barrier_stat)
24939         [ "$b_status" = "'frozen'" ] ||
24940                 error "(6) unexpected barrier status $b_status"
24941
24942         mkdir $DIR/$tdir/d0/d10 &
24943         mkdir_pid=$!
24944
24945         touch $DIR/$tdir/d1/f13 &
24946         touch_pid=$!
24947
24948         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24949         ln_pid=$!
24950
24951         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24952         mv_pid=$!
24953
24954         rm -f $DIR/$tdir/d4/f12 &
24955         rm_pid=$!
24956
24957         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24958
24959         # To guarantee taht the 'stat' is not blocked
24960         b_status=$(barrier_stat)
24961         [ "$b_status" = "'frozen'" ] ||
24962                 error "(8) unexpected barrier status $b_status"
24963
24964         # let above commands to run at background
24965         sleep 5
24966
24967         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24968         ps -p $touch_pid || error "(10) touch should be blocked"
24969         ps -p $ln_pid || error "(11) link should be blocked"
24970         ps -p $mv_pid || error "(12) rename should be blocked"
24971         ps -p $rm_pid || error "(13) unlink should be blocked"
24972
24973         b_status=$(barrier_stat)
24974         [ "$b_status" = "'frozen'" ] ||
24975                 error "(14) unexpected barrier status $b_status"
24976
24977         do_facet mgs $LCTL barrier_thaw $FSNAME
24978         b_status=$(barrier_stat)
24979         [ "$b_status" = "'thawed'" ] ||
24980                 error "(15) unexpected barrier status $b_status"
24981
24982         wait $mkdir_pid || error "(16) mkdir should succeed"
24983         wait $touch_pid || error "(17) touch should succeed"
24984         wait $ln_pid || error "(18) link should succeed"
24985         wait $mv_pid || error "(19) rename should succeed"
24986         wait $rm_pid || error "(20) unlink should succeed"
24987
24988         post_801
24989 }
24990 run_test 801b "modification will be blocked by write barrier"
24991
24992 test_801c() {
24993         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24994
24995         prep_801
24996
24997         stop mds2 || error "(1) Fail to stop mds2"
24998
24999         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25000
25001         local b_status=$(barrier_stat)
25002         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25003                 do_facet mgs $LCTL barrier_thaw $FSNAME
25004                 error "(2) unexpected barrier status $b_status"
25005         }
25006
25007         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25008                 error "(3) Fail to rescan barrier bitmap"
25009
25010         # Do not reduce barrier time - See LU-11873
25011         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25012
25013         b_status=$(barrier_stat)
25014         [ "$b_status" = "'frozen'" ] ||
25015                 error "(4) unexpected barrier status $b_status"
25016
25017         do_facet mgs $LCTL barrier_thaw $FSNAME
25018         b_status=$(barrier_stat)
25019         [ "$b_status" = "'thawed'" ] ||
25020                 error "(5) unexpected barrier status $b_status"
25021
25022         local devname=$(mdsdevname 2)
25023
25024         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25025
25026         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25027                 error "(7) Fail to rescan barrier bitmap"
25028
25029         post_801
25030 }
25031 run_test 801c "rescan barrier bitmap"
25032
25033 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25034 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25035 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25036 saved_MOUNT_OPTS=$MOUNT_OPTS
25037
25038 cleanup_802a() {
25039         trap 0
25040
25041         stopall
25042         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25043         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25044         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25045         MOUNT_OPTS=$saved_MOUNT_OPTS
25046         setupall
25047 }
25048
25049 test_802a() {
25050         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25051         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25052         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25053                 skip "Need server version at least 2.9.55"
25054
25055         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25056
25057         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25058
25059         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25060                 error "(2) Fail to copy"
25061
25062         trap cleanup_802a EXIT
25063
25064         # sync by force before remount as readonly
25065         sync; sync_all_data; sleep 3; sync_all_data
25066
25067         stopall
25068
25069         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25070         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25071         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25072
25073         echo "Mount the server as read only"
25074         setupall server_only || error "(3) Fail to start servers"
25075
25076         echo "Mount client without ro should fail"
25077         mount_client $MOUNT &&
25078                 error "(4) Mount client without 'ro' should fail"
25079
25080         echo "Mount client with ro should succeed"
25081         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25082         mount_client $MOUNT ||
25083                 error "(5) Mount client with 'ro' should succeed"
25084
25085         echo "Modify should be refused"
25086         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25087
25088         echo "Read should be allowed"
25089         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25090                 error "(7) Read should succeed under ro mode"
25091
25092         cleanup_802a
25093 }
25094 run_test 802a "simulate readonly device"
25095
25096 test_802b() {
25097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25098         remote_mds_nodsh && skip "remote MDS with nodsh"
25099
25100         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25101                 skip "readonly option not available"
25102
25103         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25104
25105         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25106                 error "(2) Fail to copy"
25107
25108         # write back all cached data before setting MDT to readonly
25109         cancel_lru_locks
25110         sync_all_data
25111
25112         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25113         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25114
25115         echo "Modify should be refused"
25116         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25117
25118         echo "Read should be allowed"
25119         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25120                 error "(7) Read should succeed under ro mode"
25121
25122         # disable readonly
25123         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25124 }
25125 run_test 802b "be able to set MDTs to readonly"
25126
25127 test_803a() {
25128         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25129         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25130                 skip "MDS needs to be newer than 2.10.54"
25131
25132         mkdir -p $DIR/$tdir
25133         # Create some objects on all MDTs to trigger related logs objects
25134         for idx in $(seq $MDSCOUNT); do
25135                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
25136                         $DIR/$tdir/dir${idx} ||
25137                         error "Fail to create $DIR/$tdir/dir${idx}"
25138         done
25139
25140         sync; sleep 3
25141         wait_delete_completed # ensure old test cleanups are finished
25142         echo "before create:"
25143         $LFS df -i $MOUNT
25144         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25145
25146         for i in {1..10}; do
25147                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
25148                         error "Fail to create $DIR/$tdir/foo$i"
25149         done
25150
25151         sync; sleep 3
25152         echo "after create:"
25153         $LFS df -i $MOUNT
25154         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25155
25156         # allow for an llog to be cleaned up during the test
25157         [ $after_used -ge $((before_used + 10 - 1)) ] ||
25158                 error "before ($before_used) + 10 > after ($after_used)"
25159
25160         for i in {1..10}; do
25161                 rm -rf $DIR/$tdir/foo$i ||
25162                         error "Fail to remove $DIR/$tdir/foo$i"
25163         done
25164
25165         sleep 3 # avoid MDT return cached statfs
25166         wait_delete_completed
25167         echo "after unlink:"
25168         $LFS df -i $MOUNT
25169         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25170
25171         # allow for an llog to be created during the test
25172         [ $after_used -le $((before_used + 1)) ] ||
25173                 error "after ($after_used) > before ($before_used) + 1"
25174 }
25175 run_test 803a "verify agent object for remote object"
25176
25177 test_803b() {
25178         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25179         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
25180                 skip "MDS needs to be newer than 2.13.56"
25181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25182
25183         for i in $(seq 0 $((MDSCOUNT - 1))); do
25184                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
25185         done
25186
25187         local before=0
25188         local after=0
25189
25190         local tmp
25191
25192         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25193         for i in $(seq 0 $((MDSCOUNT - 1))); do
25194                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25195                         awk '/getattr/ { print $2 }')
25196                 before=$((before + tmp))
25197         done
25198         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25199         for i in $(seq 0 $((MDSCOUNT - 1))); do
25200                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25201                         awk '/getattr/ { print $2 }')
25202                 after=$((after + tmp))
25203         done
25204
25205         [ $before -eq $after ] || error "getattr count $before != $after"
25206 }
25207 run_test 803b "remote object can getattr from cache"
25208
25209 test_804() {
25210         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25211         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25212                 skip "MDS needs to be newer than 2.10.54"
25213         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
25214
25215         mkdir -p $DIR/$tdir
25216         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
25217                 error "Fail to create $DIR/$tdir/dir0"
25218
25219         local fid=$($LFS path2fid $DIR/$tdir/dir0)
25220         local dev=$(mdsdevname 2)
25221
25222         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25223                 grep ${fid} || error "NOT found agent entry for dir0"
25224
25225         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
25226                 error "Fail to create $DIR/$tdir/dir1"
25227
25228         touch $DIR/$tdir/dir1/foo0 ||
25229                 error "Fail to create $DIR/$tdir/dir1/foo0"
25230         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
25231         local rc=0
25232
25233         for idx in $(seq $MDSCOUNT); do
25234                 dev=$(mdsdevname $idx)
25235                 do_facet mds${idx} \
25236                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25237                         grep ${fid} && rc=$idx
25238         done
25239
25240         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
25241                 error "Fail to rename foo0 to foo1"
25242         if [ $rc -eq 0 ]; then
25243                 for idx in $(seq $MDSCOUNT); do
25244                         dev=$(mdsdevname $idx)
25245                         do_facet mds${idx} \
25246                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25247                         grep ${fid} && rc=$idx
25248                 done
25249         fi
25250
25251         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
25252                 error "Fail to rename foo1 to foo2"
25253         if [ $rc -eq 0 ]; then
25254                 for idx in $(seq $MDSCOUNT); do
25255                         dev=$(mdsdevname $idx)
25256                         do_facet mds${idx} \
25257                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25258                         grep ${fid} && rc=$idx
25259                 done
25260         fi
25261
25262         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
25263
25264         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
25265                 error "Fail to link to $DIR/$tdir/dir1/foo2"
25266         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
25267                 error "Fail to rename foo2 to foo0"
25268         unlink $DIR/$tdir/dir1/foo0 ||
25269                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
25270         rm -rf $DIR/$tdir/dir0 ||
25271                 error "Fail to rm $DIR/$tdir/dir0"
25272
25273         for idx in $(seq $MDSCOUNT); do
25274                 dev=$(mdsdevname $idx)
25275                 rc=0
25276
25277                 stop mds${idx}
25278                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25279                         rc=$?
25280                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25281                         error "mount mds$idx failed"
25282                 df $MOUNT > /dev/null 2>&1
25283
25284                 # e2fsck should not return error
25285                 [ $rc -eq 0 ] ||
25286                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25287         done
25288 }
25289 run_test 804 "verify agent entry for remote entry"
25290
25291 cleanup_805() {
25292         do_facet $SINGLEMDS zfs set quota=$old $fsset
25293         unlinkmany $DIR/$tdir/f- 1000000
25294         trap 0
25295 }
25296
25297 test_805() {
25298         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25299         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25300         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25301                 skip "netfree not implemented before 0.7"
25302         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25303                 skip "Need MDS version at least 2.10.57"
25304
25305         local fsset
25306         local freekb
25307         local usedkb
25308         local old
25309         local quota
25310         local pref="osd-zfs.$FSNAME-MDT0000."
25311
25312         # limit available space on MDS dataset to meet nospace issue
25313         # quickly. then ZFS 0.7.2 can use reserved space if asked
25314         # properly (using netfree flag in osd_declare_destroy()
25315         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25316         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25317                 gawk '{print $3}')
25318         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25319         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25320         let "usedkb=usedkb-freekb"
25321         let "freekb=freekb/2"
25322         if let "freekb > 5000"; then
25323                 let "freekb=5000"
25324         fi
25325         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25326         trap cleanup_805 EXIT
25327         mkdir $DIR/$tdir
25328         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25329                 error "Can't set PFL layout"
25330         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25331         rm -rf $DIR/$tdir || error "not able to remove"
25332         do_facet $SINGLEMDS zfs set quota=$old $fsset
25333         trap 0
25334 }
25335 run_test 805 "ZFS can remove from full fs"
25336
25337 # Size-on-MDS test
25338 check_lsom_data()
25339 {
25340         local file=$1
25341         local size=$($LFS getsom -s $file)
25342         local expect=$(stat -c %s $file)
25343
25344         [[ $size == $expect ]] ||
25345                 error "$file expected size: $expect, got: $size"
25346
25347         local blocks=$($LFS getsom -b $file)
25348         expect=$(stat -c %b $file)
25349         [[ $blocks == $expect ]] ||
25350                 error "$file expected blocks: $expect, got: $blocks"
25351 }
25352
25353 check_lsom_size()
25354 {
25355         local size=$($LFS getsom -s $1)
25356         local expect=$2
25357
25358         [[ $size == $expect ]] ||
25359                 error "$file expected size: $expect, got: $size"
25360 }
25361
25362 test_806() {
25363         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25364                 skip "Need MDS version at least 2.11.52"
25365
25366         local bs=1048576
25367
25368         touch $DIR/$tfile || error "touch $tfile failed"
25369
25370         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25371         save_lustre_params client "llite.*.xattr_cache" > $save
25372         lctl set_param llite.*.xattr_cache=0
25373         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25374
25375         # single-threaded write
25376         echo "Test SOM for single-threaded write"
25377         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25378                 error "write $tfile failed"
25379         check_lsom_size $DIR/$tfile $bs
25380
25381         local num=32
25382         local size=$(($num * $bs))
25383         local offset=0
25384         local i
25385
25386         echo "Test SOM for single client multi-threaded($num) write"
25387         $TRUNCATE $DIR/$tfile 0
25388         for ((i = 0; i < $num; i++)); do
25389                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25390                 local pids[$i]=$!
25391                 offset=$((offset + $bs))
25392         done
25393         for (( i=0; i < $num; i++ )); do
25394                 wait ${pids[$i]}
25395         done
25396         check_lsom_size $DIR/$tfile $size
25397
25398         $TRUNCATE $DIR/$tfile 0
25399         for ((i = 0; i < $num; i++)); do
25400                 offset=$((offset - $bs))
25401                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25402                 local pids[$i]=$!
25403         done
25404         for (( i=0; i < $num; i++ )); do
25405                 wait ${pids[$i]}
25406         done
25407         check_lsom_size $DIR/$tfile $size
25408
25409         # multi-client writes
25410         num=$(get_node_count ${CLIENTS//,/ })
25411         size=$(($num * $bs))
25412         offset=0
25413         i=0
25414
25415         echo "Test SOM for multi-client ($num) writes"
25416         $TRUNCATE $DIR/$tfile 0
25417         for client in ${CLIENTS//,/ }; do
25418                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25419                 local pids[$i]=$!
25420                 i=$((i + 1))
25421                 offset=$((offset + $bs))
25422         done
25423         for (( i=0; i < $num; i++ )); do
25424                 wait ${pids[$i]}
25425         done
25426         check_lsom_size $DIR/$tfile $offset
25427
25428         i=0
25429         $TRUNCATE $DIR/$tfile 0
25430         for client in ${CLIENTS//,/ }; do
25431                 offset=$((offset - $bs))
25432                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25433                 local pids[$i]=$!
25434                 i=$((i + 1))
25435         done
25436         for (( i=0; i < $num; i++ )); do
25437                 wait ${pids[$i]}
25438         done
25439         check_lsom_size $DIR/$tfile $size
25440
25441         # verify truncate
25442         echo "Test SOM for truncate"
25443         $TRUNCATE $DIR/$tfile 1048576
25444         check_lsom_size $DIR/$tfile 1048576
25445         $TRUNCATE $DIR/$tfile 1234
25446         check_lsom_size $DIR/$tfile 1234
25447
25448         # verify SOM blocks count
25449         echo "Verify SOM block count"
25450         $TRUNCATE $DIR/$tfile 0
25451         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25452                 error "failed to write file $tfile"
25453         check_lsom_data $DIR/$tfile
25454 }
25455 run_test 806 "Verify Lazy Size on MDS"
25456
25457 test_807() {
25458         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25459         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25460                 skip "Need MDS version at least 2.11.52"
25461
25462         # Registration step
25463         changelog_register || error "changelog_register failed"
25464         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25465         changelog_users $SINGLEMDS | grep -q $cl_user ||
25466                 error "User $cl_user not found in changelog_users"
25467
25468         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25469         save_lustre_params client "llite.*.xattr_cache" > $save
25470         lctl set_param llite.*.xattr_cache=0
25471         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25472
25473         rm -rf $DIR/$tdir || error "rm $tdir failed"
25474         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25475         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25476         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25477         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25478                 error "truncate $tdir/trunc failed"
25479
25480         local bs=1048576
25481         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25482                 error "write $tfile failed"
25483
25484         # multi-client wirtes
25485         local num=$(get_node_count ${CLIENTS//,/ })
25486         local offset=0
25487         local i=0
25488
25489         echo "Test SOM for multi-client ($num) writes"
25490         touch $DIR/$tfile || error "touch $tfile failed"
25491         $TRUNCATE $DIR/$tfile 0
25492         for client in ${CLIENTS//,/ }; do
25493                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25494                 local pids[$i]=$!
25495                 i=$((i + 1))
25496                 offset=$((offset + $bs))
25497         done
25498         for (( i=0; i < $num; i++ )); do
25499                 wait ${pids[$i]}
25500         done
25501
25502         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25503         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25504         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25505         check_lsom_data $DIR/$tdir/trunc
25506         check_lsom_data $DIR/$tdir/single_dd
25507         check_lsom_data $DIR/$tfile
25508
25509         rm -rf $DIR/$tdir
25510         # Deregistration step
25511         changelog_deregister || error "changelog_deregister failed"
25512 }
25513 run_test 807 "verify LSOM syncing tool"
25514
25515 check_som_nologged()
25516 {
25517         local lines=$($LFS changelog $FSNAME-MDT0000 |
25518                 grep 'x=trusted.som' | wc -l)
25519         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25520 }
25521
25522 test_808() {
25523         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25524                 skip "Need MDS version at least 2.11.55"
25525
25526         # Registration step
25527         changelog_register || error "changelog_register failed"
25528
25529         touch $DIR/$tfile || error "touch $tfile failed"
25530         check_som_nologged
25531
25532         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25533                 error "write $tfile failed"
25534         check_som_nologged
25535
25536         $TRUNCATE $DIR/$tfile 1234
25537         check_som_nologged
25538
25539         $TRUNCATE $DIR/$tfile 1048576
25540         check_som_nologged
25541
25542         # Deregistration step
25543         changelog_deregister || error "changelog_deregister failed"
25544 }
25545 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25546
25547 check_som_nodata()
25548 {
25549         $LFS getsom $1
25550         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25551 }
25552
25553 test_809() {
25554         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25555                 skip "Need MDS version at least 2.11.56"
25556
25557         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25558                 error "failed to create DoM-only file $DIR/$tfile"
25559         touch $DIR/$tfile || error "touch $tfile failed"
25560         check_som_nodata $DIR/$tfile
25561
25562         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25563                 error "write $tfile failed"
25564         check_som_nodata $DIR/$tfile
25565
25566         $TRUNCATE $DIR/$tfile 1234
25567         check_som_nodata $DIR/$tfile
25568
25569         $TRUNCATE $DIR/$tfile 4097
25570         check_som_nodata $DIR/$file
25571 }
25572 run_test 809 "Verify no SOM xattr store for DoM-only files"
25573
25574 test_810() {
25575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25576         $GSS && skip_env "could not run with gss"
25577         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25578                 skip "OST < 2.12.58 doesn't align checksum"
25579
25580         set_checksums 1
25581         stack_trap "set_checksums $ORIG_CSUM" EXIT
25582         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25583
25584         local csum
25585         local before
25586         local after
25587         for csum in $CKSUM_TYPES; do
25588                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25589                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25590                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25591                         eval set -- $i
25592                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25593                         before=$(md5sum $DIR/$tfile)
25594                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25595                         after=$(md5sum $DIR/$tfile)
25596                         [ "$before" == "$after" ] ||
25597                                 error "$csum: $before != $after bs=$1 seek=$2"
25598                 done
25599         done
25600 }
25601 run_test 810 "partial page writes on ZFS (LU-11663)"
25602
25603 test_812a() {
25604         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25605                 skip "OST < 2.12.51 doesn't support this fail_loc"
25606
25607         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25608         # ensure ost1 is connected
25609         stat $DIR/$tfile >/dev/null || error "can't stat"
25610         wait_osc_import_state client ost1 FULL
25611         # no locks, no reqs to let the connection idle
25612         cancel_lru_locks osc
25613
25614         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25615 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25616         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25617         wait_osc_import_state client ost1 CONNECTING
25618         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25619
25620         stat $DIR/$tfile >/dev/null || error "can't stat file"
25621 }
25622 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
25623
25624 test_812b() { # LU-12378
25625         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25626                 skip "OST < 2.12.51 doesn't support this fail_loc"
25627
25628         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
25629         # ensure ost1 is connected
25630         stat $DIR/$tfile >/dev/null || error "can't stat"
25631         wait_osc_import_state client ost1 FULL
25632         # no locks, no reqs to let the connection idle
25633         cancel_lru_locks osc
25634
25635         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25636 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25637         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25638         wait_osc_import_state client ost1 CONNECTING
25639         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25640
25641         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
25642         wait_osc_import_state client ost1 IDLE
25643 }
25644 run_test 812b "do not drop no resend request for idle connect"
25645
25646 test_812c() {
25647         local old
25648
25649         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
25650
25651         $LFS setstripe -c 1 -o 0 $DIR/$tfile
25652         $LFS getstripe $DIR/$tfile
25653         $LCTL set_param osc.*.idle_timeout=10
25654         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
25655         # ensure ost1 is connected
25656         stat $DIR/$tfile >/dev/null || error "can't stat"
25657         wait_osc_import_state client ost1 FULL
25658         # no locks, no reqs to let the connection idle
25659         cancel_lru_locks osc
25660
25661 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
25662         $LCTL set_param fail_loc=0x80000533
25663         sleep 15
25664         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
25665 }
25666 run_test 812c "idle import vs lock enqueue race"
25667
25668 test_813() {
25669         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
25670         [ -z "$file_heat_sav" ] && skip "no file heat support"
25671
25672         local readsample
25673         local writesample
25674         local readbyte
25675         local writebyte
25676         local readsample1
25677         local writesample1
25678         local readbyte1
25679         local writebyte1
25680
25681         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
25682         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
25683
25684         $LCTL set_param -n llite.*.file_heat=1
25685         echo "Turn on file heat"
25686         echo "Period second: $period_second, Decay percentage: $decay_pct"
25687
25688         echo "QQQQ" > $DIR/$tfile
25689         echo "QQQQ" > $DIR/$tfile
25690         echo "QQQQ" > $DIR/$tfile
25691         cat $DIR/$tfile > /dev/null
25692         cat $DIR/$tfile > /dev/null
25693         cat $DIR/$tfile > /dev/null
25694         cat $DIR/$tfile > /dev/null
25695
25696         local out=$($LFS heat_get $DIR/$tfile)
25697
25698         $LFS heat_get $DIR/$tfile
25699         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25700         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25701         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25702         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25703
25704         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
25705         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
25706         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
25707         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
25708
25709         sleep $((period_second + 3))
25710         echo "Sleep $((period_second + 3)) seconds..."
25711         # The recursion formula to calculate the heat of the file f is as
25712         # follow:
25713         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
25714         # Where Hi is the heat value in the period between time points i*I and
25715         # (i+1)*I; Ci is the access count in the period; the symbol P refers
25716         # to the weight of Ci.
25717         out=$($LFS heat_get $DIR/$tfile)
25718         $LFS heat_get $DIR/$tfile
25719         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25720         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25721         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25722         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25723
25724         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
25725                 error "read sample ($readsample) is wrong"
25726         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
25727                 error "write sample ($writesample) is wrong"
25728         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
25729                 error "read bytes ($readbyte) is wrong"
25730         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
25731                 error "write bytes ($writebyte) is wrong"
25732
25733         echo "QQQQ" > $DIR/$tfile
25734         echo "QQQQ" > $DIR/$tfile
25735         echo "QQQQ" > $DIR/$tfile
25736         cat $DIR/$tfile > /dev/null
25737         cat $DIR/$tfile > /dev/null
25738         cat $DIR/$tfile > /dev/null
25739         cat $DIR/$tfile > /dev/null
25740
25741         sleep $((period_second + 3))
25742         echo "Sleep $((period_second + 3)) seconds..."
25743
25744         out=$($LFS heat_get $DIR/$tfile)
25745         $LFS heat_get $DIR/$tfile
25746         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25747         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25748         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25749         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25750
25751         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
25752                 4 * $decay_pct) / 100") -eq 1 ] ||
25753                 error "read sample ($readsample1) is wrong"
25754         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
25755                 3 * $decay_pct) / 100") -eq 1 ] ||
25756                 error "write sample ($writesample1) is wrong"
25757         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
25758                 20 * $decay_pct) / 100") -eq 1 ] ||
25759                 error "read bytes ($readbyte1) is wrong"
25760         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
25761                 15 * $decay_pct) / 100") -eq 1 ] ||
25762                 error "write bytes ($writebyte1) is wrong"
25763
25764         echo "Turn off file heat for the file $DIR/$tfile"
25765         $LFS heat_set -o $DIR/$tfile
25766
25767         echo "QQQQ" > $DIR/$tfile
25768         echo "QQQQ" > $DIR/$tfile
25769         echo "QQQQ" > $DIR/$tfile
25770         cat $DIR/$tfile > /dev/null
25771         cat $DIR/$tfile > /dev/null
25772         cat $DIR/$tfile > /dev/null
25773         cat $DIR/$tfile > /dev/null
25774
25775         out=$($LFS heat_get $DIR/$tfile)
25776         $LFS heat_get $DIR/$tfile
25777         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25778         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25779         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25780         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25781
25782         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25783         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25784         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25785         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25786
25787         echo "Trun on file heat for the file $DIR/$tfile"
25788         $LFS heat_set -O $DIR/$tfile
25789
25790         echo "QQQQ" > $DIR/$tfile
25791         echo "QQQQ" > $DIR/$tfile
25792         echo "QQQQ" > $DIR/$tfile
25793         cat $DIR/$tfile > /dev/null
25794         cat $DIR/$tfile > /dev/null
25795         cat $DIR/$tfile > /dev/null
25796         cat $DIR/$tfile > /dev/null
25797
25798         out=$($LFS heat_get $DIR/$tfile)
25799         $LFS heat_get $DIR/$tfile
25800         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25801         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25802         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25803         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25804
25805         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
25806         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
25807         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
25808         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
25809
25810         $LFS heat_set -c $DIR/$tfile
25811         $LCTL set_param -n llite.*.file_heat=0
25812         echo "Turn off file heat support for the Lustre filesystem"
25813
25814         echo "QQQQ" > $DIR/$tfile
25815         echo "QQQQ" > $DIR/$tfile
25816         echo "QQQQ" > $DIR/$tfile
25817         cat $DIR/$tfile > /dev/null
25818         cat $DIR/$tfile > /dev/null
25819         cat $DIR/$tfile > /dev/null
25820         cat $DIR/$tfile > /dev/null
25821
25822         out=$($LFS heat_get $DIR/$tfile)
25823         $LFS heat_get $DIR/$tfile
25824         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25825         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25826         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25827         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25828
25829         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25830         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25831         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25832         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25833
25834         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
25835         rm -f $DIR/$tfile
25836 }
25837 run_test 813 "File heat verfication"
25838
25839 test_814()
25840 {
25841         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25842         echo -n y >> $DIR/$tfile
25843         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25844         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25845 }
25846 run_test 814 "sparse cp works as expected (LU-12361)"
25847
25848 test_815()
25849 {
25850         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25851         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25852 }
25853 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25854
25855 test_816() {
25856         local ost1_imp=$(get_osc_import_name client ost1)
25857         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25858                          cut -d'.' -f2)
25859
25860         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25861         # ensure ost1 is connected
25862
25863         stat $DIR/$tfile >/dev/null || error "can't stat"
25864         wait_osc_import_state client ost1 FULL
25865         # no locks, no reqs to let the connection idle
25866         cancel_lru_locks osc
25867         lru_resize_disable osc
25868         local before
25869         local now
25870         before=$($LCTL get_param -n \
25871                  ldlm.namespaces.$imp_name.lru_size)
25872
25873         wait_osc_import_state client ost1 IDLE
25874         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25875         now=$($LCTL get_param -n \
25876               ldlm.namespaces.$imp_name.lru_size)
25877         [ $before == $now ] || error "lru_size changed $before != $now"
25878 }
25879 run_test 816 "do not reset lru_resize on idle reconnect"
25880
25881 cleanup_817() {
25882         umount $tmpdir
25883         exportfs -u localhost:$DIR/nfsexp
25884         rm -rf $DIR/nfsexp
25885 }
25886
25887 test_817() {
25888         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25889
25890         mkdir -p $DIR/nfsexp
25891         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25892                 error "failed to export nfs"
25893
25894         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25895         stack_trap cleanup_817 EXIT
25896
25897         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25898                 error "failed to mount nfs to $tmpdir"
25899
25900         cp /bin/true $tmpdir
25901         $DIR/nfsexp/true || error "failed to execute 'true' command"
25902 }
25903 run_test 817 "nfsd won't cache write lock for exec file"
25904
25905 test_818() {
25906         mkdir $DIR/$tdir
25907         $LFS setstripe -c1 -i0 $DIR/$tfile
25908         $LFS setstripe -c1 -i1 $DIR/$tfile
25909         stop $SINGLEMDS
25910         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25911         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25912         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25913                 error "start $SINGLEMDS failed"
25914         rm -rf $DIR/$tdir
25915 }
25916 run_test 818 "unlink with failed llog"
25917
25918 test_819a() {
25919         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25920         cancel_lru_locks osc
25921         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25922         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25923         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25924         rm -f $TDIR/$tfile
25925 }
25926 run_test 819a "too big niobuf in read"
25927
25928 test_819b() {
25929         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25930         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25931         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25932         cancel_lru_locks osc
25933         sleep 1
25934         rm -f $TDIR/$tfile
25935 }
25936 run_test 819b "too big niobuf in write"
25937
25938
25939 function test_820_start_ost() {
25940         sleep 5
25941
25942         for num in $(seq $OSTCOUNT); do
25943                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25944         done
25945 }
25946
25947 test_820() {
25948         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25949
25950         mkdir $DIR/$tdir
25951         umount_client $MOUNT || error "umount failed"
25952         for num in $(seq $OSTCOUNT); do
25953                 stop ost$num
25954         done
25955
25956         # mount client with no active OSTs
25957         # so that the client can't initialize max LOV EA size
25958         # from OSC notifications
25959         mount_client $MOUNT || error "mount failed"
25960         # delay OST starting to keep this 0 max EA size for a while
25961         test_820_start_ost &
25962
25963         # create a directory on MDS2
25964         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25965                 error "Failed to create directory"
25966         # open intent should update default EA size
25967         # see mdc_update_max_ea_from_body()
25968         # notice this is the very first RPC to MDS2
25969         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25970         ret=$?
25971         echo $out
25972         # With SSK, this situation can lead to -EPERM being returned.
25973         # In that case, simply retry.
25974         if [ $ret -ne 0 ] && $SHARED_KEY; then
25975                 if echo "$out" | grep -q "not permitted"; then
25976                         cp /etc/services $DIR/$tdir/mds2
25977                         ret=$?
25978                 fi
25979         fi
25980         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25981 }
25982 run_test 820 "update max EA from open intent"
25983
25984 test_822() {
25985         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
25986
25987         save_lustre_params mds1 \
25988                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
25989         do_facet $SINGLEMDS "$LCTL set_param -n \
25990                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
25991         do_facet $SINGLEMDS "$LCTL set_param -n \
25992                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
25993
25994         # wait for statfs update to clear OS_STATFS_NOPRECREATE
25995         local maxage=$(do_facet mds1 $LCTL get_param -n \
25996                        osp.$FSNAME-OST0000*MDT0000.maxage)
25997         sleep $((maxage + 1))
25998
25999         #define OBD_FAIL_NET_ERROR_RPC          0x532
26000         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26001
26002         stack_trap "restore_lustre_params < $p; rm $p"
26003
26004         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26005                       osp.$FSNAME-OST0000*MDT0000.create_count")
26006         for i in $(seq 1 $count); do
26007                 touch $DIR/$tfile.${i} || error "touch failed"
26008         done
26009 }
26010 run_test 822 "test precreate failure"
26011
26012 #
26013 # tests that do cleanup/setup should be run at the end
26014 #
26015
26016 test_900() {
26017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26018         local ls
26019
26020         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26021         $LCTL set_param fail_loc=0x903
26022
26023         cancel_lru_locks MGC
26024
26025         FAIL_ON_ERROR=true cleanup
26026         FAIL_ON_ERROR=true setup
26027 }
26028 run_test 900 "umount should not race with any mgc requeue thread"
26029
26030 # LUS-6253/LU-11185
26031 test_901() {
26032         local oldc
26033         local newc
26034         local olds
26035         local news
26036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26037
26038         # some get_param have a bug to handle dot in param name
26039         cancel_lru_locks MGC
26040         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26041         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26042         umount_client $MOUNT || error "umount failed"
26043         mount_client $MOUNT || error "mount failed"
26044         cancel_lru_locks MGC
26045         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26046         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26047
26048         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26049         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26050
26051         return 0
26052 }
26053 run_test 901 "don't leak a mgc lock on client umount"
26054
26055 # LU-13377
26056 test_902() {
26057         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26058                 skip "client does not have LU-13377 fix"
26059         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26060         $LCTL set_param fail_loc=0x1415
26061         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26062         cancel_lru_locks osc
26063         rm -f $DIR/$tfile
26064 }
26065 run_test 902 "test short write doesn't hang lustre"
26066
26067 complete $SECONDS
26068 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26069 check_and_cleanup_lustre
26070 if [ "$I_MOUNTED" != "yes" ]; then
26071         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26072 fi
26073 exit_status