Whamcloud - gitweb
LU-14616 readahead: fix reserving for unaliged read
[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         $LCTL get_param llite.*.max_cached_mb
9889         $LCTL get_param llite.*.read_ahead_stats
9890         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9891                      get_named_value 'misses' | calc_total)
9892
9893         for ((i = 0; i < $count; i++)); do
9894                 rm -rf $file.$i 2>/dev/null
9895         done
9896
9897         #10000 means 20% reads are missing in readahead
9898         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9899 }
9900 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9901
9902 test_101f() {
9903         which iozone || skip_env "no iozone installed"
9904
9905         local old_debug=$($LCTL get_param debug)
9906         old_debug=${old_debug#*=}
9907         $LCTL set_param debug="reada mmap"
9908
9909         # create a test file
9910         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9911
9912         echo Cancel LRU locks on lustre client to flush the client cache
9913         cancel_lru_locks osc
9914
9915         echo Reset readahead stats
9916         $LCTL set_param -n llite.*.read_ahead_stats=0
9917
9918         echo mmap read the file with small block size
9919         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9920                 > /dev/null 2>&1
9921
9922         echo checking missing pages
9923         $LCTL get_param llite.*.read_ahead_stats
9924         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9925                         get_named_value 'misses' | calc_total)
9926
9927         $LCTL set_param debug="$old_debug"
9928         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9929         rm -f $DIR/$tfile
9930 }
9931 run_test 101f "check mmap read performance"
9932
9933 test_101g_brw_size_test() {
9934         local mb=$1
9935         local pages=$((mb * 1048576 / PAGE_SIZE))
9936         local file=$DIR/$tfile
9937
9938         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9939                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9940         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9941                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9942                         return 2
9943         done
9944
9945         stack_trap "rm -f $file" EXIT
9946         $LCTL set_param -n osc.*.rpc_stats=0
9947
9948         # 10 RPCs should be enough for the test
9949         local count=10
9950         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9951                 { error "dd write ${mb} MB blocks failed"; return 3; }
9952         cancel_lru_locks osc
9953         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9954                 { error "dd write ${mb} MB blocks failed"; return 4; }
9955
9956         # calculate number of full-sized read and write RPCs
9957         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9958                 sed -n '/pages per rpc/,/^$/p' |
9959                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9960                 END { print reads,writes }'))
9961         # allow one extra full-sized read RPC for async readahead
9962         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9963                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9964         [[ ${rpcs[1]} == $count ]] ||
9965                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9966 }
9967
9968 test_101g() {
9969         remote_ost_nodsh && skip "remote OST with nodsh"
9970
9971         local rpcs
9972         local osts=$(get_facets OST)
9973         local list=$(comma_list $(osts_nodes))
9974         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9975         local brw_size="obdfilter.*.brw_size"
9976
9977         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9978
9979         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9980
9981         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9982                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9983                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9984            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9985                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9986                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9987
9988                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9989                         suffix="M"
9990
9991                 if [[ $orig_mb -lt 16 ]]; then
9992                         save_lustre_params $osts "$brw_size" > $p
9993                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9994                                 error "set 16MB RPC size failed"
9995
9996                         echo "remount client to enable new RPC size"
9997                         remount_client $MOUNT || error "remount_client failed"
9998                 fi
9999
10000                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10001                 # should be able to set brw_size=12, but no rpc_stats for that
10002                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10003         fi
10004
10005         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10006
10007         if [[ $orig_mb -lt 16 ]]; then
10008                 restore_lustre_params < $p
10009                 remount_client $MOUNT || error "remount_client restore failed"
10010         fi
10011
10012         rm -f $p $DIR/$tfile
10013 }
10014 run_test 101g "Big bulk(4/16 MiB) readahead"
10015
10016 test_101h() {
10017         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10018
10019         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10020                 error "dd 70M file failed"
10021         echo Cancel LRU locks on lustre client to flush the client cache
10022         cancel_lru_locks osc
10023
10024         echo "Reset readahead stats"
10025         $LCTL set_param -n llite.*.read_ahead_stats 0
10026
10027         echo "Read 10M of data but cross 64M bundary"
10028         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10029         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10030                      get_named_value 'misses' | calc_total)
10031         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10032         rm -f $p $DIR/$tfile
10033 }
10034 run_test 101h "Readahead should cover current read window"
10035
10036 test_101i() {
10037         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10038                 error "dd 10M file failed"
10039
10040         local max_per_file_mb=$($LCTL get_param -n \
10041                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10042         cancel_lru_locks osc
10043         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10044         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10045                 error "set max_read_ahead_per_file_mb to 1 failed"
10046
10047         echo "Reset readahead stats"
10048         $LCTL set_param llite.*.read_ahead_stats=0
10049
10050         dd if=$DIR/$tfile of=/dev/null bs=2M
10051
10052         $LCTL get_param llite.*.read_ahead_stats
10053         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10054                      awk '/misses/ { print $2 }')
10055         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10056         rm -f $DIR/$tfile
10057 }
10058 run_test 101i "allow current readahead to exceed reservation"
10059
10060 test_101j() {
10061         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10062                 error "setstripe $DIR/$tfile failed"
10063         local file_size=$((1048576 * 16))
10064         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10065         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10066
10067         echo Disable read-ahead
10068         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10069
10070         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10071         for blk in $PAGE_SIZE 1048576 $file_size; do
10072                 cancel_lru_locks osc
10073                 echo "Reset readahead stats"
10074                 $LCTL set_param -n llite.*.read_ahead_stats=0
10075                 local count=$(($file_size / $blk))
10076                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10077                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10078                              get_named_value 'failed.to.fast.read' | calc_total)
10079                 $LCTL get_param -n llite.*.read_ahead_stats
10080                 [ $miss -eq $count ] || error "expected $count got $miss"
10081         done
10082
10083         rm -f $p $DIR/$tfile
10084 }
10085 run_test 101j "A complete read block should be submitted when no RA"
10086
10087 setup_test102() {
10088         test_mkdir $DIR/$tdir
10089         chown $RUNAS_ID $DIR/$tdir
10090         STRIPE_SIZE=65536
10091         STRIPE_OFFSET=1
10092         STRIPE_COUNT=$OSTCOUNT
10093         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10094
10095         trap cleanup_test102 EXIT
10096         cd $DIR
10097         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10098         cd $DIR/$tdir
10099         for num in 1 2 3 4; do
10100                 for count in $(seq 1 $STRIPE_COUNT); do
10101                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10102                                 local size=`expr $STRIPE_SIZE \* $num`
10103                                 local file=file"$num-$idx-$count"
10104                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10105                         done
10106                 done
10107         done
10108
10109         cd $DIR
10110         $1 tar cf $TMP/f102.tar $tdir --xattrs
10111 }
10112
10113 cleanup_test102() {
10114         trap 0
10115         rm -f $TMP/f102.tar
10116         rm -rf $DIR/d0.sanity/d102
10117 }
10118
10119 test_102a() {
10120         [ "$UID" != 0 ] && skip "must run as root"
10121         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10122                 skip_env "must have user_xattr"
10123
10124         [ -z "$(which setfattr 2>/dev/null)" ] &&
10125                 skip_env "could not find setfattr"
10126
10127         local testfile=$DIR/$tfile
10128
10129         touch $testfile
10130         echo "set/get xattr..."
10131         setfattr -n trusted.name1 -v value1 $testfile ||
10132                 error "setfattr -n trusted.name1=value1 $testfile failed"
10133         getfattr -n trusted.name1 $testfile 2> /dev/null |
10134           grep "trusted.name1=.value1" ||
10135                 error "$testfile missing trusted.name1=value1"
10136
10137         setfattr -n user.author1 -v author1 $testfile ||
10138                 error "setfattr -n user.author1=author1 $testfile failed"
10139         getfattr -n user.author1 $testfile 2> /dev/null |
10140           grep "user.author1=.author1" ||
10141                 error "$testfile missing trusted.author1=author1"
10142
10143         echo "listxattr..."
10144         setfattr -n trusted.name2 -v value2 $testfile ||
10145                 error "$testfile unable to set trusted.name2"
10146         setfattr -n trusted.name3 -v value3 $testfile ||
10147                 error "$testfile unable to set trusted.name3"
10148         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10149             grep "trusted.name" | wc -l) -eq 3 ] ||
10150                 error "$testfile missing 3 trusted.name xattrs"
10151
10152         setfattr -n user.author2 -v author2 $testfile ||
10153                 error "$testfile unable to set user.author2"
10154         setfattr -n user.author3 -v author3 $testfile ||
10155                 error "$testfile unable to set user.author3"
10156         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10157             grep "user.author" | wc -l) -eq 3 ] ||
10158                 error "$testfile missing 3 user.author xattrs"
10159
10160         echo "remove xattr..."
10161         setfattr -x trusted.name1 $testfile ||
10162                 error "$testfile error deleting trusted.name1"
10163         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10164                 error "$testfile did not delete trusted.name1 xattr"
10165
10166         setfattr -x user.author1 $testfile ||
10167                 error "$testfile error deleting user.author1"
10168         echo "set lustre special xattr ..."
10169         $LFS setstripe -c1 $testfile
10170         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10171                 awk -F "=" '/trusted.lov/ { print $2 }' )
10172         setfattr -n "trusted.lov" -v $lovea $testfile ||
10173                 error "$testfile doesn't ignore setting trusted.lov again"
10174         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10175                 error "$testfile allow setting invalid trusted.lov"
10176         rm -f $testfile
10177 }
10178 run_test 102a "user xattr test =================================="
10179
10180 check_102b_layout() {
10181         local layout="$*"
10182         local testfile=$DIR/$tfile
10183
10184         echo "test layout '$layout'"
10185         $LFS setstripe $layout $testfile || error "setstripe failed"
10186         $LFS getstripe -y $testfile
10187
10188         echo "get/set/list trusted.lov xattr ..." # b=10930
10189         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10190         [[ "$value" =~ "trusted.lov" ]] ||
10191                 error "can't get trusted.lov from $testfile"
10192         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10193                 error "getstripe failed"
10194
10195         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10196
10197         value=$(cut -d= -f2 <<<$value)
10198         # LU-13168: truncated xattr should fail if short lov_user_md header
10199         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10200                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10201         for len in $lens; do
10202                 echo "setfattr $len $testfile.2"
10203                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10204                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10205         done
10206         local stripe_size=$($LFS getstripe -S $testfile.2)
10207         local stripe_count=$($LFS getstripe -c $testfile.2)
10208         [[ $stripe_size -eq 65536 ]] ||
10209                 error "stripe size $stripe_size != 65536"
10210         [[ $stripe_count -eq $stripe_count_orig ]] ||
10211                 error "stripe count $stripe_count != $stripe_count_orig"
10212         rm $testfile $testfile.2
10213 }
10214
10215 test_102b() {
10216         [ -z "$(which setfattr 2>/dev/null)" ] &&
10217                 skip_env "could not find setfattr"
10218         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10219
10220         # check plain layout
10221         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10222
10223         # and also check composite layout
10224         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10225
10226 }
10227 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10228
10229 test_102c() {
10230         [ -z "$(which setfattr 2>/dev/null)" ] &&
10231                 skip_env "could not find setfattr"
10232         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10233
10234         # b10930: get/set/list lustre.lov xattr
10235         echo "get/set/list lustre.lov xattr ..."
10236         test_mkdir $DIR/$tdir
10237         chown $RUNAS_ID $DIR/$tdir
10238         local testfile=$DIR/$tdir/$tfile
10239         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10240                 error "setstripe failed"
10241         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10242                 error "getstripe failed"
10243         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10244         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10245
10246         local testfile2=${testfile}2
10247         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10248                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10249
10250         $RUNAS $MCREATE $testfile2
10251         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10252         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10253         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10254         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10255         [ $stripe_count -eq $STRIPECOUNT ] ||
10256                 error "stripe count $stripe_count != $STRIPECOUNT"
10257 }
10258 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10259
10260 compare_stripe_info1() {
10261         local stripe_index_all_zero=true
10262
10263         for num in 1 2 3 4; do
10264                 for count in $(seq 1 $STRIPE_COUNT); do
10265                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10266                                 local size=$((STRIPE_SIZE * num))
10267                                 local file=file"$num-$offset-$count"
10268                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10269                                 [[ $stripe_size -ne $size ]] &&
10270                                     error "$file: size $stripe_size != $size"
10271                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10272                                 # allow fewer stripes to be created, ORI-601
10273                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10274                                     error "$file: count $stripe_count != $count"
10275                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10276                                 [[ $stripe_index -ne 0 ]] &&
10277                                         stripe_index_all_zero=false
10278                         done
10279                 done
10280         done
10281         $stripe_index_all_zero &&
10282                 error "all files are being extracted starting from OST index 0"
10283         return 0
10284 }
10285
10286 have_xattrs_include() {
10287         tar --help | grep -q xattrs-include &&
10288                 echo --xattrs-include="lustre.*"
10289 }
10290
10291 test_102d() {
10292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10293         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10294
10295         XINC=$(have_xattrs_include)
10296         setup_test102
10297         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10298         cd $DIR/$tdir/$tdir
10299         compare_stripe_info1
10300 }
10301 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10302
10303 test_102f() {
10304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10305         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10306
10307         XINC=$(have_xattrs_include)
10308         setup_test102
10309         test_mkdir $DIR/$tdir.restore
10310         cd $DIR
10311         tar cf - --xattrs $tdir | tar xf - \
10312                 -C $DIR/$tdir.restore --xattrs $XINC
10313         cd $DIR/$tdir.restore/$tdir
10314         compare_stripe_info1
10315 }
10316 run_test 102f "tar copy files, not keep osts"
10317
10318 grow_xattr() {
10319         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10320                 skip "must have user_xattr"
10321         [ -z "$(which setfattr 2>/dev/null)" ] &&
10322                 skip_env "could not find setfattr"
10323         [ -z "$(which getfattr 2>/dev/null)" ] &&
10324                 skip_env "could not find getfattr"
10325
10326         local xsize=${1:-1024}  # in bytes
10327         local file=$DIR/$tfile
10328         local value="$(generate_string $xsize)"
10329         local xbig=trusted.big
10330         local toobig=$2
10331
10332         touch $file
10333         log "save $xbig on $file"
10334         if [ -z "$toobig" ]
10335         then
10336                 setfattr -n $xbig -v $value $file ||
10337                         error "saving $xbig on $file failed"
10338         else
10339                 setfattr -n $xbig -v $value $file &&
10340                         error "saving $xbig on $file succeeded"
10341                 return 0
10342         fi
10343
10344         local orig=$(get_xattr_value $xbig $file)
10345         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10346
10347         local xsml=trusted.sml
10348         log "save $xsml on $file"
10349         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10350
10351         local new=$(get_xattr_value $xbig $file)
10352         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10353
10354         log "grow $xsml on $file"
10355         setfattr -n $xsml -v "$value" $file ||
10356                 error "growing $xsml on $file failed"
10357
10358         new=$(get_xattr_value $xbig $file)
10359         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10360         log "$xbig still valid after growing $xsml"
10361
10362         rm -f $file
10363 }
10364
10365 test_102h() { # bug 15777
10366         grow_xattr 1024
10367 }
10368 run_test 102h "grow xattr from inside inode to external block"
10369
10370 test_102ha() {
10371         large_xattr_enabled || skip_env "ea_inode feature disabled"
10372
10373         echo "setting xattr of max xattr size: $(max_xattr_size)"
10374         grow_xattr $(max_xattr_size)
10375
10376         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10377         echo "This should fail:"
10378         grow_xattr $(($(max_xattr_size) + 10)) 1
10379 }
10380 run_test 102ha "grow xattr from inside inode to external inode"
10381
10382 test_102i() { # bug 17038
10383         [ -z "$(which getfattr 2>/dev/null)" ] &&
10384                 skip "could not find getfattr"
10385
10386         touch $DIR/$tfile
10387         ln -s $DIR/$tfile $DIR/${tfile}link
10388         getfattr -n trusted.lov $DIR/$tfile ||
10389                 error "lgetxattr on $DIR/$tfile failed"
10390         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10391                 grep -i "no such attr" ||
10392                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10393         rm -f $DIR/$tfile $DIR/${tfile}link
10394 }
10395 run_test 102i "lgetxattr test on symbolic link ============"
10396
10397 test_102j() {
10398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10399         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10400
10401         XINC=$(have_xattrs_include)
10402         setup_test102 "$RUNAS"
10403         chown $RUNAS_ID $DIR/$tdir
10404         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10405         cd $DIR/$tdir/$tdir
10406         compare_stripe_info1 "$RUNAS"
10407 }
10408 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10409
10410 test_102k() {
10411         [ -z "$(which setfattr 2>/dev/null)" ] &&
10412                 skip "could not find setfattr"
10413
10414         touch $DIR/$tfile
10415         # b22187 just check that does not crash for regular file.
10416         setfattr -n trusted.lov $DIR/$tfile
10417         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10418         local test_kdir=$DIR/$tdir
10419         test_mkdir $test_kdir
10420         local default_size=$($LFS getstripe -S $test_kdir)
10421         local default_count=$($LFS getstripe -c $test_kdir)
10422         local default_offset=$($LFS getstripe -i $test_kdir)
10423         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10424                 error 'dir setstripe failed'
10425         setfattr -n trusted.lov $test_kdir
10426         local stripe_size=$($LFS getstripe -S $test_kdir)
10427         local stripe_count=$($LFS getstripe -c $test_kdir)
10428         local stripe_offset=$($LFS getstripe -i $test_kdir)
10429         [ $stripe_size -eq $default_size ] ||
10430                 error "stripe size $stripe_size != $default_size"
10431         [ $stripe_count -eq $default_count ] ||
10432                 error "stripe count $stripe_count != $default_count"
10433         [ $stripe_offset -eq $default_offset ] ||
10434                 error "stripe offset $stripe_offset != $default_offset"
10435         rm -rf $DIR/$tfile $test_kdir
10436 }
10437 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10438
10439 test_102l() {
10440         [ -z "$(which getfattr 2>/dev/null)" ] &&
10441                 skip "could not find getfattr"
10442
10443         # LU-532 trusted. xattr is invisible to non-root
10444         local testfile=$DIR/$tfile
10445
10446         touch $testfile
10447
10448         echo "listxattr as user..."
10449         chown $RUNAS_ID $testfile
10450         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10451             grep -q "trusted" &&
10452                 error "$testfile trusted xattrs are user visible"
10453
10454         return 0;
10455 }
10456 run_test 102l "listxattr size test =================================="
10457
10458 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10459         local path=$DIR/$tfile
10460         touch $path
10461
10462         listxattr_size_check $path || error "listattr_size_check $path failed"
10463 }
10464 run_test 102m "Ensure listxattr fails on small bufffer ========"
10465
10466 cleanup_test102
10467
10468 getxattr() { # getxattr path name
10469         # Return the base64 encoding of the value of xattr name on path.
10470         local path=$1
10471         local name=$2
10472
10473         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10474         # file: $path
10475         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10476         #
10477         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10478
10479         getfattr --absolute-names --encoding=base64 --name=$name $path |
10480                 awk -F= -v name=$name '$1 == name {
10481                         print substr($0, index($0, "=") + 1);
10482         }'
10483 }
10484
10485 test_102n() { # LU-4101 mdt: protect internal xattrs
10486         [ -z "$(which setfattr 2>/dev/null)" ] &&
10487                 skip "could not find setfattr"
10488         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10489         then
10490                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10491         fi
10492
10493         local file0=$DIR/$tfile.0
10494         local file1=$DIR/$tfile.1
10495         local xattr0=$TMP/$tfile.0
10496         local xattr1=$TMP/$tfile.1
10497         local namelist="lov lma lmv link fid version som hsm"
10498         local name
10499         local value
10500
10501         rm -rf $file0 $file1 $xattr0 $xattr1
10502         touch $file0 $file1
10503
10504         # Get 'before' xattrs of $file1.
10505         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10506
10507         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10508                 namelist+=" lfsck_namespace"
10509         for name in $namelist; do
10510                 # Try to copy xattr from $file0 to $file1.
10511                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10512
10513                 setfattr --name=trusted.$name --value="$value" $file1 ||
10514                         error "setxattr 'trusted.$name' failed"
10515
10516                 # Try to set a garbage xattr.
10517                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10518
10519                 if [[ x$name == "xlov" ]]; then
10520                         setfattr --name=trusted.lov --value="$value" $file1 &&
10521                         error "setxattr invalid 'trusted.lov' success"
10522                 else
10523                         setfattr --name=trusted.$name --value="$value" $file1 ||
10524                                 error "setxattr invalid 'trusted.$name' failed"
10525                 fi
10526
10527                 # Try to remove the xattr from $file1. We don't care if this
10528                 # appears to succeed or fail, we just don't want there to be
10529                 # any changes or crashes.
10530                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10531         done
10532
10533         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10534         then
10535                 name="lfsck_ns"
10536                 # Try to copy xattr from $file0 to $file1.
10537                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10538
10539                 setfattr --name=trusted.$name --value="$value" $file1 ||
10540                         error "setxattr 'trusted.$name' failed"
10541
10542                 # Try to set a garbage xattr.
10543                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10544
10545                 setfattr --name=trusted.$name --value="$value" $file1 ||
10546                         error "setxattr 'trusted.$name' failed"
10547
10548                 # Try to remove the xattr from $file1. We don't care if this
10549                 # appears to succeed or fail, we just don't want there to be
10550                 # any changes or crashes.
10551                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10552         fi
10553
10554         # Get 'after' xattrs of file1.
10555         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10556
10557         if ! diff $xattr0 $xattr1; then
10558                 error "before and after xattrs of '$file1' differ"
10559         fi
10560
10561         rm -rf $file0 $file1 $xattr0 $xattr1
10562
10563         return 0
10564 }
10565 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10566
10567 test_102p() { # LU-4703 setxattr did not check ownership
10568         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10569                 skip "MDS needs to be at least 2.5.56"
10570
10571         local testfile=$DIR/$tfile
10572
10573         touch $testfile
10574
10575         echo "setfacl as user..."
10576         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10577         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10578
10579         echo "setfattr as user..."
10580         setfacl -m "u:$RUNAS_ID:---" $testfile
10581         $RUNAS setfattr -x system.posix_acl_access $testfile
10582         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10583 }
10584 run_test 102p "check setxattr(2) correctly fails without permission"
10585
10586 test_102q() {
10587         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10588                 skip "MDS needs to be at least 2.6.92"
10589
10590         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10591 }
10592 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10593
10594 test_102r() {
10595         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10596                 skip "MDS needs to be at least 2.6.93"
10597
10598         touch $DIR/$tfile || error "touch"
10599         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10600         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10601         rm $DIR/$tfile || error "rm"
10602
10603         #normal directory
10604         mkdir -p $DIR/$tdir || error "mkdir"
10605         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10606         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10607         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10608                 error "$testfile error deleting user.author1"
10609         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10610                 grep "user.$(basename $tdir)" &&
10611                 error "$tdir did not delete user.$(basename $tdir)"
10612         rmdir $DIR/$tdir || error "rmdir"
10613
10614         #striped directory
10615         test_mkdir $DIR/$tdir
10616         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10617         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10618         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10619                 error "$testfile error deleting user.author1"
10620         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10621                 grep "user.$(basename $tdir)" &&
10622                 error "$tdir did not delete user.$(basename $tdir)"
10623         rmdir $DIR/$tdir || error "rm striped dir"
10624 }
10625 run_test 102r "set EAs with empty values"
10626
10627 test_102s() {
10628         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10629                 skip "MDS needs to be at least 2.11.52"
10630
10631         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10632
10633         save_lustre_params client "llite.*.xattr_cache" > $save
10634
10635         for cache in 0 1; do
10636                 lctl set_param llite.*.xattr_cache=$cache
10637
10638                 rm -f $DIR/$tfile
10639                 touch $DIR/$tfile || error "touch"
10640                 for prefix in lustre security system trusted user; do
10641                         # Note getxattr() may fail with 'Operation not
10642                         # supported' or 'No such attribute' depending
10643                         # on prefix and cache.
10644                         getfattr -n $prefix.n102s $DIR/$tfile &&
10645                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10646                 done
10647         done
10648
10649         restore_lustre_params < $save
10650 }
10651 run_test 102s "getting nonexistent xattrs should fail"
10652
10653 test_102t() {
10654         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10655                 skip "MDS needs to be at least 2.11.52"
10656
10657         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10658
10659         save_lustre_params client "llite.*.xattr_cache" > $save
10660
10661         for cache in 0 1; do
10662                 lctl set_param llite.*.xattr_cache=$cache
10663
10664                 for buf_size in 0 256; do
10665                         rm -f $DIR/$tfile
10666                         touch $DIR/$tfile || error "touch"
10667                         setfattr -n user.multiop $DIR/$tfile
10668                         $MULTIOP $DIR/$tfile oa$buf_size ||
10669                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10670                 done
10671         done
10672
10673         restore_lustre_params < $save
10674 }
10675 run_test 102t "zero length xattr values handled correctly"
10676
10677 run_acl_subtest()
10678 {
10679     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10680     return $?
10681 }
10682
10683 test_103a() {
10684         [ "$UID" != 0 ] && skip "must run as root"
10685         $GSS && skip_env "could not run under gss"
10686         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10687                 skip_env "must have acl enabled"
10688         [ -z "$(which setfacl 2>/dev/null)" ] &&
10689                 skip_env "could not find setfacl"
10690         remote_mds_nodsh && skip "remote MDS with nodsh"
10691
10692         gpasswd -a daemon bin                           # LU-5641
10693         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10694
10695         declare -a identity_old
10696
10697         for num in $(seq $MDSCOUNT); do
10698                 switch_identity $num true || identity_old[$num]=$?
10699         done
10700
10701         SAVE_UMASK=$(umask)
10702         umask 0022
10703         mkdir -p $DIR/$tdir
10704         cd $DIR/$tdir
10705
10706         echo "performing cp ..."
10707         run_acl_subtest cp || error "run_acl_subtest cp failed"
10708         echo "performing getfacl-noacl..."
10709         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10710         echo "performing misc..."
10711         run_acl_subtest misc || error  "misc test failed"
10712         echo "performing permissions..."
10713         run_acl_subtest permissions || error "permissions failed"
10714         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10715         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10716                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10717                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10718         then
10719                 echo "performing permissions xattr..."
10720                 run_acl_subtest permissions_xattr ||
10721                         error "permissions_xattr failed"
10722         fi
10723         echo "performing setfacl..."
10724         run_acl_subtest setfacl || error  "setfacl test failed"
10725
10726         # inheritance test got from HP
10727         echo "performing inheritance..."
10728         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10729         chmod +x make-tree || error "chmod +x failed"
10730         run_acl_subtest inheritance || error "inheritance test failed"
10731         rm -f make-tree
10732
10733         echo "LU-974 ignore umask when acl is enabled..."
10734         run_acl_subtest 974 || error "LU-974 umask test failed"
10735         if [ $MDSCOUNT -ge 2 ]; then
10736                 run_acl_subtest 974_remote ||
10737                         error "LU-974 umask test failed under remote dir"
10738         fi
10739
10740         echo "LU-2561 newly created file is same size as directory..."
10741         if [ "$mds1_FSTYPE" != "zfs" ]; then
10742                 run_acl_subtest 2561 || error "LU-2561 test failed"
10743         else
10744                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10745         fi
10746
10747         run_acl_subtest 4924 || error "LU-4924 test failed"
10748
10749         cd $SAVE_PWD
10750         umask $SAVE_UMASK
10751
10752         for num in $(seq $MDSCOUNT); do
10753                 if [ "${identity_old[$num]}" = 1 ]; then
10754                         switch_identity $num false || identity_old[$num]=$?
10755                 fi
10756         done
10757 }
10758 run_test 103a "acl test"
10759
10760 test_103b() {
10761         declare -a pids
10762         local U
10763
10764         for U in {0..511}; do
10765                 {
10766                 local O=$(printf "%04o" $U)
10767
10768                 umask $(printf "%04o" $((511 ^ $O)))
10769                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10770                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10771
10772                 (( $S == ($O & 0666) )) ||
10773                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10774
10775                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10776                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10777                 (( $S == ($O & 0666) )) ||
10778                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10779
10780                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10781                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10782                 (( $S == ($O & 0666) )) ||
10783                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10784                 rm -f $DIR/$tfile.[smp]$0
10785                 } &
10786                 local pid=$!
10787
10788                 # limit the concurrently running threads to 64. LU-11878
10789                 local idx=$((U % 64))
10790                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10791                 pids[idx]=$pid
10792         done
10793         wait
10794 }
10795 run_test 103b "umask lfs setstripe"
10796
10797 test_103c() {
10798         mkdir -p $DIR/$tdir
10799         cp -rp $DIR/$tdir $DIR/$tdir.bak
10800
10801         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10802                 error "$DIR/$tdir shouldn't contain default ACL"
10803         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10804                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10805         true
10806 }
10807 run_test 103c "'cp -rp' won't set empty acl"
10808
10809 test_103e() {
10810         local numacl
10811         local fileacl
10812         local saved_debug=$($LCTL get_param -n debug)
10813
10814         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
10815                 skip "MDS needs to be at least 2.14.0"
10816
10817         large_xattr_enabled || skip_env "ea_inode feature disabled"
10818
10819         mkdir -p $DIR/$tdir
10820         # add big LOV EA to cause reply buffer overflow earlier
10821         $LFS setstripe -C 1000 $DIR/$tdir
10822         lctl set_param mdc.*-mdc*.stats=clear
10823
10824         $LCTL set_param debug=0
10825         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
10826         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
10827
10828         # add a large number of default ACLs (expect 8000+ for 2.13+)
10829         for U in {2..7000}; do
10830                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
10831                         error "Able to add just $U default ACLs"
10832         done
10833         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10834         echo "$numacl default ACLs created"
10835
10836         stat $DIR/$tdir || error "Cannot stat directory"
10837         # check file creation
10838         touch $DIR/$tdir/$tfile ||
10839                 error "failed to create $tfile with $numacl default ACLs"
10840         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
10841         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10842         echo "$fileacl ACLs were inherited"
10843         (( $fileacl == $numacl )) ||
10844                 error "Not all default ACLs were inherited: $numacl != $fileacl"
10845         # check that new ACLs creation adds new ACLs to inherited ACLs
10846         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
10847                 error "Cannot set new ACL"
10848         numacl=$((numacl + 1))
10849         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10850         (( $fileacl == $numacl )) ||
10851                 error "failed to add new ACL: $fileacl != $numacl as expected"
10852         # adds more ACLs to a file to reach their maximum at 8000+
10853         numacl=0
10854         for U in {20000..25000}; do
10855                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
10856                 numacl=$((numacl + 1))
10857         done
10858         echo "Added $numacl more ACLs to the file"
10859         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10860         echo "Total $fileacl ACLs in file"
10861         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
10862         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
10863         rmdir $DIR/$tdir || error "Cannot remove directory"
10864 }
10865 run_test 103e "inheritance of big amount of default ACLs"
10866
10867 test_104a() {
10868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10869
10870         touch $DIR/$tfile
10871         lfs df || error "lfs df failed"
10872         lfs df -ih || error "lfs df -ih failed"
10873         lfs df -h $DIR || error "lfs df -h $DIR failed"
10874         lfs df -i $DIR || error "lfs df -i $DIR failed"
10875         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10876         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10877
10878         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10879         lctl --device %$OSC deactivate
10880         lfs df || error "lfs df with deactivated OSC failed"
10881         lctl --device %$OSC activate
10882         # wait the osc back to normal
10883         wait_osc_import_ready client ost
10884
10885         lfs df || error "lfs df with reactivated OSC failed"
10886         rm -f $DIR/$tfile
10887 }
10888 run_test 104a "lfs df [-ih] [path] test ========================="
10889
10890 test_104b() {
10891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10892         [ $RUNAS_ID -eq $UID ] &&
10893                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10894
10895         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10896                         grep "Permission denied" | wc -l)))
10897         if [ $denied_cnt -ne 0 ]; then
10898                 error "lfs check servers test failed"
10899         fi
10900 }
10901 run_test 104b "$RUNAS lfs check servers test ===================="
10902
10903 test_105a() {
10904         # doesn't work on 2.4 kernels
10905         touch $DIR/$tfile
10906         if $(flock_is_enabled); then
10907                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10908         else
10909                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10910         fi
10911         rm -f $DIR/$tfile
10912 }
10913 run_test 105a "flock when mounted without -o flock test ========"
10914
10915 test_105b() {
10916         touch $DIR/$tfile
10917         if $(flock_is_enabled); then
10918                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10919         else
10920                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10921         fi
10922         rm -f $DIR/$tfile
10923 }
10924 run_test 105b "fcntl when mounted without -o flock test ========"
10925
10926 test_105c() {
10927         touch $DIR/$tfile
10928         if $(flock_is_enabled); then
10929                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10930         else
10931                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10932         fi
10933         rm -f $DIR/$tfile
10934 }
10935 run_test 105c "lockf when mounted without -o flock test"
10936
10937 test_105d() { # bug 15924
10938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10939
10940         test_mkdir $DIR/$tdir
10941         flock_is_enabled || skip_env "mount w/o flock enabled"
10942         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10943         $LCTL set_param fail_loc=0x80000315
10944         flocks_test 2 $DIR/$tdir
10945 }
10946 run_test 105d "flock race (should not freeze) ========"
10947
10948 test_105e() { # bug 22660 && 22040
10949         flock_is_enabled || skip_env "mount w/o flock enabled"
10950
10951         touch $DIR/$tfile
10952         flocks_test 3 $DIR/$tfile
10953 }
10954 run_test 105e "Two conflicting flocks from same process"
10955
10956 test_106() { #bug 10921
10957         test_mkdir $DIR/$tdir
10958         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10959         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10960 }
10961 run_test 106 "attempt exec of dir followed by chown of that dir"
10962
10963 test_107() {
10964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10965
10966         CDIR=`pwd`
10967         local file=core
10968
10969         cd $DIR
10970         rm -f $file
10971
10972         local save_pattern=$(sysctl -n kernel.core_pattern)
10973         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10974         sysctl -w kernel.core_pattern=$file
10975         sysctl -w kernel.core_uses_pid=0
10976
10977         ulimit -c unlimited
10978         sleep 60 &
10979         SLEEPPID=$!
10980
10981         sleep 1
10982
10983         kill -s 11 $SLEEPPID
10984         wait $SLEEPPID
10985         if [ -e $file ]; then
10986                 size=`stat -c%s $file`
10987                 [ $size -eq 0 ] && error "Fail to create core file $file"
10988         else
10989                 error "Fail to create core file $file"
10990         fi
10991         rm -f $file
10992         sysctl -w kernel.core_pattern=$save_pattern
10993         sysctl -w kernel.core_uses_pid=$save_uses_pid
10994         cd $CDIR
10995 }
10996 run_test 107 "Coredump on SIG"
10997
10998 test_110() {
10999         test_mkdir $DIR/$tdir
11000         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11001         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11002                 error "mkdir with 256 char should fail, but did not"
11003         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11004                 error "create with 255 char failed"
11005         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11006                 error "create with 256 char should fail, but did not"
11007
11008         ls -l $DIR/$tdir
11009         rm -rf $DIR/$tdir
11010 }
11011 run_test 110 "filename length checking"
11012
11013 #
11014 # Purpose: To verify dynamic thread (OSS) creation.
11015 #
11016 test_115() {
11017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11018         remote_ost_nodsh && skip "remote OST with nodsh"
11019
11020         # Lustre does not stop service threads once they are started.
11021         # Reset number of running threads to default.
11022         stopall
11023         setupall
11024
11025         local OSTIO_pre
11026         local save_params="$TMP/sanity-$TESTNAME.parameters"
11027
11028         # Get ll_ost_io count before I/O
11029         OSTIO_pre=$(do_facet ost1 \
11030                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11031         # Exit if lustre is not running (ll_ost_io not running).
11032         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11033
11034         echo "Starting with $OSTIO_pre threads"
11035         local thread_max=$((OSTIO_pre * 2))
11036         local rpc_in_flight=$((thread_max * 2))
11037         # Number of I/O Process proposed to be started.
11038         local nfiles
11039         local facets=$(get_facets OST)
11040
11041         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11042         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11043
11044         # Set in_flight to $rpc_in_flight
11045         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11046                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11047         nfiles=${rpc_in_flight}
11048         # Set ost thread_max to $thread_max
11049         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11050
11051         # 5 Minutes should be sufficient for max number of OSS
11052         # threads(thread_max) to be created.
11053         local timeout=300
11054
11055         # Start I/O.
11056         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11057         test_mkdir $DIR/$tdir
11058         for i in $(seq $nfiles); do
11059                 local file=$DIR/$tdir/${tfile}-$i
11060                 $LFS setstripe -c -1 -i 0 $file
11061                 ($WTL $file $timeout)&
11062         done
11063
11064         # I/O Started - Wait for thread_started to reach thread_max or report
11065         # error if thread_started is more than thread_max.
11066         echo "Waiting for thread_started to reach thread_max"
11067         local thread_started=0
11068         local end_time=$((SECONDS + timeout))
11069
11070         while [ $SECONDS -le $end_time ] ; do
11071                 echo -n "."
11072                 # Get ost i/o thread_started count.
11073                 thread_started=$(do_facet ost1 \
11074                         "$LCTL get_param \
11075                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11076                 # Break out if thread_started is equal/greater than thread_max
11077                 if [[ $thread_started -ge $thread_max ]]; then
11078                         echo ll_ost_io thread_started $thread_started, \
11079                                 equal/greater than thread_max $thread_max
11080                         break
11081                 fi
11082                 sleep 1
11083         done
11084
11085         # Cleanup - We have the numbers, Kill i/o jobs if running.
11086         jobcount=($(jobs -p))
11087         for i in $(seq 0 $((${#jobcount[@]}-1)))
11088         do
11089                 kill -9 ${jobcount[$i]}
11090                 if [ $? -ne 0 ] ; then
11091                         echo Warning: \
11092                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11093                 fi
11094         done
11095
11096         # Cleanup files left by WTL binary.
11097         for i in $(seq $nfiles); do
11098                 local file=$DIR/$tdir/${tfile}-$i
11099                 rm -rf $file
11100                 if [ $? -ne 0 ] ; then
11101                         echo "Warning: Failed to delete file $file"
11102                 fi
11103         done
11104
11105         restore_lustre_params <$save_params
11106         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11107
11108         # Error out if no new thread has started or Thread started is greater
11109         # than thread max.
11110         if [[ $thread_started -le $OSTIO_pre ||
11111                         $thread_started -gt $thread_max ]]; then
11112                 error "ll_ost_io: thread_started $thread_started" \
11113                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11114                       "No new thread started or thread started greater " \
11115                       "than thread_max."
11116         fi
11117 }
11118 run_test 115 "verify dynamic thread creation===================="
11119
11120 free_min_max () {
11121         wait_delete_completed
11122         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11123         echo "OST kbytes available: ${AVAIL[@]}"
11124         MAXV=${AVAIL[0]}
11125         MAXI=0
11126         MINV=${AVAIL[0]}
11127         MINI=0
11128         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11129                 #echo OST $i: ${AVAIL[i]}kb
11130                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11131                         MAXV=${AVAIL[i]}
11132                         MAXI=$i
11133                 fi
11134                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11135                         MINV=${AVAIL[i]}
11136                         MINI=$i
11137                 fi
11138         done
11139         echo "Min free space: OST $MINI: $MINV"
11140         echo "Max free space: OST $MAXI: $MAXV"
11141 }
11142
11143 test_116a() { # was previously test_116()
11144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11145         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11146         remote_mds_nodsh && skip "remote MDS with nodsh"
11147
11148         echo -n "Free space priority "
11149         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11150                 head -n1
11151         declare -a AVAIL
11152         free_min_max
11153
11154         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11155         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11156         trap simple_cleanup_common EXIT
11157
11158         # Check if we need to generate uneven OSTs
11159         test_mkdir -p $DIR/$tdir/OST${MINI}
11160         local FILL=$((MINV / 4))
11161         local DIFF=$((MAXV - MINV))
11162         local DIFF2=$((DIFF * 100 / MINV))
11163
11164         local threshold=$(do_facet $SINGLEMDS \
11165                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11166         threshold=${threshold%%%}
11167         echo -n "Check for uneven OSTs: "
11168         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11169
11170         if [[ $DIFF2 -gt $threshold ]]; then
11171                 echo "ok"
11172                 echo "Don't need to fill OST$MINI"
11173         else
11174                 # generate uneven OSTs. Write 2% over the QOS threshold value
11175                 echo "no"
11176                 DIFF=$((threshold - DIFF2 + 2))
11177                 DIFF2=$((MINV * DIFF / 100))
11178                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11179                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11180                         error "setstripe failed"
11181                 DIFF=$((DIFF2 / 2048))
11182                 i=0
11183                 while [ $i -lt $DIFF ]; do
11184                         i=$((i + 1))
11185                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11186                                 bs=2M count=1 2>/dev/null
11187                         echo -n .
11188                 done
11189                 echo .
11190                 sync
11191                 sleep_maxage
11192                 free_min_max
11193         fi
11194
11195         DIFF=$((MAXV - MINV))
11196         DIFF2=$((DIFF * 100 / MINV))
11197         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11198         if [ $DIFF2 -gt $threshold ]; then
11199                 echo "ok"
11200         else
11201                 echo "failed - QOS mode won't be used"
11202                 simple_cleanup_common
11203                 skip "QOS imbalance criteria not met"
11204         fi
11205
11206         MINI1=$MINI
11207         MINV1=$MINV
11208         MAXI1=$MAXI
11209         MAXV1=$MAXV
11210
11211         # now fill using QOS
11212         $LFS setstripe -c 1 $DIR/$tdir
11213         FILL=$((FILL / 200))
11214         if [ $FILL -gt 600 ]; then
11215                 FILL=600
11216         fi
11217         echo "writing $FILL files to QOS-assigned OSTs"
11218         i=0
11219         while [ $i -lt $FILL ]; do
11220                 i=$((i + 1))
11221                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11222                         count=1 2>/dev/null
11223                 echo -n .
11224         done
11225         echo "wrote $i 200k files"
11226         sync
11227         sleep_maxage
11228
11229         echo "Note: free space may not be updated, so measurements might be off"
11230         free_min_max
11231         DIFF2=$((MAXV - MINV))
11232         echo "free space delta: orig $DIFF final $DIFF2"
11233         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11234         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11235         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11236         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11237         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11238         if [[ $DIFF -gt 0 ]]; then
11239                 FILL=$((DIFF2 * 100 / DIFF - 100))
11240                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11241         fi
11242
11243         # Figure out which files were written where
11244         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11245                awk '/'$MINI1': / {print $2; exit}')
11246         echo $UUID
11247         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11248         echo "$MINC files created on smaller OST $MINI1"
11249         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11250                awk '/'$MAXI1': / {print $2; exit}')
11251         echo $UUID
11252         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11253         echo "$MAXC files created on larger OST $MAXI1"
11254         if [[ $MINC -gt 0 ]]; then
11255                 FILL=$((MAXC * 100 / MINC - 100))
11256                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11257         fi
11258         [[ $MAXC -gt $MINC ]] ||
11259                 error_ignore LU-9 "stripe QOS didn't balance free space"
11260         simple_cleanup_common
11261 }
11262 run_test 116a "stripe QOS: free space balance ==================="
11263
11264 test_116b() { # LU-2093
11265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11266         remote_mds_nodsh && skip "remote MDS with nodsh"
11267
11268 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11269         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11270                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11271         [ -z "$old_rr" ] && skip "no QOS"
11272         do_facet $SINGLEMDS lctl set_param \
11273                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11274         mkdir -p $DIR/$tdir
11275         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11276         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11277         do_facet $SINGLEMDS lctl set_param fail_loc=0
11278         rm -rf $DIR/$tdir
11279         do_facet $SINGLEMDS lctl set_param \
11280                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11281 }
11282 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11283
11284 test_117() # bug 10891
11285 {
11286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11287
11288         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11289         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11290         lctl set_param fail_loc=0x21e
11291         > $DIR/$tfile || error "truncate failed"
11292         lctl set_param fail_loc=0
11293         echo "Truncate succeeded."
11294         rm -f $DIR/$tfile
11295 }
11296 run_test 117 "verify osd extend =========="
11297
11298 NO_SLOW_RESENDCOUNT=4
11299 export OLD_RESENDCOUNT=""
11300 set_resend_count () {
11301         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11302         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11303         lctl set_param -n $PROC_RESENDCOUNT $1
11304         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11305 }
11306
11307 # for reduce test_118* time (b=14842)
11308 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11309
11310 # Reset async IO behavior after error case
11311 reset_async() {
11312         FILE=$DIR/reset_async
11313
11314         # Ensure all OSCs are cleared
11315         $LFS setstripe -c -1 $FILE
11316         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11317         sync
11318         rm $FILE
11319 }
11320
11321 test_118a() #bug 11710
11322 {
11323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11324
11325         reset_async
11326
11327         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11328         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11329         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11330
11331         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11332                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11333                 return 1;
11334         fi
11335         rm -f $DIR/$tfile
11336 }
11337 run_test 118a "verify O_SYNC works =========="
11338
11339 test_118b()
11340 {
11341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11342         remote_ost_nodsh && skip "remote OST with nodsh"
11343
11344         reset_async
11345
11346         #define OBD_FAIL_SRV_ENOENT 0x217
11347         set_nodes_failloc "$(osts_nodes)" 0x217
11348         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11349         RC=$?
11350         set_nodes_failloc "$(osts_nodes)" 0
11351         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11352         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11353                     grep -c writeback)
11354
11355         if [[ $RC -eq 0 ]]; then
11356                 error "Must return error due to dropped pages, rc=$RC"
11357                 return 1;
11358         fi
11359
11360         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11361                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11362                 return 1;
11363         fi
11364
11365         echo "Dirty pages not leaked on ENOENT"
11366
11367         # Due to the above error the OSC will issue all RPCs syncronously
11368         # until a subsequent RPC completes successfully without error.
11369         $MULTIOP $DIR/$tfile Ow4096yc
11370         rm -f $DIR/$tfile
11371
11372         return 0
11373 }
11374 run_test 118b "Reclaim dirty pages on fatal error =========="
11375
11376 test_118c()
11377 {
11378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11379
11380         # for 118c, restore the original resend count, LU-1940
11381         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11382                                 set_resend_count $OLD_RESENDCOUNT
11383         remote_ost_nodsh && skip "remote OST with nodsh"
11384
11385         reset_async
11386
11387         #define OBD_FAIL_OST_EROFS               0x216
11388         set_nodes_failloc "$(osts_nodes)" 0x216
11389
11390         # multiop should block due to fsync until pages are written
11391         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11392         MULTIPID=$!
11393         sleep 1
11394
11395         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11396                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11397         fi
11398
11399         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11400                     grep -c writeback)
11401         if [[ $WRITEBACK -eq 0 ]]; then
11402                 error "No page in writeback, writeback=$WRITEBACK"
11403         fi
11404
11405         set_nodes_failloc "$(osts_nodes)" 0
11406         wait $MULTIPID
11407         RC=$?
11408         if [[ $RC -ne 0 ]]; then
11409                 error "Multiop fsync failed, rc=$RC"
11410         fi
11411
11412         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11413         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11414                     grep -c writeback)
11415         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11416                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11417         fi
11418
11419         rm -f $DIR/$tfile
11420         echo "Dirty pages flushed via fsync on EROFS"
11421         return 0
11422 }
11423 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11424
11425 # continue to use small resend count to reduce test_118* time (b=14842)
11426 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11427
11428 test_118d()
11429 {
11430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11431         remote_ost_nodsh && skip "remote OST with nodsh"
11432
11433         reset_async
11434
11435         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11436         set_nodes_failloc "$(osts_nodes)" 0x214
11437         # multiop should block due to fsync until pages are written
11438         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11439         MULTIPID=$!
11440         sleep 1
11441
11442         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11443                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11444         fi
11445
11446         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11447                     grep -c writeback)
11448         if [[ $WRITEBACK -eq 0 ]]; then
11449                 error "No page in writeback, writeback=$WRITEBACK"
11450         fi
11451
11452         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11453         set_nodes_failloc "$(osts_nodes)" 0
11454
11455         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11456         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11457                     grep -c writeback)
11458         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11459                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11460         fi
11461
11462         rm -f $DIR/$tfile
11463         echo "Dirty pages gaurenteed flushed via fsync"
11464         return 0
11465 }
11466 run_test 118d "Fsync validation inject a delay of the bulk =========="
11467
11468 test_118f() {
11469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11470
11471         reset_async
11472
11473         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11474         lctl set_param fail_loc=0x8000040a
11475
11476         # Should simulate EINVAL error which is fatal
11477         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11478         RC=$?
11479         if [[ $RC -eq 0 ]]; then
11480                 error "Must return error due to dropped pages, rc=$RC"
11481         fi
11482
11483         lctl set_param fail_loc=0x0
11484
11485         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11486         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11487         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11488                     grep -c writeback)
11489         if [[ $LOCKED -ne 0 ]]; then
11490                 error "Locked pages remain in cache, locked=$LOCKED"
11491         fi
11492
11493         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11494                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11495         fi
11496
11497         rm -f $DIR/$tfile
11498         echo "No pages locked after fsync"
11499
11500         reset_async
11501         return 0
11502 }
11503 run_test 118f "Simulate unrecoverable OSC side error =========="
11504
11505 test_118g() {
11506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11507
11508         reset_async
11509
11510         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11511         lctl set_param fail_loc=0x406
11512
11513         # simulate local -ENOMEM
11514         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11515         RC=$?
11516
11517         lctl set_param fail_loc=0
11518         if [[ $RC -eq 0 ]]; then
11519                 error "Must return error due to dropped pages, rc=$RC"
11520         fi
11521
11522         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11523         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11524         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11525                         grep -c writeback)
11526         if [[ $LOCKED -ne 0 ]]; then
11527                 error "Locked pages remain in cache, locked=$LOCKED"
11528         fi
11529
11530         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11531                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11532         fi
11533
11534         rm -f $DIR/$tfile
11535         echo "No pages locked after fsync"
11536
11537         reset_async
11538         return 0
11539 }
11540 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11541
11542 test_118h() {
11543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11544         remote_ost_nodsh && skip "remote OST with nodsh"
11545
11546         reset_async
11547
11548         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11549         set_nodes_failloc "$(osts_nodes)" 0x20e
11550         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11551         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11552         RC=$?
11553
11554         set_nodes_failloc "$(osts_nodes)" 0
11555         if [[ $RC -eq 0 ]]; then
11556                 error "Must return error due to dropped pages, rc=$RC"
11557         fi
11558
11559         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11560         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11561         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11562                     grep -c writeback)
11563         if [[ $LOCKED -ne 0 ]]; then
11564                 error "Locked pages remain in cache, locked=$LOCKED"
11565         fi
11566
11567         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11568                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11569         fi
11570
11571         rm -f $DIR/$tfile
11572         echo "No pages locked after fsync"
11573
11574         return 0
11575 }
11576 run_test 118h "Verify timeout in handling recoverables errors  =========="
11577
11578 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11579
11580 test_118i() {
11581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11582         remote_ost_nodsh && skip "remote OST with nodsh"
11583
11584         reset_async
11585
11586         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11587         set_nodes_failloc "$(osts_nodes)" 0x20e
11588
11589         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11590         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11591         PID=$!
11592         sleep 5
11593         set_nodes_failloc "$(osts_nodes)" 0
11594
11595         wait $PID
11596         RC=$?
11597         if [[ $RC -ne 0 ]]; then
11598                 error "got error, but should be not, rc=$RC"
11599         fi
11600
11601         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11602         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11603         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11604         if [[ $LOCKED -ne 0 ]]; then
11605                 error "Locked pages remain in cache, locked=$LOCKED"
11606         fi
11607
11608         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11609                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11610         fi
11611
11612         rm -f $DIR/$tfile
11613         echo "No pages locked after fsync"
11614
11615         return 0
11616 }
11617 run_test 118i "Fix error before timeout in recoverable error  =========="
11618
11619 [ "$SLOW" = "no" ] && set_resend_count 4
11620
11621 test_118j() {
11622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11623         remote_ost_nodsh && skip "remote OST with nodsh"
11624
11625         reset_async
11626
11627         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11628         set_nodes_failloc "$(osts_nodes)" 0x220
11629
11630         # return -EIO from OST
11631         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11632         RC=$?
11633         set_nodes_failloc "$(osts_nodes)" 0x0
11634         if [[ $RC -eq 0 ]]; then
11635                 error "Must return error due to dropped pages, rc=$RC"
11636         fi
11637
11638         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11639         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11640         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11641         if [[ $LOCKED -ne 0 ]]; then
11642                 error "Locked pages remain in cache, locked=$LOCKED"
11643         fi
11644
11645         # in recoverable error on OST we want resend and stay until it finished
11646         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11647                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11648         fi
11649
11650         rm -f $DIR/$tfile
11651         echo "No pages locked after fsync"
11652
11653         return 0
11654 }
11655 run_test 118j "Simulate unrecoverable OST side error =========="
11656
11657 test_118k()
11658 {
11659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11660         remote_ost_nodsh && skip "remote OSTs with nodsh"
11661
11662         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11663         set_nodes_failloc "$(osts_nodes)" 0x20e
11664         test_mkdir $DIR/$tdir
11665
11666         for ((i=0;i<10;i++)); do
11667                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11668                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11669                 SLEEPPID=$!
11670                 sleep 0.500s
11671                 kill $SLEEPPID
11672                 wait $SLEEPPID
11673         done
11674
11675         set_nodes_failloc "$(osts_nodes)" 0
11676         rm -rf $DIR/$tdir
11677 }
11678 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11679
11680 test_118l() # LU-646
11681 {
11682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11683
11684         test_mkdir $DIR/$tdir
11685         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11686         rm -rf $DIR/$tdir
11687 }
11688 run_test 118l "fsync dir"
11689
11690 test_118m() # LU-3066
11691 {
11692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11693
11694         test_mkdir $DIR/$tdir
11695         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11696         rm -rf $DIR/$tdir
11697 }
11698 run_test 118m "fdatasync dir ========="
11699
11700 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11701
11702 test_118n()
11703 {
11704         local begin
11705         local end
11706
11707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11708         remote_ost_nodsh && skip "remote OSTs with nodsh"
11709
11710         # Sleep to avoid a cached response.
11711         #define OBD_STATFS_CACHE_SECONDS 1
11712         sleep 2
11713
11714         # Inject a 10 second delay in the OST_STATFS handler.
11715         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11716         set_nodes_failloc "$(osts_nodes)" 0x242
11717
11718         begin=$SECONDS
11719         stat --file-system $MOUNT > /dev/null
11720         end=$SECONDS
11721
11722         set_nodes_failloc "$(osts_nodes)" 0
11723
11724         if ((end - begin > 20)); then
11725             error "statfs took $((end - begin)) seconds, expected 10"
11726         fi
11727 }
11728 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11729
11730 test_119a() # bug 11737
11731 {
11732         BSIZE=$((512 * 1024))
11733         directio write $DIR/$tfile 0 1 $BSIZE
11734         # We ask to read two blocks, which is more than a file size.
11735         # directio will indicate an error when requested and actual
11736         # sizes aren't equeal (a normal situation in this case) and
11737         # print actual read amount.
11738         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11739         if [ "$NOB" != "$BSIZE" ]; then
11740                 error "read $NOB bytes instead of $BSIZE"
11741         fi
11742         rm -f $DIR/$tfile
11743 }
11744 run_test 119a "Short directIO read must return actual read amount"
11745
11746 test_119b() # bug 11737
11747 {
11748         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11749
11750         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11751         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11752         sync
11753         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11754                 error "direct read failed"
11755         rm -f $DIR/$tfile
11756 }
11757 run_test 119b "Sparse directIO read must return actual read amount"
11758
11759 test_119c() # bug 13099
11760 {
11761         BSIZE=1048576
11762         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11763         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11764         rm -f $DIR/$tfile
11765 }
11766 run_test 119c "Testing for direct read hitting hole"
11767
11768 test_119d() # bug 15950
11769 {
11770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11771
11772         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11773         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11774         BSIZE=1048576
11775         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11776         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11777         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11778         lctl set_param fail_loc=0x40d
11779         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11780         pid_dio=$!
11781         sleep 1
11782         cat $DIR/$tfile > /dev/null &
11783         lctl set_param fail_loc=0
11784         pid_reads=$!
11785         wait $pid_dio
11786         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11787         sleep 2
11788         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11789         error "the read rpcs have not completed in 2s"
11790         rm -f $DIR/$tfile
11791         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11792 }
11793 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11794
11795 test_120a() {
11796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11797         remote_mds_nodsh && skip "remote MDS with nodsh"
11798         test_mkdir -i0 -c1 $DIR/$tdir
11799         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11800                 skip_env "no early lock cancel on server"
11801
11802         lru_resize_disable mdc
11803         lru_resize_disable osc
11804         cancel_lru_locks mdc
11805         # asynchronous object destroy at MDT could cause bl ast to client
11806         cancel_lru_locks osc
11807
11808         stat $DIR/$tdir > /dev/null
11809         can1=$(do_facet mds1 \
11810                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11811                awk '/ldlm_cancel/ {print $2}')
11812         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11813                awk '/ldlm_bl_callback/ {print $2}')
11814         test_mkdir -i0 -c1 $DIR/$tdir/d1
11815         can2=$(do_facet mds1 \
11816                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11817                awk '/ldlm_cancel/ {print $2}')
11818         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11819                awk '/ldlm_bl_callback/ {print $2}')
11820         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11821         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11822         lru_resize_enable mdc
11823         lru_resize_enable osc
11824 }
11825 run_test 120a "Early Lock Cancel: mkdir test"
11826
11827 test_120b() {
11828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11829         remote_mds_nodsh && skip "remote MDS with nodsh"
11830         test_mkdir $DIR/$tdir
11831         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11832                 skip_env "no early lock cancel on server"
11833
11834         lru_resize_disable mdc
11835         lru_resize_disable osc
11836         cancel_lru_locks mdc
11837         stat $DIR/$tdir > /dev/null
11838         can1=$(do_facet $SINGLEMDS \
11839                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11840                awk '/ldlm_cancel/ {print $2}')
11841         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11842                awk '/ldlm_bl_callback/ {print $2}')
11843         touch $DIR/$tdir/f1
11844         can2=$(do_facet $SINGLEMDS \
11845                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11846                awk '/ldlm_cancel/ {print $2}')
11847         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11848                awk '/ldlm_bl_callback/ {print $2}')
11849         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11850         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11851         lru_resize_enable mdc
11852         lru_resize_enable osc
11853 }
11854 run_test 120b "Early Lock Cancel: create test"
11855
11856 test_120c() {
11857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11858         remote_mds_nodsh && skip "remote MDS with nodsh"
11859         test_mkdir -i0 -c1 $DIR/$tdir
11860         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11861                 skip "no early lock cancel on server"
11862
11863         lru_resize_disable mdc
11864         lru_resize_disable osc
11865         test_mkdir -i0 -c1 $DIR/$tdir/d1
11866         test_mkdir -i0 -c1 $DIR/$tdir/d2
11867         touch $DIR/$tdir/d1/f1
11868         cancel_lru_locks mdc
11869         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11870         can1=$(do_facet mds1 \
11871                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11872                awk '/ldlm_cancel/ {print $2}')
11873         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11874                awk '/ldlm_bl_callback/ {print $2}')
11875         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11876         can2=$(do_facet mds1 \
11877                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11878                awk '/ldlm_cancel/ {print $2}')
11879         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11880                awk '/ldlm_bl_callback/ {print $2}')
11881         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11882         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11883         lru_resize_enable mdc
11884         lru_resize_enable osc
11885 }
11886 run_test 120c "Early Lock Cancel: link test"
11887
11888 test_120d() {
11889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11890         remote_mds_nodsh && skip "remote MDS with nodsh"
11891         test_mkdir -i0 -c1 $DIR/$tdir
11892         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11893                 skip_env "no early lock cancel on server"
11894
11895         lru_resize_disable mdc
11896         lru_resize_disable osc
11897         touch $DIR/$tdir
11898         cancel_lru_locks mdc
11899         stat $DIR/$tdir > /dev/null
11900         can1=$(do_facet mds1 \
11901                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11902                awk '/ldlm_cancel/ {print $2}')
11903         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11904                awk '/ldlm_bl_callback/ {print $2}')
11905         chmod a+x $DIR/$tdir
11906         can2=$(do_facet mds1 \
11907                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11908                awk '/ldlm_cancel/ {print $2}')
11909         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11910                awk '/ldlm_bl_callback/ {print $2}')
11911         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11912         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11913         lru_resize_enable mdc
11914         lru_resize_enable osc
11915 }
11916 run_test 120d "Early Lock Cancel: setattr test"
11917
11918 test_120e() {
11919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11920         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11921                 skip_env "no early lock cancel on server"
11922         remote_mds_nodsh && skip "remote MDS with nodsh"
11923
11924         local dlmtrace_set=false
11925
11926         test_mkdir -i0 -c1 $DIR/$tdir
11927         lru_resize_disable mdc
11928         lru_resize_disable osc
11929         ! $LCTL get_param debug | grep -q dlmtrace &&
11930                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11931         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11932         cancel_lru_locks mdc
11933         cancel_lru_locks osc
11934         dd if=$DIR/$tdir/f1 of=/dev/null
11935         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11936         # XXX client can not do early lock cancel of OST lock
11937         # during unlink (LU-4206), so cancel osc lock now.
11938         sleep 2
11939         cancel_lru_locks osc
11940         can1=$(do_facet mds1 \
11941                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11942                awk '/ldlm_cancel/ {print $2}')
11943         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11944                awk '/ldlm_bl_callback/ {print $2}')
11945         unlink $DIR/$tdir/f1
11946         sleep 5
11947         can2=$(do_facet mds1 \
11948                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11949                awk '/ldlm_cancel/ {print $2}')
11950         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11951                awk '/ldlm_bl_callback/ {print $2}')
11952         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11953                 $LCTL dk $TMP/cancel.debug.txt
11954         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11955                 $LCTL dk $TMP/blocking.debug.txt
11956         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11957         lru_resize_enable mdc
11958         lru_resize_enable osc
11959 }
11960 run_test 120e "Early Lock Cancel: unlink test"
11961
11962 test_120f() {
11963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11964         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11965                 skip_env "no early lock cancel on server"
11966         remote_mds_nodsh && skip "remote MDS with nodsh"
11967
11968         test_mkdir -i0 -c1 $DIR/$tdir
11969         lru_resize_disable mdc
11970         lru_resize_disable osc
11971         test_mkdir -i0 -c1 $DIR/$tdir/d1
11972         test_mkdir -i0 -c1 $DIR/$tdir/d2
11973         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11974         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11975         cancel_lru_locks mdc
11976         cancel_lru_locks osc
11977         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11978         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11979         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11980         # XXX client can not do early lock cancel of OST lock
11981         # during rename (LU-4206), so cancel osc lock now.
11982         sleep 2
11983         cancel_lru_locks osc
11984         can1=$(do_facet mds1 \
11985                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11986                awk '/ldlm_cancel/ {print $2}')
11987         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11988                awk '/ldlm_bl_callback/ {print $2}')
11989         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11990         sleep 5
11991         can2=$(do_facet mds1 \
11992                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11993                awk '/ldlm_cancel/ {print $2}')
11994         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11995                awk '/ldlm_bl_callback/ {print $2}')
11996         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11997         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11998         lru_resize_enable mdc
11999         lru_resize_enable osc
12000 }
12001 run_test 120f "Early Lock Cancel: rename test"
12002
12003 test_120g() {
12004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12005         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12006                 skip_env "no early lock cancel on server"
12007         remote_mds_nodsh && skip "remote MDS with nodsh"
12008
12009         lru_resize_disable mdc
12010         lru_resize_disable osc
12011         count=10000
12012         echo create $count files
12013         test_mkdir $DIR/$tdir
12014         cancel_lru_locks mdc
12015         cancel_lru_locks osc
12016         t0=$(date +%s)
12017
12018         can0=$(do_facet $SINGLEMDS \
12019                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12020                awk '/ldlm_cancel/ {print $2}')
12021         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12022                awk '/ldlm_bl_callback/ {print $2}')
12023         createmany -o $DIR/$tdir/f $count
12024         sync
12025         can1=$(do_facet $SINGLEMDS \
12026                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12027                awk '/ldlm_cancel/ {print $2}')
12028         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12029                awk '/ldlm_bl_callback/ {print $2}')
12030         t1=$(date +%s)
12031         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12032         echo rm $count files
12033         rm -r $DIR/$tdir
12034         sync
12035         can2=$(do_facet $SINGLEMDS \
12036                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12037                awk '/ldlm_cancel/ {print $2}')
12038         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12039                awk '/ldlm_bl_callback/ {print $2}')
12040         t2=$(date +%s)
12041         echo total: $count removes in $((t2-t1))
12042         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12043         sleep 2
12044         # wait for commitment of removal
12045         lru_resize_enable mdc
12046         lru_resize_enable osc
12047 }
12048 run_test 120g "Early Lock Cancel: performance test"
12049
12050 test_121() { #bug #10589
12051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12052
12053         rm -rf $DIR/$tfile
12054         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12055 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12056         lctl set_param fail_loc=0x310
12057         cancel_lru_locks osc > /dev/null
12058         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12059         lctl set_param fail_loc=0
12060         [[ $reads -eq $writes ]] ||
12061                 error "read $reads blocks, must be $writes blocks"
12062 }
12063 run_test 121 "read cancel race ========="
12064
12065 test_123a_base() { # was test 123, statahead(bug 11401)
12066         local lsx="$1"
12067
12068         SLOWOK=0
12069         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12070                 log "testing UP system. Performance may be lower than expected."
12071                 SLOWOK=1
12072         fi
12073
12074         rm -rf $DIR/$tdir
12075         test_mkdir $DIR/$tdir
12076         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12077         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12078         MULT=10
12079         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12080                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12081
12082                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12083                 lctl set_param -n llite.*.statahead_max 0
12084                 lctl get_param llite.*.statahead_max
12085                 cancel_lru_locks mdc
12086                 cancel_lru_locks osc
12087                 stime=$(date +%s)
12088                 time $lsx $DIR/$tdir | wc -l
12089                 etime=$(date +%s)
12090                 delta=$((etime - stime))
12091                 log "$lsx $i files without statahead: $delta sec"
12092                 lctl set_param llite.*.statahead_max=$max
12093
12094                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12095                         grep "statahead wrong:" | awk '{print $3}')
12096                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12097                 cancel_lru_locks mdc
12098                 cancel_lru_locks osc
12099                 stime=$(date +%s)
12100                 time $lsx $DIR/$tdir | wc -l
12101                 etime=$(date +%s)
12102                 delta_sa=$((etime - stime))
12103                 log "$lsx $i files with statahead: $delta_sa sec"
12104                 lctl get_param -n llite.*.statahead_stats
12105                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12106                         grep "statahead wrong:" | awk '{print $3}')
12107
12108                 [[ $swrong -lt $ewrong ]] &&
12109                         log "statahead was stopped, maybe too many locks held!"
12110                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12111
12112                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12113                         max=$(lctl get_param -n llite.*.statahead_max |
12114                                 head -n 1)
12115                         lctl set_param -n llite.*.statahead_max 0
12116                         lctl get_param llite.*.statahead_max
12117                         cancel_lru_locks mdc
12118                         cancel_lru_locks osc
12119                         stime=$(date +%s)
12120                         time $lsx $DIR/$tdir | wc -l
12121                         etime=$(date +%s)
12122                         delta=$((etime - stime))
12123                         log "$lsx $i files again without statahead: $delta sec"
12124                         lctl set_param llite.*.statahead_max=$max
12125                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12126                                 if [  $SLOWOK -eq 0 ]; then
12127                                         error "$lsx $i files is slower with statahead!"
12128                                 else
12129                                         log "$lsx $i files is slower with statahead!"
12130                                 fi
12131                                 break
12132                         fi
12133                 fi
12134
12135                 [ $delta -gt 20 ] && break
12136                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12137                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12138         done
12139         log "$lsx done"
12140
12141         stime=$(date +%s)
12142         rm -r $DIR/$tdir
12143         sync
12144         etime=$(date +%s)
12145         delta=$((etime - stime))
12146         log "rm -r $DIR/$tdir/: $delta seconds"
12147         log "rm done"
12148         lctl get_param -n llite.*.statahead_stats
12149 }
12150
12151 test_123aa() {
12152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12153
12154         test_123a_base "ls -l"
12155 }
12156 run_test 123aa "verify statahead work"
12157
12158 test_123ab() {
12159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12160
12161         statx_supported || skip_env "Test must be statx() syscall supported"
12162
12163         test_123a_base "$STATX -l"
12164 }
12165 run_test 123ab "verify statahead work by using statx"
12166
12167 test_123ac() {
12168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12169
12170         statx_supported || skip_env "Test must be statx() syscall supported"
12171
12172         local rpcs_before
12173         local rpcs_after
12174         local agl_before
12175         local agl_after
12176
12177         cancel_lru_locks $OSC
12178         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12179         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12180                 awk '/agl.total:/ {print $3}')
12181         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12182         test_123a_base "$STATX --cached=always -D"
12183         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12184                 awk '/agl.total:/ {print $3}')
12185         [ $agl_before -eq $agl_after ] ||
12186                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12187         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12188         [ $rpcs_after -eq $rpcs_before ] ||
12189                 error "$STATX should not send glimpse RPCs to $OSC"
12190 }
12191 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12192
12193 test_123b () { # statahead(bug 15027)
12194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12195
12196         test_mkdir $DIR/$tdir
12197         createmany -o $DIR/$tdir/$tfile-%d 1000
12198
12199         cancel_lru_locks mdc
12200         cancel_lru_locks osc
12201
12202 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12203         lctl set_param fail_loc=0x80000803
12204         ls -lR $DIR/$tdir > /dev/null
12205         log "ls done"
12206         lctl set_param fail_loc=0x0
12207         lctl get_param -n llite.*.statahead_stats
12208         rm -r $DIR/$tdir
12209         sync
12210
12211 }
12212 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12213
12214 test_123c() {
12215         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12216
12217         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12218         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12219         touch $DIR/$tdir.1/{1..3}
12220         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12221
12222         remount_client $MOUNT
12223
12224         $MULTIOP $DIR/$tdir.0 Q
12225
12226         # let statahead to complete
12227         ls -l $DIR/$tdir.0 > /dev/null
12228
12229         testid=$(echo $TESTNAME | tr '_' ' ')
12230         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12231                 error "statahead warning" || true
12232 }
12233 run_test 123c "Can not initialize inode warning on DNE statahead"
12234
12235 test_124a() {
12236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12237         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12238                 skip_env "no lru resize on server"
12239
12240         local NR=2000
12241
12242         test_mkdir $DIR/$tdir
12243
12244         log "create $NR files at $DIR/$tdir"
12245         createmany -o $DIR/$tdir/f $NR ||
12246                 error "failed to create $NR files in $DIR/$tdir"
12247
12248         cancel_lru_locks mdc
12249         ls -l $DIR/$tdir > /dev/null
12250
12251         local NSDIR=""
12252         local LRU_SIZE=0
12253         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12254                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12255                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12256                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12257                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12258                         log "NSDIR=$NSDIR"
12259                         log "NS=$(basename $NSDIR)"
12260                         break
12261                 fi
12262         done
12263
12264         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12265                 skip "Not enough cached locks created!"
12266         fi
12267         log "LRU=$LRU_SIZE"
12268
12269         local SLEEP=30
12270
12271         # We know that lru resize allows one client to hold $LIMIT locks
12272         # for 10h. After that locks begin to be killed by client.
12273         local MAX_HRS=10
12274         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12275         log "LIMIT=$LIMIT"
12276         if [ $LIMIT -lt $LRU_SIZE ]; then
12277                 skip "Limit is too small $LIMIT"
12278         fi
12279
12280         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12281         # killing locks. Some time was spent for creating locks. This means
12282         # that up to the moment of sleep finish we must have killed some of
12283         # them (10-100 locks). This depends on how fast ther were created.
12284         # Many of them were touched in almost the same moment and thus will
12285         # be killed in groups.
12286         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12287
12288         # Use $LRU_SIZE_B here to take into account real number of locks
12289         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12290         local LRU_SIZE_B=$LRU_SIZE
12291         log "LVF=$LVF"
12292         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12293         log "OLD_LVF=$OLD_LVF"
12294         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12295
12296         # Let's make sure that we really have some margin. Client checks
12297         # cached locks every 10 sec.
12298         SLEEP=$((SLEEP+20))
12299         log "Sleep ${SLEEP} sec"
12300         local SEC=0
12301         while ((SEC<$SLEEP)); do
12302                 echo -n "..."
12303                 sleep 5
12304                 SEC=$((SEC+5))
12305                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12306                 echo -n "$LRU_SIZE"
12307         done
12308         echo ""
12309         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12310         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12311
12312         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12313                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12314                 unlinkmany $DIR/$tdir/f $NR
12315                 return
12316         }
12317
12318         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12319         log "unlink $NR files at $DIR/$tdir"
12320         unlinkmany $DIR/$tdir/f $NR
12321 }
12322 run_test 124a "lru resize ======================================="
12323
12324 get_max_pool_limit()
12325 {
12326         local limit=$($LCTL get_param \
12327                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12328         local max=0
12329         for l in $limit; do
12330                 if [[ $l -gt $max ]]; then
12331                         max=$l
12332                 fi
12333         done
12334         echo $max
12335 }
12336
12337 test_124b() {
12338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12339         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12340                 skip_env "no lru resize on server"
12341
12342         LIMIT=$(get_max_pool_limit)
12343
12344         NR=$(($(default_lru_size)*20))
12345         if [[ $NR -gt $LIMIT ]]; then
12346                 log "Limit lock number by $LIMIT locks"
12347                 NR=$LIMIT
12348         fi
12349
12350         IFree=$(mdsrate_inodes_available)
12351         if [ $IFree -lt $NR ]; then
12352                 log "Limit lock number by $IFree inodes"
12353                 NR=$IFree
12354         fi
12355
12356         lru_resize_disable mdc
12357         test_mkdir -p $DIR/$tdir/disable_lru_resize
12358
12359         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12360         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12361         cancel_lru_locks mdc
12362         stime=`date +%s`
12363         PID=""
12364         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12365         PID="$PID $!"
12366         sleep 2
12367         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12368         PID="$PID $!"
12369         sleep 2
12370         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12371         PID="$PID $!"
12372         wait $PID
12373         etime=`date +%s`
12374         nolruresize_delta=$((etime-stime))
12375         log "ls -la time: $nolruresize_delta seconds"
12376         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12377         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12378
12379         lru_resize_enable mdc
12380         test_mkdir -p $DIR/$tdir/enable_lru_resize
12381
12382         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12383         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12384         cancel_lru_locks mdc
12385         stime=`date +%s`
12386         PID=""
12387         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12388         PID="$PID $!"
12389         sleep 2
12390         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12391         PID="$PID $!"
12392         sleep 2
12393         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12394         PID="$PID $!"
12395         wait $PID
12396         etime=`date +%s`
12397         lruresize_delta=$((etime-stime))
12398         log "ls -la time: $lruresize_delta seconds"
12399         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12400
12401         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12402                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12403         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12404                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12405         else
12406                 log "lru resize performs the same with no lru resize"
12407         fi
12408         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12409 }
12410 run_test 124b "lru resize (performance test) ======================="
12411
12412 test_124c() {
12413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12414         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12415                 skip_env "no lru resize on server"
12416
12417         # cache ununsed locks on client
12418         local nr=100
12419         cancel_lru_locks mdc
12420         test_mkdir $DIR/$tdir
12421         createmany -o $DIR/$tdir/f $nr ||
12422                 error "failed to create $nr files in $DIR/$tdir"
12423         ls -l $DIR/$tdir > /dev/null
12424
12425         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12426         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12427         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12428         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12429         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12430
12431         # set lru_max_age to 1 sec
12432         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12433         echo "sleep $((recalc_p * 2)) seconds..."
12434         sleep $((recalc_p * 2))
12435
12436         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12437         # restore lru_max_age
12438         $LCTL set_param -n $nsdir.lru_max_age $max_age
12439         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12440         unlinkmany $DIR/$tdir/f $nr
12441 }
12442 run_test 124c "LRUR cancel very aged locks"
12443
12444 test_124d() {
12445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12446         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12447                 skip_env "no lru resize on server"
12448
12449         # cache ununsed locks on client
12450         local nr=100
12451
12452         lru_resize_disable mdc
12453         stack_trap "lru_resize_enable mdc" EXIT
12454
12455         cancel_lru_locks mdc
12456
12457         # asynchronous object destroy at MDT could cause bl ast to client
12458         test_mkdir $DIR/$tdir
12459         createmany -o $DIR/$tdir/f $nr ||
12460                 error "failed to create $nr files in $DIR/$tdir"
12461         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12462
12463         ls -l $DIR/$tdir > /dev/null
12464
12465         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12466         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12467         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12468         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12469
12470         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12471
12472         # set lru_max_age to 1 sec
12473         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12474         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12475
12476         echo "sleep $((recalc_p * 2)) seconds..."
12477         sleep $((recalc_p * 2))
12478
12479         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12480
12481         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12482 }
12483 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12484
12485 test_125() { # 13358
12486         $LCTL get_param -n llite.*.client_type | grep -q local ||
12487                 skip "must run as local client"
12488         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12489                 skip_env "must have acl enabled"
12490         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12491
12492         test_mkdir $DIR/$tdir
12493         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12494         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12495         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12496 }
12497 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12498
12499 test_126() { # bug 12829/13455
12500         $GSS && skip_env "must run as gss disabled"
12501         $LCTL get_param -n llite.*.client_type | grep -q local ||
12502                 skip "must run as local client"
12503         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12504
12505         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12506         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12507         rm -f $DIR/$tfile
12508         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12509 }
12510 run_test 126 "check that the fsgid provided by the client is taken into account"
12511
12512 test_127a() { # bug 15521
12513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12514         local name count samp unit min max sum sumsq
12515
12516         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12517         echo "stats before reset"
12518         $LCTL get_param osc.*.stats
12519         $LCTL set_param osc.*.stats=0
12520         local fsize=$((2048 * 1024))
12521
12522         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12523         cancel_lru_locks osc
12524         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12525
12526         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12527         stack_trap "rm -f $TMP/$tfile.tmp"
12528         while read name count samp unit min max sum sumsq; do
12529                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12530                 [ ! $min ] && error "Missing min value for $name proc entry"
12531                 eval $name=$count || error "Wrong proc format"
12532
12533                 case $name in
12534                 read_bytes|write_bytes)
12535                         [[ "$unit" =~ "bytes" ]] ||
12536                                 error "unit is not 'bytes': $unit"
12537                         (( $min >= 4096 )) || error "min is too small: $min"
12538                         (( $min <= $fsize )) || error "min is too big: $min"
12539                         (( $max >= 4096 )) || error "max is too small: $max"
12540                         (( $max <= $fsize )) || error "max is too big: $max"
12541                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12542                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12543                                 error "sumsquare is too small: $sumsq"
12544                         (( $sumsq <= $fsize * $fsize )) ||
12545                                 error "sumsquare is too big: $sumsq"
12546                         ;;
12547                 ost_read|ost_write)
12548                         [[ "$unit" =~ "usec" ]] ||
12549                                 error "unit is not 'usec': $unit"
12550                         ;;
12551                 *)      ;;
12552                 esac
12553         done < $DIR/$tfile.tmp
12554
12555         #check that we actually got some stats
12556         [ "$read_bytes" ] || error "Missing read_bytes stats"
12557         [ "$write_bytes" ] || error "Missing write_bytes stats"
12558         [ "$read_bytes" != 0 ] || error "no read done"
12559         [ "$write_bytes" != 0 ] || error "no write done"
12560 }
12561 run_test 127a "verify the client stats are sane"
12562
12563 test_127b() { # bug LU-333
12564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12565         local name count samp unit min max sum sumsq
12566
12567         echo "stats before reset"
12568         $LCTL get_param llite.*.stats
12569         $LCTL set_param llite.*.stats=0
12570
12571         # perform 2 reads and writes so MAX is different from SUM.
12572         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12573         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12574         cancel_lru_locks osc
12575         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12576         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12577
12578         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12579         stack_trap "rm -f $TMP/$tfile.tmp"
12580         while read name count samp unit min max sum sumsq; do
12581                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12582                 eval $name=$count || error "Wrong proc format"
12583
12584                 case $name in
12585                 read_bytes|write_bytes)
12586                         [[ "$unit" =~ "bytes" ]] ||
12587                                 error "unit is not 'bytes': $unit"
12588                         (( $count == 2 )) || error "count is not 2: $count"
12589                         (( $min == $PAGE_SIZE )) ||
12590                                 error "min is not $PAGE_SIZE: $min"
12591                         (( $max == $PAGE_SIZE )) ||
12592                                 error "max is not $PAGE_SIZE: $max"
12593                         (( $sum == $PAGE_SIZE * 2 )) ||
12594                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12595                         ;;
12596                 read|write)
12597                         [[ "$unit" =~ "usec" ]] ||
12598                                 error "unit is not 'usec': $unit"
12599                         ;;
12600                 *)      ;;
12601                 esac
12602         done < $TMP/$tfile.tmp
12603
12604         #check that we actually got some stats
12605         [ "$read_bytes" ] || error "Missing read_bytes stats"
12606         [ "$write_bytes" ] || error "Missing write_bytes stats"
12607         [ "$read_bytes" != 0 ] || error "no read done"
12608         [ "$write_bytes" != 0 ] || error "no write done"
12609 }
12610 run_test 127b "verify the llite client stats are sane"
12611
12612 test_127c() { # LU-12394
12613         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12614         local size
12615         local bsize
12616         local reads
12617         local writes
12618         local count
12619
12620         $LCTL set_param llite.*.extents_stats=1
12621         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12622
12623         # Use two stripes so there is enough space in default config
12624         $LFS setstripe -c 2 $DIR/$tfile
12625
12626         # Extent stats start at 0-4K and go in power of two buckets
12627         # LL_HIST_START = 12 --> 2^12 = 4K
12628         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12629         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12630         # small configs
12631         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12632                 do
12633                 # Write and read, 2x each, second time at a non-zero offset
12634                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12635                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12636                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12637                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12638                 rm -f $DIR/$tfile
12639         done
12640
12641         $LCTL get_param llite.*.extents_stats
12642
12643         count=2
12644         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12645                 do
12646                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12647                                 grep -m 1 $bsize)
12648                 reads=$(echo $bucket | awk '{print $5}')
12649                 writes=$(echo $bucket | awk '{print $9}')
12650                 [ "$reads" -eq $count ] ||
12651                         error "$reads reads in < $bsize bucket, expect $count"
12652                 [ "$writes" -eq $count ] ||
12653                         error "$writes writes in < $bsize bucket, expect $count"
12654         done
12655
12656         # Test mmap write and read
12657         $LCTL set_param llite.*.extents_stats=c
12658         size=512
12659         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12660         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12661         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12662
12663         $LCTL get_param llite.*.extents_stats
12664
12665         count=$(((size*1024) / PAGE_SIZE))
12666
12667         bsize=$((2 * PAGE_SIZE / 1024))K
12668
12669         bucket=$($LCTL get_param -n llite.*.extents_stats |
12670                         grep -m 1 $bsize)
12671         reads=$(echo $bucket | awk '{print $5}')
12672         writes=$(echo $bucket | awk '{print $9}')
12673         # mmap writes fault in the page first, creating an additonal read
12674         [ "$reads" -eq $((2 * count)) ] ||
12675                 error "$reads reads in < $bsize bucket, expect $count"
12676         [ "$writes" -eq $count ] ||
12677                 error "$writes writes in < $bsize bucket, expect $count"
12678 }
12679 run_test 127c "test llite extent stats with regular & mmap i/o"
12680
12681 test_128() { # bug 15212
12682         touch $DIR/$tfile
12683         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12684                 find $DIR/$tfile
12685                 find $DIR/$tfile
12686         EOF
12687
12688         result=$(grep error $TMP/$tfile.log)
12689         rm -f $DIR/$tfile $TMP/$tfile.log
12690         [ -z "$result" ] ||
12691                 error "consecutive find's under interactive lfs failed"
12692 }
12693 run_test 128 "interactive lfs for 2 consecutive find's"
12694
12695 set_dir_limits () {
12696         local mntdev
12697         local canondev
12698         local node
12699
12700         local ldproc=/proc/fs/ldiskfs
12701         local facets=$(get_facets MDS)
12702
12703         for facet in ${facets//,/ }; do
12704                 canondev=$(ldiskfs_canon \
12705                            *.$(convert_facet2label $facet).mntdev $facet)
12706                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12707                         ldproc=/sys/fs/ldiskfs
12708                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12709                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12710         done
12711 }
12712
12713 check_mds_dmesg() {
12714         local facets=$(get_facets MDS)
12715         for facet in ${facets//,/ }; do
12716                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12717         done
12718         return 1
12719 }
12720
12721 test_129() {
12722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12723         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12724                 skip "Need MDS version with at least 2.5.56"
12725         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12726                 skip_env "ldiskfs only test"
12727         fi
12728         remote_mds_nodsh && skip "remote MDS with nodsh"
12729
12730         local ENOSPC=28
12731         local has_warning=false
12732
12733         rm -rf $DIR/$tdir
12734         mkdir -p $DIR/$tdir
12735
12736         # block size of mds1
12737         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12738         set_dir_limits $maxsize $((maxsize * 6 / 8))
12739         stack_trap "set_dir_limits 0 0"
12740         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12741         local dirsize=$(stat -c%s "$DIR/$tdir")
12742         local nfiles=0
12743         while (( $dirsize <= $maxsize )); do
12744                 $MCREATE $DIR/$tdir/file_base_$nfiles
12745                 rc=$?
12746                 # check two errors:
12747                 # ENOSPC for ext4 max_dir_size, which has been used since
12748                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12749                 if (( rc == ENOSPC )); then
12750                         set_dir_limits 0 0
12751                         echo "rc=$rc returned as expected after $nfiles files"
12752
12753                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12754                                 error "create failed w/o dir size limit"
12755
12756                         # messages may be rate limited if test is run repeatedly
12757                         check_mds_dmesg '"is approaching max"' ||
12758                                 echo "warning message should be output"
12759                         check_mds_dmesg '"has reached max"' ||
12760                                 echo "reached message should be output"
12761
12762                         dirsize=$(stat -c%s "$DIR/$tdir")
12763
12764                         [[ $dirsize -ge $maxsize ]] && return 0
12765                         error "dirsize $dirsize < $maxsize after $nfiles files"
12766                 elif (( rc != 0 )); then
12767                         break
12768                 fi
12769                 nfiles=$((nfiles + 1))
12770                 dirsize=$(stat -c%s "$DIR/$tdir")
12771         done
12772
12773         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12774 }
12775 run_test 129 "test directory size limit ========================"
12776
12777 OLDIFS="$IFS"
12778 cleanup_130() {
12779         trap 0
12780         IFS="$OLDIFS"
12781 }
12782
12783 test_130a() {
12784         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12785         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12786
12787         trap cleanup_130 EXIT RETURN
12788
12789         local fm_file=$DIR/$tfile
12790         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12791         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12792                 error "dd failed for $fm_file"
12793
12794         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12795         filefrag -ves $fm_file
12796         RC=$?
12797         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12798                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12799         [ $RC != 0 ] && error "filefrag $fm_file failed"
12800
12801         filefrag_op=$(filefrag -ve -k $fm_file |
12802                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12803         lun=$($LFS getstripe -i $fm_file)
12804
12805         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12806         IFS=$'\n'
12807         tot_len=0
12808         for line in $filefrag_op
12809         do
12810                 frag_lun=`echo $line | cut -d: -f5`
12811                 ext_len=`echo $line | cut -d: -f4`
12812                 if (( $frag_lun != $lun )); then
12813                         cleanup_130
12814                         error "FIEMAP on 1-stripe file($fm_file) failed"
12815                         return
12816                 fi
12817                 (( tot_len += ext_len ))
12818         done
12819
12820         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12821                 cleanup_130
12822                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12823                 return
12824         fi
12825
12826         cleanup_130
12827
12828         echo "FIEMAP on single striped file succeeded"
12829 }
12830 run_test 130a "FIEMAP (1-stripe file)"
12831
12832 test_130b() {
12833         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12834
12835         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12836         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12837
12838         trap cleanup_130 EXIT RETURN
12839
12840         local fm_file=$DIR/$tfile
12841         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12842                         error "setstripe on $fm_file"
12843         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12844                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12845
12846         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12847                 error "dd failed on $fm_file"
12848
12849         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12850         filefrag_op=$(filefrag -ve -k $fm_file |
12851                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12852
12853         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12854                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12855
12856         IFS=$'\n'
12857         tot_len=0
12858         num_luns=1
12859         for line in $filefrag_op
12860         do
12861                 frag_lun=$(echo $line | cut -d: -f5 |
12862                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12863                 ext_len=$(echo $line | cut -d: -f4)
12864                 if (( $frag_lun != $last_lun )); then
12865                         if (( tot_len != 1024 )); then
12866                                 cleanup_130
12867                                 error "FIEMAP on $fm_file failed; returned " \
12868                                 "len $tot_len for OST $last_lun instead of 1024"
12869                                 return
12870                         else
12871                                 (( num_luns += 1 ))
12872                                 tot_len=0
12873                         fi
12874                 fi
12875                 (( tot_len += ext_len ))
12876                 last_lun=$frag_lun
12877         done
12878         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12879                 cleanup_130
12880                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12881                         "luns or wrong len for OST $last_lun"
12882                 return
12883         fi
12884
12885         cleanup_130
12886
12887         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12888 }
12889 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12890
12891 test_130c() {
12892         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12893
12894         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12895         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12896
12897         trap cleanup_130 EXIT RETURN
12898
12899         local fm_file=$DIR/$tfile
12900         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12901         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12902                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12903
12904         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12905                         error "dd failed on $fm_file"
12906
12907         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12908         filefrag_op=$(filefrag -ve -k $fm_file |
12909                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12910
12911         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12912                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12913
12914         IFS=$'\n'
12915         tot_len=0
12916         num_luns=1
12917         for line in $filefrag_op
12918         do
12919                 frag_lun=$(echo $line | cut -d: -f5 |
12920                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12921                 ext_len=$(echo $line | cut -d: -f4)
12922                 if (( $frag_lun != $last_lun )); then
12923                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12924                         if (( logical != 512 )); then
12925                                 cleanup_130
12926                                 error "FIEMAP on $fm_file failed; returned " \
12927                                 "logical start for lun $logical instead of 512"
12928                                 return
12929                         fi
12930                         if (( tot_len != 512 )); then
12931                                 cleanup_130
12932                                 error "FIEMAP on $fm_file failed; returned " \
12933                                 "len $tot_len for OST $last_lun instead of 1024"
12934                                 return
12935                         else
12936                                 (( num_luns += 1 ))
12937                                 tot_len=0
12938                         fi
12939                 fi
12940                 (( tot_len += ext_len ))
12941                 last_lun=$frag_lun
12942         done
12943         if (( num_luns != 2 || tot_len != 512 )); then
12944                 cleanup_130
12945                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12946                         "luns or wrong len for OST $last_lun"
12947                 return
12948         fi
12949
12950         cleanup_130
12951
12952         echo "FIEMAP on 2-stripe file with hole succeeded"
12953 }
12954 run_test 130c "FIEMAP (2-stripe file with hole)"
12955
12956 test_130d() {
12957         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12958
12959         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12960         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12961
12962         trap cleanup_130 EXIT RETURN
12963
12964         local fm_file=$DIR/$tfile
12965         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12966                         error "setstripe on $fm_file"
12967         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12968                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12969
12970         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12971         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12972                 error "dd failed on $fm_file"
12973
12974         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12975         filefrag_op=$(filefrag -ve -k $fm_file |
12976                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12977
12978         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12979                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12980
12981         IFS=$'\n'
12982         tot_len=0
12983         num_luns=1
12984         for line in $filefrag_op
12985         do
12986                 frag_lun=$(echo $line | cut -d: -f5 |
12987                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12988                 ext_len=$(echo $line | cut -d: -f4)
12989                 if (( $frag_lun != $last_lun )); then
12990                         if (( tot_len != 1024 )); then
12991                                 cleanup_130
12992                                 error "FIEMAP on $fm_file failed; returned " \
12993                                 "len $tot_len for OST $last_lun instead of 1024"
12994                                 return
12995                         else
12996                                 (( num_luns += 1 ))
12997                                 tot_len=0
12998                         fi
12999                 fi
13000                 (( tot_len += ext_len ))
13001                 last_lun=$frag_lun
13002         done
13003         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13004                 cleanup_130
13005                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13006                         "luns or wrong len for OST $last_lun"
13007                 return
13008         fi
13009
13010         cleanup_130
13011
13012         echo "FIEMAP on N-stripe file succeeded"
13013 }
13014 run_test 130d "FIEMAP (N-stripe file)"
13015
13016 test_130e() {
13017         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13018
13019         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13020         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13021
13022         trap cleanup_130 EXIT RETURN
13023
13024         local fm_file=$DIR/$tfile
13025         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13026
13027         NUM_BLKS=512
13028         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13029         for ((i = 0; i < $NUM_BLKS; i++)); do
13030                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13031                         conv=notrunc > /dev/null 2>&1
13032         done
13033
13034         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13035         filefrag_op=$(filefrag -ve -k $fm_file |
13036                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13037
13038         last_lun=$(echo $filefrag_op | cut -d: -f5)
13039
13040         IFS=$'\n'
13041         tot_len=0
13042         num_luns=1
13043         for line in $filefrag_op; do
13044                 frag_lun=$(echo $line | cut -d: -f5)
13045                 ext_len=$(echo $line | cut -d: -f4)
13046                 if [[ "$frag_lun" != "$last_lun" ]]; then
13047                         if (( tot_len != $EXPECTED_LEN )); then
13048                                 cleanup_130
13049                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13050                         else
13051                                 (( num_luns += 1 ))
13052                                 tot_len=0
13053                         fi
13054                 fi
13055                 (( tot_len += ext_len ))
13056                 last_lun=$frag_lun
13057         done
13058         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13059                 cleanup_130
13060                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13061         fi
13062
13063         echo "FIEMAP with continuation calls succeeded"
13064 }
13065 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13066
13067 test_130f() {
13068         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13069         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13070
13071         local fm_file=$DIR/$tfile
13072         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13073                 error "multiop create with lov_delay_create on $fm_file"
13074
13075         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13076         filefrag_extents=$(filefrag -vek $fm_file |
13077                            awk '/extents? found/ { print $2 }')
13078         if [[ "$filefrag_extents" != "0" ]]; then
13079                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13080         fi
13081
13082         rm -f $fm_file
13083 }
13084 run_test 130f "FIEMAP (unstriped file)"
13085
13086 test_130g() {
13087         local file=$DIR/$tfile
13088         local nr=$((OSTCOUNT * 100))
13089
13090         $LFS setstripe -C $nr $file ||
13091                 error "failed to setstripe -C $nr $file"
13092
13093         dd if=/dev/zero of=$file count=$nr bs=1M
13094         sync
13095         nr=$($LFS getstripe -c $file)
13096
13097         local extents=$(filefrag -v $file |
13098                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13099
13100         echo "filefrag list $extents extents in file with stripecount $nr"
13101         if (( extents < nr )); then
13102                 $LFS getstripe $file
13103                 filefrag -v $file
13104                 error "filefrag printed $extents < $nr extents"
13105         fi
13106
13107         rm -f $file
13108 }
13109 run_test 130g "FIEMAP (overstripe file)"
13110
13111 # Test for writev/readv
13112 test_131a() {
13113         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13114                 error "writev test failed"
13115         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13116                 error "readv failed"
13117         rm -f $DIR/$tfile
13118 }
13119 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13120
13121 test_131b() {
13122         local fsize=$((524288 + 1048576 + 1572864))
13123         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13124                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13125                         error "append writev test failed"
13126
13127         ((fsize += 1572864 + 1048576))
13128         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13129                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13130                         error "append writev test failed"
13131         rm -f $DIR/$tfile
13132 }
13133 run_test 131b "test append writev"
13134
13135 test_131c() {
13136         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13137         error "NOT PASS"
13138 }
13139 run_test 131c "test read/write on file w/o objects"
13140
13141 test_131d() {
13142         rwv -f $DIR/$tfile -w -n 1 1572864
13143         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13144         if [ "$NOB" != 1572864 ]; then
13145                 error "Short read filed: read $NOB bytes instead of 1572864"
13146         fi
13147         rm -f $DIR/$tfile
13148 }
13149 run_test 131d "test short read"
13150
13151 test_131e() {
13152         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13153         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13154         error "read hitting hole failed"
13155         rm -f $DIR/$tfile
13156 }
13157 run_test 131e "test read hitting hole"
13158
13159 check_stats() {
13160         local facet=$1
13161         local op=$2
13162         local want=${3:-0}
13163         local res
13164
13165         case $facet in
13166         mds*) res=$(do_facet $facet \
13167                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13168                  ;;
13169         ost*) res=$(do_facet $facet \
13170                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13171                  ;;
13172         *) error "Wrong facet '$facet'" ;;
13173         esac
13174         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13175         # if the argument $3 is zero, it means any stat increment is ok.
13176         if [[ $want -gt 0 ]]; then
13177                 local count=$(echo $res | awk '{ print $2 }')
13178                 [[ $count -ne $want ]] &&
13179                         error "The $op counter on $facet is $count, not $want"
13180         fi
13181 }
13182
13183 test_133a() {
13184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13185         remote_ost_nodsh && skip "remote OST with nodsh"
13186         remote_mds_nodsh && skip "remote MDS with nodsh"
13187         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13188                 skip_env "MDS doesn't support rename stats"
13189
13190         local testdir=$DIR/${tdir}/stats_testdir
13191
13192         mkdir -p $DIR/${tdir}
13193
13194         # clear stats.
13195         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13196         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13197
13198         # verify mdt stats first.
13199         mkdir ${testdir} || error "mkdir failed"
13200         check_stats $SINGLEMDS "mkdir" 1
13201         touch ${testdir}/${tfile} || error "touch failed"
13202         check_stats $SINGLEMDS "open" 1
13203         check_stats $SINGLEMDS "close" 1
13204         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13205                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13206                 check_stats $SINGLEMDS "mknod" 2
13207         }
13208         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13209         check_stats $SINGLEMDS "unlink" 1
13210         rm -f ${testdir}/${tfile} || error "file remove failed"
13211         check_stats $SINGLEMDS "unlink" 2
13212
13213         # remove working dir and check mdt stats again.
13214         rmdir ${testdir} || error "rmdir failed"
13215         check_stats $SINGLEMDS "rmdir" 1
13216
13217         local testdir1=$DIR/${tdir}/stats_testdir1
13218         mkdir -p ${testdir}
13219         mkdir -p ${testdir1}
13220         touch ${testdir1}/test1
13221         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13222         check_stats $SINGLEMDS "crossdir_rename" 1
13223
13224         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13225         check_stats $SINGLEMDS "samedir_rename" 1
13226
13227         rm -rf $DIR/${tdir}
13228 }
13229 run_test 133a "Verifying MDT stats ========================================"
13230
13231 test_133b() {
13232         local res
13233
13234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13235         remote_ost_nodsh && skip "remote OST with nodsh"
13236         remote_mds_nodsh && skip "remote MDS with nodsh"
13237
13238         local testdir=$DIR/${tdir}/stats_testdir
13239
13240         mkdir -p ${testdir} || error "mkdir failed"
13241         touch ${testdir}/${tfile} || error "touch failed"
13242         cancel_lru_locks mdc
13243
13244         # clear stats.
13245         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13246         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13247
13248         # extra mdt stats verification.
13249         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13250         check_stats $SINGLEMDS "setattr" 1
13251         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13252         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13253         then            # LU-1740
13254                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13255                 check_stats $SINGLEMDS "getattr" 1
13256         fi
13257         rm -rf $DIR/${tdir}
13258
13259         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13260         # so the check below is not reliable
13261         [ $MDSCOUNT -eq 1 ] || return 0
13262
13263         # Sleep to avoid a cached response.
13264         #define OBD_STATFS_CACHE_SECONDS 1
13265         sleep 2
13266         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13267         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13268         $LFS df || error "lfs failed"
13269         check_stats $SINGLEMDS "statfs" 1
13270
13271         # check aggregated statfs (LU-10018)
13272         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13273                 return 0
13274         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13275                 return 0
13276         sleep 2
13277         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13278         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13279         df $DIR
13280         check_stats $SINGLEMDS "statfs" 1
13281
13282         # We want to check that the client didn't send OST_STATFS to
13283         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13284         # extra care is needed here.
13285         if remote_mds; then
13286                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13287                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13288
13289                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13290                 [ "$res" ] && error "OST got STATFS"
13291         fi
13292
13293         return 0
13294 }
13295 run_test 133b "Verifying extra MDT stats =================================="
13296
13297 test_133c() {
13298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13299         remote_ost_nodsh && skip "remote OST with nodsh"
13300         remote_mds_nodsh && skip "remote MDS with nodsh"
13301
13302         local testdir=$DIR/$tdir/stats_testdir
13303
13304         test_mkdir -p $testdir
13305
13306         # verify obdfilter stats.
13307         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13308         sync
13309         cancel_lru_locks osc
13310         wait_delete_completed
13311
13312         # clear stats.
13313         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13314         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13315
13316         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13317                 error "dd failed"
13318         sync
13319         cancel_lru_locks osc
13320         check_stats ost1 "write" 1
13321
13322         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13323         check_stats ost1 "read" 1
13324
13325         > $testdir/$tfile || error "truncate failed"
13326         check_stats ost1 "punch" 1
13327
13328         rm -f $testdir/$tfile || error "file remove failed"
13329         wait_delete_completed
13330         check_stats ost1 "destroy" 1
13331
13332         rm -rf $DIR/$tdir
13333 }
13334 run_test 133c "Verifying OST stats ========================================"
13335
13336 order_2() {
13337         local value=$1
13338         local orig=$value
13339         local order=1
13340
13341         while [ $value -ge 2 ]; do
13342                 order=$((order*2))
13343                 value=$((value/2))
13344         done
13345
13346         if [ $orig -gt $order ]; then
13347                 order=$((order*2))
13348         fi
13349         echo $order
13350 }
13351
13352 size_in_KMGT() {
13353     local value=$1
13354     local size=('K' 'M' 'G' 'T');
13355     local i=0
13356     local size_string=$value
13357
13358     while [ $value -ge 1024 ]; do
13359         if [ $i -gt 3 ]; then
13360             #T is the biggest unit we get here, if that is bigger,
13361             #just return XXXT
13362             size_string=${value}T
13363             break
13364         fi
13365         value=$((value >> 10))
13366         if [ $value -lt 1024 ]; then
13367             size_string=${value}${size[$i]}
13368             break
13369         fi
13370         i=$((i + 1))
13371     done
13372
13373     echo $size_string
13374 }
13375
13376 get_rename_size() {
13377         local size=$1
13378         local context=${2:-.}
13379         local sample=$(do_facet $SINGLEMDS $LCTL \
13380                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13381                 grep -A1 $context |
13382                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13383         echo $sample
13384 }
13385
13386 test_133d() {
13387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13388         remote_ost_nodsh && skip "remote OST with nodsh"
13389         remote_mds_nodsh && skip "remote MDS with nodsh"
13390         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13391                 skip_env "MDS doesn't support rename stats"
13392
13393         local testdir1=$DIR/${tdir}/stats_testdir1
13394         local testdir2=$DIR/${tdir}/stats_testdir2
13395         mkdir -p $DIR/${tdir}
13396
13397         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13398
13399         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13400         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13401
13402         createmany -o $testdir1/test 512 || error "createmany failed"
13403
13404         # check samedir rename size
13405         mv ${testdir1}/test0 ${testdir1}/test_0
13406
13407         local testdir1_size=$(ls -l $DIR/${tdir} |
13408                 awk '/stats_testdir1/ {print $5}')
13409         local testdir2_size=$(ls -l $DIR/${tdir} |
13410                 awk '/stats_testdir2/ {print $5}')
13411
13412         testdir1_size=$(order_2 $testdir1_size)
13413         testdir2_size=$(order_2 $testdir2_size)
13414
13415         testdir1_size=$(size_in_KMGT $testdir1_size)
13416         testdir2_size=$(size_in_KMGT $testdir2_size)
13417
13418         echo "source rename dir size: ${testdir1_size}"
13419         echo "target rename dir size: ${testdir2_size}"
13420
13421         local cmd="do_facet $SINGLEMDS $LCTL "
13422         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13423
13424         eval $cmd || error "$cmd failed"
13425         local samedir=$($cmd | grep 'same_dir')
13426         local same_sample=$(get_rename_size $testdir1_size)
13427         [ -z "$samedir" ] && error "samedir_rename_size count error"
13428         [[ $same_sample -eq 1 ]] ||
13429                 error "samedir_rename_size error $same_sample"
13430         echo "Check same dir rename stats success"
13431
13432         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13433
13434         # check crossdir rename size
13435         mv ${testdir1}/test_0 ${testdir2}/test_0
13436
13437         testdir1_size=$(ls -l $DIR/${tdir} |
13438                 awk '/stats_testdir1/ {print $5}')
13439         testdir2_size=$(ls -l $DIR/${tdir} |
13440                 awk '/stats_testdir2/ {print $5}')
13441
13442         testdir1_size=$(order_2 $testdir1_size)
13443         testdir2_size=$(order_2 $testdir2_size)
13444
13445         testdir1_size=$(size_in_KMGT $testdir1_size)
13446         testdir2_size=$(size_in_KMGT $testdir2_size)
13447
13448         echo "source rename dir size: ${testdir1_size}"
13449         echo "target rename dir size: ${testdir2_size}"
13450
13451         eval $cmd || error "$cmd failed"
13452         local crossdir=$($cmd | grep 'crossdir')
13453         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13454         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13455         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13456         [[ $src_sample -eq 1 ]] ||
13457                 error "crossdir_rename_size error $src_sample"
13458         [[ $tgt_sample -eq 1 ]] ||
13459                 error "crossdir_rename_size error $tgt_sample"
13460         echo "Check cross dir rename stats success"
13461         rm -rf $DIR/${tdir}
13462 }
13463 run_test 133d "Verifying rename_stats ========================================"
13464
13465 test_133e() {
13466         remote_mds_nodsh && skip "remote MDS with nodsh"
13467         remote_ost_nodsh && skip "remote OST with nodsh"
13468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13469
13470         local testdir=$DIR/${tdir}/stats_testdir
13471         local ctr f0 f1 bs=32768 count=42 sum
13472
13473         mkdir -p ${testdir} || error "mkdir failed"
13474
13475         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13476
13477         for ctr in {write,read}_bytes; do
13478                 sync
13479                 cancel_lru_locks osc
13480
13481                 do_facet ost1 $LCTL set_param -n \
13482                         "obdfilter.*.exports.clear=clear"
13483
13484                 if [ $ctr = write_bytes ]; then
13485                         f0=/dev/zero
13486                         f1=${testdir}/${tfile}
13487                 else
13488                         f0=${testdir}/${tfile}
13489                         f1=/dev/null
13490                 fi
13491
13492                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13493                         error "dd failed"
13494                 sync
13495                 cancel_lru_locks osc
13496
13497                 sum=$(do_facet ost1 $LCTL get_param \
13498                         "obdfilter.*.exports.*.stats" |
13499                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13500                                 $1 == ctr { sum += $7 }
13501                                 END { printf("%0.0f", sum) }')
13502
13503                 if ((sum != bs * count)); then
13504                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13505                 fi
13506         done
13507
13508         rm -rf $DIR/${tdir}
13509 }
13510 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13511
13512 test_133f() {
13513         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13514                 skip "too old lustre for get_param -R ($facet_ver)"
13515
13516         # verifying readability.
13517         $LCTL get_param -R '*' &> /dev/null
13518
13519         # Verifing writability with badarea_io.
13520         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13521                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13522                 error "client badarea_io failed"
13523
13524         # remount the FS in case writes/reads /proc break the FS
13525         cleanup || error "failed to unmount"
13526         setup || error "failed to setup"
13527 }
13528 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13529
13530 test_133g() {
13531         remote_mds_nodsh && skip "remote MDS with nodsh"
13532         remote_ost_nodsh && skip "remote OST with nodsh"
13533
13534         local facet
13535         for facet in mds1 ost1; do
13536                 local facet_ver=$(lustre_version_code $facet)
13537                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13538                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13539                 else
13540                         log "$facet: too old lustre for get_param -R"
13541                 fi
13542                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13543                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13544                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13545                                 xargs badarea_io" ||
13546                                         error "$facet badarea_io failed"
13547                 else
13548                         skip_noexit "$facet: too old lustre for get_param -R"
13549                 fi
13550         done
13551
13552         # remount the FS in case writes/reads /proc break the FS
13553         cleanup || error "failed to unmount"
13554         setup || error "failed to setup"
13555 }
13556 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13557
13558 test_133h() {
13559         remote_mds_nodsh && skip "remote MDS with nodsh"
13560         remote_ost_nodsh && skip "remote OST with nodsh"
13561         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13562                 skip "Need MDS version at least 2.9.54"
13563
13564         local facet
13565         for facet in client mds1 ost1; do
13566                 # Get the list of files that are missing the terminating newline
13567                 local plist=$(do_facet $facet
13568                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13569                 local ent
13570                 for ent in $plist; do
13571                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13572                                 awk -v FS='\v' -v RS='\v\v' \
13573                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13574                                         print FILENAME}'" 2>/dev/null)
13575                         [ -z $missing ] || {
13576                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13577                                 error "file does not end with newline: $facet-$ent"
13578                         }
13579                 done
13580         done
13581 }
13582 run_test 133h "Proc files should end with newlines"
13583
13584 test_134a() {
13585         remote_mds_nodsh && skip "remote MDS with nodsh"
13586         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13587                 skip "Need MDS version at least 2.7.54"
13588
13589         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13590         cancel_lru_locks mdc
13591
13592         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13593         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13594         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13595
13596         local nr=1000
13597         createmany -o $DIR/$tdir/f $nr ||
13598                 error "failed to create $nr files in $DIR/$tdir"
13599         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13600
13601         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13602         do_facet mds1 $LCTL set_param fail_loc=0x327
13603         do_facet mds1 $LCTL set_param fail_val=500
13604         touch $DIR/$tdir/m
13605
13606         echo "sleep 10 seconds ..."
13607         sleep 10
13608         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13609
13610         do_facet mds1 $LCTL set_param fail_loc=0
13611         do_facet mds1 $LCTL set_param fail_val=0
13612         [ $lck_cnt -lt $unused ] ||
13613                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13614
13615         rm $DIR/$tdir/m
13616         unlinkmany $DIR/$tdir/f $nr
13617 }
13618 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13619
13620 test_134b() {
13621         remote_mds_nodsh && skip "remote MDS with nodsh"
13622         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13623                 skip "Need MDS version at least 2.7.54"
13624
13625         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13626         cancel_lru_locks mdc
13627
13628         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13629                         ldlm.lock_reclaim_threshold_mb)
13630         # disable reclaim temporarily
13631         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13632
13633         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13634         do_facet mds1 $LCTL set_param fail_loc=0x328
13635         do_facet mds1 $LCTL set_param fail_val=500
13636
13637         $LCTL set_param debug=+trace
13638
13639         local nr=600
13640         createmany -o $DIR/$tdir/f $nr &
13641         local create_pid=$!
13642
13643         echo "Sleep $TIMEOUT seconds ..."
13644         sleep $TIMEOUT
13645         if ! ps -p $create_pid  > /dev/null 2>&1; then
13646                 do_facet mds1 $LCTL set_param fail_loc=0
13647                 do_facet mds1 $LCTL set_param fail_val=0
13648                 do_facet mds1 $LCTL set_param \
13649                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13650                 error "createmany finished incorrectly!"
13651         fi
13652         do_facet mds1 $LCTL set_param fail_loc=0
13653         do_facet mds1 $LCTL set_param fail_val=0
13654         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13655         wait $create_pid || return 1
13656
13657         unlinkmany $DIR/$tdir/f $nr
13658 }
13659 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13660
13661 test_135() {
13662         remote_mds_nodsh && skip "remote MDS with nodsh"
13663         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13664                 skip "Need MDS version at least 2.13.50"
13665         local fname
13666
13667         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13668
13669 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13670         #set only one record at plain llog
13671         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13672
13673         #fill already existed plain llog each 64767
13674         #wrapping whole catalog
13675         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13676
13677         createmany -o $DIR/$tdir/$tfile_ 64700
13678         for (( i = 0; i < 64700; i = i + 2 ))
13679         do
13680                 rm $DIR/$tdir/$tfile_$i &
13681                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13682                 local pid=$!
13683                 wait $pid
13684         done
13685
13686         #waiting osp synchronization
13687         wait_delete_completed
13688 }
13689 run_test 135 "Race catalog processing"
13690
13691 test_136() {
13692         remote_mds_nodsh && skip "remote MDS with nodsh"
13693         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13694                 skip "Need MDS version at least 2.13.50"
13695         local fname
13696
13697         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13698         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13699         #set only one record at plain llog
13700 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13701         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13702
13703         #fill already existed 2 plain llogs each 64767
13704         #wrapping whole catalog
13705         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13706         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13707         wait_delete_completed
13708
13709         createmany -o $DIR/$tdir/$tfile_ 10
13710         sleep 25
13711
13712         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13713         for (( i = 0; i < 10; i = i + 3 ))
13714         do
13715                 rm $DIR/$tdir/$tfile_$i &
13716                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13717                 local pid=$!
13718                 wait $pid
13719                 sleep 7
13720                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13721         done
13722
13723         #waiting osp synchronization
13724         wait_delete_completed
13725 }
13726 run_test 136 "Race catalog processing 2"
13727
13728 test_140() { #bug-17379
13729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13730
13731         test_mkdir $DIR/$tdir
13732         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13733         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13734
13735         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13736         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13737         local i=0
13738         while i=$((i + 1)); do
13739                 test_mkdir $i
13740                 cd $i || error "Changing to $i"
13741                 ln -s ../stat stat || error "Creating stat symlink"
13742                 # Read the symlink until ELOOP present,
13743                 # not LBUGing the system is considered success,
13744                 # we didn't overrun the stack.
13745                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13746                 if [ $ret -ne 0 ]; then
13747                         if [ $ret -eq 40 ]; then
13748                                 break  # -ELOOP
13749                         else
13750                                 error "Open stat symlink"
13751                                         return
13752                         fi
13753                 fi
13754         done
13755         i=$((i - 1))
13756         echo "The symlink depth = $i"
13757         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13758                 error "Invalid symlink depth"
13759
13760         # Test recursive symlink
13761         ln -s symlink_self symlink_self
13762         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13763         echo "open symlink_self returns $ret"
13764         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13765 }
13766 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13767
13768 test_150a() {
13769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13770
13771         local TF="$TMP/$tfile"
13772
13773         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13774         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13775         cp $TF $DIR/$tfile
13776         cancel_lru_locks $OSC
13777         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13778         remount_client $MOUNT
13779         df -P $MOUNT
13780         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13781
13782         $TRUNCATE $TF 6000
13783         $TRUNCATE $DIR/$tfile 6000
13784         cancel_lru_locks $OSC
13785         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13786
13787         echo "12345" >>$TF
13788         echo "12345" >>$DIR/$tfile
13789         cancel_lru_locks $OSC
13790         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13791
13792         echo "12345" >>$TF
13793         echo "12345" >>$DIR/$tfile
13794         cancel_lru_locks $OSC
13795         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13796 }
13797 run_test 150a "truncate/append tests"
13798
13799 test_150b() {
13800         check_set_fallocate_or_skip
13801
13802         touch $DIR/$tfile
13803         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13804         check_fallocate $DIR/$tfile || error "fallocate failed"
13805 }
13806 run_test 150b "Verify fallocate (prealloc) functionality"
13807
13808 test_150bb() {
13809         check_set_fallocate_or_skip
13810
13811         touch $DIR/$tfile
13812         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13813         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13814         > $DIR/$tfile
13815         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13816         # precomputed md5sum for 20MB of zeroes
13817         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13818         local sum=($(md5sum $DIR/$tfile))
13819
13820         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13821
13822         check_set_fallocate 1
13823
13824         > $DIR/$tfile
13825         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13826         sum=($(md5sum $DIR/$tfile))
13827
13828         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13829 }
13830 run_test 150bb "Verify fallocate modes both zero space"
13831
13832 test_150c() {
13833         check_set_fallocate_or_skip
13834
13835         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13836         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13837         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13838         sync; sync_all_data
13839         cancel_lru_locks $OSC
13840         sleep 5
13841         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13842         want=$((OSTCOUNT * 1048576))
13843
13844         # Must allocate all requested space, not more than 5% extra
13845         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13846                 error "bytes $bytes is not $want"
13847
13848         rm -f $DIR/$tfile
13849         # verify fallocate on PFL file
13850         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13851                 error "Create $DIR/$tfile failed"
13852         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13853                         error "fallocate failed"
13854         sync; sync_all_data
13855         cancel_lru_locks $OSC
13856         sleep 5
13857         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13858         local want=$((1024 * 1048576))
13859
13860         # Must allocate all requested space, not more than 5% extra
13861         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13862                 error "bytes $bytes is not $want"
13863 }
13864 run_test 150c "Verify fallocate Size and Blocks"
13865
13866 test_150d() {
13867         check_set_fallocate_or_skip
13868
13869         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13870         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13871         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13872         sync; sync_all_data
13873         cancel_lru_locks $OSC
13874         sleep 5
13875         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13876         local want=$((OSTCOUNT * 1048576))
13877
13878         # Must allocate all requested space, not more than 5% extra
13879         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13880                 error "bytes $bytes is not $want"
13881 }
13882 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13883
13884 test_150e() {
13885         check_set_fallocate_or_skip
13886
13887         echo "df before:"
13888         $LFS df
13889         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13890         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13891                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13892
13893         # Find OST with Minimum Size
13894         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13895                        sort -un | head -1)
13896
13897         # Get 100MB per OST of the available space to reduce run time
13898         # else 60% of the available space if we are running SLOW tests
13899         if [ $SLOW == "no" ]; then
13900                 local space=$((1024 * 100 * OSTCOUNT))
13901         else
13902                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
13903         fi
13904
13905         fallocate -l${space}k $DIR/$tfile ||
13906                 error "fallocate ${space}k $DIR/$tfile failed"
13907         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13908
13909         # get size immediately after fallocate. This should be correctly
13910         # updated
13911         local size=$(stat -c '%s' $DIR/$tfile)
13912         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13913
13914         # Sleep for a while for statfs to get updated. And not pull from cache.
13915         sleep 2
13916
13917         echo "df after fallocate:"
13918         $LFS df
13919
13920         (( size / 1024 == space )) || error "size $size != requested $space"
13921         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13922                 error "used $used < space $space"
13923
13924         rm $DIR/$tfile || error "rm failed"
13925         sync
13926         wait_delete_completed
13927
13928         echo "df after unlink:"
13929         $LFS df
13930 }
13931 run_test 150e "Verify 60% of available OST space consumed by fallocate"
13932
13933 test_150f() {
13934         local size
13935         local blocks
13936         local want_size_before=20480 # in bytes
13937         local want_blocks_before=40 # 512 sized blocks
13938         local want_blocks_after=24  # 512 sized blocks
13939         local length=$(((want_blocks_before - want_blocks_after) * 512))
13940
13941         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
13942                 skip "need at least 2.14.0 for fallocate punch"
13943
13944         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
13945                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
13946         fi
13947
13948         check_set_fallocate_or_skip
13949         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13950
13951         echo "Verify fallocate punch: Range within the file range"
13952         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
13953                 error "dd failed for bs 4096 and count 5"
13954
13955         # Call fallocate with punch range which is within the file range
13956         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
13957                 error "fallocate failed: offset 4096 and length $length"
13958         # client must see changes immediately after fallocate
13959         size=$(stat -c '%s' $DIR/$tfile)
13960         blocks=$(stat -c '%b' $DIR/$tfile)
13961
13962         # Verify punch worked.
13963         (( blocks == want_blocks_after )) ||
13964                 error "punch failed: blocks $blocks != $want_blocks_after"
13965
13966         (( size == want_size_before )) ||
13967                 error "punch failed: size $size != $want_size_before"
13968
13969         # Verify there is hole in file
13970         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
13971         # precomputed md5sum
13972         local expect="4a9a834a2db02452929c0a348273b4aa"
13973
13974         cksum=($(md5sum $DIR/$tfile))
13975         [[ "${cksum[0]}" == "$expect" ]] ||
13976                 error "unexpected MD5SUM after punch: ${cksum[0]}"
13977
13978         # Start second sub-case for fallocate punch.
13979         echo "Verify fallocate punch: Range overlapping and less than blocksize"
13980         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
13981                 error "dd failed for bs 4096 and count 5"
13982
13983         # Punch range less than block size will have no change in block count
13984         want_blocks_after=40  # 512 sized blocks
13985
13986         # Punch overlaps two blocks and less than blocksize
13987         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
13988                 error "fallocate failed: offset 4000 length 3000"
13989         size=$(stat -c '%s' $DIR/$tfile)
13990         blocks=$(stat -c '%b' $DIR/$tfile)
13991
13992         # Verify punch worked.
13993         (( blocks == want_blocks_after )) ||
13994                 error "punch failed: blocks $blocks != $want_blocks_after"
13995
13996         (( size == want_size_before )) ||
13997                 error "punch failed: size $size != $want_size_before"
13998
13999         # Verify if range is really zero'ed out. We expect Zeros.
14000         # precomputed md5sum
14001         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14002         cksum=($(md5sum $DIR/$tfile))
14003         [[ "${cksum[0]}" == "$expect" ]] ||
14004                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14005 }
14006 run_test 150f "Verify fallocate punch functionality"
14007
14008 test_150g() {
14009         local space
14010         local size
14011         local blocks
14012         local blocks_after
14013         local size_after
14014         local BS=4096 # Block size in bytes
14015
14016         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14017                 skip "need at least 2.14.0 for fallocate punch"
14018
14019         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14020                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14021         fi
14022
14023         check_set_fallocate_or_skip
14024         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14025
14026         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14027                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14028
14029         # Get 100MB per OST of the available space to reduce run time
14030         # else 60% of the available space if we are running SLOW tests
14031         if [ $SLOW == "no" ]; then
14032                 space=$((1024 * 100 * OSTCOUNT))
14033         else
14034                 # Find OST with Minimum Size
14035                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14036                         sort -un | head -1)
14037                 echo "min size OST: $space"
14038                 space=$(((space * 60)/100 * OSTCOUNT))
14039         fi
14040         # space in 1k units, round to 4k blocks
14041         local blkcount=$((space * 1024 / $BS))
14042
14043         echo "Verify fallocate punch: Very large Range"
14044         fallocate -l${space}k $DIR/$tfile ||
14045                 error "fallocate ${space}k $DIR/$tfile failed"
14046         # write 1M at the end, start and in the middle
14047         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14048                 error "dd failed: bs $BS count 256"
14049         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14050                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14051         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14052                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14053
14054         # Gather stats.
14055         size=$(stat -c '%s' $DIR/$tfile)
14056
14057         # gather punch length.
14058         local punch_size=$((size - (BS * 2)))
14059
14060         echo "punch_size = $punch_size"
14061         echo "size - punch_size: $((size - punch_size))"
14062         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14063
14064         # Call fallocate to punch all except 2 blocks. We leave the
14065         # first and the last block
14066         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14067         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14068                 error "fallocate failed: offset $BS length $punch_size"
14069
14070         size_after=$(stat -c '%s' $DIR/$tfile)
14071         blocks_after=$(stat -c '%b' $DIR/$tfile)
14072
14073         # Verify punch worked.
14074         # Size should be kept
14075         (( size == size_after )) ||
14076                 error "punch failed: size $size != $size_after"
14077
14078         # two 4k data blocks to remain plus possible 1 extra extent block
14079         (( blocks_after <= ((BS / 512) * 3) )) ||
14080                 error "too many blocks remains: $blocks_after"
14081
14082         # Verify that file has hole between the first and the last blocks
14083         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14084         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14085
14086         echo "Hole at [$hole_start, $hole_end)"
14087         (( hole_start == BS )) ||
14088                 error "no hole at offset $BS after punch"
14089
14090         (( hole_end == BS + punch_size )) ||
14091                 error "data at offset $hole_end < $((BS + punch_size))"
14092 }
14093 run_test 150g "Verify fallocate punch on large range"
14094
14095 #LU-2902 roc_hit was not able to read all values from lproc
14096 function roc_hit_init() {
14097         local list=$(comma_list $(osts_nodes))
14098         local dir=$DIR/$tdir-check
14099         local file=$dir/$tfile
14100         local BEFORE
14101         local AFTER
14102         local idx
14103
14104         test_mkdir $dir
14105         #use setstripe to do a write to every ost
14106         for i in $(seq 0 $((OSTCOUNT-1))); do
14107                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14108                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14109                 idx=$(printf %04x $i)
14110                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14111                         awk '$1 == "cache_access" {sum += $7}
14112                                 END { printf("%0.0f", sum) }')
14113
14114                 cancel_lru_locks osc
14115                 cat $file >/dev/null
14116
14117                 AFTER=$(get_osd_param $list *OST*$idx stats |
14118                         awk '$1 == "cache_access" {sum += $7}
14119                                 END { printf("%0.0f", sum) }')
14120
14121                 echo BEFORE:$BEFORE AFTER:$AFTER
14122                 if ! let "AFTER - BEFORE == 4"; then
14123                         rm -rf $dir
14124                         error "roc_hit is not safe to use"
14125                 fi
14126                 rm $file
14127         done
14128
14129         rm -rf $dir
14130 }
14131
14132 function roc_hit() {
14133         local list=$(comma_list $(osts_nodes))
14134         echo $(get_osd_param $list '' stats |
14135                 awk '$1 == "cache_hit" {sum += $7}
14136                         END { printf("%0.0f", sum) }')
14137 }
14138
14139 function set_cache() {
14140         local on=1
14141
14142         if [ "$2" == "off" ]; then
14143                 on=0;
14144         fi
14145         local list=$(comma_list $(osts_nodes))
14146         set_osd_param $list '' $1_cache_enable $on
14147
14148         cancel_lru_locks osc
14149 }
14150
14151 test_151() {
14152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14153         remote_ost_nodsh && skip "remote OST with nodsh"
14154
14155         local CPAGES=3
14156         local list=$(comma_list $(osts_nodes))
14157
14158         # check whether obdfilter is cache capable at all
14159         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14160                 skip "not cache-capable obdfilter"
14161         fi
14162
14163         # check cache is enabled on all obdfilters
14164         if get_osd_param $list '' read_cache_enable | grep 0; then
14165                 skip "oss cache is disabled"
14166         fi
14167
14168         set_osd_param $list '' writethrough_cache_enable 1
14169
14170         # check write cache is enabled on all obdfilters
14171         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14172                 skip "oss write cache is NOT enabled"
14173         fi
14174
14175         roc_hit_init
14176
14177         #define OBD_FAIL_OBD_NO_LRU  0x609
14178         do_nodes $list $LCTL set_param fail_loc=0x609
14179
14180         # pages should be in the case right after write
14181         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14182                 error "dd failed"
14183
14184         local BEFORE=$(roc_hit)
14185         cancel_lru_locks osc
14186         cat $DIR/$tfile >/dev/null
14187         local AFTER=$(roc_hit)
14188
14189         do_nodes $list $LCTL set_param fail_loc=0
14190
14191         if ! let "AFTER - BEFORE == CPAGES"; then
14192                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14193         fi
14194
14195         cancel_lru_locks osc
14196         # invalidates OST cache
14197         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14198         set_osd_param $list '' read_cache_enable 0
14199         cat $DIR/$tfile >/dev/null
14200
14201         # now data shouldn't be found in the cache
14202         BEFORE=$(roc_hit)
14203         cancel_lru_locks osc
14204         cat $DIR/$tfile >/dev/null
14205         AFTER=$(roc_hit)
14206         if let "AFTER - BEFORE != 0"; then
14207                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14208         fi
14209
14210         set_osd_param $list '' read_cache_enable 1
14211         rm -f $DIR/$tfile
14212 }
14213 run_test 151 "test cache on oss and controls ==============================="
14214
14215 test_152() {
14216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14217
14218         local TF="$TMP/$tfile"
14219
14220         # simulate ENOMEM during write
14221 #define OBD_FAIL_OST_NOMEM      0x226
14222         lctl set_param fail_loc=0x80000226
14223         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14224         cp $TF $DIR/$tfile
14225         sync || error "sync failed"
14226         lctl set_param fail_loc=0
14227
14228         # discard client's cache
14229         cancel_lru_locks osc
14230
14231         # simulate ENOMEM during read
14232         lctl set_param fail_loc=0x80000226
14233         cmp $TF $DIR/$tfile || error "cmp failed"
14234         lctl set_param fail_loc=0
14235
14236         rm -f $TF
14237 }
14238 run_test 152 "test read/write with enomem ============================"
14239
14240 test_153() {
14241         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14242 }
14243 run_test 153 "test if fdatasync does not crash ======================="
14244
14245 dot_lustre_fid_permission_check() {
14246         local fid=$1
14247         local ffid=$MOUNT/.lustre/fid/$fid
14248         local test_dir=$2
14249
14250         echo "stat fid $fid"
14251         stat $ffid > /dev/null || error "stat $ffid failed."
14252         echo "touch fid $fid"
14253         touch $ffid || error "touch $ffid failed."
14254         echo "write to fid $fid"
14255         cat /etc/hosts > $ffid || error "write $ffid failed."
14256         echo "read fid $fid"
14257         diff /etc/hosts $ffid || error "read $ffid failed."
14258         echo "append write to fid $fid"
14259         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14260         echo "rename fid $fid"
14261         mv $ffid $test_dir/$tfile.1 &&
14262                 error "rename $ffid to $tfile.1 should fail."
14263         touch $test_dir/$tfile.1
14264         mv $test_dir/$tfile.1 $ffid &&
14265                 error "rename $tfile.1 to $ffid should fail."
14266         rm -f $test_dir/$tfile.1
14267         echo "truncate fid $fid"
14268         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14269         echo "link fid $fid"
14270         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14271         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14272                 echo "setfacl fid $fid"
14273                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14274                 echo "getfacl fid $fid"
14275                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14276         fi
14277         echo "unlink fid $fid"
14278         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14279         echo "mknod fid $fid"
14280         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14281
14282         fid=[0xf00000400:0x1:0x0]
14283         ffid=$MOUNT/.lustre/fid/$fid
14284
14285         echo "stat non-exist fid $fid"
14286         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14287         echo "write to non-exist fid $fid"
14288         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14289         echo "link new fid $fid"
14290         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14291
14292         mkdir -p $test_dir/$tdir
14293         touch $test_dir/$tdir/$tfile
14294         fid=$($LFS path2fid $test_dir/$tdir)
14295         rc=$?
14296         [ $rc -ne 0 ] &&
14297                 error "error: could not get fid for $test_dir/$dir/$tfile."
14298
14299         ffid=$MOUNT/.lustre/fid/$fid
14300
14301         echo "ls $fid"
14302         ls $ffid > /dev/null || error "ls $ffid failed."
14303         echo "touch $fid/$tfile.1"
14304         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14305
14306         echo "touch $MOUNT/.lustre/fid/$tfile"
14307         touch $MOUNT/.lustre/fid/$tfile && \
14308                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14309
14310         echo "setxattr to $MOUNT/.lustre/fid"
14311         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14312
14313         echo "listxattr for $MOUNT/.lustre/fid"
14314         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14315
14316         echo "delxattr from $MOUNT/.lustre/fid"
14317         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14318
14319         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14320         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14321                 error "touch invalid fid should fail."
14322
14323         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14324         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14325                 error "touch non-normal fid should fail."
14326
14327         echo "rename $tdir to $MOUNT/.lustre/fid"
14328         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14329                 error "rename to $MOUNT/.lustre/fid should fail."
14330
14331         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14332         then            # LU-3547
14333                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14334                 local new_obf_mode=777
14335
14336                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14337                 chmod $new_obf_mode $DIR/.lustre/fid ||
14338                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14339
14340                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14341                 [ $obf_mode -eq $new_obf_mode ] ||
14342                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14343
14344                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14345                 chmod $old_obf_mode $DIR/.lustre/fid ||
14346                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14347         fi
14348
14349         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14350         fid=$($LFS path2fid $test_dir/$tfile-2)
14351
14352         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14353         then # LU-5424
14354                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14355                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14356                         error "create lov data thru .lustre failed"
14357         fi
14358         echo "cp /etc/passwd $test_dir/$tfile-2"
14359         cp /etc/passwd $test_dir/$tfile-2 ||
14360                 error "copy to $test_dir/$tfile-2 failed."
14361         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14362         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14363                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14364
14365         rm -rf $test_dir/tfile.lnk
14366         rm -rf $test_dir/$tfile-2
14367 }
14368
14369 test_154A() {
14370         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14371                 skip "Need MDS version at least 2.4.1"
14372
14373         local tf=$DIR/$tfile
14374         touch $tf
14375
14376         local fid=$($LFS path2fid $tf)
14377         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14378
14379         # check that we get the same pathname back
14380         local rootpath
14381         local found
14382         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14383                 echo "$rootpath $fid"
14384                 found=$($LFS fid2path $rootpath "$fid")
14385                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14386                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14387         done
14388
14389         # check wrong root path format
14390         rootpath=$MOUNT"_wrong"
14391         found=$($LFS fid2path $rootpath "$fid")
14392         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14393 }
14394 run_test 154A "lfs path2fid and fid2path basic checks"
14395
14396 test_154B() {
14397         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14398                 skip "Need MDS version at least 2.4.1"
14399
14400         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14401         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14402         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14403         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14404
14405         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14406         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14407
14408         # check that we get the same pathname
14409         echo "PFID: $PFID, name: $name"
14410         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14411         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14412         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14413                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14414
14415         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14416 }
14417 run_test 154B "verify the ll_decode_linkea tool"
14418
14419 test_154a() {
14420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14421         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14422         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14423                 skip "Need MDS version at least 2.2.51"
14424         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14425
14426         cp /etc/hosts $DIR/$tfile
14427
14428         fid=$($LFS path2fid $DIR/$tfile)
14429         rc=$?
14430         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14431
14432         dot_lustre_fid_permission_check "$fid" $DIR ||
14433                 error "dot lustre permission check $fid failed"
14434
14435         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14436
14437         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14438
14439         touch $MOUNT/.lustre/file &&
14440                 error "creation is not allowed under .lustre"
14441
14442         mkdir $MOUNT/.lustre/dir &&
14443                 error "mkdir is not allowed under .lustre"
14444
14445         rm -rf $DIR/$tfile
14446 }
14447 run_test 154a "Open-by-FID"
14448
14449 test_154b() {
14450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14451         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14452         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14453         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14454                 skip "Need MDS version at least 2.2.51"
14455
14456         local remote_dir=$DIR/$tdir/remote_dir
14457         local MDTIDX=1
14458         local rc=0
14459
14460         mkdir -p $DIR/$tdir
14461         $LFS mkdir -i $MDTIDX $remote_dir ||
14462                 error "create remote directory failed"
14463
14464         cp /etc/hosts $remote_dir/$tfile
14465
14466         fid=$($LFS path2fid $remote_dir/$tfile)
14467         rc=$?
14468         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14469
14470         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14471                 error "dot lustre permission check $fid failed"
14472         rm -rf $DIR/$tdir
14473 }
14474 run_test 154b "Open-by-FID for remote directory"
14475
14476 test_154c() {
14477         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14478                 skip "Need MDS version at least 2.4.1"
14479
14480         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14481         local FID1=$($LFS path2fid $DIR/$tfile.1)
14482         local FID2=$($LFS path2fid $DIR/$tfile.2)
14483         local FID3=$($LFS path2fid $DIR/$tfile.3)
14484
14485         local N=1
14486         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14487                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14488                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14489                 local want=FID$N
14490                 [ "$FID" = "${!want}" ] ||
14491                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14492                 N=$((N + 1))
14493         done
14494
14495         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14496         do
14497                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14498                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14499                 N=$((N + 1))
14500         done
14501 }
14502 run_test 154c "lfs path2fid and fid2path multiple arguments"
14503
14504 test_154d() {
14505         remote_mds_nodsh && skip "remote MDS with nodsh"
14506         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14507                 skip "Need MDS version at least 2.5.53"
14508
14509         if remote_mds; then
14510                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14511         else
14512                 nid="0@lo"
14513         fi
14514         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14515         local fd
14516         local cmd
14517
14518         rm -f $DIR/$tfile
14519         touch $DIR/$tfile
14520
14521         local fid=$($LFS path2fid $DIR/$tfile)
14522         # Open the file
14523         fd=$(free_fd)
14524         cmd="exec $fd<$DIR/$tfile"
14525         eval $cmd
14526         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14527         echo "$fid_list" | grep "$fid"
14528         rc=$?
14529
14530         cmd="exec $fd>/dev/null"
14531         eval $cmd
14532         if [ $rc -ne 0 ]; then
14533                 error "FID $fid not found in open files list $fid_list"
14534         fi
14535 }
14536 run_test 154d "Verify open file fid"
14537
14538 test_154e()
14539 {
14540         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14541                 skip "Need MDS version at least 2.6.50"
14542
14543         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14544                 error ".lustre returned by readdir"
14545         fi
14546 }
14547 run_test 154e ".lustre is not returned by readdir"
14548
14549 test_154f() {
14550         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14551
14552         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14553         test_mkdir -p -c1 $DIR/$tdir/d
14554         # test dirs inherit from its stripe
14555         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14556         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14557         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14558         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14559         touch $DIR/f
14560
14561         # get fid of parents
14562         local FID0=$($LFS path2fid $DIR/$tdir/d)
14563         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14564         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14565         local FID3=$($LFS path2fid $DIR)
14566
14567         # check that path2fid --parents returns expected <parent_fid>/name
14568         # 1) test for a directory (single parent)
14569         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14570         [ "$parent" == "$FID0/foo1" ] ||
14571                 error "expected parent: $FID0/foo1, got: $parent"
14572
14573         # 2) test for a file with nlink > 1 (multiple parents)
14574         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14575         echo "$parent" | grep -F "$FID1/$tfile" ||
14576                 error "$FID1/$tfile not returned in parent list"
14577         echo "$parent" | grep -F "$FID2/link" ||
14578                 error "$FID2/link not returned in parent list"
14579
14580         # 3) get parent by fid
14581         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14582         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14583         echo "$parent" | grep -F "$FID1/$tfile" ||
14584                 error "$FID1/$tfile not returned in parent list (by fid)"
14585         echo "$parent" | grep -F "$FID2/link" ||
14586                 error "$FID2/link not returned in parent list (by fid)"
14587
14588         # 4) test for entry in root directory
14589         parent=$($LFS path2fid --parents $DIR/f)
14590         echo "$parent" | grep -F "$FID3/f" ||
14591                 error "$FID3/f not returned in parent list"
14592
14593         # 5) test it on root directory
14594         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14595                 error "$MOUNT should not have parents"
14596
14597         # enable xattr caching and check that linkea is correctly updated
14598         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14599         save_lustre_params client "llite.*.xattr_cache" > $save
14600         lctl set_param llite.*.xattr_cache 1
14601
14602         # 6.1) linkea update on rename
14603         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14604
14605         # get parents by fid
14606         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14607         # foo1 should no longer be returned in parent list
14608         echo "$parent" | grep -F "$FID1" &&
14609                 error "$FID1 should no longer be in parent list"
14610         # the new path should appear
14611         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14612                 error "$FID2/$tfile.moved is not in parent list"
14613
14614         # 6.2) linkea update on unlink
14615         rm -f $DIR/$tdir/d/foo2/link
14616         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14617         # foo2/link should no longer be returned in parent list
14618         echo "$parent" | grep -F "$FID2/link" &&
14619                 error "$FID2/link should no longer be in parent list"
14620         true
14621
14622         rm -f $DIR/f
14623         restore_lustre_params < $save
14624         rm -f $save
14625 }
14626 run_test 154f "get parent fids by reading link ea"
14627
14628 test_154g()
14629 {
14630         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14631         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14632            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14633                 skip "Need MDS version at least 2.6.92"
14634
14635         mkdir -p $DIR/$tdir
14636         llapi_fid_test -d $DIR/$tdir
14637 }
14638 run_test 154g "various llapi FID tests"
14639
14640 test_155_small_load() {
14641     local temp=$TMP/$tfile
14642     local file=$DIR/$tfile
14643
14644     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14645         error "dd of=$temp bs=6096 count=1 failed"
14646     cp $temp $file
14647     cancel_lru_locks $OSC
14648     cmp $temp $file || error "$temp $file differ"
14649
14650     $TRUNCATE $temp 6000
14651     $TRUNCATE $file 6000
14652     cmp $temp $file || error "$temp $file differ (truncate1)"
14653
14654     echo "12345" >>$temp
14655     echo "12345" >>$file
14656     cmp $temp $file || error "$temp $file differ (append1)"
14657
14658     echo "12345" >>$temp
14659     echo "12345" >>$file
14660     cmp $temp $file || error "$temp $file differ (append2)"
14661
14662     rm -f $temp $file
14663     true
14664 }
14665
14666 test_155_big_load() {
14667         remote_ost_nodsh && skip "remote OST with nodsh"
14668
14669         local temp=$TMP/$tfile
14670         local file=$DIR/$tfile
14671
14672         free_min_max
14673         local cache_size=$(do_facet ost$((MAXI+1)) \
14674                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14675         local large_file_size=$((cache_size * 2))
14676
14677         echo "OSS cache size: $cache_size KB"
14678         echo "Large file size: $large_file_size KB"
14679
14680         [ $MAXV -le $large_file_size ] &&
14681                 skip_env "max available OST size needs > $large_file_size KB"
14682
14683         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14684
14685         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14686                 error "dd of=$temp bs=$large_file_size count=1k failed"
14687         cp $temp $file
14688         ls -lh $temp $file
14689         cancel_lru_locks osc
14690         cmp $temp $file || error "$temp $file differ"
14691
14692         rm -f $temp $file
14693         true
14694 }
14695
14696 save_writethrough() {
14697         local facets=$(get_facets OST)
14698
14699         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14700 }
14701
14702 test_155a() {
14703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14704
14705         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14706
14707         save_writethrough $p
14708
14709         set_cache read on
14710         set_cache writethrough on
14711         test_155_small_load
14712         restore_lustre_params < $p
14713         rm -f $p
14714 }
14715 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14716
14717 test_155b() {
14718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14719
14720         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14721
14722         save_writethrough $p
14723
14724         set_cache read on
14725         set_cache writethrough off
14726         test_155_small_load
14727         restore_lustre_params < $p
14728         rm -f $p
14729 }
14730 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14731
14732 test_155c() {
14733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14734
14735         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14736
14737         save_writethrough $p
14738
14739         set_cache read off
14740         set_cache writethrough on
14741         test_155_small_load
14742         restore_lustre_params < $p
14743         rm -f $p
14744 }
14745 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14746
14747 test_155d() {
14748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14749
14750         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14751
14752         save_writethrough $p
14753
14754         set_cache read off
14755         set_cache writethrough off
14756         test_155_small_load
14757         restore_lustre_params < $p
14758         rm -f $p
14759 }
14760 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14761
14762 test_155e() {
14763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14764
14765         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14766
14767         save_writethrough $p
14768
14769         set_cache read on
14770         set_cache writethrough on
14771         test_155_big_load
14772         restore_lustre_params < $p
14773         rm -f $p
14774 }
14775 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14776
14777 test_155f() {
14778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14779
14780         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14781
14782         save_writethrough $p
14783
14784         set_cache read on
14785         set_cache writethrough off
14786         test_155_big_load
14787         restore_lustre_params < $p
14788         rm -f $p
14789 }
14790 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14791
14792 test_155g() {
14793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14794
14795         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14796
14797         save_writethrough $p
14798
14799         set_cache read off
14800         set_cache writethrough on
14801         test_155_big_load
14802         restore_lustre_params < $p
14803         rm -f $p
14804 }
14805 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14806
14807 test_155h() {
14808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14809
14810         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14811
14812         save_writethrough $p
14813
14814         set_cache read off
14815         set_cache writethrough off
14816         test_155_big_load
14817         restore_lustre_params < $p
14818         rm -f $p
14819 }
14820 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14821
14822 test_156() {
14823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14824         remote_ost_nodsh && skip "remote OST with nodsh"
14825         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14826                 skip "stats not implemented on old servers"
14827         [ "$ost1_FSTYPE" = "zfs" ] &&
14828                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14829
14830         local CPAGES=3
14831         local BEFORE
14832         local AFTER
14833         local file="$DIR/$tfile"
14834         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14835
14836         save_writethrough $p
14837         roc_hit_init
14838
14839         log "Turn on read and write cache"
14840         set_cache read on
14841         set_cache writethrough on
14842
14843         log "Write data and read it back."
14844         log "Read should be satisfied from the cache."
14845         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14846         BEFORE=$(roc_hit)
14847         cancel_lru_locks osc
14848         cat $file >/dev/null
14849         AFTER=$(roc_hit)
14850         if ! let "AFTER - BEFORE == CPAGES"; then
14851                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14852         else
14853                 log "cache hits: before: $BEFORE, after: $AFTER"
14854         fi
14855
14856         log "Read again; it should be satisfied from the cache."
14857         BEFORE=$AFTER
14858         cancel_lru_locks osc
14859         cat $file >/dev/null
14860         AFTER=$(roc_hit)
14861         if ! let "AFTER - BEFORE == CPAGES"; then
14862                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14863         else
14864                 log "cache hits:: before: $BEFORE, after: $AFTER"
14865         fi
14866
14867         log "Turn off the read cache and turn on the write cache"
14868         set_cache read off
14869         set_cache writethrough on
14870
14871         log "Read again; it should be satisfied from the cache."
14872         BEFORE=$(roc_hit)
14873         cancel_lru_locks osc
14874         cat $file >/dev/null
14875         AFTER=$(roc_hit)
14876         if ! let "AFTER - BEFORE == CPAGES"; then
14877                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14878         else
14879                 log "cache hits:: before: $BEFORE, after: $AFTER"
14880         fi
14881
14882         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14883                 # > 2.12.56 uses pagecache if cached
14884                 log "Read again; it should not be satisfied from the cache."
14885                 BEFORE=$AFTER
14886                 cancel_lru_locks osc
14887                 cat $file >/dev/null
14888                 AFTER=$(roc_hit)
14889                 if ! let "AFTER - BEFORE == 0"; then
14890                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14891                 else
14892                         log "cache hits:: before: $BEFORE, after: $AFTER"
14893                 fi
14894         fi
14895
14896         log "Write data and read it back."
14897         log "Read should be satisfied from the cache."
14898         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14899         BEFORE=$(roc_hit)
14900         cancel_lru_locks osc
14901         cat $file >/dev/null
14902         AFTER=$(roc_hit)
14903         if ! let "AFTER - BEFORE == CPAGES"; then
14904                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14905         else
14906                 log "cache hits:: before: $BEFORE, after: $AFTER"
14907         fi
14908
14909         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14910                 # > 2.12.56 uses pagecache if cached
14911                 log "Read again; it should not be satisfied from the cache."
14912                 BEFORE=$AFTER
14913                 cancel_lru_locks osc
14914                 cat $file >/dev/null
14915                 AFTER=$(roc_hit)
14916                 if ! let "AFTER - BEFORE == 0"; then
14917                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14918                 else
14919                         log "cache hits:: before: $BEFORE, after: $AFTER"
14920                 fi
14921         fi
14922
14923         log "Turn off read and write cache"
14924         set_cache read off
14925         set_cache writethrough off
14926
14927         log "Write data and read it back"
14928         log "It should not be satisfied from the cache."
14929         rm -f $file
14930         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14931         cancel_lru_locks osc
14932         BEFORE=$(roc_hit)
14933         cat $file >/dev/null
14934         AFTER=$(roc_hit)
14935         if ! let "AFTER - BEFORE == 0"; then
14936                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14937         else
14938                 log "cache hits:: before: $BEFORE, after: $AFTER"
14939         fi
14940
14941         log "Turn on the read cache and turn off the write cache"
14942         set_cache read on
14943         set_cache writethrough off
14944
14945         log "Write data and read it back"
14946         log "It should not be satisfied from the cache."
14947         rm -f $file
14948         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14949         BEFORE=$(roc_hit)
14950         cancel_lru_locks osc
14951         cat $file >/dev/null
14952         AFTER=$(roc_hit)
14953         if ! let "AFTER - BEFORE == 0"; then
14954                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14955         else
14956                 log "cache hits:: before: $BEFORE, after: $AFTER"
14957         fi
14958
14959         log "Read again; it should be satisfied from the cache."
14960         BEFORE=$(roc_hit)
14961         cancel_lru_locks osc
14962         cat $file >/dev/null
14963         AFTER=$(roc_hit)
14964         if ! let "AFTER - BEFORE == CPAGES"; then
14965                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14966         else
14967                 log "cache hits:: before: $BEFORE, after: $AFTER"
14968         fi
14969
14970         restore_lustre_params < $p
14971         rm -f $p $file
14972 }
14973 run_test 156 "Verification of tunables"
14974
14975 test_160a() {
14976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14977         remote_mds_nodsh && skip "remote MDS with nodsh"
14978         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14979                 skip "Need MDS version at least 2.2.0"
14980
14981         changelog_register || error "changelog_register failed"
14982         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14983         changelog_users $SINGLEMDS | grep -q $cl_user ||
14984                 error "User $cl_user not found in changelog_users"
14985
14986         # change something
14987         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14988         changelog_clear 0 || error "changelog_clear failed"
14989         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14990         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14991         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14992         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14993         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14994         rm $DIR/$tdir/pics/desktop.jpg
14995
14996         changelog_dump | tail -10
14997
14998         echo "verifying changelog mask"
14999         changelog_chmask "-MKDIR"
15000         changelog_chmask "-CLOSE"
15001
15002         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15003         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15004
15005         changelog_chmask "+MKDIR"
15006         changelog_chmask "+CLOSE"
15007
15008         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15009         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15010
15011         changelog_dump | tail -10
15012         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15013         CLOSES=$(changelog_dump | grep -c "CLOSE")
15014         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15015         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15016
15017         # verify contents
15018         echo "verifying target fid"
15019         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15020         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15021         [ "$fidc" == "$fidf" ] ||
15022                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15023         echo "verifying parent fid"
15024         # The FID returned from the Changelog may be the directory shard on
15025         # a different MDT, and not the FID returned by path2fid on the parent.
15026         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15027         # since this is what will matter when recreating this file in the tree.
15028         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15029         local pathp=$($LFS fid2path $MOUNT "$fidp")
15030         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15031                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15032
15033         echo "getting records for $cl_user"
15034         changelog_users $SINGLEMDS
15035         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15036         local nclr=3
15037         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15038                 error "changelog_clear failed"
15039         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15040         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15041         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15042                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15043
15044         local min0_rec=$(changelog_users $SINGLEMDS |
15045                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15046         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15047                           awk '{ print $1; exit; }')
15048
15049         changelog_dump | tail -n 5
15050         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15051         [ $first_rec == $((min0_rec + 1)) ] ||
15052                 error "first index should be $min0_rec + 1 not $first_rec"
15053
15054         # LU-3446 changelog index reset on MDT restart
15055         local cur_rec1=$(changelog_users $SINGLEMDS |
15056                          awk '/^current.index:/ { print $NF }')
15057         changelog_clear 0 ||
15058                 error "clear all changelog records for $cl_user failed"
15059         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15060         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15061                 error "Fail to start $SINGLEMDS"
15062         local cur_rec2=$(changelog_users $SINGLEMDS |
15063                          awk '/^current.index:/ { print $NF }')
15064         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15065         [ $cur_rec1 == $cur_rec2 ] ||
15066                 error "current index should be $cur_rec1 not $cur_rec2"
15067
15068         echo "verifying users from this test are deregistered"
15069         changelog_deregister || error "changelog_deregister failed"
15070         changelog_users $SINGLEMDS | grep -q $cl_user &&
15071                 error "User '$cl_user' still in changelog_users"
15072
15073         # lctl get_param -n mdd.*.changelog_users
15074         # current index: 144
15075         # ID    index (idle seconds)
15076         # cl3   144 (2)
15077         if ! changelog_users $SINGLEMDS | grep "^cl"; then
15078                 # this is the normal case where all users were deregistered
15079                 # make sure no new records are added when no users are present
15080                 local last_rec1=$(changelog_users $SINGLEMDS |
15081                                   awk '/^current.index:/ { print $NF }')
15082                 touch $DIR/$tdir/chloe
15083                 local last_rec2=$(changelog_users $SINGLEMDS |
15084                                   awk '/^current.index:/ { print $NF }')
15085                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15086                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15087         else
15088                 # any changelog users must be leftovers from a previous test
15089                 changelog_users $SINGLEMDS
15090                 echo "other changelog users; can't verify off"
15091         fi
15092 }
15093 run_test 160a "changelog sanity"
15094
15095 test_160b() { # LU-3587
15096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15097         remote_mds_nodsh && skip "remote MDS with nodsh"
15098         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15099                 skip "Need MDS version at least 2.2.0"
15100
15101         changelog_register || error "changelog_register failed"
15102         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15103         changelog_users $SINGLEMDS | grep -q $cl_user ||
15104                 error "User '$cl_user' not found in changelog_users"
15105
15106         local longname1=$(str_repeat a 255)
15107         local longname2=$(str_repeat b 255)
15108
15109         cd $DIR
15110         echo "creating very long named file"
15111         touch $longname1 || error "create of '$longname1' failed"
15112         echo "renaming very long named file"
15113         mv $longname1 $longname2
15114
15115         changelog_dump | grep RENME | tail -n 5
15116         rm -f $longname2
15117 }
15118 run_test 160b "Verify that very long rename doesn't crash in changelog"
15119
15120 test_160c() {
15121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15122         remote_mds_nodsh && skip "remote MDS with nodsh"
15123
15124         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15125                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15126                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15127                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15128
15129         local rc=0
15130
15131         # Registration step
15132         changelog_register || error "changelog_register failed"
15133
15134         rm -rf $DIR/$tdir
15135         mkdir -p $DIR/$tdir
15136         $MCREATE $DIR/$tdir/foo_160c
15137         changelog_chmask "-TRUNC"
15138         $TRUNCATE $DIR/$tdir/foo_160c 200
15139         changelog_chmask "+TRUNC"
15140         $TRUNCATE $DIR/$tdir/foo_160c 199
15141         changelog_dump | tail -n 5
15142         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15143         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15144 }
15145 run_test 160c "verify that changelog log catch the truncate event"
15146
15147 test_160d() {
15148         remote_mds_nodsh && skip "remote MDS with nodsh"
15149         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15151         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15152                 skip "Need MDS version at least 2.7.60"
15153
15154         # Registration step
15155         changelog_register || error "changelog_register failed"
15156
15157         mkdir -p $DIR/$tdir/migrate_dir
15158         changelog_clear 0 || error "changelog_clear failed"
15159
15160         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15161         changelog_dump | tail -n 5
15162         local migrates=$(changelog_dump | grep -c "MIGRT")
15163         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15164 }
15165 run_test 160d "verify that changelog log catch the migrate event"
15166
15167 test_160e() {
15168         remote_mds_nodsh && skip "remote MDS with nodsh"
15169
15170         # Create a user
15171         changelog_register || error "changelog_register failed"
15172
15173         # Delete a future user (expect fail)
15174         local MDT0=$(facet_svc $SINGLEMDS)
15175         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15176         local rc=$?
15177
15178         if [ $rc -eq 0 ]; then
15179                 error "Deleted non-existant user cl77"
15180         elif [ $rc -ne 2 ]; then
15181                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15182         fi
15183
15184         # Clear to a bad index (1 billion should be safe)
15185         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15186         rc=$?
15187
15188         if [ $rc -eq 0 ]; then
15189                 error "Successfully cleared to invalid CL index"
15190         elif [ $rc -ne 22 ]; then
15191                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15192         fi
15193 }
15194 run_test 160e "changelog negative testing (should return errors)"
15195
15196 test_160f() {
15197         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15198         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15199                 skip "Need MDS version at least 2.10.56"
15200
15201         local mdts=$(comma_list $(mdts_nodes))
15202
15203         # Create a user
15204         changelog_register || error "first changelog_register failed"
15205         changelog_register || error "second changelog_register failed"
15206         local cl_users
15207         declare -A cl_user1
15208         declare -A cl_user2
15209         local user_rec1
15210         local user_rec2
15211         local i
15212
15213         # generate some changelog records to accumulate on each MDT
15214         # use all_char because created files should be evenly distributed
15215         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15216                 error "test_mkdir $tdir failed"
15217         log "$(date +%s): creating first files"
15218         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15219                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15220                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15221         done
15222
15223         # check changelogs have been generated
15224         local start=$SECONDS
15225         local idle_time=$((MDSCOUNT * 5 + 5))
15226         local nbcl=$(changelog_dump | wc -l)
15227         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15228
15229         for param in "changelog_max_idle_time=$idle_time" \
15230                      "changelog_gc=1" \
15231                      "changelog_min_gc_interval=2" \
15232                      "changelog_min_free_cat_entries=3"; do
15233                 local MDT0=$(facet_svc $SINGLEMDS)
15234                 local var="${param%=*}"
15235                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15236
15237                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15238                 do_nodes $mdts $LCTL set_param mdd.*.$param
15239         done
15240
15241         # force cl_user2 to be idle (1st part), but also cancel the
15242         # cl_user1 records so that it is not evicted later in the test.
15243         local sleep1=$((idle_time / 2))
15244         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15245         sleep $sleep1
15246
15247         # simulate changelog catalog almost full
15248         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15249         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15250
15251         for i in $(seq $MDSCOUNT); do
15252                 cl_users=(${CL_USERS[mds$i]})
15253                 cl_user1[mds$i]="${cl_users[0]}"
15254                 cl_user2[mds$i]="${cl_users[1]}"
15255
15256                 [ -n "${cl_user1[mds$i]}" ] ||
15257                         error "mds$i: no user registered"
15258                 [ -n "${cl_user2[mds$i]}" ] ||
15259                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15260
15261                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15262                 [ -n "$user_rec1" ] ||
15263                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15264                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15265                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15266                 [ -n "$user_rec2" ] ||
15267                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15268                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15269                      "$user_rec1 + 2 == $user_rec2"
15270                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15271                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15272                               "$user_rec1 + 2, but is $user_rec2"
15273                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15274                 [ -n "$user_rec2" ] ||
15275                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15276                 [ $user_rec1 == $user_rec2 ] ||
15277                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15278                               "$user_rec1, but is $user_rec2"
15279         done
15280
15281         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15282         local sleep2=$((idle_time - (SECONDS - start) + 1))
15283         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15284         sleep $sleep2
15285
15286         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15287         # cl_user1 should be OK because it recently processed records.
15288         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15289         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15290                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15291                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15292         done
15293
15294         # ensure gc thread is done
15295         for i in $(mdts_nodes); do
15296                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15297                         error "$i: GC-thread not done"
15298         done
15299
15300         local first_rec
15301         for (( i = 1; i <= MDSCOUNT; i++ )); do
15302                 # check cl_user1 still registered
15303                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15304                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15305                 # check cl_user2 unregistered
15306                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15307                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15308
15309                 # check changelogs are present and starting at $user_rec1 + 1
15310                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15311                 [ -n "$user_rec1" ] ||
15312                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15313                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15314                             awk '{ print $1; exit; }')
15315
15316                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15317                 [ $((user_rec1 + 1)) == $first_rec ] ||
15318                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15319         done
15320 }
15321 run_test 160f "changelog garbage collect (timestamped users)"
15322
15323 test_160g() {
15324         remote_mds_nodsh && skip "remote MDS with nodsh"
15325         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15326                 skip "Need MDS version at least 2.10.56"
15327
15328         local mdts=$(comma_list $(mdts_nodes))
15329
15330         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15331         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15332
15333         # Create a user
15334         changelog_register || error "first changelog_register failed"
15335         changelog_register || error "second changelog_register failed"
15336         local cl_users
15337         declare -A cl_user1
15338         declare -A cl_user2
15339         local user_rec1
15340         local user_rec2
15341         local i
15342
15343         # generate some changelog records to accumulate on each MDT
15344         # use all_char because created files should be evenly distributed
15345         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15346                 error "test_mkdir $tdir failed"
15347         for ((i = 0; i < MDSCOUNT; i++)); do
15348                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15349                         error "create $DIR/$tdir/d$i.1 failed"
15350         done
15351
15352         # check changelogs have been generated
15353         local nbcl=$(changelog_dump | wc -l)
15354         (( $nbcl > 0 )) || error "no changelogs found"
15355
15356         # reduce the max_idle_indexes value to make sure we exceed it
15357         for param in "changelog_max_idle_indexes=1" \
15358                      "changelog_gc=1" \
15359                      "changelog_min_gc_interval=2" \
15360                      "changelog_min_free_cat_entries=3"; do
15361                 local MDT0=$(facet_svc $SINGLEMDS)
15362                 local var="${param%=*}"
15363                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15364
15365                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15366                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15367                         error "unable to set mdd.*.$param"
15368         done
15369
15370         # simulate changelog catalog almost full
15371         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15372         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15373
15374         local start=$SECONDS
15375         for i in $(seq $MDSCOUNT); do
15376                 cl_users=(${CL_USERS[mds$i]})
15377                 cl_user1[mds$i]="${cl_users[0]}"
15378                 cl_user2[mds$i]="${cl_users[1]}"
15379
15380                 [ -n "${cl_user1[mds$i]}" ] ||
15381                         error "mds$i: no user registered"
15382                 [ -n "${cl_user2[mds$i]}" ] ||
15383                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15384
15385                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15386                 [ -n "$user_rec1" ] ||
15387                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15388                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15389                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15390                 [ -n "$user_rec2" ] ||
15391                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15392                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15393                      "$user_rec1 + 2 == $user_rec2"
15394                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15395                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15396                               "$user_rec1 + 2, but is $user_rec2"
15397                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15398                 [ -n "$user_rec2" ] ||
15399                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15400                 [ $user_rec1 == $user_rec2 ] ||
15401                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15402                               "$user_rec1, but is $user_rec2"
15403         done
15404
15405         # ensure we are past the previous changelog_min_gc_interval set above
15406         local sleep2=$((start + 2 - SECONDS))
15407         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15408
15409         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15410         # cl_user1 should be OK because it recently processed records.
15411         for ((i = 0; i < MDSCOUNT; i++)); do
15412                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15413                         error "create $DIR/$tdir/d$i.3 failed"
15414         done
15415
15416         # ensure gc thread is done
15417         for i in $(mdts_nodes); do
15418                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15419                         error "$i: GC-thread not done"
15420         done
15421
15422         local first_rec
15423         for (( i = 1; i <= MDSCOUNT; i++ )); do
15424                 # check cl_user1 still registered
15425                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15426                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15427                 # check cl_user2 unregistered
15428                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15429                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15430
15431                 # check changelogs are present and starting at $user_rec1 + 1
15432                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15433                 [ -n "$user_rec1" ] ||
15434                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15435                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15436                             awk '{ print $1; exit; }')
15437
15438                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15439                 [ $((user_rec1 + 1)) == $first_rec ] ||
15440                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15441         done
15442 }
15443 run_test 160g "changelog garbage collect (old users)"
15444
15445 test_160h() {
15446         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15447         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15448                 skip "Need MDS version at least 2.10.56"
15449
15450         local mdts=$(comma_list $(mdts_nodes))
15451
15452         # Create a user
15453         changelog_register || error "first changelog_register failed"
15454         changelog_register || error "second changelog_register failed"
15455         local cl_users
15456         declare -A cl_user1
15457         declare -A cl_user2
15458         local user_rec1
15459         local user_rec2
15460         local i
15461
15462         # generate some changelog records to accumulate on each MDT
15463         # use all_char because created files should be evenly distributed
15464         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15465                 error "test_mkdir $tdir failed"
15466         for ((i = 0; i < MDSCOUNT; i++)); do
15467                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15468                         error "create $DIR/$tdir/d$i.1 failed"
15469         done
15470
15471         # check changelogs have been generated
15472         local nbcl=$(changelog_dump | wc -l)
15473         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15474
15475         for param in "changelog_max_idle_time=10" \
15476                      "changelog_gc=1" \
15477                      "changelog_min_gc_interval=2"; do
15478                 local MDT0=$(facet_svc $SINGLEMDS)
15479                 local var="${param%=*}"
15480                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15481
15482                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15483                 do_nodes $mdts $LCTL set_param mdd.*.$param
15484         done
15485
15486         # force cl_user2 to be idle (1st part)
15487         sleep 9
15488
15489         for i in $(seq $MDSCOUNT); do
15490                 cl_users=(${CL_USERS[mds$i]})
15491                 cl_user1[mds$i]="${cl_users[0]}"
15492                 cl_user2[mds$i]="${cl_users[1]}"
15493
15494                 [ -n "${cl_user1[mds$i]}" ] ||
15495                         error "mds$i: no user registered"
15496                 [ -n "${cl_user2[mds$i]}" ] ||
15497                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15498
15499                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15500                 [ -n "$user_rec1" ] ||
15501                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15502                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15503                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15504                 [ -n "$user_rec2" ] ||
15505                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15506                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15507                      "$user_rec1 + 2 == $user_rec2"
15508                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15509                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15510                               "$user_rec1 + 2, but is $user_rec2"
15511                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15512                 [ -n "$user_rec2" ] ||
15513                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15514                 [ $user_rec1 == $user_rec2 ] ||
15515                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15516                               "$user_rec1, but is $user_rec2"
15517         done
15518
15519         # force cl_user2 to be idle (2nd part) and to reach
15520         # changelog_max_idle_time
15521         sleep 2
15522
15523         # force each GC-thread start and block then
15524         # one per MDT/MDD, set fail_val accordingly
15525         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15526         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15527
15528         # generate more changelogs to trigger fail_loc
15529         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15530                 error "create $DIR/$tdir/${tfile}bis failed"
15531
15532         # stop MDT to stop GC-thread, should be done in back-ground as it will
15533         # block waiting for the thread to be released and exit
15534         declare -A stop_pids
15535         for i in $(seq $MDSCOUNT); do
15536                 stop mds$i &
15537                 stop_pids[mds$i]=$!
15538         done
15539
15540         for i in $(mdts_nodes); do
15541                 local facet
15542                 local nb=0
15543                 local facets=$(facets_up_on_host $i)
15544
15545                 for facet in ${facets//,/ }; do
15546                         if [[ $facet == mds* ]]; then
15547                                 nb=$((nb + 1))
15548                         fi
15549                 done
15550                 # ensure each MDS's gc threads are still present and all in "R"
15551                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15552                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15553                         error "$i: expected $nb GC-thread"
15554                 wait_update $i \
15555                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15556                         "R" 20 ||
15557                         error "$i: GC-thread not found in R-state"
15558                 # check umounts of each MDT on MDS have reached kthread_stop()
15559                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15560                         error "$i: expected $nb umount"
15561                 wait_update $i \
15562                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15563                         error "$i: umount not found in D-state"
15564         done
15565
15566         # release all GC-threads
15567         do_nodes $mdts $LCTL set_param fail_loc=0
15568
15569         # wait for MDT stop to complete
15570         for i in $(seq $MDSCOUNT); do
15571                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15572         done
15573
15574         # XXX
15575         # may try to check if any orphan changelog records are present
15576         # via ldiskfs/zfs and llog_reader...
15577
15578         # re-start/mount MDTs
15579         for i in $(seq $MDSCOUNT); do
15580                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15581                         error "Fail to start mds$i"
15582         done
15583
15584         local first_rec
15585         for i in $(seq $MDSCOUNT); do
15586                 # check cl_user1 still registered
15587                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15588                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15589                 # check cl_user2 unregistered
15590                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15591                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15592
15593                 # check changelogs are present and starting at $user_rec1 + 1
15594                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15595                 [ -n "$user_rec1" ] ||
15596                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15597                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15598                             awk '{ print $1; exit; }')
15599
15600                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15601                 [ $((user_rec1 + 1)) == $first_rec ] ||
15602                         error "mds$i: first index should be $user_rec1 + 1, " \
15603                               "but is $first_rec"
15604         done
15605 }
15606 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15607               "during mount"
15608
15609 test_160i() {
15610
15611         local mdts=$(comma_list $(mdts_nodes))
15612
15613         changelog_register || error "first changelog_register failed"
15614
15615         # generate some changelog records to accumulate on each MDT
15616         # use all_char because created files should be evenly distributed
15617         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15618                 error "test_mkdir $tdir failed"
15619         for ((i = 0; i < MDSCOUNT; i++)); do
15620                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15621                         error "create $DIR/$tdir/d$i.1 failed"
15622         done
15623
15624         # check changelogs have been generated
15625         local nbcl=$(changelog_dump | wc -l)
15626         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15627
15628         # simulate race between register and unregister
15629         # XXX as fail_loc is set per-MDS, with DNE configs the race
15630         # simulation will only occur for one MDT per MDS and for the
15631         # others the normal race scenario will take place
15632         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15633         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15634         do_nodes $mdts $LCTL set_param fail_val=1
15635
15636         # unregister 1st user
15637         changelog_deregister &
15638         local pid1=$!
15639         # wait some time for deregister work to reach race rdv
15640         sleep 2
15641         # register 2nd user
15642         changelog_register || error "2nd user register failed"
15643
15644         wait $pid1 || error "1st user deregister failed"
15645
15646         local i
15647         local last_rec
15648         declare -A LAST_REC
15649         for i in $(seq $MDSCOUNT); do
15650                 if changelog_users mds$i | grep "^cl"; then
15651                         # make sure new records are added with one user present
15652                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15653                                           awk '/^current.index:/ { print $NF }')
15654                 else
15655                         error "mds$i has no user registered"
15656                 fi
15657         done
15658
15659         # generate more changelog records to accumulate on each MDT
15660         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15661                 error "create $DIR/$tdir/${tfile}bis failed"
15662
15663         for i in $(seq $MDSCOUNT); do
15664                 last_rec=$(changelog_users $SINGLEMDS |
15665                            awk '/^current.index:/ { print $NF }')
15666                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15667                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15668                         error "changelogs are off on mds$i"
15669         done
15670 }
15671 run_test 160i "changelog user register/unregister race"
15672
15673 test_160j() {
15674         remote_mds_nodsh && skip "remote MDS with nodsh"
15675         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15676                 skip "Need MDS version at least 2.12.56"
15677
15678         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15679         stack_trap "umount $MOUNT2" EXIT
15680
15681         changelog_register || error "first changelog_register failed"
15682         stack_trap "changelog_deregister" EXIT
15683
15684         # generate some changelog
15685         # use all_char because created files should be evenly distributed
15686         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15687                 error "mkdir $tdir failed"
15688         for ((i = 0; i < MDSCOUNT; i++)); do
15689                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15690                         error "create $DIR/$tdir/d$i.1 failed"
15691         done
15692
15693         # open the changelog device
15694         exec 3>/dev/changelog-$FSNAME-MDT0000
15695         stack_trap "exec 3>&-" EXIT
15696         exec 4</dev/changelog-$FSNAME-MDT0000
15697         stack_trap "exec 4<&-" EXIT
15698
15699         # umount the first lustre mount
15700         umount $MOUNT
15701         stack_trap "mount_client $MOUNT" EXIT
15702
15703         # read changelog, which may or may not fail, but should not crash
15704         cat <&4 >/dev/null
15705
15706         # clear changelog
15707         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15708         changelog_users $SINGLEMDS | grep -q $cl_user ||
15709                 error "User $cl_user not found in changelog_users"
15710
15711         printf 'clear:'$cl_user':0' >&3
15712 }
15713 run_test 160j "client can be umounted while its chanangelog is being used"
15714
15715 test_160k() {
15716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15717         remote_mds_nodsh && skip "remote MDS with nodsh"
15718
15719         mkdir -p $DIR/$tdir/1/1
15720
15721         changelog_register || error "changelog_register failed"
15722         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15723
15724         changelog_users $SINGLEMDS | grep -q $cl_user ||
15725                 error "User '$cl_user' not found in changelog_users"
15726 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15727         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15728         rmdir $DIR/$tdir/1/1 & sleep 1
15729         mkdir $DIR/$tdir/2
15730         touch $DIR/$tdir/2/2
15731         rm -rf $DIR/$tdir/2
15732
15733         wait
15734         sleep 4
15735
15736         changelog_dump | grep rmdir || error "rmdir not recorded"
15737 }
15738 run_test 160k "Verify that changelog records are not lost"
15739
15740 # Verifies that a file passed as a parameter has recently had an operation
15741 # performed on it that has generated an MTIME changelog which contains the
15742 # correct parent FID. As files might reside on a different MDT from the
15743 # parent directory in DNE configurations, the FIDs are translated to paths
15744 # before being compared, which should be identical
15745 compare_mtime_changelog() {
15746         local file="${1}"
15747         local mdtidx
15748         local mtime
15749         local cl_fid
15750         local pdir
15751         local dir
15752
15753         mdtidx=$($LFS getstripe --mdt-index $file)
15754         mdtidx=$(printf "%04x" $mdtidx)
15755
15756         # Obtain the parent FID from the MTIME changelog
15757         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15758         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15759
15760         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15761         [ -z "$cl_fid" ] && error "parent FID not present"
15762
15763         # Verify that the path for the parent FID is the same as the path for
15764         # the test directory
15765         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15766
15767         dir=$(dirname $1)
15768
15769         [[ "${pdir%/}" == "$dir" ]] ||
15770                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15771 }
15772
15773 test_160l() {
15774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15775
15776         remote_mds_nodsh && skip "remote MDS with nodsh"
15777         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15778                 skip "Need MDS version at least 2.13.55"
15779
15780         local cl_user
15781
15782         changelog_register || error "changelog_register failed"
15783         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15784
15785         changelog_users $SINGLEMDS | grep -q $cl_user ||
15786                 error "User '$cl_user' not found in changelog_users"
15787
15788         # Clear some types so that MTIME changelogs are generated
15789         changelog_chmask "-CREAT"
15790         changelog_chmask "-CLOSE"
15791
15792         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15793
15794         # Test CL_MTIME during setattr
15795         touch $DIR/$tdir/$tfile
15796         compare_mtime_changelog $DIR/$tdir/$tfile
15797
15798         # Test CL_MTIME during close
15799         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15800         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15801 }
15802 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15803
15804 test_160m() {
15805         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15806         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
15807                 skip "Need MDS version at least 2.14.51"
15808         local cl_users
15809         local cl_user1
15810         local cl_user2
15811         local pid1
15812
15813         # Create a user
15814         changelog_register || error "first changelog_register failed"
15815         changelog_register || error "second changelog_register failed"
15816
15817         cl_users=(${CL_USERS[mds1]})
15818         cl_user1="${cl_users[0]}"
15819         cl_user2="${cl_users[1]}"
15820         # generate some changelog records to accumulate on MDT0
15821         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
15822         createmany -m $DIR/$tdir/$tfile 50 ||
15823                 error "create $DIR/$tdir/$tfile failed"
15824         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
15825         rm -f $DIR/$tdir
15826
15827         # check changelogs have been generated
15828         local nbcl=$(changelog_dump | wc -l)
15829         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15830
15831 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
15832         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
15833
15834         __changelog_clear mds1 $cl_user1 +10
15835         __changelog_clear mds1 $cl_user2 0 &
15836         pid1=$!
15837         sleep 2
15838         __changelog_clear mds1 $cl_user1 0 ||
15839                 error "fail to cancel record for $cl_user1"
15840         wait $pid1
15841         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
15842 }
15843 run_test 160m "Changelog clear race"
15844
15845
15846 test_161a() {
15847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15848
15849         test_mkdir -c1 $DIR/$tdir
15850         cp /etc/hosts $DIR/$tdir/$tfile
15851         test_mkdir -c1 $DIR/$tdir/foo1
15852         test_mkdir -c1 $DIR/$tdir/foo2
15853         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15854         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15855         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15856         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15857         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15858         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15859                 $LFS fid2path $DIR $FID
15860                 error "bad link ea"
15861         fi
15862         # middle
15863         rm $DIR/$tdir/foo2/zachary
15864         # last
15865         rm $DIR/$tdir/foo2/thor
15866         # first
15867         rm $DIR/$tdir/$tfile
15868         # rename
15869         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15870         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15871                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15872         rm $DIR/$tdir/foo2/maggie
15873
15874         # overflow the EA
15875         local longname=$tfile.avg_len_is_thirty_two_
15876         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15877                 error_noexit 'failed to unlink many hardlinks'" EXIT
15878         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15879                 error "failed to hardlink many files"
15880         links=$($LFS fid2path $DIR $FID | wc -l)
15881         echo -n "${links}/1000 links in link EA"
15882         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15883 }
15884 run_test 161a "link ea sanity"
15885
15886 test_161b() {
15887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15888         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15889
15890         local MDTIDX=1
15891         local remote_dir=$DIR/$tdir/remote_dir
15892
15893         mkdir -p $DIR/$tdir
15894         $LFS mkdir -i $MDTIDX $remote_dir ||
15895                 error "create remote directory failed"
15896
15897         cp /etc/hosts $remote_dir/$tfile
15898         mkdir -p $remote_dir/foo1
15899         mkdir -p $remote_dir/foo2
15900         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15901         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15902         ln $remote_dir/$tfile $remote_dir/foo1/luna
15903         ln $remote_dir/$tfile $remote_dir/foo2/thor
15904
15905         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15906                      tr -d ']')
15907         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15908                 $LFS fid2path $DIR $FID
15909                 error "bad link ea"
15910         fi
15911         # middle
15912         rm $remote_dir/foo2/zachary
15913         # last
15914         rm $remote_dir/foo2/thor
15915         # first
15916         rm $remote_dir/$tfile
15917         # rename
15918         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15919         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15920         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15921                 $LFS fid2path $DIR $FID
15922                 error "bad link rename"
15923         fi
15924         rm $remote_dir/foo2/maggie
15925
15926         # overflow the EA
15927         local longname=filename_avg_len_is_thirty_two_
15928         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15929                 error "failed to hardlink many files"
15930         links=$($LFS fid2path $DIR $FID | wc -l)
15931         echo -n "${links}/1000 links in link EA"
15932         [[ ${links} -gt 60 ]] ||
15933                 error "expected at least 60 links in link EA"
15934         unlinkmany $remote_dir/foo2/$longname 1000 ||
15935         error "failed to unlink many hardlinks"
15936 }
15937 run_test 161b "link ea sanity under remote directory"
15938
15939 test_161c() {
15940         remote_mds_nodsh && skip "remote MDS with nodsh"
15941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15942         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15943                 skip "Need MDS version at least 2.1.5"
15944
15945         # define CLF_RENAME_LAST 0x0001
15946         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15947         changelog_register || error "changelog_register failed"
15948
15949         rm -rf $DIR/$tdir
15950         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15951         touch $DIR/$tdir/foo_161c
15952         touch $DIR/$tdir/bar_161c
15953         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15954         changelog_dump | grep RENME | tail -n 5
15955         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15956         changelog_clear 0 || error "changelog_clear failed"
15957         if [ x$flags != "x0x1" ]; then
15958                 error "flag $flags is not 0x1"
15959         fi
15960
15961         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15962         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15963         touch $DIR/$tdir/foo_161c
15964         touch $DIR/$tdir/bar_161c
15965         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15966         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15967         changelog_dump | grep RENME | tail -n 5
15968         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15969         changelog_clear 0 || error "changelog_clear failed"
15970         if [ x$flags != "x0x0" ]; then
15971                 error "flag $flags is not 0x0"
15972         fi
15973         echo "rename overwrite a target having nlink > 1," \
15974                 "changelog record has flags of $flags"
15975
15976         # rename doesn't overwrite a target (changelog flag 0x0)
15977         touch $DIR/$tdir/foo_161c
15978         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15979         changelog_dump | grep RENME | tail -n 5
15980         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15981         changelog_clear 0 || error "changelog_clear failed"
15982         if [ x$flags != "x0x0" ]; then
15983                 error "flag $flags is not 0x0"
15984         fi
15985         echo "rename doesn't overwrite a target," \
15986                 "changelog record has flags of $flags"
15987
15988         # define CLF_UNLINK_LAST 0x0001
15989         # unlink a file having nlink = 1 (changelog flag 0x1)
15990         rm -f $DIR/$tdir/foo2_161c
15991         changelog_dump | grep UNLNK | tail -n 5
15992         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15993         changelog_clear 0 || error "changelog_clear failed"
15994         if [ x$flags != "x0x1" ]; then
15995                 error "flag $flags is not 0x1"
15996         fi
15997         echo "unlink a file having nlink = 1," \
15998                 "changelog record has flags of $flags"
15999
16000         # unlink a file having nlink > 1 (changelog flag 0x0)
16001         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16002         rm -f $DIR/$tdir/foobar_161c
16003         changelog_dump | grep UNLNK | tail -n 5
16004         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16005         changelog_clear 0 || error "changelog_clear failed"
16006         if [ x$flags != "x0x0" ]; then
16007                 error "flag $flags is not 0x0"
16008         fi
16009         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16010 }
16011 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16012
16013 test_161d() {
16014         remote_mds_nodsh && skip "remote MDS with nodsh"
16015         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16016
16017         local pid
16018         local fid
16019
16020         changelog_register || error "changelog_register failed"
16021
16022         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16023         # interfer with $MOUNT/.lustre/fid/ access
16024         mkdir $DIR/$tdir
16025         [[ $? -eq 0 ]] || error "mkdir failed"
16026
16027         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16028         $LCTL set_param fail_loc=0x8000140c
16029         # 5s pause
16030         $LCTL set_param fail_val=5
16031
16032         # create file
16033         echo foofoo > $DIR/$tdir/$tfile &
16034         pid=$!
16035
16036         # wait for create to be delayed
16037         sleep 2
16038
16039         ps -p $pid
16040         [[ $? -eq 0 ]] || error "create should be blocked"
16041
16042         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16043         stack_trap "rm -f $tempfile"
16044         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16045         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16046         # some delay may occur during ChangeLog publishing and file read just
16047         # above, that could allow file write to happen finally
16048         [[ -s $tempfile ]] && echo "file should be empty"
16049
16050         $LCTL set_param fail_loc=0
16051
16052         wait $pid
16053         [[ $? -eq 0 ]] || error "create failed"
16054 }
16055 run_test 161d "create with concurrent .lustre/fid access"
16056
16057 check_path() {
16058         local expected="$1"
16059         shift
16060         local fid="$2"
16061
16062         local path
16063         path=$($LFS fid2path "$@")
16064         local rc=$?
16065
16066         if [ $rc -ne 0 ]; then
16067                 error "path looked up of '$expected' failed: rc=$rc"
16068         elif [ "$path" != "$expected" ]; then
16069                 error "path looked up '$path' instead of '$expected'"
16070         else
16071                 echo "FID '$fid' resolves to path '$path' as expected"
16072         fi
16073 }
16074
16075 test_162a() { # was test_162
16076         test_mkdir -p -c1 $DIR/$tdir/d2
16077         touch $DIR/$tdir/d2/$tfile
16078         touch $DIR/$tdir/d2/x1
16079         touch $DIR/$tdir/d2/x2
16080         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16081         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16082         # regular file
16083         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16084         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16085
16086         # softlink
16087         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16088         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16089         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16090
16091         # softlink to wrong file
16092         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16093         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16094         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16095
16096         # hardlink
16097         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16098         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16099         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16100         # fid2path dir/fsname should both work
16101         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16102         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16103
16104         # hardlink count: check that there are 2 links
16105         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16106         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16107
16108         # hardlink indexing: remove the first link
16109         rm $DIR/$tdir/d2/p/q/r/hlink
16110         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16111 }
16112 run_test 162a "path lookup sanity"
16113
16114 test_162b() {
16115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16116         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16117
16118         mkdir $DIR/$tdir
16119         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16120                                 error "create striped dir failed"
16121
16122         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16123                                         tail -n 1 | awk '{print $2}')
16124         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16125
16126         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16127         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16128
16129         # regular file
16130         for ((i=0;i<5;i++)); do
16131                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16132                         error "get fid for f$i failed"
16133                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16134
16135                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16136                         error "get fid for d$i failed"
16137                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16138         done
16139
16140         return 0
16141 }
16142 run_test 162b "striped directory path lookup sanity"
16143
16144 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16145 test_162c() {
16146         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16147                 skip "Need MDS version at least 2.7.51"
16148
16149         local lpath=$tdir.local
16150         local rpath=$tdir.remote
16151
16152         test_mkdir $DIR/$lpath
16153         test_mkdir $DIR/$rpath
16154
16155         for ((i = 0; i <= 101; i++)); do
16156                 lpath="$lpath/$i"
16157                 mkdir $DIR/$lpath
16158                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16159                         error "get fid for local directory $DIR/$lpath failed"
16160                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16161
16162                 rpath="$rpath/$i"
16163                 test_mkdir $DIR/$rpath
16164                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16165                         error "get fid for remote directory $DIR/$rpath failed"
16166                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16167         done
16168
16169         return 0
16170 }
16171 run_test 162c "fid2path works with paths 100 or more directories deep"
16172
16173 oalr_event_count() {
16174         local event="${1}"
16175         local trace="${2}"
16176
16177         awk -v name="${FSNAME}-OST0000" \
16178             -v event="${event}" \
16179             '$1 == "TRACE" && $2 == event && $3 == name' \
16180             "${trace}" |
16181         wc -l
16182 }
16183
16184 oalr_expect_event_count() {
16185         local event="${1}"
16186         local trace="${2}"
16187         local expect="${3}"
16188         local count
16189
16190         count=$(oalr_event_count "${event}" "${trace}")
16191         if ((count == expect)); then
16192                 return 0
16193         fi
16194
16195         error_noexit "${event} event count was '${count}', expected ${expect}"
16196         cat "${trace}" >&2
16197         exit 1
16198 }
16199
16200 cleanup_165() {
16201         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16202         stop ost1
16203         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16204 }
16205
16206 setup_165() {
16207         sync # Flush previous IOs so we can count log entries.
16208         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16209         stack_trap cleanup_165 EXIT
16210 }
16211
16212 test_165a() {
16213         local trace="/tmp/${tfile}.trace"
16214         local rc
16215         local count
16216
16217         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16218                 skip "OFD access log unsupported"
16219
16220         setup_165
16221         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16222         sleep 5
16223
16224         do_facet ost1 ofd_access_log_reader --list
16225         stop ost1
16226
16227         do_facet ost1 killall -TERM ofd_access_log_reader
16228         wait
16229         rc=$?
16230
16231         if ((rc != 0)); then
16232                 error "ofd_access_log_reader exited with rc = '${rc}'"
16233         fi
16234
16235         # Parse trace file for discovery events:
16236         oalr_expect_event_count alr_log_add "${trace}" 1
16237         oalr_expect_event_count alr_log_eof "${trace}" 1
16238         oalr_expect_event_count alr_log_free "${trace}" 1
16239 }
16240 run_test 165a "ofd access log discovery"
16241
16242 test_165b() {
16243         local trace="/tmp/${tfile}.trace"
16244         local file="${DIR}/${tfile}"
16245         local pfid1
16246         local pfid2
16247         local -a entry
16248         local rc
16249         local count
16250         local size
16251         local flags
16252
16253         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16254                 skip "OFD access log unsupported"
16255
16256         setup_165
16257         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16258         sleep 5
16259
16260         do_facet ost1 ofd_access_log_reader --list
16261
16262         lfs setstripe -c 1 -i 0 "${file}"
16263         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16264                 error "cannot create '${file}'"
16265
16266         sleep 5
16267         do_facet ost1 killall -TERM ofd_access_log_reader
16268         wait
16269         rc=$?
16270
16271         if ((rc != 0)); then
16272                 error "ofd_access_log_reader exited with rc = '${rc}'"
16273         fi
16274
16275         oalr_expect_event_count alr_log_entry "${trace}" 1
16276
16277         pfid1=$($LFS path2fid "${file}")
16278
16279         # 1     2             3   4    5     6   7    8    9     10
16280         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16281         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16282
16283         echo "entry = '${entry[*]}'" >&2
16284
16285         pfid2=${entry[4]}
16286         if [[ "${pfid1}" != "${pfid2}" ]]; then
16287                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16288         fi
16289
16290         size=${entry[8]}
16291         if ((size != 1048576)); then
16292                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16293         fi
16294
16295         flags=${entry[10]}
16296         if [[ "${flags}" != "w" ]]; then
16297                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16298         fi
16299
16300         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16301         sleep 5
16302
16303         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16304                 error "cannot read '${file}'"
16305         sleep 5
16306
16307         do_facet ost1 killall -TERM ofd_access_log_reader
16308         wait
16309         rc=$?
16310
16311         if ((rc != 0)); then
16312                 error "ofd_access_log_reader exited with rc = '${rc}'"
16313         fi
16314
16315         oalr_expect_event_count alr_log_entry "${trace}" 1
16316
16317         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16318         echo "entry = '${entry[*]}'" >&2
16319
16320         pfid2=${entry[4]}
16321         if [[ "${pfid1}" != "${pfid2}" ]]; then
16322                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16323         fi
16324
16325         size=${entry[8]}
16326         if ((size != 524288)); then
16327                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16328         fi
16329
16330         flags=${entry[10]}
16331         if [[ "${flags}" != "r" ]]; then
16332                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16333         fi
16334 }
16335 run_test 165b "ofd access log entries are produced and consumed"
16336
16337 test_165c() {
16338         local trace="/tmp/${tfile}.trace"
16339         local file="${DIR}/${tdir}/${tfile}"
16340
16341         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16342                 skip "OFD access log unsupported"
16343
16344         test_mkdir "${DIR}/${tdir}"
16345
16346         setup_165
16347         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16348         sleep 5
16349
16350         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16351
16352         # 4096 / 64 = 64. Create twice as many entries.
16353         for ((i = 0; i < 128; i++)); do
16354                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16355                         error "cannot create file"
16356         done
16357
16358         sync
16359
16360         do_facet ost1 killall -TERM ofd_access_log_reader
16361         wait
16362         rc=$?
16363         if ((rc != 0)); then
16364                 error "ofd_access_log_reader exited with rc = '${rc}'"
16365         fi
16366
16367         unlinkmany  "${file}-%d" 128
16368 }
16369 run_test 165c "full ofd access logs do not block IOs"
16370
16371 oal_get_read_count() {
16372         local stats="$1"
16373
16374         # STATS lustre-OST0001 alr_read_count 1
16375
16376         do_facet ost1 cat "${stats}" |
16377         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16378              END { print count; }'
16379 }
16380
16381 oal_expect_read_count() {
16382         local stats="$1"
16383         local count
16384         local expect="$2"
16385
16386         # Ask ofd_access_log_reader to write stats.
16387         do_facet ost1 killall -USR1 ofd_access_log_reader
16388
16389         # Allow some time for things to happen.
16390         sleep 1
16391
16392         count=$(oal_get_read_count "${stats}")
16393         if ((count == expect)); then
16394                 return 0
16395         fi
16396
16397         error_noexit "bad read count, got ${count}, expected ${expect}"
16398         do_facet ost1 cat "${stats}" >&2
16399         exit 1
16400 }
16401
16402 test_165d() {
16403         local stats="/tmp/${tfile}.stats"
16404         local file="${DIR}/${tdir}/${tfile}"
16405         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16406
16407         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16408                 skip "OFD access log unsupported"
16409
16410         test_mkdir "${DIR}/${tdir}"
16411
16412         setup_165
16413         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16414         sleep 5
16415
16416         lfs setstripe -c 1 -i 0 "${file}"
16417
16418         do_facet ost1 lctl set_param "${param}=rw"
16419         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16420                 error "cannot create '${file}'"
16421         oal_expect_read_count "${stats}" 1
16422
16423         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16424                 error "cannot read '${file}'"
16425         oal_expect_read_count "${stats}" 2
16426
16427         do_facet ost1 lctl set_param "${param}=r"
16428         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16429                 error "cannot create '${file}'"
16430         oal_expect_read_count "${stats}" 2
16431
16432         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16433                 error "cannot read '${file}'"
16434         oal_expect_read_count "${stats}" 3
16435
16436         do_facet ost1 lctl set_param "${param}=w"
16437         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16438                 error "cannot create '${file}'"
16439         oal_expect_read_count "${stats}" 4
16440
16441         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16442                 error "cannot read '${file}'"
16443         oal_expect_read_count "${stats}" 4
16444
16445         do_facet ost1 lctl set_param "${param}=0"
16446         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16447                 error "cannot create '${file}'"
16448         oal_expect_read_count "${stats}" 4
16449
16450         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16451                 error "cannot read '${file}'"
16452         oal_expect_read_count "${stats}" 4
16453
16454         do_facet ost1 killall -TERM ofd_access_log_reader
16455         wait
16456         rc=$?
16457         if ((rc != 0)); then
16458                 error "ofd_access_log_reader exited with rc = '${rc}'"
16459         fi
16460 }
16461 run_test 165d "ofd_access_log mask works"
16462
16463 test_165e() {
16464         local stats="/tmp/${tfile}.stats"
16465         local file0="${DIR}/${tdir}-0/${tfile}"
16466         local file1="${DIR}/${tdir}-1/${tfile}"
16467
16468         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16469                 skip "OFD access log unsupported"
16470
16471         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16472
16473         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16474         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16475
16476         lfs setstripe -c 1 -i 0 "${file0}"
16477         lfs setstripe -c 1 -i 0 "${file1}"
16478
16479         setup_165
16480         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16481         sleep 5
16482
16483         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16484                 error "cannot create '${file0}'"
16485         sync
16486         oal_expect_read_count "${stats}" 0
16487
16488         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16489                 error "cannot create '${file1}'"
16490         sync
16491         oal_expect_read_count "${stats}" 1
16492
16493         do_facet ost1 killall -TERM ofd_access_log_reader
16494         wait
16495         rc=$?
16496         if ((rc != 0)); then
16497                 error "ofd_access_log_reader exited with rc = '${rc}'"
16498         fi
16499 }
16500 run_test 165e "ofd_access_log MDT index filter works"
16501
16502 test_165f() {
16503         local trace="/tmp/${tfile}.trace"
16504         local rc
16505         local count
16506
16507         setup_165
16508         do_facet ost1 timeout 60 ofd_access_log_reader \
16509                 --exit-on-close --debug=- --trace=- > "${trace}" &
16510         sleep 5
16511         stop ost1
16512
16513         wait
16514         rc=$?
16515
16516         if ((rc != 0)); then
16517                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16518                 cat "${trace}"
16519                 exit 1
16520         fi
16521 }
16522 run_test 165f "ofd_access_log_reader --exit-on-close works"
16523
16524 test_169() {
16525         # do directio so as not to populate the page cache
16526         log "creating a 10 Mb file"
16527         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16528                 error "multiop failed while creating a file"
16529         log "starting reads"
16530         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16531         log "truncating the file"
16532         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16533                 error "multiop failed while truncating the file"
16534         log "killing dd"
16535         kill %+ || true # reads might have finished
16536         echo "wait until dd is finished"
16537         wait
16538         log "removing the temporary file"
16539         rm -rf $DIR/$tfile || error "tmp file removal failed"
16540 }
16541 run_test 169 "parallel read and truncate should not deadlock"
16542
16543 test_170() {
16544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16545
16546         $LCTL clear     # bug 18514
16547         $LCTL debug_daemon start $TMP/${tfile}_log_good
16548         touch $DIR/$tfile
16549         $LCTL debug_daemon stop
16550         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16551                 error "sed failed to read log_good"
16552
16553         $LCTL debug_daemon start $TMP/${tfile}_log_good
16554         rm -rf $DIR/$tfile
16555         $LCTL debug_daemon stop
16556
16557         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16558                error "lctl df log_bad failed"
16559
16560         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16561         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16562
16563         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16564         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16565
16566         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16567                 error "bad_line good_line1 good_line2 are empty"
16568
16569         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16570         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16571         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16572
16573         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16574         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16575         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16576
16577         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16578                 error "bad_line_new good_line_new are empty"
16579
16580         local expected_good=$((good_line1 + good_line2*2))
16581
16582         rm -f $TMP/${tfile}*
16583         # LU-231, short malformed line may not be counted into bad lines
16584         if [ $bad_line -ne $bad_line_new ] &&
16585                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16586                 error "expected $bad_line bad lines, but got $bad_line_new"
16587                 return 1
16588         fi
16589
16590         if [ $expected_good -ne $good_line_new ]; then
16591                 error "expected $expected_good good lines, but got $good_line_new"
16592                 return 2
16593         fi
16594         true
16595 }
16596 run_test 170 "test lctl df to handle corrupted log ====================="
16597
16598 test_171() { # bug20592
16599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16600
16601         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16602         $LCTL set_param fail_loc=0x50e
16603         $LCTL set_param fail_val=3000
16604         multiop_bg_pause $DIR/$tfile O_s || true
16605         local MULTIPID=$!
16606         kill -USR1 $MULTIPID
16607         # cause log dump
16608         sleep 3
16609         wait $MULTIPID
16610         if dmesg | grep "recursive fault"; then
16611                 error "caught a recursive fault"
16612         fi
16613         $LCTL set_param fail_loc=0
16614         true
16615 }
16616 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16617
16618 # it would be good to share it with obdfilter-survey/iokit-libecho code
16619 setup_obdecho_osc () {
16620         local rc=0
16621         local ost_nid=$1
16622         local obdfilter_name=$2
16623         echo "Creating new osc for $obdfilter_name on $ost_nid"
16624         # make sure we can find loopback nid
16625         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16626
16627         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16628                            ${obdfilter_name}_osc_UUID || rc=2; }
16629         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16630                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16631         return $rc
16632 }
16633
16634 cleanup_obdecho_osc () {
16635         local obdfilter_name=$1
16636         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16637         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16638         return 0
16639 }
16640
16641 obdecho_test() {
16642         local OBD=$1
16643         local node=$2
16644         local pages=${3:-64}
16645         local rc=0
16646         local id
16647
16648         local count=10
16649         local obd_size=$(get_obd_size $node $OBD)
16650         local page_size=$(get_page_size $node)
16651         if [[ -n "$obd_size" ]]; then
16652                 local new_count=$((obd_size / (pages * page_size / 1024)))
16653                 [[ $new_count -ge $count ]] || count=$new_count
16654         fi
16655
16656         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16657         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16658                            rc=2; }
16659         if [ $rc -eq 0 ]; then
16660             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16661             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16662         fi
16663         echo "New object id is $id"
16664         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16665                            rc=4; }
16666         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16667                            "test_brw $count w v $pages $id" || rc=4; }
16668         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16669                            rc=4; }
16670         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16671                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16672         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16673                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16674         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16675         return $rc
16676 }
16677
16678 test_180a() {
16679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16680
16681         if ! [ -d /sys/fs/lustre/echo_client ] &&
16682            ! module_loaded obdecho; then
16683                 load_module obdecho/obdecho &&
16684                         stack_trap "rmmod obdecho" EXIT ||
16685                         error "unable to load obdecho on client"
16686         fi
16687
16688         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16689         local host=$($LCTL get_param -n osc.$osc.import |
16690                      awk '/current_connection:/ { print $2 }' )
16691         local target=$($LCTL get_param -n osc.$osc.import |
16692                        awk '/target:/ { print $2 }' )
16693         target=${target%_UUID}
16694
16695         if [ -n "$target" ]; then
16696                 setup_obdecho_osc $host $target &&
16697                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16698                         { error "obdecho setup failed with $?"; return; }
16699
16700                 obdecho_test ${target}_osc client ||
16701                         error "obdecho_test failed on ${target}_osc"
16702         else
16703                 $LCTL get_param osc.$osc.import
16704                 error "there is no osc.$osc.import target"
16705         fi
16706 }
16707 run_test 180a "test obdecho on osc"
16708
16709 test_180b() {
16710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16711         remote_ost_nodsh && skip "remote OST with nodsh"
16712
16713         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16714                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16715                 error "failed to load module obdecho"
16716
16717         local target=$(do_facet ost1 $LCTL dl |
16718                        awk '/obdfilter/ { print $4; exit; }')
16719
16720         if [ -n "$target" ]; then
16721                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16722         else
16723                 do_facet ost1 $LCTL dl
16724                 error "there is no obdfilter target on ost1"
16725         fi
16726 }
16727 run_test 180b "test obdecho directly on obdfilter"
16728
16729 test_180c() { # LU-2598
16730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16731         remote_ost_nodsh && skip "remote OST with nodsh"
16732         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16733                 skip "Need MDS version at least 2.4.0"
16734
16735         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16736                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16737                 error "failed to load module obdecho"
16738
16739         local target=$(do_facet ost1 $LCTL dl |
16740                        awk '/obdfilter/ { print $4; exit; }')
16741
16742         if [ -n "$target" ]; then
16743                 local pages=16384 # 64MB bulk I/O RPC size
16744
16745                 obdecho_test "$target" ost1 "$pages" ||
16746                         error "obdecho_test with pages=$pages failed with $?"
16747         else
16748                 do_facet ost1 $LCTL dl
16749                 error "there is no obdfilter target on ost1"
16750         fi
16751 }
16752 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16753
16754 test_181() { # bug 22177
16755         test_mkdir $DIR/$tdir
16756         # create enough files to index the directory
16757         createmany -o $DIR/$tdir/foobar 4000
16758         # print attributes for debug purpose
16759         lsattr -d .
16760         # open dir
16761         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16762         MULTIPID=$!
16763         # remove the files & current working dir
16764         unlinkmany $DIR/$tdir/foobar 4000
16765         rmdir $DIR/$tdir
16766         kill -USR1 $MULTIPID
16767         wait $MULTIPID
16768         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16769         return 0
16770 }
16771 run_test 181 "Test open-unlinked dir ========================"
16772
16773 test_182() {
16774         local fcount=1000
16775         local tcount=10
16776
16777         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16778
16779         $LCTL set_param mdc.*.rpc_stats=clear
16780
16781         for (( i = 0; i < $tcount; i++ )) ; do
16782                 mkdir $DIR/$tdir/$i
16783         done
16784
16785         for (( i = 0; i < $tcount; i++ )) ; do
16786                 createmany -o $DIR/$tdir/$i/f- $fcount &
16787         done
16788         wait
16789
16790         for (( i = 0; i < $tcount; i++ )) ; do
16791                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16792         done
16793         wait
16794
16795         $LCTL get_param mdc.*.rpc_stats
16796
16797         rm -rf $DIR/$tdir
16798 }
16799 run_test 182 "Test parallel modify metadata operations ================"
16800
16801 test_183() { # LU-2275
16802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16803         remote_mds_nodsh && skip "remote MDS with nodsh"
16804         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16805                 skip "Need MDS version at least 2.3.56"
16806
16807         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16808         echo aaa > $DIR/$tdir/$tfile
16809
16810 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16811         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16812
16813         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16814         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16815
16816         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16817
16818         # Flush negative dentry cache
16819         touch $DIR/$tdir/$tfile
16820
16821         # We are not checking for any leaked references here, they'll
16822         # become evident next time we do cleanup with module unload.
16823         rm -rf $DIR/$tdir
16824 }
16825 run_test 183 "No crash or request leak in case of strange dispositions ========"
16826
16827 # test suite 184 is for LU-2016, LU-2017
16828 test_184a() {
16829         check_swap_layouts_support
16830
16831         dir0=$DIR/$tdir/$testnum
16832         test_mkdir -p -c1 $dir0
16833         ref1=/etc/passwd
16834         ref2=/etc/group
16835         file1=$dir0/f1
16836         file2=$dir0/f2
16837         $LFS setstripe -c1 $file1
16838         cp $ref1 $file1
16839         $LFS setstripe -c2 $file2
16840         cp $ref2 $file2
16841         gen1=$($LFS getstripe -g $file1)
16842         gen2=$($LFS getstripe -g $file2)
16843
16844         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16845         gen=$($LFS getstripe -g $file1)
16846         [[ $gen1 != $gen ]] ||
16847                 "Layout generation on $file1 does not change"
16848         gen=$($LFS getstripe -g $file2)
16849         [[ $gen2 != $gen ]] ||
16850                 "Layout generation on $file2 does not change"
16851
16852         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16853         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16854
16855         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16856 }
16857 run_test 184a "Basic layout swap"
16858
16859 test_184b() {
16860         check_swap_layouts_support
16861
16862         dir0=$DIR/$tdir/$testnum
16863         mkdir -p $dir0 || error "creating dir $dir0"
16864         file1=$dir0/f1
16865         file2=$dir0/f2
16866         file3=$dir0/f3
16867         dir1=$dir0/d1
16868         dir2=$dir0/d2
16869         mkdir $dir1 $dir2
16870         $LFS setstripe -c1 $file1
16871         $LFS setstripe -c2 $file2
16872         $LFS setstripe -c1 $file3
16873         chown $RUNAS_ID $file3
16874         gen1=$($LFS getstripe -g $file1)
16875         gen2=$($LFS getstripe -g $file2)
16876
16877         $LFS swap_layouts $dir1 $dir2 &&
16878                 error "swap of directories layouts should fail"
16879         $LFS swap_layouts $dir1 $file1 &&
16880                 error "swap of directory and file layouts should fail"
16881         $RUNAS $LFS swap_layouts $file1 $file2 &&
16882                 error "swap of file we cannot write should fail"
16883         $LFS swap_layouts $file1 $file3 &&
16884                 error "swap of file with different owner should fail"
16885         /bin/true # to clear error code
16886 }
16887 run_test 184b "Forbidden layout swap (will generate errors)"
16888
16889 test_184c() {
16890         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16891         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16892         check_swap_layouts_support
16893         check_swap_layout_no_dom $DIR
16894
16895         local dir0=$DIR/$tdir/$testnum
16896         mkdir -p $dir0 || error "creating dir $dir0"
16897
16898         local ref1=$dir0/ref1
16899         local ref2=$dir0/ref2
16900         local file1=$dir0/file1
16901         local file2=$dir0/file2
16902         # create a file large enough for the concurrent test
16903         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16904         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16905         echo "ref file size: ref1($(stat -c %s $ref1))," \
16906              "ref2($(stat -c %s $ref2))"
16907
16908         cp $ref2 $file2
16909         dd if=$ref1 of=$file1 bs=16k &
16910         local DD_PID=$!
16911
16912         # Make sure dd starts to copy file, but wait at most 5 seconds
16913         local loops=0
16914         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16915
16916         $LFS swap_layouts $file1 $file2
16917         local rc=$?
16918         wait $DD_PID
16919         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16920         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16921
16922         # how many bytes copied before swapping layout
16923         local copied=$(stat -c %s $file2)
16924         local remaining=$(stat -c %s $ref1)
16925         remaining=$((remaining - copied))
16926         echo "Copied $copied bytes before swapping layout..."
16927
16928         cmp -n $copied $file1 $ref2 | grep differ &&
16929                 error "Content mismatch [0, $copied) of ref2 and file1"
16930         cmp -n $copied $file2 $ref1 ||
16931                 error "Content mismatch [0, $copied) of ref1 and file2"
16932         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16933                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16934
16935         # clean up
16936         rm -f $ref1 $ref2 $file1 $file2
16937 }
16938 run_test 184c "Concurrent write and layout swap"
16939
16940 test_184d() {
16941         check_swap_layouts_support
16942         check_swap_layout_no_dom $DIR
16943         [ -z "$(which getfattr 2>/dev/null)" ] &&
16944                 skip_env "no getfattr command"
16945
16946         local file1=$DIR/$tdir/$tfile-1
16947         local file2=$DIR/$tdir/$tfile-2
16948         local file3=$DIR/$tdir/$tfile-3
16949         local lovea1
16950         local lovea2
16951
16952         mkdir -p $DIR/$tdir
16953         touch $file1 || error "create $file1 failed"
16954         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16955                 error "create $file2 failed"
16956         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16957                 error "create $file3 failed"
16958         lovea1=$(get_layout_param $file1)
16959
16960         $LFS swap_layouts $file2 $file3 ||
16961                 error "swap $file2 $file3 layouts failed"
16962         $LFS swap_layouts $file1 $file2 ||
16963                 error "swap $file1 $file2 layouts failed"
16964
16965         lovea2=$(get_layout_param $file2)
16966         echo "$lovea1"
16967         echo "$lovea2"
16968         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16969
16970         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16971         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16972 }
16973 run_test 184d "allow stripeless layouts swap"
16974
16975 test_184e() {
16976         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16977                 skip "Need MDS version at least 2.6.94"
16978         check_swap_layouts_support
16979         check_swap_layout_no_dom $DIR
16980         [ -z "$(which getfattr 2>/dev/null)" ] &&
16981                 skip_env "no getfattr command"
16982
16983         local file1=$DIR/$tdir/$tfile-1
16984         local file2=$DIR/$tdir/$tfile-2
16985         local file3=$DIR/$tdir/$tfile-3
16986         local lovea
16987
16988         mkdir -p $DIR/$tdir
16989         touch $file1 || error "create $file1 failed"
16990         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16991                 error "create $file2 failed"
16992         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16993                 error "create $file3 failed"
16994
16995         $LFS swap_layouts $file1 $file2 ||
16996                 error "swap $file1 $file2 layouts failed"
16997
16998         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16999         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17000
17001         echo 123 > $file1 || error "Should be able to write into $file1"
17002
17003         $LFS swap_layouts $file1 $file3 ||
17004                 error "swap $file1 $file3 layouts failed"
17005
17006         echo 123 > $file1 || error "Should be able to write into $file1"
17007
17008         rm -rf $file1 $file2 $file3
17009 }
17010 run_test 184e "Recreate layout after stripeless layout swaps"
17011
17012 test_184f() {
17013         # Create a file with name longer than sizeof(struct stat) ==
17014         # 144 to see if we can get chars from the file name to appear
17015         # in the returned striping. Note that 'f' == 0x66.
17016         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17017
17018         mkdir -p $DIR/$tdir
17019         mcreate $DIR/$tdir/$file
17020         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17021                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17022         fi
17023 }
17024 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17025
17026 test_185() { # LU-2441
17027         # LU-3553 - no volatile file support in old servers
17028         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17029                 skip "Need MDS version at least 2.3.60"
17030
17031         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17032         touch $DIR/$tdir/spoo
17033         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17034         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17035                 error "cannot create/write a volatile file"
17036         [ "$FILESET" == "" ] &&
17037         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17038                 error "FID is still valid after close"
17039
17040         multiop_bg_pause $DIR/$tdir vVw4096_c
17041         local multi_pid=$!
17042
17043         local OLD_IFS=$IFS
17044         IFS=":"
17045         local fidv=($fid)
17046         IFS=$OLD_IFS
17047         # assume that the next FID for this client is sequential, since stdout
17048         # is unfortunately eaten by multiop_bg_pause
17049         local n=$((${fidv[1]} + 1))
17050         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17051         if [ "$FILESET" == "" ]; then
17052                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17053                         error "FID is missing before close"
17054         fi
17055         kill -USR1 $multi_pid
17056         # 1 second delay, so if mtime change we will see it
17057         sleep 1
17058         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17059         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17060 }
17061 run_test 185 "Volatile file support"
17062
17063 function create_check_volatile() {
17064         local idx=$1
17065         local tgt
17066
17067         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17068         local PID=$!
17069         sleep 1
17070         local FID=$(cat /tmp/${tfile}.fid)
17071         [ "$FID" == "" ] && error "can't get FID for volatile"
17072         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17073         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17074         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17075         kill -USR1 $PID
17076         wait
17077         sleep 1
17078         cancel_lru_locks mdc # flush opencache
17079         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17080         return 0
17081 }
17082
17083 test_185a(){
17084         # LU-12516 - volatile creation via .lustre
17085         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17086                 skip "Need MDS version at least 2.3.55"
17087
17088         create_check_volatile 0
17089         [ $MDSCOUNT -lt 2 ] && return 0
17090
17091         # DNE case
17092         create_check_volatile 1
17093
17094         return 0
17095 }
17096 run_test 185a "Volatile file creation in .lustre/fid/"
17097
17098 test_187a() {
17099         remote_mds_nodsh && skip "remote MDS with nodsh"
17100         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17101                 skip "Need MDS version at least 2.3.0"
17102
17103         local dir0=$DIR/$tdir/$testnum
17104         mkdir -p $dir0 || error "creating dir $dir0"
17105
17106         local file=$dir0/file1
17107         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17108         local dv1=$($LFS data_version $file)
17109         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17110         local dv2=$($LFS data_version $file)
17111         [[ $dv1 != $dv2 ]] ||
17112                 error "data version did not change on write $dv1 == $dv2"
17113
17114         # clean up
17115         rm -f $file1
17116 }
17117 run_test 187a "Test data version change"
17118
17119 test_187b() {
17120         remote_mds_nodsh && skip "remote MDS with nodsh"
17121         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17122                 skip "Need MDS version at least 2.3.0"
17123
17124         local dir0=$DIR/$tdir/$testnum
17125         mkdir -p $dir0 || error "creating dir $dir0"
17126
17127         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17128         [[ ${DV[0]} != ${DV[1]} ]] ||
17129                 error "data version did not change on write"\
17130                       " ${DV[0]} == ${DV[1]}"
17131
17132         # clean up
17133         rm -f $file1
17134 }
17135 run_test 187b "Test data version change on volatile file"
17136
17137 test_200() {
17138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17139         remote_mgs_nodsh && skip "remote MGS with nodsh"
17140         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17141
17142         local POOL=${POOL:-cea1}
17143         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17144         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17145         # Pool OST targets
17146         local first_ost=0
17147         local last_ost=$(($OSTCOUNT - 1))
17148         local ost_step=2
17149         local ost_list=$(seq $first_ost $ost_step $last_ost)
17150         local ost_range="$first_ost $last_ost $ost_step"
17151         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17152         local file_dir=$POOL_ROOT/file_tst
17153         local subdir=$test_path/subdir
17154         local rc=0
17155
17156         while : ; do
17157                 # former test_200a test_200b
17158                 pool_add $POOL                          || { rc=$? ; break; }
17159                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17160                 # former test_200c test_200d
17161                 mkdir -p $test_path
17162                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17163                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17164                 mkdir -p $subdir
17165                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17166                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17167                                                         || { rc=$? ; break; }
17168                 # former test_200e test_200f
17169                 local files=$((OSTCOUNT*3))
17170                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17171                                                         || { rc=$? ; break; }
17172                 pool_create_files $POOL $file_dir $files "$ost_list" \
17173                                                         || { rc=$? ; break; }
17174                 # former test_200g test_200h
17175                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17176                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17177
17178                 # former test_201a test_201b test_201c
17179                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17180
17181                 local f=$test_path/$tfile
17182                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17183                 pool_remove $POOL $f                    || { rc=$? ; break; }
17184                 break
17185         done
17186
17187         destroy_test_pools
17188
17189         return $rc
17190 }
17191 run_test 200 "OST pools"
17192
17193 # usage: default_attr <count | size | offset>
17194 default_attr() {
17195         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17196 }
17197
17198 # usage: check_default_stripe_attr
17199 check_default_stripe_attr() {
17200         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17201         case $1 in
17202         --stripe-count|-c)
17203                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17204         --stripe-size|-S)
17205                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17206         --stripe-index|-i)
17207                 EXPECTED=-1;;
17208         *)
17209                 error "unknown getstripe attr '$1'"
17210         esac
17211
17212         [ $ACTUAL == $EXPECTED ] ||
17213                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17214 }
17215
17216 test_204a() {
17217         test_mkdir $DIR/$tdir
17218         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17219
17220         check_default_stripe_attr --stripe-count
17221         check_default_stripe_attr --stripe-size
17222         check_default_stripe_attr --stripe-index
17223 }
17224 run_test 204a "Print default stripe attributes"
17225
17226 test_204b() {
17227         test_mkdir $DIR/$tdir
17228         $LFS setstripe --stripe-count 1 $DIR/$tdir
17229
17230         check_default_stripe_attr --stripe-size
17231         check_default_stripe_attr --stripe-index
17232 }
17233 run_test 204b "Print default stripe size and offset"
17234
17235 test_204c() {
17236         test_mkdir $DIR/$tdir
17237         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17238
17239         check_default_stripe_attr --stripe-count
17240         check_default_stripe_attr --stripe-index
17241 }
17242 run_test 204c "Print default stripe count and offset"
17243
17244 test_204d() {
17245         test_mkdir $DIR/$tdir
17246         $LFS setstripe --stripe-index 0 $DIR/$tdir
17247
17248         check_default_stripe_attr --stripe-count
17249         check_default_stripe_attr --stripe-size
17250 }
17251 run_test 204d "Print default stripe count and size"
17252
17253 test_204e() {
17254         test_mkdir $DIR/$tdir
17255         $LFS setstripe -d $DIR/$tdir
17256
17257         check_default_stripe_attr --stripe-count --raw
17258         check_default_stripe_attr --stripe-size --raw
17259         check_default_stripe_attr --stripe-index --raw
17260 }
17261 run_test 204e "Print raw stripe attributes"
17262
17263 test_204f() {
17264         test_mkdir $DIR/$tdir
17265         $LFS setstripe --stripe-count 1 $DIR/$tdir
17266
17267         check_default_stripe_attr --stripe-size --raw
17268         check_default_stripe_attr --stripe-index --raw
17269 }
17270 run_test 204f "Print raw stripe size and offset"
17271
17272 test_204g() {
17273         test_mkdir $DIR/$tdir
17274         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17275
17276         check_default_stripe_attr --stripe-count --raw
17277         check_default_stripe_attr --stripe-index --raw
17278 }
17279 run_test 204g "Print raw stripe count and offset"
17280
17281 test_204h() {
17282         test_mkdir $DIR/$tdir
17283         $LFS setstripe --stripe-index 0 $DIR/$tdir
17284
17285         check_default_stripe_attr --stripe-count --raw
17286         check_default_stripe_attr --stripe-size --raw
17287 }
17288 run_test 204h "Print raw stripe count and size"
17289
17290 # Figure out which job scheduler is being used, if any,
17291 # or use a fake one
17292 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17293         JOBENV=SLURM_JOB_ID
17294 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17295         JOBENV=LSB_JOBID
17296 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17297         JOBENV=PBS_JOBID
17298 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17299         JOBENV=LOADL_STEP_ID
17300 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17301         JOBENV=JOB_ID
17302 else
17303         $LCTL list_param jobid_name > /dev/null 2>&1
17304         if [ $? -eq 0 ]; then
17305                 JOBENV=nodelocal
17306         else
17307                 JOBENV=FAKE_JOBID
17308         fi
17309 fi
17310 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17311
17312 verify_jobstats() {
17313         local cmd=($1)
17314         shift
17315         local facets="$@"
17316
17317 # we don't really need to clear the stats for this test to work, since each
17318 # command has a unique jobid, but it makes debugging easier if needed.
17319 #       for facet in $facets; do
17320 #               local dev=$(convert_facet2label $facet)
17321 #               # clear old jobstats
17322 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17323 #       done
17324
17325         # use a new JobID for each test, or we might see an old one
17326         [ "$JOBENV" = "FAKE_JOBID" ] &&
17327                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17328
17329         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17330
17331         [ "$JOBENV" = "nodelocal" ] && {
17332                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17333                 $LCTL set_param jobid_name=$FAKE_JOBID
17334                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17335         }
17336
17337         log "Test: ${cmd[*]}"
17338         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17339
17340         if [ $JOBENV = "FAKE_JOBID" ]; then
17341                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17342         else
17343                 ${cmd[*]}
17344         fi
17345
17346         # all files are created on OST0000
17347         for facet in $facets; do
17348                 local stats="*.$(convert_facet2label $facet).job_stats"
17349
17350                 # strip out libtool wrappers for in-tree executables
17351                 if [ $(do_facet $facet lctl get_param $stats |
17352                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17353                         do_facet $facet lctl get_param $stats
17354                         error "No jobstats for $JOBVAL found on $facet::$stats"
17355                 fi
17356         done
17357 }
17358
17359 jobstats_set() {
17360         local new_jobenv=$1
17361
17362         set_persistent_param_and_check client "jobid_var" \
17363                 "$FSNAME.sys.jobid_var" $new_jobenv
17364 }
17365
17366 test_205a() { # Job stats
17367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17368         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17369                 skip "Need MDS version with at least 2.7.1"
17370         remote_mgs_nodsh && skip "remote MGS with nodsh"
17371         remote_mds_nodsh && skip "remote MDS with nodsh"
17372         remote_ost_nodsh && skip "remote OST with nodsh"
17373         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17374                 skip "Server doesn't support jobstats"
17375         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17376
17377         local old_jobenv=$($LCTL get_param -n jobid_var)
17378         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17379
17380         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17381                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17382         else
17383                 stack_trap "do_facet mgs $PERM_CMD \
17384                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17385         fi
17386         changelog_register
17387
17388         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17389                                 mdt.*.job_cleanup_interval | head -n 1)
17390         local new_interval=5
17391         do_facet $SINGLEMDS \
17392                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17393         stack_trap "do_facet $SINGLEMDS \
17394                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17395         local start=$SECONDS
17396
17397         local cmd
17398         # mkdir
17399         cmd="mkdir $DIR/$tdir"
17400         verify_jobstats "$cmd" "$SINGLEMDS"
17401         # rmdir
17402         cmd="rmdir $DIR/$tdir"
17403         verify_jobstats "$cmd" "$SINGLEMDS"
17404         # mkdir on secondary MDT
17405         if [ $MDSCOUNT -gt 1 ]; then
17406                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17407                 verify_jobstats "$cmd" "mds2"
17408         fi
17409         # mknod
17410         cmd="mknod $DIR/$tfile c 1 3"
17411         verify_jobstats "$cmd" "$SINGLEMDS"
17412         # unlink
17413         cmd="rm -f $DIR/$tfile"
17414         verify_jobstats "$cmd" "$SINGLEMDS"
17415         # create all files on OST0000 so verify_jobstats can find OST stats
17416         # open & close
17417         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17418         verify_jobstats "$cmd" "$SINGLEMDS"
17419         # setattr
17420         cmd="touch $DIR/$tfile"
17421         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17422         # write
17423         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17424         verify_jobstats "$cmd" "ost1"
17425         # read
17426         cancel_lru_locks osc
17427         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17428         verify_jobstats "$cmd" "ost1"
17429         # truncate
17430         cmd="$TRUNCATE $DIR/$tfile 0"
17431         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17432         # rename
17433         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17434         verify_jobstats "$cmd" "$SINGLEMDS"
17435         # jobstats expiry - sleep until old stats should be expired
17436         local left=$((new_interval + 5 - (SECONDS - start)))
17437         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17438                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17439                         "0" $left
17440         cmd="mkdir $DIR/$tdir.expire"
17441         verify_jobstats "$cmd" "$SINGLEMDS"
17442         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17443             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17444
17445         # Ensure that jobid are present in changelog (if supported by MDS)
17446         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17447                 changelog_dump | tail -10
17448                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17449                 [ $jobids -eq 9 ] ||
17450                         error "Wrong changelog jobid count $jobids != 9"
17451
17452                 # LU-5862
17453                 JOBENV="disable"
17454                 jobstats_set $JOBENV
17455                 touch $DIR/$tfile
17456                 changelog_dump | grep $tfile
17457                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17458                 [ $jobids -eq 0 ] ||
17459                         error "Unexpected jobids when jobid_var=$JOBENV"
17460         fi
17461
17462         # test '%j' access to environment variable - if supported
17463         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17464                 JOBENV="JOBCOMPLEX"
17465                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17466
17467                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17468         fi
17469
17470         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17471                 JOBENV="JOBCOMPLEX"
17472                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17473
17474                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17475         fi
17476
17477         # test '%j' access to per-session jobid - if supported
17478         if lctl list_param jobid_this_session > /dev/null 2>&1
17479         then
17480                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17481                 lctl set_param jobid_this_session=$USER
17482
17483                 JOBENV="JOBCOMPLEX"
17484                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17485
17486                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17487         fi
17488 }
17489 run_test 205a "Verify job stats"
17490
17491 # LU-13117, LU-13597
17492 test_205b() {
17493         job_stats="mdt.*.job_stats"
17494         $LCTL set_param $job_stats=clear
17495         # Setting jobid_var to USER might not be supported
17496         $LCTL set_param jobid_var=USER || true
17497         $LCTL set_param jobid_name="%e.%u"
17498         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17499         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17500                 grep "job_id:.*foolish" &&
17501                         error "Unexpected jobid found"
17502         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17503                 grep "open:.*min.*max.*sum" ||
17504                         error "wrong job_stats format found"
17505 }
17506 run_test 205b "Verify job stats jobid and output format"
17507
17508 # LU-13733
17509 test_205c() {
17510         $LCTL set_param llite.*.stats=0
17511         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17512         $LCTL get_param llite.*.stats
17513         $LCTL get_param llite.*.stats | grep \
17514                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17515                         error "wrong client stats format found"
17516 }
17517 run_test 205c "Verify client stats format"
17518
17519 # LU-1480, LU-1773 and LU-1657
17520 test_206() {
17521         mkdir -p $DIR/$tdir
17522         $LFS setstripe -c -1 $DIR/$tdir
17523 #define OBD_FAIL_LOV_INIT 0x1403
17524         $LCTL set_param fail_loc=0xa0001403
17525         $LCTL set_param fail_val=1
17526         touch $DIR/$tdir/$tfile || true
17527 }
17528 run_test 206 "fail lov_init_raid0() doesn't lbug"
17529
17530 test_207a() {
17531         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17532         local fsz=`stat -c %s $DIR/$tfile`
17533         cancel_lru_locks mdc
17534
17535         # do not return layout in getattr intent
17536 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17537         $LCTL set_param fail_loc=0x170
17538         local sz=`stat -c %s $DIR/$tfile`
17539
17540         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17541
17542         rm -rf $DIR/$tfile
17543 }
17544 run_test 207a "can refresh layout at glimpse"
17545
17546 test_207b() {
17547         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17548         local cksum=`md5sum $DIR/$tfile`
17549         local fsz=`stat -c %s $DIR/$tfile`
17550         cancel_lru_locks mdc
17551         cancel_lru_locks osc
17552
17553         # do not return layout in getattr intent
17554 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17555         $LCTL set_param fail_loc=0x171
17556
17557         # it will refresh layout after the file is opened but before read issues
17558         echo checksum is "$cksum"
17559         echo "$cksum" |md5sum -c --quiet || error "file differs"
17560
17561         rm -rf $DIR/$tfile
17562 }
17563 run_test 207b "can refresh layout at open"
17564
17565 test_208() {
17566         # FIXME: in this test suite, only RD lease is used. This is okay
17567         # for now as only exclusive open is supported. After generic lease
17568         # is done, this test suite should be revised. - Jinshan
17569
17570         remote_mds_nodsh && skip "remote MDS with nodsh"
17571         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17572                 skip "Need MDS version at least 2.4.52"
17573
17574         echo "==== test 1: verify get lease work"
17575         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17576
17577         echo "==== test 2: verify lease can be broken by upcoming open"
17578         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17579         local PID=$!
17580         sleep 1
17581
17582         $MULTIOP $DIR/$tfile oO_RDONLY:c
17583         kill -USR1 $PID && wait $PID || error "break lease error"
17584
17585         echo "==== test 3: verify lease can't be granted if an open already exists"
17586         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17587         local PID=$!
17588         sleep 1
17589
17590         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17591         kill -USR1 $PID && wait $PID || error "open file error"
17592
17593         echo "==== test 4: lease can sustain over recovery"
17594         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17595         PID=$!
17596         sleep 1
17597
17598         fail mds1
17599
17600         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17601
17602         echo "==== test 5: lease broken can't be regained by replay"
17603         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17604         PID=$!
17605         sleep 1
17606
17607         # open file to break lease and then recovery
17608         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17609         fail mds1
17610
17611         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17612
17613         rm -f $DIR/$tfile
17614 }
17615 run_test 208 "Exclusive open"
17616
17617 test_209() {
17618         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17619                 skip_env "must have disp_stripe"
17620
17621         touch $DIR/$tfile
17622         sync; sleep 5; sync;
17623
17624         echo 3 > /proc/sys/vm/drop_caches
17625         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17626                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17627         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17628
17629         # open/close 500 times
17630         for i in $(seq 500); do
17631                 cat $DIR/$tfile
17632         done
17633
17634         echo 3 > /proc/sys/vm/drop_caches
17635         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17636                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17637         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17638
17639         echo "before: $req_before, after: $req_after"
17640         [ $((req_after - req_before)) -ge 300 ] &&
17641                 error "open/close requests are not freed"
17642         return 0
17643 }
17644 run_test 209 "read-only open/close requests should be freed promptly"
17645
17646 test_210() {
17647         local pid
17648
17649         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17650         pid=$!
17651         sleep 1
17652
17653         $LFS getstripe $DIR/$tfile
17654         kill -USR1 $pid
17655         wait $pid || error "multiop failed"
17656
17657         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17658         pid=$!
17659         sleep 1
17660
17661         $LFS getstripe $DIR/$tfile
17662         kill -USR1 $pid
17663         wait $pid || error "multiop failed"
17664 }
17665 run_test 210 "lfs getstripe does not break leases"
17666
17667 test_212() {
17668         size=`date +%s`
17669         size=$((size % 8192 + 1))
17670         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17671         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17672         rm -f $DIR/f212 $DIR/f212.xyz
17673 }
17674 run_test 212 "Sendfile test ============================================"
17675
17676 test_213() {
17677         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17678         cancel_lru_locks osc
17679         lctl set_param fail_loc=0x8000040f
17680         # generate a read lock
17681         cat $DIR/$tfile > /dev/null
17682         # write to the file, it will try to cancel the above read lock.
17683         cat /etc/hosts >> $DIR/$tfile
17684 }
17685 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17686
17687 test_214() { # for bug 20133
17688         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17689         for (( i=0; i < 340; i++ )) ; do
17690                 touch $DIR/$tdir/d214c/a$i
17691         done
17692
17693         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17694         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17695         ls $DIR/d214c || error "ls $DIR/d214c failed"
17696         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17697         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17698 }
17699 run_test 214 "hash-indexed directory test - bug 20133"
17700
17701 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17702 create_lnet_proc_files() {
17703         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17704 }
17705
17706 # counterpart of create_lnet_proc_files
17707 remove_lnet_proc_files() {
17708         rm -f $TMP/lnet_$1.sys
17709 }
17710
17711 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17712 # 3rd arg as regexp for body
17713 check_lnet_proc_stats() {
17714         local l=$(cat "$TMP/lnet_$1" |wc -l)
17715         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17716
17717         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17718 }
17719
17720 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17721 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17722 # optional and can be regexp for 2nd line (lnet.routes case)
17723 check_lnet_proc_entry() {
17724         local blp=2          # blp stands for 'position of 1st line of body'
17725         [ -z "$5" ] || blp=3 # lnet.routes case
17726
17727         local l=$(cat "$TMP/lnet_$1" |wc -l)
17728         # subtracting one from $blp because the body can be empty
17729         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17730
17731         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17732                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17733
17734         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17735                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17736
17737         # bail out if any unexpected line happened
17738         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17739         [ "$?" != 0 ] || error "$2 misformatted"
17740 }
17741
17742 test_215() { # for bugs 18102, 21079, 21517
17743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17744
17745         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17746         local P='[1-9][0-9]*'           # positive numeric
17747         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17748         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17749         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17750         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17751
17752         local L1 # regexp for 1st line
17753         local L2 # regexp for 2nd line (optional)
17754         local BR # regexp for the rest (body)
17755
17756         # lnet.stats should look as 11 space-separated non-negative numerics
17757         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17758         create_lnet_proc_files "stats"
17759         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17760         remove_lnet_proc_files "stats"
17761
17762         # lnet.routes should look like this:
17763         # Routing disabled/enabled
17764         # net hops priority state router
17765         # where net is a string like tcp0, hops > 0, priority >= 0,
17766         # state is up/down,
17767         # router is a string like 192.168.1.1@tcp2
17768         L1="^Routing (disabled|enabled)$"
17769         L2="^net +hops +priority +state +router$"
17770         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17771         create_lnet_proc_files "routes"
17772         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17773         remove_lnet_proc_files "routes"
17774
17775         # lnet.routers should look like this:
17776         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17777         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17778         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17779         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17780         L1="^ref +rtr_ref +alive +router$"
17781         BR="^$P +$P +(up|down) +$NID$"
17782         create_lnet_proc_files "routers"
17783         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17784         remove_lnet_proc_files "routers"
17785
17786         # lnet.peers should look like this:
17787         # nid refs state last max rtr min tx min queue
17788         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17789         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17790         # numeric (0 or >0 or <0), queue >= 0.
17791         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17792         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17793         create_lnet_proc_files "peers"
17794         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17795         remove_lnet_proc_files "peers"
17796
17797         # lnet.buffers  should look like this:
17798         # pages count credits min
17799         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17800         L1="^pages +count +credits +min$"
17801         BR="^ +$N +$N +$I +$I$"
17802         create_lnet_proc_files "buffers"
17803         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17804         remove_lnet_proc_files "buffers"
17805
17806         # lnet.nis should look like this:
17807         # nid status alive refs peer rtr max tx min
17808         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17809         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17810         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17811         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17812         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17813         create_lnet_proc_files "nis"
17814         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17815         remove_lnet_proc_files "nis"
17816
17817         # can we successfully write to lnet.stats?
17818         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17819 }
17820 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17821
17822 test_216() { # bug 20317
17823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17824         remote_ost_nodsh && skip "remote OST with nodsh"
17825
17826         local node
17827         local facets=$(get_facets OST)
17828         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17829
17830         save_lustre_params client "osc.*.contention_seconds" > $p
17831         save_lustre_params $facets \
17832                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17833         save_lustre_params $facets \
17834                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17835         save_lustre_params $facets \
17836                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17837         clear_stats osc.*.osc_stats
17838
17839         # agressive lockless i/o settings
17840         do_nodes $(comma_list $(osts_nodes)) \
17841                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17842                         ldlm.namespaces.filter-*.contended_locks=0 \
17843                         ldlm.namespaces.filter-*.contention_seconds=60"
17844         lctl set_param -n osc.*.contention_seconds=60
17845
17846         $DIRECTIO write $DIR/$tfile 0 10 4096
17847         $CHECKSTAT -s 40960 $DIR/$tfile
17848
17849         # disable lockless i/o
17850         do_nodes $(comma_list $(osts_nodes)) \
17851                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17852                         ldlm.namespaces.filter-*.contended_locks=32 \
17853                         ldlm.namespaces.filter-*.contention_seconds=0"
17854         lctl set_param -n osc.*.contention_seconds=0
17855         clear_stats osc.*.osc_stats
17856
17857         dd if=/dev/zero of=$DIR/$tfile count=0
17858         $CHECKSTAT -s 0 $DIR/$tfile
17859
17860         restore_lustre_params <$p
17861         rm -f $p
17862         rm $DIR/$tfile
17863 }
17864 run_test 216 "check lockless direct write updates file size and kms correctly"
17865
17866 test_217() { # bug 22430
17867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17868
17869         local node
17870         local nid
17871
17872         for node in $(nodes_list); do
17873                 nid=$(host_nids_address $node $NETTYPE)
17874                 if [[ $nid = *-* ]] ; then
17875                         echo "lctl ping $(h2nettype $nid)"
17876                         lctl ping $(h2nettype $nid)
17877                 else
17878                         echo "skipping $node (no hyphen detected)"
17879                 fi
17880         done
17881 }
17882 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17883
17884 test_218() {
17885        # do directio so as not to populate the page cache
17886        log "creating a 10 Mb file"
17887        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17888        log "starting reads"
17889        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17890        log "truncating the file"
17891        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17892        log "killing dd"
17893        kill %+ || true # reads might have finished
17894        echo "wait until dd is finished"
17895        wait
17896        log "removing the temporary file"
17897        rm -rf $DIR/$tfile || error "tmp file removal failed"
17898 }
17899 run_test 218 "parallel read and truncate should not deadlock"
17900
17901 test_219() {
17902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17903
17904         # write one partial page
17905         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17906         # set no grant so vvp_io_commit_write will do sync write
17907         $LCTL set_param fail_loc=0x411
17908         # write a full page at the end of file
17909         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17910
17911         $LCTL set_param fail_loc=0
17912         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17913         $LCTL set_param fail_loc=0x411
17914         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17915
17916         # LU-4201
17917         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17918         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17919 }
17920 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17921
17922 test_220() { #LU-325
17923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17924         remote_ost_nodsh && skip "remote OST with nodsh"
17925         remote_mds_nodsh && skip "remote MDS with nodsh"
17926         remote_mgs_nodsh && skip "remote MGS with nodsh"
17927
17928         local OSTIDX=0
17929
17930         # create on MDT0000 so the last_id and next_id are correct
17931         mkdir $DIR/$tdir
17932         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17933         OST=${OST%_UUID}
17934
17935         # on the mdt's osc
17936         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17937         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17938                         osp.$mdtosc_proc1.prealloc_last_id)
17939         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17940                         osp.$mdtosc_proc1.prealloc_next_id)
17941
17942         $LFS df -i
17943
17944         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17945         #define OBD_FAIL_OST_ENOINO              0x229
17946         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17947         create_pool $FSNAME.$TESTNAME || return 1
17948         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17949
17950         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17951
17952         MDSOBJS=$((last_id - next_id))
17953         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17954
17955         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17956         echo "OST still has $count kbytes free"
17957
17958         echo "create $MDSOBJS files @next_id..."
17959         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17960
17961         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17962                         osp.$mdtosc_proc1.prealloc_last_id)
17963         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17964                         osp.$mdtosc_proc1.prealloc_next_id)
17965
17966         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17967         $LFS df -i
17968
17969         echo "cleanup..."
17970
17971         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17972         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17973
17974         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17975                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17976         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17977                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17978         echo "unlink $MDSOBJS files @$next_id..."
17979         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17980 }
17981 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17982
17983 test_221() {
17984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17985
17986         dd if=`which date` of=$MOUNT/date oflag=sync
17987         chmod +x $MOUNT/date
17988
17989         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17990         $LCTL set_param fail_loc=0x80001401
17991
17992         $MOUNT/date > /dev/null
17993         rm -f $MOUNT/date
17994 }
17995 run_test 221 "make sure fault and truncate race to not cause OOM"
17996
17997 test_222a () {
17998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17999
18000         rm -rf $DIR/$tdir
18001         test_mkdir $DIR/$tdir
18002         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18003         createmany -o $DIR/$tdir/$tfile 10
18004         cancel_lru_locks mdc
18005         cancel_lru_locks osc
18006         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18007         $LCTL set_param fail_loc=0x31a
18008         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18009         $LCTL set_param fail_loc=0
18010         rm -r $DIR/$tdir
18011 }
18012 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18013
18014 test_222b () {
18015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18016
18017         rm -rf $DIR/$tdir
18018         test_mkdir $DIR/$tdir
18019         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18020         createmany -o $DIR/$tdir/$tfile 10
18021         cancel_lru_locks mdc
18022         cancel_lru_locks osc
18023         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18024         $LCTL set_param fail_loc=0x31a
18025         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18026         $LCTL set_param fail_loc=0
18027 }
18028 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18029
18030 test_223 () {
18031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18032
18033         rm -rf $DIR/$tdir
18034         test_mkdir $DIR/$tdir
18035         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18036         createmany -o $DIR/$tdir/$tfile 10
18037         cancel_lru_locks mdc
18038         cancel_lru_locks osc
18039         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18040         $LCTL set_param fail_loc=0x31b
18041         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18042         $LCTL set_param fail_loc=0
18043         rm -r $DIR/$tdir
18044 }
18045 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18046
18047 test_224a() { # LU-1039, MRP-303
18048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18049
18050         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18051         $LCTL set_param fail_loc=0x508
18052         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18053         $LCTL set_param fail_loc=0
18054         df $DIR
18055 }
18056 run_test 224a "Don't panic on bulk IO failure"
18057
18058 test_224b() { # LU-1039, MRP-303
18059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18060
18061         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18062         cancel_lru_locks osc
18063         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18064         $LCTL set_param fail_loc=0x515
18065         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18066         $LCTL set_param fail_loc=0
18067         df $DIR
18068 }
18069 run_test 224b "Don't panic on bulk IO failure"
18070
18071 test_224c() { # LU-6441
18072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18073         remote_mds_nodsh && skip "remote MDS with nodsh"
18074
18075         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18076         save_writethrough $p
18077         set_cache writethrough on
18078
18079         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18080         local at_max=$($LCTL get_param -n at_max)
18081         local timeout=$($LCTL get_param -n timeout)
18082         local test_at="at_max"
18083         local param_at="$FSNAME.sys.at_max"
18084         local test_timeout="timeout"
18085         local param_timeout="$FSNAME.sys.timeout"
18086
18087         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18088
18089         set_persistent_param_and_check client "$test_at" "$param_at" 0
18090         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18091
18092         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18093         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18094         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18095         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18096         sync
18097         do_facet ost1 "$LCTL set_param fail_loc=0"
18098
18099         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18100         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18101                 $timeout
18102
18103         $LCTL set_param -n $pages_per_rpc
18104         restore_lustre_params < $p
18105         rm -f $p
18106 }
18107 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18108
18109 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18110 test_225a () {
18111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18112         if [ -z ${MDSSURVEY} ]; then
18113                 skip_env "mds-survey not found"
18114         fi
18115         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18116                 skip "Need MDS version at least 2.2.51"
18117
18118         local mds=$(facet_host $SINGLEMDS)
18119         local target=$(do_nodes $mds 'lctl dl' |
18120                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18121
18122         local cmd1="file_count=1000 thrhi=4"
18123         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18124         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18125         local cmd="$cmd1 $cmd2 $cmd3"
18126
18127         rm -f ${TMP}/mds_survey*
18128         echo + $cmd
18129         eval $cmd || error "mds-survey with zero-stripe failed"
18130         cat ${TMP}/mds_survey*
18131         rm -f ${TMP}/mds_survey*
18132 }
18133 run_test 225a "Metadata survey sanity with zero-stripe"
18134
18135 test_225b () {
18136         if [ -z ${MDSSURVEY} ]; then
18137                 skip_env "mds-survey not found"
18138         fi
18139         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18140                 skip "Need MDS version at least 2.2.51"
18141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18142         remote_mds_nodsh && skip "remote MDS with nodsh"
18143         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18144                 skip_env "Need to mount OST to test"
18145         fi
18146
18147         local mds=$(facet_host $SINGLEMDS)
18148         local target=$(do_nodes $mds 'lctl dl' |
18149                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18150
18151         local cmd1="file_count=1000 thrhi=4"
18152         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18153         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18154         local cmd="$cmd1 $cmd2 $cmd3"
18155
18156         rm -f ${TMP}/mds_survey*
18157         echo + $cmd
18158         eval $cmd || error "mds-survey with stripe_count failed"
18159         cat ${TMP}/mds_survey*
18160         rm -f ${TMP}/mds_survey*
18161 }
18162 run_test 225b "Metadata survey sanity with stripe_count = 1"
18163
18164 mcreate_path2fid () {
18165         local mode=$1
18166         local major=$2
18167         local minor=$3
18168         local name=$4
18169         local desc=$5
18170         local path=$DIR/$tdir/$name
18171         local fid
18172         local rc
18173         local fid_path
18174
18175         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18176                 error "cannot create $desc"
18177
18178         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18179         rc=$?
18180         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18181
18182         fid_path=$($LFS fid2path $MOUNT $fid)
18183         rc=$?
18184         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18185
18186         [ "$path" == "$fid_path" ] ||
18187                 error "fid2path returned $fid_path, expected $path"
18188
18189         echo "pass with $path and $fid"
18190 }
18191
18192 test_226a () {
18193         rm -rf $DIR/$tdir
18194         mkdir -p $DIR/$tdir
18195
18196         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18197         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18198         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18199         mcreate_path2fid 0040666 0 0 dir "directory"
18200         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18201         mcreate_path2fid 0100666 0 0 file "regular file"
18202         mcreate_path2fid 0120666 0 0 link "symbolic link"
18203         mcreate_path2fid 0140666 0 0 sock "socket"
18204 }
18205 run_test 226a "call path2fid and fid2path on files of all type"
18206
18207 test_226b () {
18208         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18209
18210         local MDTIDX=1
18211
18212         rm -rf $DIR/$tdir
18213         mkdir -p $DIR/$tdir
18214         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18215                 error "create remote directory failed"
18216         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18217         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18218                                 "character special file (null)"
18219         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18220                                 "character special file (no device)"
18221         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18222         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18223                                 "block special file (loop)"
18224         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18225         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18226         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18227 }
18228 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18229
18230 test_226c () {
18231         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18232         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18233                 skip "Need MDS version at least 2.13.55"
18234
18235         local submnt=/mnt/submnt
18236         local srcfile=/etc/passwd
18237         local dstfile=$submnt/passwd
18238         local path
18239         local fid
18240
18241         rm -rf $DIR/$tdir
18242         rm -rf $submnt
18243         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18244                 error "create remote directory failed"
18245         mkdir -p $submnt || error "create $submnt failed"
18246         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18247                 error "mount $submnt failed"
18248         stack_trap "umount $submnt" EXIT
18249
18250         cp $srcfile $dstfile
18251         fid=$($LFS path2fid $dstfile)
18252         path=$($LFS fid2path $submnt "$fid")
18253         [ "$path" = "$dstfile" ] ||
18254                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18255 }
18256 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18257
18258 # LU-1299 Executing or running ldd on a truncated executable does not
18259 # cause an out-of-memory condition.
18260 test_227() {
18261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18262         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18263
18264         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18265         chmod +x $MOUNT/date
18266
18267         $MOUNT/date > /dev/null
18268         ldd $MOUNT/date > /dev/null
18269         rm -f $MOUNT/date
18270 }
18271 run_test 227 "running truncated executable does not cause OOM"
18272
18273 # LU-1512 try to reuse idle OI blocks
18274 test_228a() {
18275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18276         remote_mds_nodsh && skip "remote MDS with nodsh"
18277         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18278
18279         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18280         local myDIR=$DIR/$tdir
18281
18282         mkdir -p $myDIR
18283         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18284         $LCTL set_param fail_loc=0x80001002
18285         createmany -o $myDIR/t- 10000
18286         $LCTL set_param fail_loc=0
18287         # The guard is current the largest FID holder
18288         touch $myDIR/guard
18289         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18290                     tr -d '[')
18291         local IDX=$(($SEQ % 64))
18292
18293         do_facet $SINGLEMDS sync
18294         # Make sure journal flushed.
18295         sleep 6
18296         local blk1=$(do_facet $SINGLEMDS \
18297                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18298                      grep Blockcount | awk '{print $4}')
18299
18300         # Remove old files, some OI blocks will become idle.
18301         unlinkmany $myDIR/t- 10000
18302         # Create new files, idle OI blocks should be reused.
18303         createmany -o $myDIR/t- 2000
18304         do_facet $SINGLEMDS sync
18305         # Make sure journal flushed.
18306         sleep 6
18307         local blk2=$(do_facet $SINGLEMDS \
18308                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18309                      grep Blockcount | awk '{print $4}')
18310
18311         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18312 }
18313 run_test 228a "try to reuse idle OI blocks"
18314
18315 test_228b() {
18316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18317         remote_mds_nodsh && skip "remote MDS with nodsh"
18318         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18319
18320         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18321         local myDIR=$DIR/$tdir
18322
18323         mkdir -p $myDIR
18324         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18325         $LCTL set_param fail_loc=0x80001002
18326         createmany -o $myDIR/t- 10000
18327         $LCTL set_param fail_loc=0
18328         # The guard is current the largest FID holder
18329         touch $myDIR/guard
18330         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18331                     tr -d '[')
18332         local IDX=$(($SEQ % 64))
18333
18334         do_facet $SINGLEMDS sync
18335         # Make sure journal flushed.
18336         sleep 6
18337         local blk1=$(do_facet $SINGLEMDS \
18338                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18339                      grep Blockcount | awk '{print $4}')
18340
18341         # Remove old files, some OI blocks will become idle.
18342         unlinkmany $myDIR/t- 10000
18343
18344         # stop the MDT
18345         stop $SINGLEMDS || error "Fail to stop MDT."
18346         # remount the MDT
18347         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18348
18349         df $MOUNT || error "Fail to df."
18350         # Create new files, idle OI blocks should be reused.
18351         createmany -o $myDIR/t- 2000
18352         do_facet $SINGLEMDS sync
18353         # Make sure journal flushed.
18354         sleep 6
18355         local blk2=$(do_facet $SINGLEMDS \
18356                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18357                      grep Blockcount | awk '{print $4}')
18358
18359         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18360 }
18361 run_test 228b "idle OI blocks can be reused after MDT restart"
18362
18363 #LU-1881
18364 test_228c() {
18365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18366         remote_mds_nodsh && skip "remote MDS with nodsh"
18367         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18368
18369         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18370         local myDIR=$DIR/$tdir
18371
18372         mkdir -p $myDIR
18373         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18374         $LCTL set_param fail_loc=0x80001002
18375         # 20000 files can guarantee there are index nodes in the OI file
18376         createmany -o $myDIR/t- 20000
18377         $LCTL set_param fail_loc=0
18378         # The guard is current the largest FID holder
18379         touch $myDIR/guard
18380         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18381                     tr -d '[')
18382         local IDX=$(($SEQ % 64))
18383
18384         do_facet $SINGLEMDS sync
18385         # Make sure journal flushed.
18386         sleep 6
18387         local blk1=$(do_facet $SINGLEMDS \
18388                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18389                      grep Blockcount | awk '{print $4}')
18390
18391         # Remove old files, some OI blocks will become idle.
18392         unlinkmany $myDIR/t- 20000
18393         rm -f $myDIR/guard
18394         # The OI file should become empty now
18395
18396         # Create new files, idle OI blocks should be reused.
18397         createmany -o $myDIR/t- 2000
18398         do_facet $SINGLEMDS sync
18399         # Make sure journal flushed.
18400         sleep 6
18401         local blk2=$(do_facet $SINGLEMDS \
18402                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18403                      grep Blockcount | awk '{print $4}')
18404
18405         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18406 }
18407 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18408
18409 test_229() { # LU-2482, LU-3448
18410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18411         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18412         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18413                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18414
18415         rm -f $DIR/$tfile
18416
18417         # Create a file with a released layout and stripe count 2.
18418         $MULTIOP $DIR/$tfile H2c ||
18419                 error "failed to create file with released layout"
18420
18421         $LFS getstripe -v $DIR/$tfile
18422
18423         local pattern=$($LFS getstripe -L $DIR/$tfile)
18424         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18425
18426         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18427                 error "getstripe"
18428         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18429         stat $DIR/$tfile || error "failed to stat released file"
18430
18431         chown $RUNAS_ID $DIR/$tfile ||
18432                 error "chown $RUNAS_ID $DIR/$tfile failed"
18433
18434         chgrp $RUNAS_ID $DIR/$tfile ||
18435                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18436
18437         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18438         rm $DIR/$tfile || error "failed to remove released file"
18439 }
18440 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18441
18442 test_230a() {
18443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18444         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18445         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18446                 skip "Need MDS version at least 2.11.52"
18447
18448         local MDTIDX=1
18449
18450         test_mkdir $DIR/$tdir
18451         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18452         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18453         [ $mdt_idx -ne 0 ] &&
18454                 error "create local directory on wrong MDT $mdt_idx"
18455
18456         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18457                         error "create remote directory failed"
18458         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18459         [ $mdt_idx -ne $MDTIDX ] &&
18460                 error "create remote directory on wrong MDT $mdt_idx"
18461
18462         createmany -o $DIR/$tdir/test_230/t- 10 ||
18463                 error "create files on remote directory failed"
18464         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18465         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18466         rm -r $DIR/$tdir || error "unlink remote directory failed"
18467 }
18468 run_test 230a "Create remote directory and files under the remote directory"
18469
18470 test_230b() {
18471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18472         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18473         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18474                 skip "Need MDS version at least 2.11.52"
18475
18476         local MDTIDX=1
18477         local mdt_index
18478         local i
18479         local file
18480         local pid
18481         local stripe_count
18482         local migrate_dir=$DIR/$tdir/migrate_dir
18483         local other_dir=$DIR/$tdir/other_dir
18484
18485         test_mkdir $DIR/$tdir
18486         test_mkdir -i0 -c1 $migrate_dir
18487         test_mkdir -i0 -c1 $other_dir
18488         for ((i=0; i<10; i++)); do
18489                 mkdir -p $migrate_dir/dir_${i}
18490                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18491                         error "create files under remote dir failed $i"
18492         done
18493
18494         cp /etc/passwd $migrate_dir/$tfile
18495         cp /etc/passwd $other_dir/$tfile
18496         chattr +SAD $migrate_dir
18497         chattr +SAD $migrate_dir/$tfile
18498
18499         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18500         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18501         local old_dir_mode=$(stat -c%f $migrate_dir)
18502         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18503
18504         mkdir -p $migrate_dir/dir_default_stripe2
18505         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18506         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18507
18508         mkdir -p $other_dir
18509         ln $migrate_dir/$tfile $other_dir/luna
18510         ln $migrate_dir/$tfile $migrate_dir/sofia
18511         ln $other_dir/$tfile $migrate_dir/david
18512         ln -s $migrate_dir/$tfile $other_dir/zachary
18513         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18514         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18515
18516         local len
18517         local lnktgt
18518
18519         # inline symlink
18520         for len in 58 59 60; do
18521                 lnktgt=$(str_repeat 'l' $len)
18522                 touch $migrate_dir/$lnktgt
18523                 ln -s $lnktgt $migrate_dir/${len}char_ln
18524         done
18525
18526         # PATH_MAX
18527         for len in 4094 4095; do
18528                 lnktgt=$(str_repeat 'l' $len)
18529                 ln -s $lnktgt $migrate_dir/${len}char_ln
18530         done
18531
18532         # NAME_MAX
18533         for len in 254 255; do
18534                 touch $migrate_dir/$(str_repeat 'l' $len)
18535         done
18536
18537         $LFS migrate -m $MDTIDX $migrate_dir ||
18538                 error "fails on migrating remote dir to MDT1"
18539
18540         echo "migratate to MDT1, then checking.."
18541         for ((i = 0; i < 10; i++)); do
18542                 for file in $(find $migrate_dir/dir_${i}); do
18543                         mdt_index=$($LFS getstripe -m $file)
18544                         # broken symlink getstripe will fail
18545                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18546                                 error "$file is not on MDT${MDTIDX}"
18547                 done
18548         done
18549
18550         # the multiple link file should still in MDT0
18551         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18552         [ $mdt_index == 0 ] ||
18553                 error "$file is not on MDT${MDTIDX}"
18554
18555         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18556         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18557                 error " expect $old_dir_flag get $new_dir_flag"
18558
18559         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18560         [ "$old_file_flag" = "$new_file_flag" ] ||
18561                 error " expect $old_file_flag get $new_file_flag"
18562
18563         local new_dir_mode=$(stat -c%f $migrate_dir)
18564         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18565                 error "expect mode $old_dir_mode get $new_dir_mode"
18566
18567         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18568         [ "$old_file_mode" = "$new_file_mode" ] ||
18569                 error "expect mode $old_file_mode get $new_file_mode"
18570
18571         diff /etc/passwd $migrate_dir/$tfile ||
18572                 error "$tfile different after migration"
18573
18574         diff /etc/passwd $other_dir/luna ||
18575                 error "luna different after migration"
18576
18577         diff /etc/passwd $migrate_dir/sofia ||
18578                 error "sofia different after migration"
18579
18580         diff /etc/passwd $migrate_dir/david ||
18581                 error "david different after migration"
18582
18583         diff /etc/passwd $other_dir/zachary ||
18584                 error "zachary different after migration"
18585
18586         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18587                 error "${tfile}_ln different after migration"
18588
18589         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18590                 error "${tfile}_ln_other different after migration"
18591
18592         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18593         [ $stripe_count = 2 ] ||
18594                 error "dir strpe_count $d != 2 after migration."
18595
18596         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18597         [ $stripe_count = 2 ] ||
18598                 error "file strpe_count $d != 2 after migration."
18599
18600         #migrate back to MDT0
18601         MDTIDX=0
18602
18603         $LFS migrate -m $MDTIDX $migrate_dir ||
18604                 error "fails on migrating remote dir to MDT0"
18605
18606         echo "migrate back to MDT0, checking.."
18607         for file in $(find $migrate_dir); do
18608                 mdt_index=$($LFS getstripe -m $file)
18609                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18610                         error "$file is not on MDT${MDTIDX}"
18611         done
18612
18613         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18614         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18615                 error " expect $old_dir_flag get $new_dir_flag"
18616
18617         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18618         [ "$old_file_flag" = "$new_file_flag" ] ||
18619                 error " expect $old_file_flag get $new_file_flag"
18620
18621         local new_dir_mode=$(stat -c%f $migrate_dir)
18622         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18623                 error "expect mode $old_dir_mode get $new_dir_mode"
18624
18625         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18626         [ "$old_file_mode" = "$new_file_mode" ] ||
18627                 error "expect mode $old_file_mode get $new_file_mode"
18628
18629         diff /etc/passwd ${migrate_dir}/$tfile ||
18630                 error "$tfile different after migration"
18631
18632         diff /etc/passwd ${other_dir}/luna ||
18633                 error "luna different after migration"
18634
18635         diff /etc/passwd ${migrate_dir}/sofia ||
18636                 error "sofia different after migration"
18637
18638         diff /etc/passwd ${other_dir}/zachary ||
18639                 error "zachary different after migration"
18640
18641         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18642                 error "${tfile}_ln different after migration"
18643
18644         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18645                 error "${tfile}_ln_other different after migration"
18646
18647         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18648         [ $stripe_count = 2 ] ||
18649                 error "dir strpe_count $d != 2 after migration."
18650
18651         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18652         [ $stripe_count = 2 ] ||
18653                 error "file strpe_count $d != 2 after migration."
18654
18655         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18656 }
18657 run_test 230b "migrate directory"
18658
18659 test_230c() {
18660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18661         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18662         remote_mds_nodsh && skip "remote MDS with nodsh"
18663         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18664                 skip "Need MDS version at least 2.11.52"
18665
18666         local MDTIDX=1
18667         local total=3
18668         local mdt_index
18669         local file
18670         local migrate_dir=$DIR/$tdir/migrate_dir
18671
18672         #If migrating directory fails in the middle, all entries of
18673         #the directory is still accessiable.
18674         test_mkdir $DIR/$tdir
18675         test_mkdir -i0 -c1 $migrate_dir
18676         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18677         stat $migrate_dir
18678         createmany -o $migrate_dir/f $total ||
18679                 error "create files under ${migrate_dir} failed"
18680
18681         # fail after migrating top dir, and this will fail only once, so the
18682         # first sub file migration will fail (currently f3), others succeed.
18683         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18684         do_facet mds1 lctl set_param fail_loc=0x1801
18685         local t=$(ls $migrate_dir | wc -l)
18686         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18687                 error "migrate should fail"
18688         local u=$(ls $migrate_dir | wc -l)
18689         [ "$u" == "$t" ] || error "$u != $t during migration"
18690
18691         # add new dir/file should succeed
18692         mkdir $migrate_dir/dir ||
18693                 error "mkdir failed under migrating directory"
18694         touch $migrate_dir/file ||
18695                 error "create file failed under migrating directory"
18696
18697         # add file with existing name should fail
18698         for file in $migrate_dir/f*; do
18699                 stat $file > /dev/null || error "stat $file failed"
18700                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18701                         error "open(O_CREAT|O_EXCL) $file should fail"
18702                 $MULTIOP $file m && error "create $file should fail"
18703                 touch $DIR/$tdir/remote_dir/$tfile ||
18704                         error "touch $tfile failed"
18705                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18706                         error "link $file should fail"
18707                 mdt_index=$($LFS getstripe -m $file)
18708                 if [ $mdt_index == 0 ]; then
18709                         # file failed to migrate is not allowed to rename to
18710                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18711                                 error "rename to $file should fail"
18712                 else
18713                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18714                                 error "rename to $file failed"
18715                 fi
18716                 echo hello >> $file || error "write $file failed"
18717         done
18718
18719         # resume migration with different options should fail
18720         $LFS migrate -m 0 $migrate_dir &&
18721                 error "migrate -m 0 $migrate_dir should fail"
18722
18723         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18724                 error "migrate -c 2 $migrate_dir should fail"
18725
18726         # resume migration should succeed
18727         $LFS migrate -m $MDTIDX $migrate_dir ||
18728                 error "migrate $migrate_dir failed"
18729
18730         echo "Finish migration, then checking.."
18731         for file in $(find $migrate_dir); do
18732                 mdt_index=$($LFS getstripe -m $file)
18733                 [ $mdt_index == $MDTIDX ] ||
18734                         error "$file is not on MDT${MDTIDX}"
18735         done
18736
18737         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18738 }
18739 run_test 230c "check directory accessiblity if migration failed"
18740
18741 test_230d() {
18742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18743         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18744         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18745                 skip "Need MDS version at least 2.11.52"
18746         # LU-11235
18747         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18748
18749         local migrate_dir=$DIR/$tdir/migrate_dir
18750         local old_index
18751         local new_index
18752         local old_count
18753         local new_count
18754         local new_hash
18755         local mdt_index
18756         local i
18757         local j
18758
18759         old_index=$((RANDOM % MDSCOUNT))
18760         old_count=$((MDSCOUNT - old_index))
18761         new_index=$((RANDOM % MDSCOUNT))
18762         new_count=$((MDSCOUNT - new_index))
18763         new_hash=1 # for all_char
18764
18765         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18766         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18767
18768         test_mkdir $DIR/$tdir
18769         test_mkdir -i $old_index -c $old_count $migrate_dir
18770
18771         for ((i=0; i<100; i++)); do
18772                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18773                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18774                         error "create files under remote dir failed $i"
18775         done
18776
18777         echo -n "Migrate from MDT$old_index "
18778         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18779         echo -n "to MDT$new_index"
18780         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18781         echo
18782
18783         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18784         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18785                 error "migrate remote dir error"
18786
18787         echo "Finish migration, then checking.."
18788         for file in $(find $migrate_dir); do
18789                 mdt_index=$($LFS getstripe -m $file)
18790                 if [ $mdt_index -lt $new_index ] ||
18791                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18792                         error "$file is on MDT$mdt_index"
18793                 fi
18794         done
18795
18796         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18797 }
18798 run_test 230d "check migrate big directory"
18799
18800 test_230e() {
18801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18802         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18803         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18804                 skip "Need MDS version at least 2.11.52"
18805
18806         local i
18807         local j
18808         local a_fid
18809         local b_fid
18810
18811         mkdir -p $DIR/$tdir
18812         mkdir $DIR/$tdir/migrate_dir
18813         mkdir $DIR/$tdir/other_dir
18814         touch $DIR/$tdir/migrate_dir/a
18815         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18816         ls $DIR/$tdir/other_dir
18817
18818         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18819                 error "migrate dir fails"
18820
18821         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18822         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18823
18824         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18825         [ $mdt_index == 0 ] || error "a is not on MDT0"
18826
18827         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18828                 error "migrate dir fails"
18829
18830         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18831         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18832
18833         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18834         [ $mdt_index == 1 ] || error "a is not on MDT1"
18835
18836         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18837         [ $mdt_index == 1 ] || error "b is not on MDT1"
18838
18839         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18840         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18841
18842         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18843
18844         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18845 }
18846 run_test 230e "migrate mulitple local link files"
18847
18848 test_230f() {
18849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18850         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18851         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18852                 skip "Need MDS version at least 2.11.52"
18853
18854         local a_fid
18855         local ln_fid
18856
18857         mkdir -p $DIR/$tdir
18858         mkdir $DIR/$tdir/migrate_dir
18859         $LFS mkdir -i1 $DIR/$tdir/other_dir
18860         touch $DIR/$tdir/migrate_dir/a
18861         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18862         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18863         ls $DIR/$tdir/other_dir
18864
18865         # a should be migrated to MDT1, since no other links on MDT0
18866         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18867                 error "#1 migrate dir fails"
18868         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18869         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18870         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18871         [ $mdt_index == 1 ] || error "a is not on MDT1"
18872
18873         # a should stay on MDT1, because it is a mulitple link file
18874         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18875                 error "#2 migrate dir fails"
18876         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18877         [ $mdt_index == 1 ] || error "a is not on MDT1"
18878
18879         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18880                 error "#3 migrate dir fails"
18881
18882         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18883         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18884         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18885
18886         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18887         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18888
18889         # a should be migrated to MDT0, since no other links on MDT1
18890         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18891                 error "#4 migrate dir fails"
18892         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18893         [ $mdt_index == 0 ] || error "a is not on MDT0"
18894
18895         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18896 }
18897 run_test 230f "migrate mulitple remote link files"
18898
18899 test_230g() {
18900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18902         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18903                 skip "Need MDS version at least 2.11.52"
18904
18905         mkdir -p $DIR/$tdir/migrate_dir
18906
18907         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18908                 error "migrating dir to non-exist MDT succeeds"
18909         true
18910 }
18911 run_test 230g "migrate dir to non-exist MDT"
18912
18913 test_230h() {
18914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18915         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18916         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18917                 skip "Need MDS version at least 2.11.52"
18918
18919         local mdt_index
18920
18921         mkdir -p $DIR/$tdir/migrate_dir
18922
18923         $LFS migrate -m1 $DIR &&
18924                 error "migrating mountpoint1 should fail"
18925
18926         $LFS migrate -m1 $DIR/$tdir/.. &&
18927                 error "migrating mountpoint2 should fail"
18928
18929         # same as mv
18930         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18931                 error "migrating $tdir/migrate_dir/.. should fail"
18932
18933         true
18934 }
18935 run_test 230h "migrate .. and root"
18936
18937 test_230i() {
18938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18939         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18940         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18941                 skip "Need MDS version at least 2.11.52"
18942
18943         mkdir -p $DIR/$tdir/migrate_dir
18944
18945         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18946                 error "migration fails with a tailing slash"
18947
18948         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18949                 error "migration fails with two tailing slashes"
18950 }
18951 run_test 230i "lfs migrate -m tolerates trailing slashes"
18952
18953 test_230j() {
18954         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18955         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18956                 skip "Need MDS version at least 2.11.52"
18957
18958         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18959         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18960                 error "create $tfile failed"
18961         cat /etc/passwd > $DIR/$tdir/$tfile
18962
18963         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18964
18965         cmp /etc/passwd $DIR/$tdir/$tfile ||
18966                 error "DoM file mismatch after migration"
18967 }
18968 run_test 230j "DoM file data not changed after dir migration"
18969
18970 test_230k() {
18971         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18972         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18973                 skip "Need MDS version at least 2.11.56"
18974
18975         local total=20
18976         local files_on_starting_mdt=0
18977
18978         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18979         $LFS getdirstripe $DIR/$tdir
18980         for i in $(seq $total); do
18981                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18982                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18983                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18984         done
18985
18986         echo "$files_on_starting_mdt files on MDT0"
18987
18988         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18989         $LFS getdirstripe $DIR/$tdir
18990
18991         files_on_starting_mdt=0
18992         for i in $(seq $total); do
18993                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18994                         error "file $tfile.$i mismatch after migration"
18995                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18996                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18997         done
18998
18999         echo "$files_on_starting_mdt files on MDT1 after migration"
19000         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19001
19002         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19003         $LFS getdirstripe $DIR/$tdir
19004
19005         files_on_starting_mdt=0
19006         for i in $(seq $total); do
19007                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19008                         error "file $tfile.$i mismatch after 2nd migration"
19009                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19010                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19011         done
19012
19013         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19014         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19015
19016         true
19017 }
19018 run_test 230k "file data not changed after dir migration"
19019
19020 test_230l() {
19021         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19022         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19023                 skip "Need MDS version at least 2.11.56"
19024
19025         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19026         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19027                 error "create files under remote dir failed $i"
19028         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19029 }
19030 run_test 230l "readdir between MDTs won't crash"
19031
19032 test_230m() {
19033         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19034         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19035                 skip "Need MDS version at least 2.11.56"
19036
19037         local MDTIDX=1
19038         local mig_dir=$DIR/$tdir/migrate_dir
19039         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19040         local shortstr="b"
19041         local val
19042
19043         echo "Creating files and dirs with xattrs"
19044         test_mkdir $DIR/$tdir
19045         test_mkdir -i0 -c1 $mig_dir
19046         mkdir $mig_dir/dir
19047         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19048                 error "cannot set xattr attr1 on dir"
19049         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19050                 error "cannot set xattr attr2 on dir"
19051         touch $mig_dir/dir/f0
19052         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19053                 error "cannot set xattr attr1 on file"
19054         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19055                 error "cannot set xattr attr2 on file"
19056         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19057         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19058         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19059         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19060         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19061         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19062         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19063         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19064         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19065
19066         echo "Migrating to MDT1"
19067         $LFS migrate -m $MDTIDX $mig_dir ||
19068                 error "fails on migrating dir to MDT1"
19069
19070         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19071         echo "Checking xattrs"
19072         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19073         [ "$val" = $longstr ] ||
19074                 error "expecting xattr1 $longstr on dir, found $val"
19075         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19076         [ "$val" = $shortstr ] ||
19077                 error "expecting xattr2 $shortstr on dir, found $val"
19078         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19079         [ "$val" = $longstr ] ||
19080                 error "expecting xattr1 $longstr on file, found $val"
19081         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19082         [ "$val" = $shortstr ] ||
19083                 error "expecting xattr2 $shortstr on file, found $val"
19084 }
19085 run_test 230m "xattrs not changed after dir migration"
19086
19087 test_230n() {
19088         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19089         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19090                 skip "Need MDS version at least 2.13.53"
19091
19092         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19093         cat /etc/hosts > $DIR/$tdir/$tfile
19094         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19095         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19096
19097         cmp /etc/hosts $DIR/$tdir/$tfile ||
19098                 error "File data mismatch after migration"
19099 }
19100 run_test 230n "Dir migration with mirrored file"
19101
19102 test_230o() {
19103         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19104         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19105                 skip "Need MDS version at least 2.13.52"
19106
19107         local mdts=$(comma_list $(mdts_nodes))
19108         local timeout=100
19109         local restripe_status
19110         local delta
19111         local i
19112
19113         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19114
19115         # in case "crush" hash type is not set
19116         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19117
19118         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19119                            mdt.*MDT0000.enable_dir_restripe)
19120         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19121         stack_trap "do_nodes $mdts $LCTL set_param \
19122                     mdt.*.enable_dir_restripe=$restripe_status"
19123
19124         mkdir $DIR/$tdir
19125         createmany -m $DIR/$tdir/f 100 ||
19126                 error "create files under remote dir failed $i"
19127         createmany -d $DIR/$tdir/d 100 ||
19128                 error "create dirs under remote dir failed $i"
19129
19130         for i in $(seq 2 $MDSCOUNT); do
19131                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19132                 $LFS setdirstripe -c $i $DIR/$tdir ||
19133                         error "split -c $i $tdir failed"
19134                 wait_update $HOSTNAME \
19135                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19136                         error "dir split not finished"
19137                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19138                         awk '/migrate/ {sum += $2} END { print sum }')
19139                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19140                 # delta is around total_files/stripe_count
19141                 (( $delta < 200 / (i - 1) + 4 )) ||
19142                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19143         done
19144 }
19145 run_test 230o "dir split"
19146
19147 test_230p() {
19148         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19149         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19150                 skip "Need MDS version at least 2.13.52"
19151
19152         local mdts=$(comma_list $(mdts_nodes))
19153         local timeout=100
19154         local restripe_status
19155         local delta
19156         local i
19157
19158         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19159
19160         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19161
19162         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19163                            mdt.*MDT0000.enable_dir_restripe)
19164         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19165         stack_trap "do_nodes $mdts $LCTL set_param \
19166                     mdt.*.enable_dir_restripe=$restripe_status"
19167
19168         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19169         createmany -m $DIR/$tdir/f 100 ||
19170                 error "create files under remote dir failed $i"
19171         createmany -d $DIR/$tdir/d 100 ||
19172                 error "create dirs under remote dir failed $i"
19173
19174         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19175                 local mdt_hash="crush"
19176
19177                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19178                 $LFS setdirstripe -c $i $DIR/$tdir ||
19179                         error "split -c $i $tdir failed"
19180                 [ $i -eq 1 ] && mdt_hash="none"
19181                 wait_update $HOSTNAME \
19182                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19183                         error "dir merge not finished"
19184                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19185                         awk '/migrate/ {sum += $2} END { print sum }')
19186                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19187                 # delta is around total_files/stripe_count
19188                 (( $delta < 200 / i + 4 )) ||
19189                         error "$delta files migrated >= $((200 / i + 4))"
19190         done
19191 }
19192 run_test 230p "dir merge"
19193
19194 test_230q() {
19195         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19196         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19197                 skip "Need MDS version at least 2.13.52"
19198
19199         local mdts=$(comma_list $(mdts_nodes))
19200         local saved_threshold=$(do_facet mds1 \
19201                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19202         local saved_delta=$(do_facet mds1 \
19203                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19204         local threshold=100
19205         local delta=2
19206         local total=0
19207         local stripe_count=0
19208         local stripe_index
19209         local nr_files
19210         local create
19211
19212         # test with fewer files on ZFS
19213         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19214
19215         stack_trap "do_nodes $mdts $LCTL set_param \
19216                     mdt.*.dir_split_count=$saved_threshold"
19217         stack_trap "do_nodes $mdts $LCTL set_param \
19218                     mdt.*.dir_split_delta=$saved_delta"
19219         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19220         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19221         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19222         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19223         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19224         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19225
19226         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19227         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19228
19229         create=$((threshold * 3 / 2))
19230         while [ $stripe_count -lt $MDSCOUNT ]; do
19231                 createmany -m $DIR/$tdir/f $total $create ||
19232                         error "create sub files failed"
19233                 stat $DIR/$tdir > /dev/null
19234                 total=$((total + create))
19235                 stripe_count=$((stripe_count + delta))
19236                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19237
19238                 wait_update $HOSTNAME \
19239                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19240                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19241
19242                 wait_update $HOSTNAME \
19243                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19244                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19245
19246                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19247                 echo "$nr_files/$total files on MDT$stripe_index after split"
19248                 # allow 10% margin of imbalance with crush hash
19249                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19250                         error "$nr_files files on MDT$stripe_index after split"
19251
19252                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19253                 [ $nr_files -eq $total ] ||
19254                         error "total sub files $nr_files != $total"
19255         done
19256 }
19257 run_test 230q "dir auto split"
19258
19259 test_230r() {
19260         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19261         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19262         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19263                 skip "Need MDS version at least 2.13.54"
19264
19265         # maximum amount of local locks:
19266         # parent striped dir - 2 locks
19267         # new stripe in parent to migrate to - 1 lock
19268         # source and target - 2 locks
19269         # Total 5 locks for regular file
19270         mkdir -p $DIR/$tdir
19271         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19272         touch $DIR/$tdir/dir1/eee
19273
19274         # create 4 hardlink for 4 more locks
19275         # Total: 9 locks > RS_MAX_LOCKS (8)
19276         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19277         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19278         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19279         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19280         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19281         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19282         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19283         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19284
19285         cancel_lru_locks mdc
19286
19287         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19288                 error "migrate dir fails"
19289
19290         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19291 }
19292 run_test 230r "migrate with too many local locks"
19293
19294 test_230s() {
19295         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19296                 skip "Need MDS version at least 2.13.57"
19297
19298         local mdts=$(comma_list $(mdts_nodes))
19299         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19300                                 mdt.*MDT0000.enable_dir_restripe)
19301
19302         stack_trap "do_nodes $mdts $LCTL set_param \
19303                     mdt.*.enable_dir_restripe=$restripe_status"
19304
19305         local st
19306         for st in 0 1; do
19307                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19308                 test_mkdir $DIR/$tdir
19309                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19310                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19311                 rmdir $DIR/$tdir
19312         done
19313 }
19314 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19315
19316 test_230t()
19317 {
19318         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19319         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19320                 skip "Need MDS version at least 2.14.50"
19321
19322         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19323         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19324         $LFS project -p 1 -s $DIR/$tdir ||
19325                 error "set $tdir project id failed"
19326         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19327                 error "set subdir project id failed"
19328         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19329 }
19330 run_test 230t "migrate directory with project ID set"
19331
19332 test_231a()
19333 {
19334         # For simplicity this test assumes that max_pages_per_rpc
19335         # is the same across all OSCs
19336         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19337         local bulk_size=$((max_pages * PAGE_SIZE))
19338         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19339                                        head -n 1)
19340
19341         mkdir -p $DIR/$tdir
19342         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19343                 error "failed to set stripe with -S ${brw_size}M option"
19344
19345         # clear the OSC stats
19346         $LCTL set_param osc.*.stats=0 &>/dev/null
19347         stop_writeback
19348
19349         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19350         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19351                 oflag=direct &>/dev/null || error "dd failed"
19352
19353         sync; sleep 1; sync # just to be safe
19354         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19355         if [ x$nrpcs != "x1" ]; then
19356                 $LCTL get_param osc.*.stats
19357                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19358         fi
19359
19360         start_writeback
19361         # Drop the OSC cache, otherwise we will read from it
19362         cancel_lru_locks osc
19363
19364         # clear the OSC stats
19365         $LCTL set_param osc.*.stats=0 &>/dev/null
19366
19367         # Client reads $bulk_size.
19368         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19369                 iflag=direct &>/dev/null || error "dd failed"
19370
19371         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19372         if [ x$nrpcs != "x1" ]; then
19373                 $LCTL get_param osc.*.stats
19374                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19375         fi
19376 }
19377 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19378
19379 test_231b() {
19380         mkdir -p $DIR/$tdir
19381         local i
19382         for i in {0..1023}; do
19383                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19384                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19385                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19386         done
19387         sync
19388 }
19389 run_test 231b "must not assert on fully utilized OST request buffer"
19390
19391 test_232a() {
19392         mkdir -p $DIR/$tdir
19393         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19394
19395         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19396         do_facet ost1 $LCTL set_param fail_loc=0x31c
19397
19398         # ignore dd failure
19399         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19400
19401         do_facet ost1 $LCTL set_param fail_loc=0
19402         umount_client $MOUNT || error "umount failed"
19403         mount_client $MOUNT || error "mount failed"
19404         stop ost1 || error "cannot stop ost1"
19405         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19406 }
19407 run_test 232a "failed lock should not block umount"
19408
19409 test_232b() {
19410         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19411                 skip "Need MDS version at least 2.10.58"
19412
19413         mkdir -p $DIR/$tdir
19414         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19415         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19416         sync
19417         cancel_lru_locks osc
19418
19419         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19420         do_facet ost1 $LCTL set_param fail_loc=0x31c
19421
19422         # ignore failure
19423         $LFS data_version $DIR/$tdir/$tfile || true
19424
19425         do_facet ost1 $LCTL set_param fail_loc=0
19426         umount_client $MOUNT || error "umount failed"
19427         mount_client $MOUNT || error "mount failed"
19428         stop ost1 || error "cannot stop ost1"
19429         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19430 }
19431 run_test 232b "failed data version lock should not block umount"
19432
19433 test_233a() {
19434         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19435                 skip "Need MDS version at least 2.3.64"
19436         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19437
19438         local fid=$($LFS path2fid $MOUNT)
19439
19440         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19441                 error "cannot access $MOUNT using its FID '$fid'"
19442 }
19443 run_test 233a "checking that OBF of the FS root succeeds"
19444
19445 test_233b() {
19446         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19447                 skip "Need MDS version at least 2.5.90"
19448         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19449
19450         local fid=$($LFS path2fid $MOUNT/.lustre)
19451
19452         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19453                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19454
19455         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19456         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19457                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19458 }
19459 run_test 233b "checking that OBF of the FS .lustre succeeds"
19460
19461 test_234() {
19462         local p="$TMP/sanityN-$TESTNAME.parameters"
19463         save_lustre_params client "llite.*.xattr_cache" > $p
19464         lctl set_param llite.*.xattr_cache 1 ||
19465                 skip_env "xattr cache is not supported"
19466
19467         mkdir -p $DIR/$tdir || error "mkdir failed"
19468         touch $DIR/$tdir/$tfile || error "touch failed"
19469         # OBD_FAIL_LLITE_XATTR_ENOMEM
19470         $LCTL set_param fail_loc=0x1405
19471         getfattr -n user.attr $DIR/$tdir/$tfile &&
19472                 error "getfattr should have failed with ENOMEM"
19473         $LCTL set_param fail_loc=0x0
19474         rm -rf $DIR/$tdir
19475
19476         restore_lustre_params < $p
19477         rm -f $p
19478 }
19479 run_test 234 "xattr cache should not crash on ENOMEM"
19480
19481 test_235() {
19482         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19483                 skip "Need MDS version at least 2.4.52"
19484
19485         flock_deadlock $DIR/$tfile
19486         local RC=$?
19487         case $RC in
19488                 0)
19489                 ;;
19490                 124) error "process hangs on a deadlock"
19491                 ;;
19492                 *) error "error executing flock_deadlock $DIR/$tfile"
19493                 ;;
19494         esac
19495 }
19496 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19497
19498 #LU-2935
19499 test_236() {
19500         check_swap_layouts_support
19501
19502         local ref1=/etc/passwd
19503         local ref2=/etc/group
19504         local file1=$DIR/$tdir/f1
19505         local file2=$DIR/$tdir/f2
19506
19507         test_mkdir -c1 $DIR/$tdir
19508         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19509         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19510         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19511         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19512         local fd=$(free_fd)
19513         local cmd="exec $fd<>$file2"
19514         eval $cmd
19515         rm $file2
19516         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19517                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19518         cmd="exec $fd>&-"
19519         eval $cmd
19520         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19521
19522         #cleanup
19523         rm -rf $DIR/$tdir
19524 }
19525 run_test 236 "Layout swap on open unlinked file"
19526
19527 # LU-4659 linkea consistency
19528 test_238() {
19529         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19530                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19531                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19532                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19533
19534         touch $DIR/$tfile
19535         ln $DIR/$tfile $DIR/$tfile.lnk
19536         touch $DIR/$tfile.new
19537         mv $DIR/$tfile.new $DIR/$tfile
19538         local fid1=$($LFS path2fid $DIR/$tfile)
19539         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19540         local path1=$($LFS fid2path $FSNAME "$fid1")
19541         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19542         local path2=$($LFS fid2path $FSNAME "$fid2")
19543         [ $tfile.lnk == $path2 ] ||
19544                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19545         rm -f $DIR/$tfile*
19546 }
19547 run_test 238 "Verify linkea consistency"
19548
19549 test_239A() { # was test_239
19550         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19551                 skip "Need MDS version at least 2.5.60"
19552
19553         local list=$(comma_list $(mdts_nodes))
19554
19555         mkdir -p $DIR/$tdir
19556         createmany -o $DIR/$tdir/f- 5000
19557         unlinkmany $DIR/$tdir/f- 5000
19558         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19559                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19560         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19561                         osp.*MDT*.sync_in_flight" | calc_sum)
19562         [ "$changes" -eq 0 ] || error "$changes not synced"
19563 }
19564 run_test 239A "osp_sync test"
19565
19566 test_239a() { #LU-5297
19567         remote_mds_nodsh && skip "remote MDS with nodsh"
19568
19569         touch $DIR/$tfile
19570         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19571         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19572         chgrp $RUNAS_GID $DIR/$tfile
19573         wait_delete_completed
19574 }
19575 run_test 239a "process invalid osp sync record correctly"
19576
19577 test_239b() { #LU-5297
19578         remote_mds_nodsh && skip "remote MDS with nodsh"
19579
19580         touch $DIR/$tfile1
19581         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19582         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19583         chgrp $RUNAS_GID $DIR/$tfile1
19584         wait_delete_completed
19585         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19586         touch $DIR/$tfile2
19587         chgrp $RUNAS_GID $DIR/$tfile2
19588         wait_delete_completed
19589 }
19590 run_test 239b "process osp sync record with ENOMEM error correctly"
19591
19592 test_240() {
19593         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19594         remote_mds_nodsh && skip "remote MDS with nodsh"
19595
19596         mkdir -p $DIR/$tdir
19597
19598         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19599                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19600         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19601                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19602
19603         umount_client $MOUNT || error "umount failed"
19604         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19605         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19606         mount_client $MOUNT || error "failed to mount client"
19607
19608         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19609         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19610 }
19611 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19612
19613 test_241_bio() {
19614         local count=$1
19615         local bsize=$2
19616
19617         for LOOP in $(seq $count); do
19618                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19619                 cancel_lru_locks $OSC || true
19620         done
19621 }
19622
19623 test_241_dio() {
19624         local count=$1
19625         local bsize=$2
19626
19627         for LOOP in $(seq $1); do
19628                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19629                         2>/dev/null
19630         done
19631 }
19632
19633 test_241a() { # was test_241
19634         local bsize=$PAGE_SIZE
19635
19636         (( bsize < 40960 )) && bsize=40960
19637         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19638         ls -la $DIR/$tfile
19639         cancel_lru_locks $OSC
19640         test_241_bio 1000 $bsize &
19641         PID=$!
19642         test_241_dio 1000 $bsize
19643         wait $PID
19644 }
19645 run_test 241a "bio vs dio"
19646
19647 test_241b() {
19648         local bsize=$PAGE_SIZE
19649
19650         (( bsize < 40960 )) && bsize=40960
19651         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19652         ls -la $DIR/$tfile
19653         test_241_dio 1000 $bsize &
19654         PID=$!
19655         test_241_dio 1000 $bsize
19656         wait $PID
19657 }
19658 run_test 241b "dio vs dio"
19659
19660 test_242() {
19661         remote_mds_nodsh && skip "remote MDS with nodsh"
19662
19663         mkdir -p $DIR/$tdir
19664         touch $DIR/$tdir/$tfile
19665
19666         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19667         do_facet mds1 lctl set_param fail_loc=0x105
19668         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19669
19670         do_facet mds1 lctl set_param fail_loc=0
19671         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19672 }
19673 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19674
19675 test_243()
19676 {
19677         test_mkdir $DIR/$tdir
19678         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19679 }
19680 run_test 243 "various group lock tests"
19681
19682 test_244a()
19683 {
19684         test_mkdir $DIR/$tdir
19685         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19686         sendfile_grouplock $DIR/$tdir/$tfile || \
19687                 error "sendfile+grouplock failed"
19688         rm -rf $DIR/$tdir
19689 }
19690 run_test 244a "sendfile with group lock tests"
19691
19692 test_244b()
19693 {
19694         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19695
19696         local threads=50
19697         local size=$((1024*1024))
19698
19699         test_mkdir $DIR/$tdir
19700         for i in $(seq 1 $threads); do
19701                 local file=$DIR/$tdir/file_$((i / 10))
19702                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19703                 local pids[$i]=$!
19704         done
19705         for i in $(seq 1 $threads); do
19706                 wait ${pids[$i]}
19707         done
19708 }
19709 run_test 244b "multi-threaded write with group lock"
19710
19711 test_245() {
19712         local flagname="multi_mod_rpcs"
19713         local connect_data_name="max_mod_rpcs"
19714         local out
19715
19716         # check if multiple modify RPCs flag is set
19717         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19718                 grep "connect_flags:")
19719         echo "$out"
19720
19721         echo "$out" | grep -qw $flagname
19722         if [ $? -ne 0 ]; then
19723                 echo "connect flag $flagname is not set"
19724                 return
19725         fi
19726
19727         # check if multiple modify RPCs data is set
19728         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19729         echo "$out"
19730
19731         echo "$out" | grep -qw $connect_data_name ||
19732                 error "import should have connect data $connect_data_name"
19733 }
19734 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19735
19736 cleanup_247() {
19737         local submount=$1
19738
19739         trap 0
19740         umount_client $submount
19741         rmdir $submount
19742 }
19743
19744 test_247a() {
19745         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19746                 grep -q subtree ||
19747                 skip_env "Fileset feature is not supported"
19748
19749         local submount=${MOUNT}_$tdir
19750
19751         mkdir $MOUNT/$tdir
19752         mkdir -p $submount || error "mkdir $submount failed"
19753         FILESET="$FILESET/$tdir" mount_client $submount ||
19754                 error "mount $submount failed"
19755         trap "cleanup_247 $submount" EXIT
19756         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19757         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19758                 error "read $MOUNT/$tdir/$tfile failed"
19759         cleanup_247 $submount
19760 }
19761 run_test 247a "mount subdir as fileset"
19762
19763 test_247b() {
19764         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19765                 skip_env "Fileset feature is not supported"
19766
19767         local submount=${MOUNT}_$tdir
19768
19769         rm -rf $MOUNT/$tdir
19770         mkdir -p $submount || error "mkdir $submount failed"
19771         SKIP_FILESET=1
19772         FILESET="$FILESET/$tdir" mount_client $submount &&
19773                 error "mount $submount should fail"
19774         rmdir $submount
19775 }
19776 run_test 247b "mount subdir that dose not exist"
19777
19778 test_247c() {
19779         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19780                 skip_env "Fileset feature is not supported"
19781
19782         local submount=${MOUNT}_$tdir
19783
19784         mkdir -p $MOUNT/$tdir/dir1
19785         mkdir -p $submount || error "mkdir $submount failed"
19786         trap "cleanup_247 $submount" EXIT
19787         FILESET="$FILESET/$tdir" mount_client $submount ||
19788                 error "mount $submount failed"
19789         local fid=$($LFS path2fid $MOUNT/)
19790         $LFS fid2path $submount $fid && error "fid2path should fail"
19791         cleanup_247 $submount
19792 }
19793 run_test 247c "running fid2path outside subdirectory root"
19794
19795 test_247d() {
19796         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19797                 skip "Fileset feature is not supported"
19798
19799         local submount=${MOUNT}_$tdir
19800
19801         mkdir -p $MOUNT/$tdir/dir1
19802         mkdir -p $submount || error "mkdir $submount failed"
19803         FILESET="$FILESET/$tdir" mount_client $submount ||
19804                 error "mount $submount failed"
19805         trap "cleanup_247 $submount" EXIT
19806
19807         local td=$submount/dir1
19808         local fid=$($LFS path2fid $td)
19809         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19810
19811         # check that we get the same pathname back
19812         local rootpath
19813         local found
19814         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19815                 echo "$rootpath $fid"
19816                 found=$($LFS fid2path $rootpath "$fid")
19817                 [ -n "found" ] || error "fid2path should succeed"
19818                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19819         done
19820         # check wrong root path format
19821         rootpath=$submount"_wrong"
19822         found=$($LFS fid2path $rootpath "$fid")
19823         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19824
19825         cleanup_247 $submount
19826 }
19827 run_test 247d "running fid2path inside subdirectory root"
19828
19829 # LU-8037
19830 test_247e() {
19831         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19832                 grep -q subtree ||
19833                 skip "Fileset feature is not supported"
19834
19835         local submount=${MOUNT}_$tdir
19836
19837         mkdir $MOUNT/$tdir
19838         mkdir -p $submount || error "mkdir $submount failed"
19839         FILESET="$FILESET/.." mount_client $submount &&
19840                 error "mount $submount should fail"
19841         rmdir $submount
19842 }
19843 run_test 247e "mount .. as fileset"
19844
19845 test_247f() {
19846         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19847         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19848                 skip "Need at least version 2.13.52"
19849         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
19850                 skip "Need at least version 2.14.50"
19851         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19852                 grep -q subtree ||
19853                 skip "Fileset feature is not supported"
19854
19855         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19856         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19857                 error "mkdir remote failed"
19858         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19859         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
19860                 error "mkdir striped failed"
19861         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19862
19863         local submount=${MOUNT}_$tdir
19864
19865         mkdir -p $submount || error "mkdir $submount failed"
19866         stack_trap "rmdir $submount"
19867
19868         local dir
19869         local stat
19870         local fileset=$FILESET
19871         local mdts=$(comma_list $(mdts_nodes))
19872
19873         stat=$(do_facet mds1 $LCTL get_param -n \
19874                 mdt.*MDT0000.enable_remote_subdir_mount)
19875         stack_trap "do_nodes $mdts $LCTL set_param \
19876                 mdt.*.enable_remote_subdir_mount=$stat"
19877
19878         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
19879         stack_trap "umount_client $submount"
19880         FILESET="$fileset/$tdir/remote" mount_client $submount &&
19881                 error "mount remote dir $dir should fail"
19882
19883         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
19884                 $tdir/striped/. ; do
19885                 FILESET="$fileset/$dir" mount_client $submount ||
19886                         error "mount $dir failed"
19887                 umount_client $submount
19888         done
19889
19890         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
19891         FILESET="$fileset/$tdir/remote" mount_client $submount ||
19892                 error "mount $tdir/remote failed"
19893 }
19894 run_test 247f "mount striped or remote directory as fileset"
19895
19896 test_247g() {
19897         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
19898         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
19899                 skip "Need at least version 2.14.50"
19900
19901         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
19902                 error "mkdir $tdir failed"
19903         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
19904
19905         local submount=${MOUNT}_$tdir
19906
19907         mkdir -p $submount || error "mkdir $submount failed"
19908         stack_trap "rmdir $submount"
19909
19910         FILESET="$fileset/$tdir" mount_client $submount ||
19911                 error "mount $dir failed"
19912         stack_trap "umount $submount"
19913
19914         local mdts=$(comma_list $(mdts_nodes))
19915
19916         local nrpcs
19917
19918         stat $submount > /dev/null
19919         cancel_lru_locks $MDC
19920         stat $submount > /dev/null
19921         stat $submount/$tfile > /dev/null
19922         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
19923         stat $submount/$tfile > /dev/null
19924         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
19925                 awk '/getattr/ {sum += $2} END {print sum}')
19926
19927         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
19928 }
19929 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
19930
19931 test_248a() {
19932         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19933         [ -z "$fast_read_sav" ] && skip "no fast read support"
19934
19935         # create a large file for fast read verification
19936         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19937
19938         # make sure the file is created correctly
19939         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19940                 { rm -f $DIR/$tfile; skip "file creation error"; }
19941
19942         echo "Test 1: verify that fast read is 4 times faster on cache read"
19943
19944         # small read with fast read enabled
19945         $LCTL set_param -n llite.*.fast_read=1
19946         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19947                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19948                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19949         # small read with fast read disabled
19950         $LCTL set_param -n llite.*.fast_read=0
19951         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19952                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19953                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19954
19955         # verify that fast read is 4 times faster for cache read
19956         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19957                 error_not_in_vm "fast read was not 4 times faster: " \
19958                            "$t_fast vs $t_slow"
19959
19960         echo "Test 2: verify the performance between big and small read"
19961         $LCTL set_param -n llite.*.fast_read=1
19962
19963         # 1k non-cache read
19964         cancel_lru_locks osc
19965         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19966                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19967                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19968
19969         # 1M non-cache read
19970         cancel_lru_locks osc
19971         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19972                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19973                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19974
19975         # verify that big IO is not 4 times faster than small IO
19976         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19977                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19978
19979         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19980         rm -f $DIR/$tfile
19981 }
19982 run_test 248a "fast read verification"
19983
19984 test_248b() {
19985         # Default short_io_bytes=16384, try both smaller and larger sizes.
19986         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19987         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19988         echo "bs=53248 count=113 normal buffered write"
19989         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19990                 error "dd of initial data file failed"
19991         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19992
19993         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19994         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19995                 error "dd with sync normal writes failed"
19996         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19997
19998         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19999         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20000                 error "dd with sync small writes failed"
20001         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20002
20003         cancel_lru_locks osc
20004
20005         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20006         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20007         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20008         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20009                 iflag=direct || error "dd with O_DIRECT small read failed"
20010         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20011         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20012                 error "compare $TMP/$tfile.1 failed"
20013
20014         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20015         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20016
20017         # just to see what the maximum tunable value is, and test parsing
20018         echo "test invalid parameter 2MB"
20019         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20020                 error "too-large short_io_bytes allowed"
20021         echo "test maximum parameter 512KB"
20022         # if we can set a larger short_io_bytes, run test regardless of version
20023         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20024                 # older clients may not allow setting it this large, that's OK
20025                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20026                         skip "Need at least client version 2.13.50"
20027                 error "medium short_io_bytes failed"
20028         fi
20029         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20030         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20031
20032         echo "test large parameter 64KB"
20033         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20034         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20035
20036         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20037         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20038                 error "dd with sync large writes failed"
20039         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20040
20041         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20042         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20043         num=$((113 * 4096 / PAGE_SIZE))
20044         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20045         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20046                 error "dd with O_DIRECT large writes failed"
20047         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20048                 error "compare $DIR/$tfile.3 failed"
20049
20050         cancel_lru_locks osc
20051
20052         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20053         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20054                 error "dd with O_DIRECT large read failed"
20055         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20056                 error "compare $TMP/$tfile.2 failed"
20057
20058         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20059         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20060                 error "dd with O_DIRECT large read failed"
20061         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20062                 error "compare $TMP/$tfile.3 failed"
20063 }
20064 run_test 248b "test short_io read and write for both small and large sizes"
20065
20066 test_249() { # LU-7890
20067         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20068                 skip "Need at least version 2.8.54"
20069
20070         rm -f $DIR/$tfile
20071         $LFS setstripe -c 1 $DIR/$tfile
20072         # Offset 2T == 4k * 512M
20073         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20074                 error "dd to 2T offset failed"
20075 }
20076 run_test 249 "Write above 2T file size"
20077
20078 test_250() {
20079         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20080          && skip "no 16TB file size limit on ZFS"
20081
20082         $LFS setstripe -c 1 $DIR/$tfile
20083         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20084         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20085         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20086         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20087                 conv=notrunc,fsync && error "append succeeded"
20088         return 0
20089 }
20090 run_test 250 "Write above 16T limit"
20091
20092 test_251() {
20093         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20094
20095         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20096         #Skip once - writing the first stripe will succeed
20097         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20098         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20099                 error "short write happened"
20100
20101         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20102         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20103                 error "short read happened"
20104
20105         rm -f $DIR/$tfile
20106 }
20107 run_test 251 "Handling short read and write correctly"
20108
20109 test_252() {
20110         remote_mds_nodsh && skip "remote MDS with nodsh"
20111         remote_ost_nodsh && skip "remote OST with nodsh"
20112         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20113                 skip_env "ldiskfs only test"
20114         fi
20115
20116         local tgt
20117         local dev
20118         local out
20119         local uuid
20120         local num
20121         local gen
20122
20123         # check lr_reader on OST0000
20124         tgt=ost1
20125         dev=$(facet_device $tgt)
20126         out=$(do_facet $tgt $LR_READER $dev)
20127         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20128         echo "$out"
20129         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20130         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20131                 error "Invalid uuid returned by $LR_READER on target $tgt"
20132         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20133
20134         # check lr_reader -c on MDT0000
20135         tgt=mds1
20136         dev=$(facet_device $tgt)
20137         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20138                 skip "$LR_READER does not support additional options"
20139         fi
20140         out=$(do_facet $tgt $LR_READER -c $dev)
20141         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20142         echo "$out"
20143         num=$(echo "$out" | grep -c "mdtlov")
20144         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20145                 error "Invalid number of mdtlov clients returned by $LR_READER"
20146         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20147
20148         # check lr_reader -cr on MDT0000
20149         out=$(do_facet $tgt $LR_READER -cr $dev)
20150         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20151         echo "$out"
20152         echo "$out" | grep -q "^reply_data:$" ||
20153                 error "$LR_READER should have returned 'reply_data' section"
20154         num=$(echo "$out" | grep -c "client_generation")
20155         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20156 }
20157 run_test 252 "check lr_reader tool"
20158
20159 test_253() {
20160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20161         remote_mds_nodsh && skip "remote MDS with nodsh"
20162         remote_mgs_nodsh && skip "remote MGS with nodsh"
20163
20164         local ostidx=0
20165         local rc=0
20166         local ost_name=$(ostname_from_index $ostidx)
20167
20168         # on the mdt's osc
20169         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20170         do_facet $SINGLEMDS $LCTL get_param -n \
20171                 osp.$mdtosc_proc1.reserved_mb_high ||
20172                 skip  "remote MDS does not support reserved_mb_high"
20173
20174         rm -rf $DIR/$tdir
20175         wait_mds_ost_sync
20176         wait_delete_completed
20177         mkdir $DIR/$tdir
20178
20179         pool_add $TESTNAME || error "Pool creation failed"
20180         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20181
20182         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20183                 error "Setstripe failed"
20184
20185         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20186
20187         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20188                     grep "watermarks")
20189         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20190
20191         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20192                         osp.$mdtosc_proc1.prealloc_status)
20193         echo "prealloc_status $oa_status"
20194
20195         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20196                 error "File creation should fail"
20197
20198         #object allocation was stopped, but we still able to append files
20199         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20200                 oflag=append || error "Append failed"
20201
20202         rm -f $DIR/$tdir/$tfile.0
20203
20204         # For this test, we want to delete the files we created to go out of
20205         # space but leave the watermark, so we remain nearly out of space
20206         ost_watermarks_enospc_delete_files $tfile $ostidx
20207
20208         wait_delete_completed
20209
20210         sleep_maxage
20211
20212         for i in $(seq 10 12); do
20213                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20214                         2>/dev/null || error "File creation failed after rm"
20215         done
20216
20217         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20218                         osp.$mdtosc_proc1.prealloc_status)
20219         echo "prealloc_status $oa_status"
20220
20221         if (( oa_status != 0 )); then
20222                 error "Object allocation still disable after rm"
20223         fi
20224 }
20225 run_test 253 "Check object allocation limit"
20226
20227 test_254() {
20228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20229         remote_mds_nodsh && skip "remote MDS with nodsh"
20230         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20231                 skip "MDS does not support changelog_size"
20232
20233         local cl_user
20234         local MDT0=$(facet_svc $SINGLEMDS)
20235
20236         changelog_register || error "changelog_register failed"
20237
20238         changelog_clear 0 || error "changelog_clear failed"
20239
20240         local size1=$(do_facet $SINGLEMDS \
20241                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20242         echo "Changelog size $size1"
20243
20244         rm -rf $DIR/$tdir
20245         $LFS mkdir -i 0 $DIR/$tdir
20246         # change something
20247         mkdir -p $DIR/$tdir/pics/2008/zachy
20248         touch $DIR/$tdir/pics/2008/zachy/timestamp
20249         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20250         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20251         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20252         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20253         rm $DIR/$tdir/pics/desktop.jpg
20254
20255         local size2=$(do_facet $SINGLEMDS \
20256                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20257         echo "Changelog size after work $size2"
20258
20259         (( $size2 > $size1 )) ||
20260                 error "new Changelog size=$size2 less than old size=$size1"
20261 }
20262 run_test 254 "Check changelog size"
20263
20264 ladvise_no_type()
20265 {
20266         local type=$1
20267         local file=$2
20268
20269         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20270                 awk -F: '{print $2}' | grep $type > /dev/null
20271         if [ $? -ne 0 ]; then
20272                 return 0
20273         fi
20274         return 1
20275 }
20276
20277 ladvise_no_ioctl()
20278 {
20279         local file=$1
20280
20281         lfs ladvise -a willread $file > /dev/null 2>&1
20282         if [ $? -eq 0 ]; then
20283                 return 1
20284         fi
20285
20286         lfs ladvise -a willread $file 2>&1 |
20287                 grep "Inappropriate ioctl for device" > /dev/null
20288         if [ $? -eq 0 ]; then
20289                 return 0
20290         fi
20291         return 1
20292 }
20293
20294 percent() {
20295         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20296 }
20297
20298 # run a random read IO workload
20299 # usage: random_read_iops <filename> <filesize> <iosize>
20300 random_read_iops() {
20301         local file=$1
20302         local fsize=$2
20303         local iosize=${3:-4096}
20304
20305         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20306                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20307 }
20308
20309 drop_file_oss_cache() {
20310         local file="$1"
20311         local nodes="$2"
20312
20313         $LFS ladvise -a dontneed $file 2>/dev/null ||
20314                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20315 }
20316
20317 ladvise_willread_performance()
20318 {
20319         local repeat=10
20320         local average_origin=0
20321         local average_cache=0
20322         local average_ladvise=0
20323
20324         for ((i = 1; i <= $repeat; i++)); do
20325                 echo "Iter $i/$repeat: reading without willread hint"
20326                 cancel_lru_locks osc
20327                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20328                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20329                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20330                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20331
20332                 cancel_lru_locks osc
20333                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20334                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20335                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20336
20337                 cancel_lru_locks osc
20338                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20339                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20340                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20341                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20342                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20343         done
20344         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20345         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20346         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20347
20348         speedup_cache=$(percent $average_cache $average_origin)
20349         speedup_ladvise=$(percent $average_ladvise $average_origin)
20350
20351         echo "Average uncached read: $average_origin"
20352         echo "Average speedup with OSS cached read: " \
20353                 "$average_cache = +$speedup_cache%"
20354         echo "Average speedup with ladvise willread: " \
20355                 "$average_ladvise = +$speedup_ladvise%"
20356
20357         local lowest_speedup=20
20358         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20359                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20360                         "got $average_cache%. Skipping ladvise willread check."
20361                 return 0
20362         fi
20363
20364         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20365         # it is still good to run until then to exercise 'ladvise willread'
20366         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20367                 [ "$ost1_FSTYPE" = "zfs" ] &&
20368                 echo "osd-zfs does not support dontneed or drop_caches" &&
20369                 return 0
20370
20371         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20372         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20373                 error_not_in_vm "Speedup with willread is less than " \
20374                         "$lowest_speedup%, got $average_ladvise%"
20375 }
20376
20377 test_255a() {
20378         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20379                 skip "lustre < 2.8.54 does not support ladvise "
20380         remote_ost_nodsh && skip "remote OST with nodsh"
20381
20382         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20383
20384         ladvise_no_type willread $DIR/$tfile &&
20385                 skip "willread ladvise is not supported"
20386
20387         ladvise_no_ioctl $DIR/$tfile &&
20388                 skip "ladvise ioctl is not supported"
20389
20390         local size_mb=100
20391         local size=$((size_mb * 1048576))
20392         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20393                 error "dd to $DIR/$tfile failed"
20394
20395         lfs ladvise -a willread $DIR/$tfile ||
20396                 error "Ladvise failed with no range argument"
20397
20398         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20399                 error "Ladvise failed with no -l or -e argument"
20400
20401         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20402                 error "Ladvise failed with only -e argument"
20403
20404         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20405                 error "Ladvise failed with only -l argument"
20406
20407         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20408                 error "End offset should not be smaller than start offset"
20409
20410         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20411                 error "End offset should not be equal to start offset"
20412
20413         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20414                 error "Ladvise failed with overflowing -s argument"
20415
20416         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20417                 error "Ladvise failed with overflowing -e argument"
20418
20419         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20420                 error "Ladvise failed with overflowing -l argument"
20421
20422         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20423                 error "Ladvise succeeded with conflicting -l and -e arguments"
20424
20425         echo "Synchronous ladvise should wait"
20426         local delay=4
20427 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20428         do_nodes $(comma_list $(osts_nodes)) \
20429                 $LCTL set_param fail_val=$delay fail_loc=0x237
20430
20431         local start_ts=$SECONDS
20432         lfs ladvise -a willread $DIR/$tfile ||
20433                 error "Ladvise failed with no range argument"
20434         local end_ts=$SECONDS
20435         local inteval_ts=$((end_ts - start_ts))
20436
20437         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20438                 error "Synchronous advice didn't wait reply"
20439         fi
20440
20441         echo "Asynchronous ladvise shouldn't wait"
20442         local start_ts=$SECONDS
20443         lfs ladvise -a willread -b $DIR/$tfile ||
20444                 error "Ladvise failed with no range argument"
20445         local end_ts=$SECONDS
20446         local inteval_ts=$((end_ts - start_ts))
20447
20448         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20449                 error "Asynchronous advice blocked"
20450         fi
20451
20452         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20453         ladvise_willread_performance
20454 }
20455 run_test 255a "check 'lfs ladvise -a willread'"
20456
20457 facet_meminfo() {
20458         local facet=$1
20459         local info=$2
20460
20461         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20462 }
20463
20464 test_255b() {
20465         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20466                 skip "lustre < 2.8.54 does not support ladvise "
20467         remote_ost_nodsh && skip "remote OST with nodsh"
20468
20469         lfs setstripe -c 1 -i 0 $DIR/$tfile
20470
20471         ladvise_no_type dontneed $DIR/$tfile &&
20472                 skip "dontneed ladvise is not supported"
20473
20474         ladvise_no_ioctl $DIR/$tfile &&
20475                 skip "ladvise ioctl is not supported"
20476
20477         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20478                 [ "$ost1_FSTYPE" = "zfs" ] &&
20479                 skip "zfs-osd does not support 'ladvise dontneed'"
20480
20481         local size_mb=100
20482         local size=$((size_mb * 1048576))
20483         # In order to prevent disturbance of other processes, only check 3/4
20484         # of the memory usage
20485         local kibibytes=$((size_mb * 1024 * 3 / 4))
20486
20487         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20488                 error "dd to $DIR/$tfile failed"
20489
20490         #force write to complete before dropping OST cache & checking memory
20491         sync
20492
20493         local total=$(facet_meminfo ost1 MemTotal)
20494         echo "Total memory: $total KiB"
20495
20496         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20497         local before_read=$(facet_meminfo ost1 Cached)
20498         echo "Cache used before read: $before_read KiB"
20499
20500         lfs ladvise -a willread $DIR/$tfile ||
20501                 error "Ladvise willread failed"
20502         local after_read=$(facet_meminfo ost1 Cached)
20503         echo "Cache used after read: $after_read KiB"
20504
20505         lfs ladvise -a dontneed $DIR/$tfile ||
20506                 error "Ladvise dontneed again failed"
20507         local no_read=$(facet_meminfo ost1 Cached)
20508         echo "Cache used after dontneed ladvise: $no_read KiB"
20509
20510         if [ $total -lt $((before_read + kibibytes)) ]; then
20511                 echo "Memory is too small, abort checking"
20512                 return 0
20513         fi
20514
20515         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20516                 error "Ladvise willread should use more memory" \
20517                         "than $kibibytes KiB"
20518         fi
20519
20520         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20521                 error "Ladvise dontneed should release more memory" \
20522                         "than $kibibytes KiB"
20523         fi
20524 }
20525 run_test 255b "check 'lfs ladvise -a dontneed'"
20526
20527 test_255c() {
20528         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20529                 skip "lustre < 2.10.50 does not support lockahead"
20530
20531         local ost1_imp=$(get_osc_import_name client ost1)
20532         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20533                          cut -d'.' -f2)
20534         local count
20535         local new_count
20536         local difference
20537         local i
20538         local rc
20539
20540         test_mkdir -p $DIR/$tdir
20541         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20542
20543         #test 10 returns only success/failure
20544         i=10
20545         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20546         rc=$?
20547         if [ $rc -eq 255 ]; then
20548                 error "Ladvise test${i} failed, ${rc}"
20549         fi
20550
20551         #test 11 counts lock enqueue requests, all others count new locks
20552         i=11
20553         count=$(do_facet ost1 \
20554                 $LCTL get_param -n ost.OSS.ost.stats)
20555         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20556
20557         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20558         rc=$?
20559         if [ $rc -eq 255 ]; then
20560                 error "Ladvise test${i} failed, ${rc}"
20561         fi
20562
20563         new_count=$(do_facet ost1 \
20564                 $LCTL get_param -n ost.OSS.ost.stats)
20565         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20566                    awk '{ print $2 }')
20567
20568         difference="$((new_count - count))"
20569         if [ $difference -ne $rc ]; then
20570                 error "Ladvise test${i}, bad enqueue count, returned " \
20571                       "${rc}, actual ${difference}"
20572         fi
20573
20574         for i in $(seq 12 21); do
20575                 # If we do not do this, we run the risk of having too many
20576                 # locks and starting lock cancellation while we are checking
20577                 # lock counts.
20578                 cancel_lru_locks osc
20579
20580                 count=$($LCTL get_param -n \
20581                        ldlm.namespaces.$imp_name.lock_unused_count)
20582
20583                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20584                 rc=$?
20585                 if [ $rc -eq 255 ]; then
20586                         error "Ladvise test ${i} failed, ${rc}"
20587                 fi
20588
20589                 new_count=$($LCTL get_param -n \
20590                        ldlm.namespaces.$imp_name.lock_unused_count)
20591                 difference="$((new_count - count))"
20592
20593                 # Test 15 output is divided by 100 to map down to valid return
20594                 if [ $i -eq 15 ]; then
20595                         rc="$((rc * 100))"
20596                 fi
20597
20598                 if [ $difference -ne $rc ]; then
20599                         error "Ladvise test ${i}, bad lock count, returned " \
20600                               "${rc}, actual ${difference}"
20601                 fi
20602         done
20603
20604         #test 22 returns only success/failure
20605         i=22
20606         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20607         rc=$?
20608         if [ $rc -eq 255 ]; then
20609                 error "Ladvise test${i} failed, ${rc}"
20610         fi
20611 }
20612 run_test 255c "suite of ladvise lockahead tests"
20613
20614 test_256() {
20615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20616         remote_mds_nodsh && skip "remote MDS with nodsh"
20617         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20618         changelog_users $SINGLEMDS | grep "^cl" &&
20619                 skip "active changelog user"
20620
20621         local cl_user
20622         local cat_sl
20623         local mdt_dev
20624
20625         mdt_dev=$(mdsdevname 1)
20626         echo $mdt_dev
20627
20628         changelog_register || error "changelog_register failed"
20629
20630         rm -rf $DIR/$tdir
20631         mkdir -p $DIR/$tdir
20632
20633         changelog_clear 0 || error "changelog_clear failed"
20634
20635         # change something
20636         touch $DIR/$tdir/{1..10}
20637
20638         # stop the MDT
20639         stop $SINGLEMDS || error "Fail to stop MDT"
20640
20641         # remount the MDT
20642
20643         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20644
20645         #after mount new plainllog is used
20646         touch $DIR/$tdir/{11..19}
20647         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20648         stack_trap "rm -f $tmpfile"
20649         cat_sl=$(do_facet $SINGLEMDS "sync; \
20650                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20651                  llog_reader $tmpfile | grep -c type=1064553b")
20652         do_facet $SINGLEMDS llog_reader $tmpfile
20653
20654         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20655
20656         changelog_clear 0 || error "changelog_clear failed"
20657
20658         cat_sl=$(do_facet $SINGLEMDS "sync; \
20659                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20660                  llog_reader $tmpfile | grep -c type=1064553b")
20661
20662         if (( cat_sl == 2 )); then
20663                 error "Empty plain llog was not deleted from changelog catalog"
20664         elif (( cat_sl != 1 )); then
20665                 error "Active plain llog shouldn't be deleted from catalog"
20666         fi
20667 }
20668 run_test 256 "Check llog delete for empty and not full state"
20669
20670 test_257() {
20671         remote_mds_nodsh && skip "remote MDS with nodsh"
20672         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20673                 skip "Need MDS version at least 2.8.55"
20674
20675         test_mkdir $DIR/$tdir
20676
20677         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20678                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20679         stat $DIR/$tdir
20680
20681 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20682         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20683         local facet=mds$((mdtidx + 1))
20684         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20685         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20686
20687         stop $facet || error "stop MDS failed"
20688         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20689                 error "start MDS fail"
20690         wait_recovery_complete $facet
20691 }
20692 run_test 257 "xattr locks are not lost"
20693
20694 # Verify we take the i_mutex when security requires it
20695 test_258a() {
20696 #define OBD_FAIL_IMUTEX_SEC 0x141c
20697         $LCTL set_param fail_loc=0x141c
20698         touch $DIR/$tfile
20699         chmod u+s $DIR/$tfile
20700         chmod a+rwx $DIR/$tfile
20701         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20702         RC=$?
20703         if [ $RC -ne 0 ]; then
20704                 error "error, failed to take i_mutex, rc=$?"
20705         fi
20706         rm -f $DIR/$tfile
20707 }
20708 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20709
20710 # Verify we do NOT take the i_mutex in the normal case
20711 test_258b() {
20712 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20713         $LCTL set_param fail_loc=0x141d
20714         touch $DIR/$tfile
20715         chmod a+rwx $DIR
20716         chmod a+rw $DIR/$tfile
20717         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20718         RC=$?
20719         if [ $RC -ne 0 ]; then
20720                 error "error, took i_mutex unnecessarily, rc=$?"
20721         fi
20722         rm -f $DIR/$tfile
20723
20724 }
20725 run_test 258b "verify i_mutex security behavior"
20726
20727 test_259() {
20728         local file=$DIR/$tfile
20729         local before
20730         local after
20731
20732         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20733
20734         stack_trap "rm -f $file" EXIT
20735
20736         wait_delete_completed
20737         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20738         echo "before: $before"
20739
20740         $LFS setstripe -i 0 -c 1 $file
20741         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20742         sync_all_data
20743         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20744         echo "after write: $after"
20745
20746 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20747         do_facet ost1 $LCTL set_param fail_loc=0x2301
20748         $TRUNCATE $file 0
20749         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20750         echo "after truncate: $after"
20751
20752         stop ost1
20753         do_facet ost1 $LCTL set_param fail_loc=0
20754         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20755         sleep 2
20756         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20757         echo "after restart: $after"
20758         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20759                 error "missing truncate?"
20760
20761         return 0
20762 }
20763 run_test 259 "crash at delayed truncate"
20764
20765 test_260() {
20766 #define OBD_FAIL_MDC_CLOSE               0x806
20767         $LCTL set_param fail_loc=0x80000806
20768         touch $DIR/$tfile
20769
20770 }
20771 run_test 260 "Check mdc_close fail"
20772
20773 ### Data-on-MDT sanity tests ###
20774 test_270a() {
20775         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20776                 skip "Need MDS version at least 2.10.55 for DoM"
20777
20778         # create DoM file
20779         local dom=$DIR/$tdir/dom_file
20780         local tmp=$DIR/$tdir/tmp_file
20781
20782         mkdir -p $DIR/$tdir
20783
20784         # basic checks for DoM component creation
20785         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20786                 error "Can set MDT layout to non-first entry"
20787
20788         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20789                 error "Can define multiple entries as MDT layout"
20790
20791         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20792
20793         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20794         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20795         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20796
20797         local mdtidx=$($LFS getstripe -m $dom)
20798         local mdtname=MDT$(printf %04x $mdtidx)
20799         local facet=mds$((mdtidx + 1))
20800         local space_check=1
20801
20802         # Skip free space checks with ZFS
20803         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20804
20805         # write
20806         sync
20807         local size_tmp=$((65536 * 3))
20808         local mdtfree1=$(do_facet $facet \
20809                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20810
20811         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20812         # check also direct IO along write
20813         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20814         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20815         sync
20816         cmp $tmp $dom || error "file data is different"
20817         [ $(stat -c%s $dom) == $size_tmp ] ||
20818                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20819         if [ $space_check == 1 ]; then
20820                 local mdtfree2=$(do_facet $facet \
20821                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20822
20823                 # increase in usage from by $size_tmp
20824                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20825                         error "MDT free space wrong after write: " \
20826                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20827         fi
20828
20829         # truncate
20830         local size_dom=10000
20831
20832         $TRUNCATE $dom $size_dom
20833         [ $(stat -c%s $dom) == $size_dom ] ||
20834                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20835         if [ $space_check == 1 ]; then
20836                 mdtfree1=$(do_facet $facet \
20837                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20838                 # decrease in usage from $size_tmp to new $size_dom
20839                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20840                   $(((size_tmp - size_dom) / 1024)) ] ||
20841                         error "MDT free space is wrong after truncate: " \
20842                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20843         fi
20844
20845         # append
20846         cat $tmp >> $dom
20847         sync
20848         size_dom=$((size_dom + size_tmp))
20849         [ $(stat -c%s $dom) == $size_dom ] ||
20850                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20851         if [ $space_check == 1 ]; then
20852                 mdtfree2=$(do_facet $facet \
20853                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20854                 # increase in usage by $size_tmp from previous
20855                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20856                         error "MDT free space is wrong after append: " \
20857                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20858         fi
20859
20860         # delete
20861         rm $dom
20862         if [ $space_check == 1 ]; then
20863                 mdtfree1=$(do_facet $facet \
20864                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20865                 # decrease in usage by $size_dom from previous
20866                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20867                         error "MDT free space is wrong after removal: " \
20868                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20869         fi
20870
20871         # combined striping
20872         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20873                 error "Can't create DoM + OST striping"
20874
20875         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20876         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20877         # check also direct IO along write
20878         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20879         sync
20880         cmp $tmp $dom || error "file data is different"
20881         [ $(stat -c%s $dom) == $size_tmp ] ||
20882                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20883         rm $dom $tmp
20884
20885         return 0
20886 }
20887 run_test 270a "DoM: basic functionality tests"
20888
20889 test_270b() {
20890         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20891                 skip "Need MDS version at least 2.10.55"
20892
20893         local dom=$DIR/$tdir/dom_file
20894         local max_size=1048576
20895
20896         mkdir -p $DIR/$tdir
20897         $LFS setstripe -E $max_size -L mdt $dom
20898
20899         # truncate over the limit
20900         $TRUNCATE $dom $(($max_size + 1)) &&
20901                 error "successful truncate over the maximum size"
20902         # write over the limit
20903         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20904                 error "successful write over the maximum size"
20905         # append over the limit
20906         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20907         echo "12345" >> $dom && error "successful append over the maximum size"
20908         rm $dom
20909
20910         return 0
20911 }
20912 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20913
20914 test_270c() {
20915         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20916                 skip "Need MDS version at least 2.10.55"
20917
20918         mkdir -p $DIR/$tdir
20919         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20920
20921         # check files inherit DoM EA
20922         touch $DIR/$tdir/first
20923         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20924                 error "bad pattern"
20925         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20926                 error "bad stripe count"
20927         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20928                 error "bad stripe size"
20929
20930         # check directory inherits DoM EA and uses it as default
20931         mkdir $DIR/$tdir/subdir
20932         touch $DIR/$tdir/subdir/second
20933         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20934                 error "bad pattern in sub-directory"
20935         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20936                 error "bad stripe count in sub-directory"
20937         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20938                 error "bad stripe size in sub-directory"
20939         return 0
20940 }
20941 run_test 270c "DoM: DoM EA inheritance tests"
20942
20943 test_270d() {
20944         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20945                 skip "Need MDS version at least 2.10.55"
20946
20947         mkdir -p $DIR/$tdir
20948         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20949
20950         # inherit default DoM striping
20951         mkdir $DIR/$tdir/subdir
20952         touch $DIR/$tdir/subdir/f1
20953
20954         # change default directory striping
20955         $LFS setstripe -c 1 $DIR/$tdir/subdir
20956         touch $DIR/$tdir/subdir/f2
20957         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20958                 error "wrong default striping in file 2"
20959         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20960                 error "bad pattern in file 2"
20961         return 0
20962 }
20963 run_test 270d "DoM: change striping from DoM to RAID0"
20964
20965 test_270e() {
20966         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20967                 skip "Need MDS version at least 2.10.55"
20968
20969         mkdir -p $DIR/$tdir/dom
20970         mkdir -p $DIR/$tdir/norm
20971         DOMFILES=20
20972         NORMFILES=10
20973         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20974         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20975
20976         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20977         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20978
20979         # find DoM files by layout
20980         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20981         [ $NUM -eq  $DOMFILES ] ||
20982                 error "lfs find -L: found $NUM, expected $DOMFILES"
20983         echo "Test 1: lfs find 20 DOM files by layout: OK"
20984
20985         # there should be 1 dir with default DOM striping
20986         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20987         [ $NUM -eq  1 ] ||
20988                 error "lfs find -L: found $NUM, expected 1 dir"
20989         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20990
20991         # find DoM files by stripe size
20992         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20993         [ $NUM -eq  $DOMFILES ] ||
20994                 error "lfs find -S: found $NUM, expected $DOMFILES"
20995         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20996
20997         # find files by stripe offset except DoM files
20998         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20999         [ $NUM -eq  $NORMFILES ] ||
21000                 error "lfs find -i: found $NUM, expected $NORMFILES"
21001         echo "Test 5: lfs find no DOM files by stripe index: OK"
21002         return 0
21003 }
21004 run_test 270e "DoM: lfs find with DoM files test"
21005
21006 test_270f() {
21007         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21008                 skip "Need MDS version at least 2.10.55"
21009
21010         local mdtname=${FSNAME}-MDT0000-mdtlov
21011         local dom=$DIR/$tdir/dom_file
21012         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21013                                                 lod.$mdtname.dom_stripesize)
21014         local dom_limit=131072
21015
21016         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21017         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21018                                                 lod.$mdtname.dom_stripesize)
21019         [ ${dom_limit} -eq ${dom_current} ] ||
21020                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21021
21022         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21023         $LFS setstripe -d $DIR/$tdir
21024         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21025                 error "Can't set directory default striping"
21026
21027         # exceed maximum stripe size
21028         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21029                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21030         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21031                 error "Able to create DoM component size more than LOD limit"
21032
21033         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21034         dom_current=$(do_facet mds1 $LCTL get_param -n \
21035                                                 lod.$mdtname.dom_stripesize)
21036         [ 0 -eq ${dom_current} ] ||
21037                 error "Can't set zero DoM stripe limit"
21038         rm $dom
21039
21040         # attempt to create DoM file on server with disabled DoM should
21041         # remove DoM entry from layout and be succeed
21042         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21043                 error "Can't create DoM file (DoM is disabled)"
21044         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21045                 error "File has DoM component while DoM is disabled"
21046         rm $dom
21047
21048         # attempt to create DoM file with only DoM stripe should return error
21049         $LFS setstripe -E $dom_limit -L mdt $dom &&
21050                 error "Able to create DoM-only file while DoM is disabled"
21051
21052         # too low values to be aligned with smallest stripe size 64K
21053         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21054         dom_current=$(do_facet mds1 $LCTL get_param -n \
21055                                                 lod.$mdtname.dom_stripesize)
21056         [ 30000 -eq ${dom_current} ] &&
21057                 error "Can set too small DoM stripe limit"
21058
21059         # 64K is a minimal stripe size in Lustre, expect limit of that size
21060         [ 65536 -eq ${dom_current} ] ||
21061                 error "Limit is not set to 64K but ${dom_current}"
21062
21063         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21064         dom_current=$(do_facet mds1 $LCTL get_param -n \
21065                                                 lod.$mdtname.dom_stripesize)
21066         echo $dom_current
21067         [ 2147483648 -eq ${dom_current} ] &&
21068                 error "Can set too large DoM stripe limit"
21069
21070         do_facet mds1 $LCTL set_param -n \
21071                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21072         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21073                 error "Can't create DoM component size after limit change"
21074         do_facet mds1 $LCTL set_param -n \
21075                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21076         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21077                 error "Can't create DoM file after limit decrease"
21078         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21079                 error "Can create big DoM component after limit decrease"
21080         touch ${dom}_def ||
21081                 error "Can't create file with old default layout"
21082
21083         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21084         return 0
21085 }
21086 run_test 270f "DoM: maximum DoM stripe size checks"
21087
21088 test_270g() {
21089         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21090                 skip "Need MDS version at least 2.13.52"
21091         local dom=$DIR/$tdir/$tfile
21092
21093         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21094         local lodname=${FSNAME}-MDT0000-mdtlov
21095
21096         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21097         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21098         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21099         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21100
21101         local dom_limit=1024
21102         local dom_threshold="50%"
21103
21104         $LFS setstripe -d $DIR/$tdir
21105         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21106                 error "Can't set directory default striping"
21107
21108         do_facet mds1 $LCTL set_param -n \
21109                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21110         # set 0 threshold and create DOM file to change tunable stripesize
21111         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21112         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21113                 error "Failed to create $dom file"
21114         # now tunable dom_cur_stripesize should reach maximum
21115         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21116                                         lod.${lodname}.dom_stripesize_cur_kb)
21117         [[ $dom_current == $dom_limit ]] ||
21118                 error "Current DOM stripesize is not maximum"
21119         rm $dom
21120
21121         # set threshold for further tests
21122         do_facet mds1 $LCTL set_param -n \
21123                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21124         echo "DOM threshold is $dom_threshold free space"
21125         local dom_def
21126         local dom_set
21127         # Spoof bfree to exceed threshold
21128         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21129         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21130         for spfree in 40 20 0 15 30 55; do
21131                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21132                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21133                         error "Failed to create $dom file"
21134                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21135                                         lod.${lodname}.dom_stripesize_cur_kb)
21136                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21137                 [[ $dom_def != $dom_current ]] ||
21138                         error "Default stripe size was not changed"
21139                 if [[ $spfree > 0 ]] ; then
21140                         dom_set=$($LFS getstripe -S $dom)
21141                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21142                                 error "DOM component size is still old"
21143                 else
21144                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21145                                 error "DoM component is set with no free space"
21146                 fi
21147                 rm $dom
21148                 dom_current=$dom_def
21149         done
21150 }
21151 run_test 270g "DoM: default DoM stripe size depends on free space"
21152
21153 test_270h() {
21154         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21155                 skip "Need MDS version at least 2.13.53"
21156
21157         local mdtname=${FSNAME}-MDT0000-mdtlov
21158         local dom=$DIR/$tdir/$tfile
21159         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21160
21161         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21162         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21163
21164         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21165         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21166                 error "can't create OST file"
21167         # mirrored file with DOM entry in the second mirror
21168         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21169                 error "can't create mirror with DoM component"
21170
21171         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21172
21173         # DOM component in the middle and has other enries in the same mirror,
21174         # should succeed but lost DoM component
21175         $LFS setstripe --copy=${dom}_1 $dom ||
21176                 error "Can't create file from OST|DOM mirror layout"
21177         # check new file has no DoM layout after all
21178         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21179                 error "File has DoM component while DoM is disabled"
21180 }
21181 run_test 270h "DoM: DoM stripe removal when disabled on server"
21182
21183 test_271a() {
21184         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21185                 skip "Need MDS version at least 2.10.55"
21186
21187         local dom=$DIR/$tdir/dom
21188
21189         mkdir -p $DIR/$tdir
21190
21191         $LFS setstripe -E 1024K -L mdt $dom
21192
21193         lctl set_param -n mdc.*.stats=clear
21194         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21195         cat $dom > /dev/null
21196         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21197         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21198         ls $dom
21199         rm -f $dom
21200 }
21201 run_test 271a "DoM: data is cached for read after write"
21202
21203 test_271b() {
21204         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21205                 skip "Need MDS version at least 2.10.55"
21206
21207         local dom=$DIR/$tdir/dom
21208
21209         mkdir -p $DIR/$tdir
21210
21211         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21212
21213         lctl set_param -n mdc.*.stats=clear
21214         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21215         cancel_lru_locks mdc
21216         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21217         # second stat to check size is cached on client
21218         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21219         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21220         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21221         rm -f $dom
21222 }
21223 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21224
21225 test_271ba() {
21226         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21227                 skip "Need MDS version at least 2.10.55"
21228
21229         local dom=$DIR/$tdir/dom
21230
21231         mkdir -p $DIR/$tdir
21232
21233         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21234
21235         lctl set_param -n mdc.*.stats=clear
21236         lctl set_param -n osc.*.stats=clear
21237         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21238         cancel_lru_locks mdc
21239         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21240         # second stat to check size is cached on client
21241         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21242         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21243         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21244         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21245         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21246         rm -f $dom
21247 }
21248 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21249
21250
21251 get_mdc_stats() {
21252         local mdtidx=$1
21253         local param=$2
21254         local mdt=MDT$(printf %04x $mdtidx)
21255
21256         if [ -z $param ]; then
21257                 lctl get_param -n mdc.*$mdt*.stats
21258         else
21259                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21260         fi
21261 }
21262
21263 test_271c() {
21264         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21265                 skip "Need MDS version at least 2.10.55"
21266
21267         local dom=$DIR/$tdir/dom
21268
21269         mkdir -p $DIR/$tdir
21270
21271         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21272
21273         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21274         local facet=mds$((mdtidx + 1))
21275
21276         cancel_lru_locks mdc
21277         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21278         createmany -o $dom 1000
21279         lctl set_param -n mdc.*.stats=clear
21280         smalliomany -w $dom 1000 200
21281         get_mdc_stats $mdtidx
21282         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21283         # Each file has 1 open, 1 IO enqueues, total 2000
21284         # but now we have also +1 getxattr for security.capability, total 3000
21285         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21286         unlinkmany $dom 1000
21287
21288         cancel_lru_locks mdc
21289         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21290         createmany -o $dom 1000
21291         lctl set_param -n mdc.*.stats=clear
21292         smalliomany -w $dom 1000 200
21293         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21294         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21295         # for OPEN and IO lock.
21296         [ $((enq - enq_2)) -ge 1000 ] ||
21297                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21298         unlinkmany $dom 1000
21299         return 0
21300 }
21301 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21302
21303 cleanup_271def_tests() {
21304         trap 0
21305         rm -f $1
21306 }
21307
21308 test_271d() {
21309         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21310                 skip "Need MDS version at least 2.10.57"
21311
21312         local dom=$DIR/$tdir/dom
21313         local tmp=$TMP/$tfile
21314         trap "cleanup_271def_tests $tmp" EXIT
21315
21316         mkdir -p $DIR/$tdir
21317
21318         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21319
21320         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21321
21322         cancel_lru_locks mdc
21323         dd if=/dev/urandom of=$tmp bs=1000 count=1
21324         dd if=$tmp of=$dom bs=1000 count=1
21325         cancel_lru_locks mdc
21326
21327         cat /etc/hosts >> $tmp
21328         lctl set_param -n mdc.*.stats=clear
21329
21330         # append data to the same file it should update local page
21331         echo "Append to the same page"
21332         cat /etc/hosts >> $dom
21333         local num=$(get_mdc_stats $mdtidx ost_read)
21334         local ra=$(get_mdc_stats $mdtidx req_active)
21335         local rw=$(get_mdc_stats $mdtidx req_waittime)
21336
21337         [ -z $num ] || error "$num READ RPC occured"
21338         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21339         echo "... DONE"
21340
21341         # compare content
21342         cmp $tmp $dom || error "file miscompare"
21343
21344         cancel_lru_locks mdc
21345         lctl set_param -n mdc.*.stats=clear
21346
21347         echo "Open and read file"
21348         cat $dom > /dev/null
21349         local num=$(get_mdc_stats $mdtidx ost_read)
21350         local ra=$(get_mdc_stats $mdtidx req_active)
21351         local rw=$(get_mdc_stats $mdtidx req_waittime)
21352
21353         [ -z $num ] || error "$num READ RPC occured"
21354         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21355         echo "... DONE"
21356
21357         # compare content
21358         cmp $tmp $dom || error "file miscompare"
21359
21360         return 0
21361 }
21362 run_test 271d "DoM: read on open (1K file in reply buffer)"
21363
21364 test_271f() {
21365         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21366                 skip "Need MDS version at least 2.10.57"
21367
21368         local dom=$DIR/$tdir/dom
21369         local tmp=$TMP/$tfile
21370         trap "cleanup_271def_tests $tmp" EXIT
21371
21372         mkdir -p $DIR/$tdir
21373
21374         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21375
21376         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21377
21378         cancel_lru_locks mdc
21379         dd if=/dev/urandom of=$tmp bs=265000 count=1
21380         dd if=$tmp of=$dom bs=265000 count=1
21381         cancel_lru_locks mdc
21382         cat /etc/hosts >> $tmp
21383         lctl set_param -n mdc.*.stats=clear
21384
21385         echo "Append to the same page"
21386         cat /etc/hosts >> $dom
21387         local num=$(get_mdc_stats $mdtidx ost_read)
21388         local ra=$(get_mdc_stats $mdtidx req_active)
21389         local rw=$(get_mdc_stats $mdtidx req_waittime)
21390
21391         [ -z $num ] || error "$num READ RPC occured"
21392         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21393         echo "... DONE"
21394
21395         # compare content
21396         cmp $tmp $dom || error "file miscompare"
21397
21398         cancel_lru_locks mdc
21399         lctl set_param -n mdc.*.stats=clear
21400
21401         echo "Open and read file"
21402         cat $dom > /dev/null
21403         local num=$(get_mdc_stats $mdtidx ost_read)
21404         local ra=$(get_mdc_stats $mdtidx req_active)
21405         local rw=$(get_mdc_stats $mdtidx req_waittime)
21406
21407         [ -z $num ] && num=0
21408         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21409         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21410         echo "... DONE"
21411
21412         # compare content
21413         cmp $tmp $dom || error "file miscompare"
21414
21415         return 0
21416 }
21417 run_test 271f "DoM: read on open (200K file and read tail)"
21418
21419 test_271g() {
21420         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21421                 skip "Skipping due to old client or server version"
21422
21423         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21424         # to get layout
21425         $CHECKSTAT -t file $DIR1/$tfile
21426
21427         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21428         MULTIOP_PID=$!
21429         sleep 1
21430         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21431         $LCTL set_param fail_loc=0x80000314
21432         rm $DIR1/$tfile || error "Unlink fails"
21433         RC=$?
21434         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21435         [ $RC -eq 0 ] || error "Failed write to stale object"
21436 }
21437 run_test 271g "Discard DoM data vs client flush race"
21438
21439 test_272a() {
21440         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21441                 skip "Need MDS version at least 2.11.50"
21442
21443         local dom=$DIR/$tdir/dom
21444         mkdir -p $DIR/$tdir
21445
21446         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21447         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21448                 error "failed to write data into $dom"
21449         local old_md5=$(md5sum $dom)
21450
21451         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21452                 error "failed to migrate to the same DoM component"
21453
21454         local new_md5=$(md5sum $dom)
21455
21456         [ "$old_md5" == "$new_md5" ] ||
21457                 error "md5sum differ: $old_md5, $new_md5"
21458
21459         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21460                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21461 }
21462 run_test 272a "DoM migration: new layout with the same DOM component"
21463
21464 test_272b() {
21465         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21466                 skip "Need MDS version at least 2.11.50"
21467
21468         local dom=$DIR/$tdir/dom
21469         mkdir -p $DIR/$tdir
21470         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21471
21472         local mdtidx=$($LFS getstripe -m $dom)
21473         local mdtname=MDT$(printf %04x $mdtidx)
21474         local facet=mds$((mdtidx + 1))
21475
21476         local mdtfree1=$(do_facet $facet \
21477                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21478         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21479                 error "failed to write data into $dom"
21480         local old_md5=$(md5sum $dom)
21481         cancel_lru_locks mdc
21482         local mdtfree1=$(do_facet $facet \
21483                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21484
21485         $LFS migrate -c2 $dom ||
21486                 error "failed to migrate to the new composite layout"
21487         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21488                 error "MDT stripe was not removed"
21489
21490         cancel_lru_locks mdc
21491         local new_md5=$(md5sum $dom)
21492         [ "$old_md5" == "$new_md5" ] ||
21493                 error "$old_md5 != $new_md5"
21494
21495         # Skip free space checks with ZFS
21496         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21497                 local mdtfree2=$(do_facet $facet \
21498                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21499                 [ $mdtfree2 -gt $mdtfree1 ] ||
21500                         error "MDT space is not freed after migration"
21501         fi
21502         return 0
21503 }
21504 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21505
21506 test_272c() {
21507         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21508                 skip "Need MDS version at least 2.11.50"
21509
21510         local dom=$DIR/$tdir/$tfile
21511         mkdir -p $DIR/$tdir
21512         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21513
21514         local mdtidx=$($LFS getstripe -m $dom)
21515         local mdtname=MDT$(printf %04x $mdtidx)
21516         local facet=mds$((mdtidx + 1))
21517
21518         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21519                 error "failed to write data into $dom"
21520         local old_md5=$(md5sum $dom)
21521         cancel_lru_locks mdc
21522         local mdtfree1=$(do_facet $facet \
21523                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21524
21525         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21526                 error "failed to migrate to the new composite layout"
21527         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21528                 error "MDT stripe was not removed"
21529
21530         cancel_lru_locks mdc
21531         local new_md5=$(md5sum $dom)
21532         [ "$old_md5" == "$new_md5" ] ||
21533                 error "$old_md5 != $new_md5"
21534
21535         # Skip free space checks with ZFS
21536         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21537                 local mdtfree2=$(do_facet $facet \
21538                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21539                 [ $mdtfree2 -gt $mdtfree1 ] ||
21540                         error "MDS space is not freed after migration"
21541         fi
21542         return 0
21543 }
21544 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21545
21546 test_272d() {
21547         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21548                 skip "Need MDS version at least 2.12.55"
21549
21550         local dom=$DIR/$tdir/$tfile
21551         mkdir -p $DIR/$tdir
21552         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21553
21554         local mdtidx=$($LFS getstripe -m $dom)
21555         local mdtname=MDT$(printf %04x $mdtidx)
21556         local facet=mds$((mdtidx + 1))
21557
21558         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21559                 error "failed to write data into $dom"
21560         local old_md5=$(md5sum $dom)
21561         cancel_lru_locks mdc
21562         local mdtfree1=$(do_facet $facet \
21563                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21564
21565         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21566                 error "failed mirroring to the new composite layout"
21567         $LFS mirror resync $dom ||
21568                 error "failed mirror resync"
21569         $LFS mirror split --mirror-id 1 -d $dom ||
21570                 error "failed mirror split"
21571
21572         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21573                 error "MDT stripe was not removed"
21574
21575         cancel_lru_locks mdc
21576         local new_md5=$(md5sum $dom)
21577         [ "$old_md5" == "$new_md5" ] ||
21578                 error "$old_md5 != $new_md5"
21579
21580         # Skip free space checks with ZFS
21581         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21582                 local mdtfree2=$(do_facet $facet \
21583                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21584                 [ $mdtfree2 -gt $mdtfree1 ] ||
21585                         error "MDS space is not freed after DOM mirror deletion"
21586         fi
21587         return 0
21588 }
21589 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21590
21591 test_272e() {
21592         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21593                 skip "Need MDS version at least 2.12.55"
21594
21595         local dom=$DIR/$tdir/$tfile
21596         mkdir -p $DIR/$tdir
21597         $LFS setstripe -c 2 $dom
21598
21599         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21600                 error "failed to write data into $dom"
21601         local old_md5=$(md5sum $dom)
21602         cancel_lru_locks mdc
21603
21604         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21605                 error "failed mirroring to the DOM layout"
21606         $LFS mirror resync $dom ||
21607                 error "failed mirror resync"
21608         $LFS mirror split --mirror-id 1 -d $dom ||
21609                 error "failed mirror split"
21610
21611         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21612                 error "MDT stripe was not removed"
21613
21614         cancel_lru_locks mdc
21615         local new_md5=$(md5sum $dom)
21616         [ "$old_md5" == "$new_md5" ] ||
21617                 error "$old_md5 != $new_md5"
21618
21619         return 0
21620 }
21621 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21622
21623 test_272f() {
21624         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21625                 skip "Need MDS version at least 2.12.55"
21626
21627         local dom=$DIR/$tdir/$tfile
21628         mkdir -p $DIR/$tdir
21629         $LFS setstripe -c 2 $dom
21630
21631         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21632                 error "failed to write data into $dom"
21633         local old_md5=$(md5sum $dom)
21634         cancel_lru_locks mdc
21635
21636         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21637                 error "failed migrating to the DOM file"
21638
21639         cancel_lru_locks mdc
21640         local new_md5=$(md5sum $dom)
21641         [ "$old_md5" != "$new_md5" ] &&
21642                 error "$old_md5 != $new_md5"
21643
21644         return 0
21645 }
21646 run_test 272f "DoM migration: OST-striped file to DOM file"
21647
21648 test_273a() {
21649         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21650                 skip "Need MDS version at least 2.11.50"
21651
21652         # Layout swap cannot be done if either file has DOM component,
21653         # this will never be supported, migration should be used instead
21654
21655         local dom=$DIR/$tdir/$tfile
21656         mkdir -p $DIR/$tdir
21657
21658         $LFS setstripe -c2 ${dom}_plain
21659         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21660         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21661                 error "can swap layout with DoM component"
21662         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21663                 error "can swap layout with DoM component"
21664
21665         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21666         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21667                 error "can swap layout with DoM component"
21668         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21669                 error "can swap layout with DoM component"
21670         return 0
21671 }
21672 run_test 273a "DoM: layout swapping should fail with DOM"
21673
21674 test_273b() {
21675         mkdir -p $DIR/$tdir
21676         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
21677
21678 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
21679         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
21680
21681         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
21682 }
21683 run_test 273b "DoM: race writeback and object destroy"
21684
21685 test_275() {
21686         remote_ost_nodsh && skip "remote OST with nodsh"
21687         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21688                 skip "Need OST version >= 2.10.57"
21689
21690         local file=$DIR/$tfile
21691         local oss
21692
21693         oss=$(comma_list $(osts_nodes))
21694
21695         dd if=/dev/urandom of=$file bs=1M count=2 ||
21696                 error "failed to create a file"
21697         cancel_lru_locks osc
21698
21699         #lock 1
21700         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21701                 error "failed to read a file"
21702
21703 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21704         $LCTL set_param fail_loc=0x8000031f
21705
21706         cancel_lru_locks osc &
21707         sleep 1
21708
21709 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21710         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21711         #IO takes another lock, but matches the PENDING one
21712         #and places it to the IO RPC
21713         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21714                 error "failed to read a file with PENDING lock"
21715 }
21716 run_test 275 "Read on a canceled duplicate lock"
21717
21718 test_276() {
21719         remote_ost_nodsh && skip "remote OST with nodsh"
21720         local pid
21721
21722         do_facet ost1 "(while true; do \
21723                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21724                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21725         pid=$!
21726
21727         for LOOP in $(seq 20); do
21728                 stop ost1
21729                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21730         done
21731         kill -9 $pid
21732         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21733                 rm $TMP/sanity_276_pid"
21734 }
21735 run_test 276 "Race between mount and obd_statfs"
21736
21737 test_277() {
21738         $LCTL set_param ldlm.namespaces.*.lru_size=0
21739         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21740         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21741                         grep ^used_mb | awk '{print $2}')
21742         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21743         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21744                 oflag=direct conv=notrunc
21745         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21746                         grep ^used_mb | awk '{print $2}')
21747         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21748 }
21749 run_test 277 "Direct IO shall drop page cache"
21750
21751 test_278() {
21752         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21753         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21754         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21755                 skip "needs the same host for mdt1 mdt2" && return
21756
21757         local pid1
21758         local pid2
21759
21760 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21761         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21762         stop mds2 &
21763         pid2=$!
21764
21765         stop mds1
21766
21767         echo "Starting MDTs"
21768         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21769         wait $pid2
21770 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21771 #will return NULL
21772         do_facet mds2 $LCTL set_param fail_loc=0
21773
21774         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21775         wait_recovery_complete mds2
21776 }
21777 run_test 278 "Race starting MDS between MDTs stop/start"
21778
21779 test_280() {
21780         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21781                 skip "Need MGS version at least 2.13.52"
21782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21783         combined_mgs_mds || skip "needs combined MGS/MDT"
21784
21785         umount_client $MOUNT
21786 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21787         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21788
21789         mount_client $MOUNT &
21790         sleep 1
21791         stop mgs || error "stop mgs failed"
21792         #for a race mgs would crash
21793         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21794         # make sure we unmount client before remounting
21795         wait
21796         umount_client $MOUNT
21797         mount_client $MOUNT || error "mount client failed"
21798 }
21799 run_test 280 "Race between MGS umount and client llog processing"
21800
21801 cleanup_test_300() {
21802         trap 0
21803         umask $SAVE_UMASK
21804 }
21805 test_striped_dir() {
21806         local mdt_index=$1
21807         local stripe_count
21808         local stripe_index
21809
21810         mkdir -p $DIR/$tdir
21811
21812         SAVE_UMASK=$(umask)
21813         trap cleanup_test_300 RETURN EXIT
21814
21815         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21816                                                 $DIR/$tdir/striped_dir ||
21817                 error "set striped dir error"
21818
21819         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21820         [ "$mode" = "755" ] || error "expect 755 got $mode"
21821
21822         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21823                 error "getdirstripe failed"
21824         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21825         if [ "$stripe_count" != "2" ]; then
21826                 error "1:stripe_count is $stripe_count, expect 2"
21827         fi
21828         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21829         if [ "$stripe_count" != "2" ]; then
21830                 error "2:stripe_count is $stripe_count, expect 2"
21831         fi
21832
21833         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21834         if [ "$stripe_index" != "$mdt_index" ]; then
21835                 error "stripe_index is $stripe_index, expect $mdt_index"
21836         fi
21837
21838         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21839                 error "nlink error after create striped dir"
21840
21841         mkdir $DIR/$tdir/striped_dir/a
21842         mkdir $DIR/$tdir/striped_dir/b
21843
21844         stat $DIR/$tdir/striped_dir/a ||
21845                 error "create dir under striped dir failed"
21846         stat $DIR/$tdir/striped_dir/b ||
21847                 error "create dir under striped dir failed"
21848
21849         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21850                 error "nlink error after mkdir"
21851
21852         rmdir $DIR/$tdir/striped_dir/a
21853         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21854                 error "nlink error after rmdir"
21855
21856         rmdir $DIR/$tdir/striped_dir/b
21857         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21858                 error "nlink error after rmdir"
21859
21860         chattr +i $DIR/$tdir/striped_dir
21861         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21862                 error "immutable flags not working under striped dir!"
21863         chattr -i $DIR/$tdir/striped_dir
21864
21865         rmdir $DIR/$tdir/striped_dir ||
21866                 error "rmdir striped dir error"
21867
21868         cleanup_test_300
21869
21870         true
21871 }
21872
21873 test_300a() {
21874         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21875                 skip "skipped for lustre < 2.7.0"
21876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21877         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21878
21879         test_striped_dir 0 || error "failed on striped dir on MDT0"
21880         test_striped_dir 1 || error "failed on striped dir on MDT0"
21881 }
21882 run_test 300a "basic striped dir sanity test"
21883
21884 test_300b() {
21885         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21886                 skip "skipped for lustre < 2.7.0"
21887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21888         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21889
21890         local i
21891         local mtime1
21892         local mtime2
21893         local mtime3
21894
21895         test_mkdir $DIR/$tdir || error "mkdir fail"
21896         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21897                 error "set striped dir error"
21898         for i in {0..9}; do
21899                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21900                 sleep 1
21901                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21902                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21903                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21904                 sleep 1
21905                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21906                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21907                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21908         done
21909         true
21910 }
21911 run_test 300b "check ctime/mtime for striped dir"
21912
21913 test_300c() {
21914         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21915                 skip "skipped for lustre < 2.7.0"
21916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21917         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21918
21919         local file_count
21920
21921         mkdir -p $DIR/$tdir
21922         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21923                 error "set striped dir error"
21924
21925         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21926                 error "chown striped dir failed"
21927
21928         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21929                 error "create 5k files failed"
21930
21931         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21932
21933         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21934
21935         rm -rf $DIR/$tdir
21936 }
21937 run_test 300c "chown && check ls under striped directory"
21938
21939 test_300d() {
21940         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21941                 skip "skipped for lustre < 2.7.0"
21942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21943         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21944
21945         local stripe_count
21946         local file
21947
21948         mkdir -p $DIR/$tdir
21949         $LFS setstripe -c 2 $DIR/$tdir
21950
21951         #local striped directory
21952         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21953                 error "set striped dir error"
21954         #look at the directories for debug purposes
21955         ls -l $DIR/$tdir
21956         $LFS getdirstripe $DIR/$tdir
21957         ls -l $DIR/$tdir/striped_dir
21958         $LFS getdirstripe $DIR/$tdir/striped_dir
21959         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21960                 error "create 10 files failed"
21961
21962         #remote striped directory
21963         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21964                 error "set striped dir error"
21965         #look at the directories for debug purposes
21966         ls -l $DIR/$tdir
21967         $LFS getdirstripe $DIR/$tdir
21968         ls -l $DIR/$tdir/remote_striped_dir
21969         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21970         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21971                 error "create 10 files failed"
21972
21973         for file in $(find $DIR/$tdir); do
21974                 stripe_count=$($LFS getstripe -c $file)
21975                 [ $stripe_count -eq 2 ] ||
21976                         error "wrong stripe $stripe_count for $file"
21977         done
21978
21979         rm -rf $DIR/$tdir
21980 }
21981 run_test 300d "check default stripe under striped directory"
21982
21983 test_300e() {
21984         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21985                 skip "Need MDS version at least 2.7.55"
21986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21987         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21988
21989         local stripe_count
21990         local file
21991
21992         mkdir -p $DIR/$tdir
21993
21994         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21995                 error "set striped dir error"
21996
21997         touch $DIR/$tdir/striped_dir/a
21998         touch $DIR/$tdir/striped_dir/b
21999         touch $DIR/$tdir/striped_dir/c
22000
22001         mkdir $DIR/$tdir/striped_dir/dir_a
22002         mkdir $DIR/$tdir/striped_dir/dir_b
22003         mkdir $DIR/$tdir/striped_dir/dir_c
22004
22005         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22006                 error "set striped adir under striped dir error"
22007
22008         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22009                 error "set striped bdir under striped dir error"
22010
22011         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22012                 error "set striped cdir under striped dir error"
22013
22014         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22015                 error "rename dir under striped dir fails"
22016
22017         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22018                 error "rename dir under different stripes fails"
22019
22020         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22021                 error "rename file under striped dir should succeed"
22022
22023         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22024                 error "rename dir under striped dir should succeed"
22025
22026         rm -rf $DIR/$tdir
22027 }
22028 run_test 300e "check rename under striped directory"
22029
22030 test_300f() {
22031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22032         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22033         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22034                 skip "Need MDS version at least 2.7.55"
22035
22036         local stripe_count
22037         local file
22038
22039         rm -rf $DIR/$tdir
22040         mkdir -p $DIR/$tdir
22041
22042         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22043                 error "set striped dir error"
22044
22045         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22046                 error "set striped dir error"
22047
22048         touch $DIR/$tdir/striped_dir/a
22049         mkdir $DIR/$tdir/striped_dir/dir_a
22050         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22051                 error "create striped dir under striped dir fails"
22052
22053         touch $DIR/$tdir/striped_dir1/b
22054         mkdir $DIR/$tdir/striped_dir1/dir_b
22055         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22056                 error "create striped dir under striped dir fails"
22057
22058         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22059                 error "rename dir under different striped dir should fail"
22060
22061         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22062                 error "rename striped dir under diff striped dir should fail"
22063
22064         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22065                 error "rename file under diff striped dirs fails"
22066
22067         rm -rf $DIR/$tdir
22068 }
22069 run_test 300f "check rename cross striped directory"
22070
22071 test_300_check_default_striped_dir()
22072 {
22073         local dirname=$1
22074         local default_count=$2
22075         local default_index=$3
22076         local stripe_count
22077         local stripe_index
22078         local dir_stripe_index
22079         local dir
22080
22081         echo "checking $dirname $default_count $default_index"
22082         $LFS setdirstripe -D -c $default_count -i $default_index \
22083                                 -H all_char $DIR/$tdir/$dirname ||
22084                 error "set default stripe on striped dir error"
22085         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22086         [ $stripe_count -eq $default_count ] ||
22087                 error "expect $default_count get $stripe_count for $dirname"
22088
22089         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22090         [ $stripe_index -eq $default_index ] ||
22091                 error "expect $default_index get $stripe_index for $dirname"
22092
22093         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22094                                                 error "create dirs failed"
22095
22096         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22097         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22098         for dir in $(find $DIR/$tdir/$dirname/*); do
22099                 stripe_count=$($LFS getdirstripe -c $dir)
22100                 (( $stripe_count == $default_count )) ||
22101                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22102                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22103                 error "stripe count $default_count != $stripe_count for $dir"
22104
22105                 stripe_index=$($LFS getdirstripe -i $dir)
22106                 [ $default_index -eq -1 ] ||
22107                         [ $stripe_index -eq $default_index ] ||
22108                         error "$stripe_index != $default_index for $dir"
22109
22110                 #check default stripe
22111                 stripe_count=$($LFS getdirstripe -D -c $dir)
22112                 [ $stripe_count -eq $default_count ] ||
22113                 error "default count $default_count != $stripe_count for $dir"
22114
22115                 stripe_index=$($LFS getdirstripe -D -i $dir)
22116                 [ $stripe_index -eq $default_index ] ||
22117                 error "default index $default_index != $stripe_index for $dir"
22118         done
22119         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22120 }
22121
22122 test_300g() {
22123         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22124         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22125                 skip "Need MDS version at least 2.7.55"
22126
22127         local dir
22128         local stripe_count
22129         local stripe_index
22130
22131         mkdir $DIR/$tdir
22132         mkdir $DIR/$tdir/normal_dir
22133
22134         #Checking when client cache stripe index
22135         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22136         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22137                 error "create striped_dir failed"
22138
22139         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22140                 error "create dir0 fails"
22141         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22142         [ $stripe_index -eq 0 ] ||
22143                 error "dir0 expect index 0 got $stripe_index"
22144
22145         mkdir $DIR/$tdir/striped_dir/dir1 ||
22146                 error "create dir1 fails"
22147         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22148         [ $stripe_index -eq 1 ] ||
22149                 error "dir1 expect index 1 got $stripe_index"
22150
22151         #check default stripe count/stripe index
22152         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22153         test_300_check_default_striped_dir normal_dir 1 0
22154         test_300_check_default_striped_dir normal_dir -1 1
22155         test_300_check_default_striped_dir normal_dir 2 -1
22156
22157         #delete default stripe information
22158         echo "delete default stripeEA"
22159         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22160                 error "set default stripe on striped dir error"
22161
22162         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22163         for dir in $(find $DIR/$tdir/normal_dir/*); do
22164                 stripe_count=$($LFS getdirstripe -c $dir)
22165                 [ $stripe_count -eq 0 ] ||
22166                         error "expect 1 get $stripe_count for $dir"
22167                 stripe_index=$($LFS getdirstripe -i $dir)
22168                 [ $stripe_index -eq 0 ] ||
22169                         error "expect 0 get $stripe_index for $dir"
22170         done
22171 }
22172 run_test 300g "check default striped directory for normal directory"
22173
22174 test_300h() {
22175         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22176         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22177                 skip "Need MDS version at least 2.7.55"
22178
22179         local dir
22180         local stripe_count
22181
22182         mkdir $DIR/$tdir
22183         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22184                 error "set striped dir error"
22185
22186         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22187         test_300_check_default_striped_dir striped_dir 1 0
22188         test_300_check_default_striped_dir striped_dir -1 1
22189         test_300_check_default_striped_dir striped_dir 2 -1
22190
22191         #delete default stripe information
22192         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22193                 error "set default stripe on striped dir error"
22194
22195         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22196         for dir in $(find $DIR/$tdir/striped_dir/*); do
22197                 stripe_count=$($LFS getdirstripe -c $dir)
22198                 [ $stripe_count -eq 0 ] ||
22199                         error "expect 1 get $stripe_count for $dir"
22200         done
22201 }
22202 run_test 300h "check default striped directory for striped directory"
22203
22204 test_300i() {
22205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22206         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22207         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22208                 skip "Need MDS version at least 2.7.55"
22209
22210         local stripe_count
22211         local file
22212
22213         mkdir $DIR/$tdir
22214
22215         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22216                 error "set striped dir error"
22217
22218         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22219                 error "create files under striped dir failed"
22220
22221         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22222                 error "set striped hashdir error"
22223
22224         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22225                 error "create dir0 under hash dir failed"
22226         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22227                 error "create dir1 under hash dir failed"
22228         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22229                 error "create dir2 under hash dir failed"
22230
22231         # unfortunately, we need to umount to clear dir layout cache for now
22232         # once we fully implement dir layout, we can drop this
22233         umount_client $MOUNT || error "umount failed"
22234         mount_client $MOUNT || error "mount failed"
22235
22236         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22237         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22238         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22239
22240         #set the stripe to be unknown hash type
22241         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22242         $LCTL set_param fail_loc=0x1901
22243         for ((i = 0; i < 10; i++)); do
22244                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22245                         error "stat f-$i failed"
22246                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22247         done
22248
22249         touch $DIR/$tdir/striped_dir/f0 &&
22250                 error "create under striped dir with unknown hash should fail"
22251
22252         $LCTL set_param fail_loc=0
22253
22254         umount_client $MOUNT || error "umount failed"
22255         mount_client $MOUNT || error "mount failed"
22256
22257         return 0
22258 }
22259 run_test 300i "client handle unknown hash type striped directory"
22260
22261 test_300j() {
22262         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22264         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22265                 skip "Need MDS version at least 2.7.55"
22266
22267         local stripe_count
22268         local file
22269
22270         mkdir $DIR/$tdir
22271
22272         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22273         $LCTL set_param fail_loc=0x1702
22274         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22275                 error "set striped dir error"
22276
22277         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22278                 error "create files under striped dir failed"
22279
22280         $LCTL set_param fail_loc=0
22281
22282         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22283
22284         return 0
22285 }
22286 run_test 300j "test large update record"
22287
22288 test_300k() {
22289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22290         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22291         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22292                 skip "Need MDS version at least 2.7.55"
22293
22294         # this test needs a huge transaction
22295         local kb
22296         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22297              osd*.$FSNAME-MDT0000.kbytestotal")
22298         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22299
22300         local stripe_count
22301         local file
22302
22303         mkdir $DIR/$tdir
22304
22305         #define OBD_FAIL_LARGE_STRIPE   0x1703
22306         $LCTL set_param fail_loc=0x1703
22307         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22308                 error "set striped dir error"
22309         $LCTL set_param fail_loc=0
22310
22311         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22312                 error "getstripeddir fails"
22313         rm -rf $DIR/$tdir/striped_dir ||
22314                 error "unlink striped dir fails"
22315
22316         return 0
22317 }
22318 run_test 300k "test large striped directory"
22319
22320 test_300l() {
22321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22322         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22323         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22324                 skip "Need MDS version at least 2.7.55"
22325
22326         local stripe_index
22327
22328         test_mkdir -p $DIR/$tdir/striped_dir
22329         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22330                         error "chown $RUNAS_ID failed"
22331         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22332                 error "set default striped dir failed"
22333
22334         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22335         $LCTL set_param fail_loc=0x80000158
22336         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22337
22338         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22339         [ $stripe_index -eq 1 ] ||
22340                 error "expect 1 get $stripe_index for $dir"
22341 }
22342 run_test 300l "non-root user to create dir under striped dir with stale layout"
22343
22344 test_300m() {
22345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22346         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22347         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22348                 skip "Need MDS version at least 2.7.55"
22349
22350         mkdir -p $DIR/$tdir/striped_dir
22351         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22352                 error "set default stripes dir error"
22353
22354         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22355
22356         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22357         [ $stripe_count -eq 0 ] ||
22358                         error "expect 0 get $stripe_count for a"
22359
22360         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22361                 error "set default stripes dir error"
22362
22363         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22364
22365         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22366         [ $stripe_count -eq 0 ] ||
22367                         error "expect 0 get $stripe_count for b"
22368
22369         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22370                 error "set default stripes dir error"
22371
22372         mkdir $DIR/$tdir/striped_dir/c &&
22373                 error "default stripe_index is invalid, mkdir c should fails"
22374
22375         rm -rf $DIR/$tdir || error "rmdir fails"
22376 }
22377 run_test 300m "setstriped directory on single MDT FS"
22378
22379 cleanup_300n() {
22380         local list=$(comma_list $(mdts_nodes))
22381
22382         trap 0
22383         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22384 }
22385
22386 test_300n() {
22387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22389         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22390                 skip "Need MDS version at least 2.7.55"
22391         remote_mds_nodsh && skip "remote MDS with nodsh"
22392
22393         local stripe_index
22394         local list=$(comma_list $(mdts_nodes))
22395
22396         trap cleanup_300n RETURN EXIT
22397         mkdir -p $DIR/$tdir
22398         chmod 777 $DIR/$tdir
22399         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22400                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22401                 error "create striped dir succeeds with gid=0"
22402
22403         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22404         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22405                 error "create striped dir fails with gid=-1"
22406
22407         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22408         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22409                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22410                 error "set default striped dir succeeds with gid=0"
22411
22412
22413         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22414         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22415                 error "set default striped dir fails with gid=-1"
22416
22417
22418         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22419         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22420                                         error "create test_dir fails"
22421         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22422                                         error "create test_dir1 fails"
22423         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22424                                         error "create test_dir2 fails"
22425         cleanup_300n
22426 }
22427 run_test 300n "non-root user to create dir under striped dir with default EA"
22428
22429 test_300o() {
22430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22431         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22432         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22433                 skip "Need MDS version at least 2.7.55"
22434
22435         local numfree1
22436         local numfree2
22437
22438         mkdir -p $DIR/$tdir
22439
22440         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22441         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22442         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22443                 skip "not enough free inodes $numfree1 $numfree2"
22444         fi
22445
22446         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22447         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22448         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22449                 skip "not enough free space $numfree1 $numfree2"
22450         fi
22451
22452         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22453                 error "setdirstripe fails"
22454
22455         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22456                 error "create dirs fails"
22457
22458         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22459         ls $DIR/$tdir/striped_dir > /dev/null ||
22460                 error "ls striped dir fails"
22461         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22462                 error "unlink big striped dir fails"
22463 }
22464 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22465
22466 test_300p() {
22467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22468         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22469         remote_mds_nodsh && skip "remote MDS with nodsh"
22470
22471         mkdir -p $DIR/$tdir
22472
22473         #define OBD_FAIL_OUT_ENOSPC     0x1704
22474         do_facet mds2 lctl set_param fail_loc=0x80001704
22475         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22476                  && error "create striped directory should fail"
22477
22478         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22479
22480         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22481         true
22482 }
22483 run_test 300p "create striped directory without space"
22484
22485 test_300q() {
22486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22487         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22488
22489         local fd=$(free_fd)
22490         local cmd="exec $fd<$tdir"
22491         cd $DIR
22492         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22493         eval $cmd
22494         cmd="exec $fd<&-"
22495         trap "eval $cmd" EXIT
22496         cd $tdir || error "cd $tdir fails"
22497         rmdir  ../$tdir || error "rmdir $tdir fails"
22498         mkdir local_dir && error "create dir succeeds"
22499         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22500         eval $cmd
22501         return 0
22502 }
22503 run_test 300q "create remote directory under orphan directory"
22504
22505 test_300r() {
22506         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22507                 skip "Need MDS version at least 2.7.55" && return
22508         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22509
22510         mkdir $DIR/$tdir
22511
22512         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22513                 error "set striped dir error"
22514
22515         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22516                 error "getstripeddir fails"
22517
22518         local stripe_count
22519         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22520                       awk '/lmv_stripe_count:/ { print $2 }')
22521
22522         [ $MDSCOUNT -ne $stripe_count ] &&
22523                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22524
22525         rm -rf $DIR/$tdir/striped_dir ||
22526                 error "unlink striped dir fails"
22527 }
22528 run_test 300r "test -1 striped directory"
22529
22530 test_300s_helper() {
22531         local count=$1
22532
22533         local stripe_dir=$DIR/$tdir/striped_dir.$count
22534
22535         $LFS mkdir -c $count $stripe_dir ||
22536                 error "lfs mkdir -c error"
22537
22538         $LFS getdirstripe $stripe_dir ||
22539                 error "lfs getdirstripe fails"
22540
22541         local stripe_count
22542         stripe_count=$($LFS getdirstripe $stripe_dir |
22543                       awk '/lmv_stripe_count:/ { print $2 }')
22544
22545         [ $count -ne $stripe_count ] &&
22546                 error_noexit "bad stripe count $stripe_count expected $count"
22547
22548         local dupe_stripes
22549         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22550                 awk '/0x/ {count[$1] += 1}; END {
22551                         for (idx in count) {
22552                                 if (count[idx]>1) {
22553                                         print "index " idx " count " count[idx]
22554                                 }
22555                         }
22556                 }')
22557
22558         if [[ -n "$dupe_stripes" ]] ; then
22559                 lfs getdirstripe $stripe_dir
22560                 error_noexit "Dupe MDT above: $dupe_stripes "
22561         fi
22562
22563         rm -rf $stripe_dir ||
22564                 error_noexit "unlink $stripe_dir fails"
22565 }
22566
22567 test_300s() {
22568         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22569                 skip "Need MDS version at least 2.7.55" && return
22570         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22571
22572         mkdir $DIR/$tdir
22573         for count in $(seq 2 $MDSCOUNT); do
22574                 test_300s_helper $count
22575         done
22576 }
22577 run_test 300s "test lfs mkdir -c without -i"
22578
22579
22580 prepare_remote_file() {
22581         mkdir $DIR/$tdir/src_dir ||
22582                 error "create remote source failed"
22583
22584         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22585                  error "cp to remote source failed"
22586         touch $DIR/$tdir/src_dir/a
22587
22588         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22589                 error "create remote target dir failed"
22590
22591         touch $DIR/$tdir/tgt_dir/b
22592
22593         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22594                 error "rename dir cross MDT failed!"
22595
22596         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22597                 error "src_child still exists after rename"
22598
22599         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22600                 error "missing file(a) after rename"
22601
22602         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22603                 error "diff after rename"
22604 }
22605
22606 test_310a() {
22607         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22609
22610         local remote_file=$DIR/$tdir/tgt_dir/b
22611
22612         mkdir -p $DIR/$tdir
22613
22614         prepare_remote_file || error "prepare remote file failed"
22615
22616         #open-unlink file
22617         $OPENUNLINK $remote_file $remote_file ||
22618                 error "openunlink $remote_file failed"
22619         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22620 }
22621 run_test 310a "open unlink remote file"
22622
22623 test_310b() {
22624         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22626
22627         local remote_file=$DIR/$tdir/tgt_dir/b
22628
22629         mkdir -p $DIR/$tdir
22630
22631         prepare_remote_file || error "prepare remote file failed"
22632
22633         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22634         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22635         $CHECKSTAT -t file $remote_file || error "check file failed"
22636 }
22637 run_test 310b "unlink remote file with multiple links while open"
22638
22639 test_310c() {
22640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22641         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22642
22643         local remote_file=$DIR/$tdir/tgt_dir/b
22644
22645         mkdir -p $DIR/$tdir
22646
22647         prepare_remote_file || error "prepare remote file failed"
22648
22649         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22650         multiop_bg_pause $remote_file O_uc ||
22651                         error "mulitop failed for remote file"
22652         MULTIPID=$!
22653         $MULTIOP $DIR/$tfile Ouc
22654         kill -USR1 $MULTIPID
22655         wait $MULTIPID
22656 }
22657 run_test 310c "open-unlink remote file with multiple links"
22658
22659 #LU-4825
22660 test_311() {
22661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22662         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22663         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22664                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22665         remote_mds_nodsh && skip "remote MDS with nodsh"
22666
22667         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22668         local mdts=$(comma_list $(mdts_nodes))
22669
22670         mkdir -p $DIR/$tdir
22671         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22672         createmany -o $DIR/$tdir/$tfile. 1000
22673
22674         # statfs data is not real time, let's just calculate it
22675         old_iused=$((old_iused + 1000))
22676
22677         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22678                         osp.*OST0000*MDT0000.create_count")
22679         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22680                                 osp.*OST0000*MDT0000.max_create_count")
22681         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22682
22683         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22684         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22685         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22686
22687         unlinkmany $DIR/$tdir/$tfile. 1000
22688
22689         do_nodes $mdts "$LCTL set_param -n \
22690                         osp.*OST0000*.max_create_count=$max_count"
22691         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22692                 do_nodes $mdts "$LCTL set_param -n \
22693                                 osp.*OST0000*.create_count=$count"
22694         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22695                         grep "=0" && error "create_count is zero"
22696
22697         local new_iused
22698         for i in $(seq 120); do
22699                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22700                 # system may be too busy to destroy all objs in time, use
22701                 # a somewhat small value to not fail autotest
22702                 [ $((old_iused - new_iused)) -gt 400 ] && break
22703                 sleep 1
22704         done
22705
22706         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22707         [ $((old_iused - new_iused)) -gt 400 ] ||
22708                 error "objs not destroyed after unlink"
22709 }
22710 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22711
22712 zfs_oid_to_objid()
22713 {
22714         local ost=$1
22715         local objid=$2
22716
22717         local vdevdir=$(dirname $(facet_vdevice $ost))
22718         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22719         local zfs_zapid=$(do_facet $ost $cmd |
22720                           grep -w "/O/0/d$((objid%32))" -C 5 |
22721                           awk '/Object/{getline; print $1}')
22722         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22723                           awk "/$objid = /"'{printf $3}')
22724
22725         echo $zfs_objid
22726 }
22727
22728 zfs_object_blksz() {
22729         local ost=$1
22730         local objid=$2
22731
22732         local vdevdir=$(dirname $(facet_vdevice $ost))
22733         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22734         local blksz=$(do_facet $ost $cmd $objid |
22735                       awk '/dblk/{getline; printf $4}')
22736
22737         case "${blksz: -1}" in
22738                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22739                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22740                 *) ;;
22741         esac
22742
22743         echo $blksz
22744 }
22745
22746 test_312() { # LU-4856
22747         remote_ost_nodsh && skip "remote OST with nodsh"
22748         [ "$ost1_FSTYPE" = "zfs" ] ||
22749                 skip_env "the test only applies to zfs"
22750
22751         local max_blksz=$(do_facet ost1 \
22752                           $ZFS get -p recordsize $(facet_device ost1) |
22753                           awk '!/VALUE/{print $3}')
22754
22755         # to make life a little bit easier
22756         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22757         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22758
22759         local tf=$DIR/$tdir/$tfile
22760         touch $tf
22761         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22762
22763         # Get ZFS object id
22764         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22765         # block size change by sequential overwrite
22766         local bs
22767
22768         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22769                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22770
22771                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22772                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22773         done
22774         rm -f $tf
22775
22776         # block size change by sequential append write
22777         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22778         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22779         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22780         local count
22781
22782         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22783                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22784                         oflag=sync conv=notrunc
22785
22786                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22787                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22788                         error "blksz error, actual $blksz, " \
22789                                 "expected: 2 * $count * $PAGE_SIZE"
22790         done
22791         rm -f $tf
22792
22793         # random write
22794         touch $tf
22795         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22796         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22797
22798         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22799         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22800         [ $blksz -eq $PAGE_SIZE ] ||
22801                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22802
22803         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22804         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22805         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22806
22807         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22808         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22809         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22810 }
22811 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22812
22813 test_313() {
22814         remote_ost_nodsh && skip "remote OST with nodsh"
22815
22816         local file=$DIR/$tfile
22817
22818         rm -f $file
22819         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22820
22821         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22822         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22823         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22824                 error "write should failed"
22825         do_facet ost1 "$LCTL set_param fail_loc=0"
22826         rm -f $file
22827 }
22828 run_test 313 "io should fail after last_rcvd update fail"
22829
22830 test_314() {
22831         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22832
22833         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22834         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22835         rm -f $DIR/$tfile
22836         wait_delete_completed
22837         do_facet ost1 "$LCTL set_param fail_loc=0"
22838 }
22839 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22840
22841 test_315() { # LU-618
22842         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22843
22844         local file=$DIR/$tfile
22845         rm -f $file
22846
22847         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22848                 error "multiop file write failed"
22849         $MULTIOP $file oO_RDONLY:r4063232_c &
22850         PID=$!
22851
22852         sleep 2
22853
22854         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22855         kill -USR1 $PID
22856
22857         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22858         rm -f $file
22859 }
22860 run_test 315 "read should be accounted"
22861
22862 test_316() {
22863         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22864         large_xattr_enabled || skip_env "ea_inode feature disabled"
22865
22866         rm -rf $DIR/$tdir/d
22867         mkdir -p $DIR/$tdir/d
22868         chown nobody $DIR/$tdir/d
22869         touch $DIR/$tdir/d/file
22870
22871         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22872 }
22873 run_test 316 "lfs mv"
22874
22875 test_317() {
22876         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22877                 skip "Need MDS version at least 2.11.53"
22878         if [ "$ost1_FSTYPE" == "zfs" ]; then
22879                 skip "LU-10370: no implementation for ZFS"
22880         fi
22881
22882         local trunc_sz
22883         local grant_blk_size
22884
22885         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22886                         awk '/grant_block_size:/ { print $2; exit; }')
22887         #
22888         # Create File of size 5M. Truncate it to below size's and verify
22889         # blocks count.
22890         #
22891         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22892                 error "Create file $DIR/$tfile failed"
22893         stack_trap "rm -f $DIR/$tfile" EXIT
22894
22895         for trunc_sz in 2097152 4097 4000 509 0; do
22896                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22897                         error "truncate $tfile to $trunc_sz failed"
22898                 local sz=$(stat --format=%s $DIR/$tfile)
22899                 local blk=$(stat --format=%b $DIR/$tfile)
22900                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22901                                      grant_blk_size) * 8))
22902
22903                 if [[ $blk -ne $trunc_blk ]]; then
22904                         $(which stat) $DIR/$tfile
22905                         error "Expected Block $trunc_blk got $blk for $tfile"
22906                 fi
22907
22908                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22909                         error "Expected Size $trunc_sz got $sz for $tfile"
22910         done
22911
22912         #
22913         # sparse file test
22914         # Create file with a hole and write actual two blocks. Block count
22915         # must be 16.
22916         #
22917         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22918                 conv=fsync || error "Create file : $DIR/$tfile"
22919
22920         # Calculate the final truncate size.
22921         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22922
22923         #
22924         # truncate to size $trunc_sz bytes. Strip the last block
22925         # The block count must drop to 8
22926         #
22927         $TRUNCATE $DIR/$tfile $trunc_sz ||
22928                 error "truncate $tfile to $trunc_sz failed"
22929
22930         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22931         sz=$(stat --format=%s $DIR/$tfile)
22932         blk=$(stat --format=%b $DIR/$tfile)
22933
22934         if [[ $blk -ne $trunc_bsz ]]; then
22935                 $(which stat) $DIR/$tfile
22936                 error "Expected Block $trunc_bsz got $blk for $tfile"
22937         fi
22938
22939         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22940                 error "Expected Size $trunc_sz got $sz for $tfile"
22941 }
22942 run_test 317 "Verify blocks get correctly update after truncate"
22943
22944 test_318() {
22945         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
22946         local old_max_active=$($LCTL get_param -n \
22947                             ${llite_name}.max_read_ahead_async_active \
22948                             2>/dev/null)
22949
22950         $LCTL set_param llite.*.max_read_ahead_async_active=256
22951         local max_active=$($LCTL get_param -n \
22952                            ${llite_name}.max_read_ahead_async_active \
22953                            2>/dev/null)
22954         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22955
22956         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22957                 error "set max_read_ahead_async_active should succeed"
22958
22959         $LCTL set_param llite.*.max_read_ahead_async_active=512
22960         max_active=$($LCTL get_param -n \
22961                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
22962         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22963
22964         # restore @max_active
22965         [ $old_max_active -ne 0 ] && $LCTL set_param \
22966                 llite.*.max_read_ahead_async_active=$old_max_active
22967
22968         local old_threshold=$($LCTL get_param -n \
22969                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
22970         local max_per_file_mb=$($LCTL get_param -n \
22971                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
22972
22973         local invalid=$(($max_per_file_mb + 1))
22974         $LCTL set_param \
22975                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22976                         && error "set $invalid should fail"
22977
22978         local valid=$(($invalid - 1))
22979         $LCTL set_param \
22980                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22981                         error "set $valid should succeed"
22982         local threshold=$($LCTL get_param -n \
22983                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
22984         [ $threshold -eq $valid ] || error \
22985                 "expect threshold $valid got $threshold"
22986         $LCTL set_param \
22987                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22988 }
22989 run_test 318 "Verify async readahead tunables"
22990
22991 test_319() {
22992         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22993
22994         local before=$(date +%s)
22995         local evict
22996         local mdir=$DIR/$tdir
22997         local file=$mdir/xxx
22998
22999         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23000         touch $file
23001
23002 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23003         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23004         $LFS mv -m1 $file &
23005
23006         sleep 1
23007         dd if=$file of=/dev/null
23008         wait
23009         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23010           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23011
23012         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23013 }
23014 run_test 319 "lost lease lock on migrate error"
23015
23016 test_398a() { # LU-4198
23017         local ost1_imp=$(get_osc_import_name client ost1)
23018         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23019                          cut -d'.' -f2)
23020
23021         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23022         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23023
23024         # request a new lock on client
23025         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23026
23027         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23028         local lock_count=$($LCTL get_param -n \
23029                            ldlm.namespaces.$imp_name.lru_size)
23030         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23031
23032         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23033
23034         # no lock cached, should use lockless IO and not enqueue new lock
23035         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23036         lock_count=$($LCTL get_param -n \
23037                      ldlm.namespaces.$imp_name.lru_size)
23038         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23039 }
23040 run_test 398a "direct IO should cancel lock otherwise lockless"
23041
23042 test_398b() { # LU-4198
23043         which fio || skip_env "no fio installed"
23044         $LFS setstripe -c -1 $DIR/$tfile
23045
23046         local size=12
23047         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23048
23049         local njobs=4
23050         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23051         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23052                 --numjobs=$njobs --fallocate=none \
23053                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23054                 --filename=$DIR/$tfile &
23055         bg_pid=$!
23056
23057         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23058         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23059                 --numjobs=$njobs --fallocate=none \
23060                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23061                 --filename=$DIR/$tfile || true
23062         wait $bg_pid
23063
23064         rm -rf $DIR/$tfile
23065 }
23066 run_test 398b "DIO and buffer IO race"
23067
23068 test_398c() { # LU-4198
23069         local ost1_imp=$(get_osc_import_name client ost1)
23070         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23071                          cut -d'.' -f2)
23072
23073         which fio || skip_env "no fio installed"
23074
23075         saved_debug=$($LCTL get_param -n debug)
23076         $LCTL set_param debug=0
23077
23078         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23079         ((size /= 1024)) # by megabytes
23080         ((size /= 2)) # write half of the OST at most
23081         [ $size -gt 40 ] && size=40 #reduce test time anyway
23082
23083         $LFS setstripe -c 1 $DIR/$tfile
23084
23085         # it seems like ldiskfs reserves more space than necessary if the
23086         # writing blocks are not mapped, so it extends the file firstly
23087         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23088         cancel_lru_locks osc
23089
23090         # clear and verify rpc_stats later
23091         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23092
23093         local njobs=4
23094         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23095         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23096                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23097                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23098                 --filename=$DIR/$tfile
23099         [ $? -eq 0 ] || error "fio write error"
23100
23101         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23102                 error "Locks were requested while doing AIO"
23103
23104         # get the percentage of 1-page I/O
23105         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23106                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23107                 awk '{print $7}')
23108         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23109
23110         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23111         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23112                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23113                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23114                 --filename=$DIR/$tfile
23115         [ $? -eq 0 ] || error "fio mixed read write error"
23116
23117         echo "AIO with large block size ${size}M"
23118         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23119                 --numjobs=1 --fallocate=none --ioengine=libaio \
23120                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23121                 --filename=$DIR/$tfile
23122         [ $? -eq 0 ] || error "fio large block size failed"
23123
23124         rm -rf $DIR/$tfile
23125         $LCTL set_param debug="$saved_debug"
23126 }
23127 run_test 398c "run fio to test AIO"
23128
23129 test_398d() { #  LU-13846
23130         test -f aiocp || skip_env "no aiocp installed"
23131         local aio_file=$DIR/aio_file
23132
23133         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23134
23135         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23136         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23137
23138         diff $DIR/$tfile $aio_file || "file diff after aiocp"
23139
23140         # make sure we don't crash and fail properly
23141         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23142                 error "aio not aligned with PAGE SIZE should fail"
23143
23144         rm -rf $DIR/$tfile $aio_file
23145 }
23146 run_test 398d "run aiocp to verify block size > stripe size"
23147
23148 test_398e() {
23149         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23150         touch $DIR/$tfile.new
23151         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23152 }
23153 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23154
23155 test_fake_rw() {
23156         local read_write=$1
23157         if [ "$read_write" = "write" ]; then
23158                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23159         elif [ "$read_write" = "read" ]; then
23160                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23161         else
23162                 error "argument error"
23163         fi
23164
23165         # turn off debug for performance testing
23166         local saved_debug=$($LCTL get_param -n debug)
23167         $LCTL set_param debug=0
23168
23169         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23170
23171         # get ost1 size - $FSNAME-OST0000
23172         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23173         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23174         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23175
23176         if [ "$read_write" = "read" ]; then
23177                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23178         fi
23179
23180         local start_time=$(date +%s.%N)
23181         $dd_cmd bs=1M count=$blocks oflag=sync ||
23182                 error "real dd $read_write error"
23183         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23184
23185         if [ "$read_write" = "write" ]; then
23186                 rm -f $DIR/$tfile
23187         fi
23188
23189         # define OBD_FAIL_OST_FAKE_RW           0x238
23190         do_facet ost1 $LCTL set_param fail_loc=0x238
23191
23192         local start_time=$(date +%s.%N)
23193         $dd_cmd bs=1M count=$blocks oflag=sync ||
23194                 error "fake dd $read_write error"
23195         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23196
23197         if [ "$read_write" = "write" ]; then
23198                 # verify file size
23199                 cancel_lru_locks osc
23200                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23201                         error "$tfile size not $blocks MB"
23202         fi
23203         do_facet ost1 $LCTL set_param fail_loc=0
23204
23205         echo "fake $read_write $duration_fake vs. normal $read_write" \
23206                 "$duration in seconds"
23207         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23208                 error_not_in_vm "fake write is slower"
23209
23210         $LCTL set_param -n debug="$saved_debug"
23211         rm -f $DIR/$tfile
23212 }
23213 test_399a() { # LU-7655 for OST fake write
23214         remote_ost_nodsh && skip "remote OST with nodsh"
23215
23216         test_fake_rw write
23217 }
23218 run_test 399a "fake write should not be slower than normal write"
23219
23220 test_399b() { # LU-8726 for OST fake read
23221         remote_ost_nodsh && skip "remote OST with nodsh"
23222         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23223                 skip_env "ldiskfs only test"
23224         fi
23225
23226         test_fake_rw read
23227 }
23228 run_test 399b "fake read should not be slower than normal read"
23229
23230 test_400a() { # LU-1606, was conf-sanity test_74
23231         if ! which $CC > /dev/null 2>&1; then
23232                 skip_env "$CC is not installed"
23233         fi
23234
23235         local extra_flags=''
23236         local out=$TMP/$tfile
23237         local prefix=/usr/include/lustre
23238         local prog
23239
23240         # Oleg removes c files in his test rig so test if any c files exist
23241         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23242                 skip_env "Needed c test files are missing"
23243
23244         if ! [[ -d $prefix ]]; then
23245                 # Assume we're running in tree and fixup the include path.
23246                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23247                 extra_flags+=" -L$LUSTRE/utils/.lib"
23248         fi
23249
23250         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23251                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
23252                         error "client api broken"
23253         done
23254         rm -f $out
23255 }
23256 run_test 400a "Lustre client api program can compile and link"
23257
23258 test_400b() { # LU-1606, LU-5011
23259         local header
23260         local out=$TMP/$tfile
23261         local prefix=/usr/include/linux/lustre
23262
23263         # We use a hard coded prefix so that this test will not fail
23264         # when run in tree. There are headers in lustre/include/lustre/
23265         # that are not packaged (like lustre_idl.h) and have more
23266         # complicated include dependencies (like config.h and lnet/types.h).
23267         # Since this test about correct packaging we just skip them when
23268         # they don't exist (see below) rather than try to fixup cppflags.
23269
23270         if ! which $CC > /dev/null 2>&1; then
23271                 skip_env "$CC is not installed"
23272         fi
23273
23274         for header in $prefix/*.h; do
23275                 if ! [[ -f "$header" ]]; then
23276                         continue
23277                 fi
23278
23279                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
23280                         continue # lustre_ioctl.h is internal header
23281                 fi
23282
23283                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
23284                         error "cannot compile '$header'"
23285         done
23286         rm -f $out
23287 }
23288 run_test 400b "packaged headers can be compiled"
23289
23290 test_401a() { #LU-7437
23291         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23292         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23293
23294         #count the number of parameters by "list_param -R"
23295         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23296         #count the number of parameters by listing proc files
23297         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23298         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23299         echo "proc_dirs='$proc_dirs'"
23300         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23301         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23302                       sort -u | wc -l)
23303
23304         [ $params -eq $procs ] ||
23305                 error "found $params parameters vs. $procs proc files"
23306
23307         # test the list_param -D option only returns directories
23308         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23309         #count the number of parameters by listing proc directories
23310         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23311                 sort -u | wc -l)
23312
23313         [ $params -eq $procs ] ||
23314                 error "found $params parameters vs. $procs proc files"
23315 }
23316 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23317
23318 test_401b() {
23319         # jobid_var may not allow arbitrary values, so use jobid_name
23320         # if available
23321         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23322                 local testname=jobid_name tmp='testing%p'
23323         else
23324                 local testname=jobid_var tmp=testing
23325         fi
23326
23327         local save=$($LCTL get_param -n $testname)
23328
23329         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23330                 error "no error returned when setting bad parameters"
23331
23332         local jobid_new=$($LCTL get_param -n foe $testname baz)
23333         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23334
23335         $LCTL set_param -n fog=bam $testname=$save bat=fog
23336         local jobid_old=$($LCTL get_param -n foe $testname bag)
23337         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23338 }
23339 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23340
23341 test_401c() {
23342         # jobid_var may not allow arbitrary values, so use jobid_name
23343         # if available
23344         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23345                 local testname=jobid_name
23346         else
23347                 local testname=jobid_var
23348         fi
23349
23350         local jobid_var_old=$($LCTL get_param -n $testname)
23351         local jobid_var_new
23352
23353         $LCTL set_param $testname= &&
23354                 error "no error returned for 'set_param a='"
23355
23356         jobid_var_new=$($LCTL get_param -n $testname)
23357         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23358                 error "$testname was changed by setting without value"
23359
23360         $LCTL set_param $testname &&
23361                 error "no error returned for 'set_param a'"
23362
23363         jobid_var_new=$($LCTL get_param -n $testname)
23364         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23365                 error "$testname was changed by setting without value"
23366 }
23367 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23368
23369 test_401d() {
23370         # jobid_var may not allow arbitrary values, so use jobid_name
23371         # if available
23372         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23373                 local testname=jobid_name new_value='foo=bar%p'
23374         else
23375                 local testname=jobid_var new_valuie=foo=bar
23376         fi
23377
23378         local jobid_var_old=$($LCTL get_param -n $testname)
23379         local jobid_var_new
23380
23381         $LCTL set_param $testname=$new_value ||
23382                 error "'set_param a=b' did not accept a value containing '='"
23383
23384         jobid_var_new=$($LCTL get_param -n $testname)
23385         [[ "$jobid_var_new" == "$new_value" ]] ||
23386                 error "'set_param a=b' failed on a value containing '='"
23387
23388         # Reset the $testname to test the other format
23389         $LCTL set_param $testname=$jobid_var_old
23390         jobid_var_new=$($LCTL get_param -n $testname)
23391         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23392                 error "failed to reset $testname"
23393
23394         $LCTL set_param $testname $new_value ||
23395                 error "'set_param a b' did not accept a value containing '='"
23396
23397         jobid_var_new=$($LCTL get_param -n $testname)
23398         [[ "$jobid_var_new" == "$new_value" ]] ||
23399                 error "'set_param a b' failed on a value containing '='"
23400
23401         $LCTL set_param $testname $jobid_var_old
23402         jobid_var_new=$($LCTL get_param -n $testname)
23403         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23404                 error "failed to reset $testname"
23405 }
23406 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23407
23408 test_402() {
23409         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23410         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23411                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23412         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23413                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23414                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23415         remote_mds_nodsh && skip "remote MDS with nodsh"
23416
23417         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23418 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23419         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23420         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23421                 echo "Touch failed - OK"
23422 }
23423 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23424
23425 test_403() {
23426         local file1=$DIR/$tfile.1
23427         local file2=$DIR/$tfile.2
23428         local tfile=$TMP/$tfile
23429
23430         rm -f $file1 $file2 $tfile
23431
23432         touch $file1
23433         ln $file1 $file2
23434
23435         # 30 sec OBD_TIMEOUT in ll_getattr()
23436         # right before populating st_nlink
23437         $LCTL set_param fail_loc=0x80001409
23438         stat -c %h $file1 > $tfile &
23439
23440         # create an alias, drop all locks and reclaim the dentry
23441         < $file2
23442         cancel_lru_locks mdc
23443         cancel_lru_locks osc
23444         sysctl -w vm.drop_caches=2
23445
23446         wait
23447
23448         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23449
23450         rm -f $tfile $file1 $file2
23451 }
23452 run_test 403 "i_nlink should not drop to zero due to aliasing"
23453
23454 test_404() { # LU-6601
23455         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23456                 skip "Need server version newer than 2.8.52"
23457         remote_mds_nodsh && skip "remote MDS with nodsh"
23458
23459         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23460                 awk '/osp .*-osc-MDT/ { print $4}')
23461
23462         local osp
23463         for osp in $mosps; do
23464                 echo "Deactivate: " $osp
23465                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23466                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23467                         awk -vp=$osp '$4 == p { print $2 }')
23468                 [ $stat = IN ] || {
23469                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23470                         error "deactivate error"
23471                 }
23472                 echo "Activate: " $osp
23473                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23474                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23475                         awk -vp=$osp '$4 == p { print $2 }')
23476                 [ $stat = UP ] || {
23477                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23478                         error "activate error"
23479                 }
23480         done
23481 }
23482 run_test 404 "validate manual {de}activated works properly for OSPs"
23483
23484 test_405() {
23485         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23486         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23487                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23488                         skip "Layout swap lock is not supported"
23489
23490         check_swap_layouts_support
23491         check_swap_layout_no_dom $DIR
23492
23493         test_mkdir $DIR/$tdir
23494         swap_lock_test -d $DIR/$tdir ||
23495                 error "One layout swap locked test failed"
23496 }
23497 run_test 405 "Various layout swap lock tests"
23498
23499 test_406() {
23500         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23501         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23502         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23504         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23505                 skip "Need MDS version at least 2.8.50"
23506
23507         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23508         local test_pool=$TESTNAME
23509
23510         pool_add $test_pool || error "pool_add failed"
23511         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23512                 error "pool_add_targets failed"
23513
23514         save_layout_restore_at_exit $MOUNT
23515
23516         # parent set default stripe count only, child will stripe from both
23517         # parent and fs default
23518         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23519                 error "setstripe $MOUNT failed"
23520         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23521         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23522         for i in $(seq 10); do
23523                 local f=$DIR/$tdir/$tfile.$i
23524                 touch $f || error "touch failed"
23525                 local count=$($LFS getstripe -c $f)
23526                 [ $count -eq $OSTCOUNT ] ||
23527                         error "$f stripe count $count != $OSTCOUNT"
23528                 local offset=$($LFS getstripe -i $f)
23529                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23530                 local size=$($LFS getstripe -S $f)
23531                 [ $size -eq $((def_stripe_size * 2)) ] ||
23532                         error "$f stripe size $size != $((def_stripe_size * 2))"
23533                 local pool=$($LFS getstripe -p $f)
23534                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23535         done
23536
23537         # change fs default striping, delete parent default striping, now child
23538         # will stripe from new fs default striping only
23539         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23540                 error "change $MOUNT default stripe failed"
23541         $LFS setstripe -c 0 $DIR/$tdir ||
23542                 error "delete $tdir default stripe failed"
23543         for i in $(seq 11 20); do
23544                 local f=$DIR/$tdir/$tfile.$i
23545                 touch $f || error "touch $f failed"
23546                 local count=$($LFS getstripe -c $f)
23547                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23548                 local offset=$($LFS getstripe -i $f)
23549                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23550                 local size=$($LFS getstripe -S $f)
23551                 [ $size -eq $def_stripe_size ] ||
23552                         error "$f stripe size $size != $def_stripe_size"
23553                 local pool=$($LFS getstripe -p $f)
23554                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23555         done
23556
23557         unlinkmany $DIR/$tdir/$tfile. 1 20
23558
23559         local f=$DIR/$tdir/$tfile
23560         pool_remove_all_targets $test_pool $f
23561         pool_remove $test_pool $f
23562 }
23563 run_test 406 "DNE support fs default striping"
23564
23565 test_407() {
23566         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23567         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23568                 skip "Need MDS version at least 2.8.55"
23569         remote_mds_nodsh && skip "remote MDS with nodsh"
23570
23571         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23572                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23573         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23574                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23575         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23576
23577         #define OBD_FAIL_DT_TXN_STOP    0x2019
23578         for idx in $(seq $MDSCOUNT); do
23579                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23580         done
23581         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23582         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23583                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23584         true
23585 }
23586 run_test 407 "transaction fail should cause operation fail"
23587
23588 test_408() {
23589         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23590
23591         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23592         lctl set_param fail_loc=0x8000040a
23593         # let ll_prepare_partial_page() fail
23594         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23595
23596         rm -f $DIR/$tfile
23597
23598         # create at least 100 unused inodes so that
23599         # shrink_icache_memory(0) should not return 0
23600         touch $DIR/$tfile-{0..100}
23601         rm -f $DIR/$tfile-{0..100}
23602         sync
23603
23604         echo 2 > /proc/sys/vm/drop_caches
23605 }
23606 run_test 408 "drop_caches should not hang due to page leaks"
23607
23608 test_409()
23609 {
23610         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23611
23612         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23613         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23614         touch $DIR/$tdir/guard || error "(2) Fail to create"
23615
23616         local PREFIX=$(str_repeat 'A' 128)
23617         echo "Create 1K hard links start at $(date)"
23618         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23619                 error "(3) Fail to hard link"
23620
23621         echo "Links count should be right although linkEA overflow"
23622         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23623         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23624         [ $linkcount -eq 1001 ] ||
23625                 error "(5) Unexpected hard links count: $linkcount"
23626
23627         echo "List all links start at $(date)"
23628         ls -l $DIR/$tdir/foo > /dev/null ||
23629                 error "(6) Fail to list $DIR/$tdir/foo"
23630
23631         echo "Unlink hard links start at $(date)"
23632         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23633                 error "(7) Fail to unlink"
23634         echo "Unlink hard links finished at $(date)"
23635 }
23636 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23637
23638 test_410()
23639 {
23640         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23641                 skip "Need client version at least 2.9.59"
23642         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23643                 skip "Need MODULES build"
23644
23645         # Create a file, and stat it from the kernel
23646         local testfile=$DIR/$tfile
23647         touch $testfile
23648
23649         local run_id=$RANDOM
23650         local my_ino=$(stat --format "%i" $testfile)
23651
23652         # Try to insert the module. This will always fail as the
23653         # module is designed to not be inserted.
23654         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23655             &> /dev/null
23656
23657         # Anything but success is a test failure
23658         dmesg | grep -q \
23659             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23660             error "no inode match"
23661 }
23662 run_test 410 "Test inode number returned from kernel thread"
23663
23664 cleanup_test411_cgroup() {
23665         trap 0
23666         rmdir "$1"
23667 }
23668
23669 test_411() {
23670         local cg_basedir=/sys/fs/cgroup/memory
23671         # LU-9966
23672         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23673                 skip "no setup for cgroup"
23674
23675         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23676                 error "test file creation failed"
23677         cancel_lru_locks osc
23678
23679         # Create a very small memory cgroup to force a slab allocation error
23680         local cgdir=$cg_basedir/osc_slab_alloc
23681         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23682         trap "cleanup_test411_cgroup $cgdir" EXIT
23683         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23684         echo 1M > $cgdir/memory.limit_in_bytes
23685
23686         # Should not LBUG, just be killed by oom-killer
23687         # dd will return 0 even allocation failure in some environment.
23688         # So don't check return value
23689         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23690         cleanup_test411_cgroup $cgdir
23691
23692         return 0
23693 }
23694 run_test 411 "Slab allocation error with cgroup does not LBUG"
23695
23696 test_412() {
23697         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23698         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23699                 skip "Need server version at least 2.10.55"
23700         fi
23701
23702         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23703                 error "mkdir failed"
23704         $LFS getdirstripe $DIR/$tdir
23705         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23706         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23707                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23708         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23709         [ $stripe_count -eq 2 ] ||
23710                 error "expect 2 get $stripe_count"
23711 }
23712 run_test 412 "mkdir on specific MDTs"
23713
23714 test_qos_mkdir() {
23715         local mkdir_cmd=$1
23716         local stripe_count=$2
23717         local mdts=$(comma_list $(mdts_nodes))
23718
23719         local testdir
23720         local lmv_qos_prio_free
23721         local lmv_qos_threshold_rr
23722         local lmv_qos_maxage
23723         local lod_qos_prio_free
23724         local lod_qos_threshold_rr
23725         local lod_qos_maxage
23726         local count
23727         local i
23728
23729         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23730         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23731         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23732                 head -n1)
23733         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23734         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23735         stack_trap "$LCTL set_param \
23736                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23737         stack_trap "$LCTL set_param \
23738                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23739         stack_trap "$LCTL set_param \
23740                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23741
23742         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23743                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23744         lod_qos_prio_free=${lod_qos_prio_free%%%}
23745         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23746                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23747         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23748         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23749                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23750         stack_trap "do_nodes $mdts $LCTL set_param \
23751                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23752         stack_trap "do_nodes $mdts $LCTL set_param \
23753                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23754                 EXIT
23755         stack_trap "do_nodes $mdts $LCTL set_param \
23756                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23757
23758         echo
23759         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23760
23761         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23762         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23763
23764         testdir=$DIR/$tdir-s$stripe_count/rr
23765
23766         for i in $(seq $((100 * MDSCOUNT))); do
23767                 eval $mkdir_cmd $testdir/subdir$i ||
23768                         error "$mkdir_cmd subdir$i failed"
23769         done
23770
23771         for i in $(seq $MDSCOUNT); do
23772                 count=$($LFS getdirstripe -i $testdir/* |
23773                                 grep ^$((i - 1))$ | wc -l)
23774                 echo "$count directories created on MDT$((i - 1))"
23775                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23776
23777                 if [ $stripe_count -gt 1 ]; then
23778                         count=$($LFS getdirstripe $testdir/* |
23779                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23780                         echo "$count stripes created on MDT$((i - 1))"
23781                         # deviation should < 5% of average
23782                         [ $count -lt $((95 * stripe_count)) ] ||
23783                         [ $count -gt $((105 * stripe_count)) ] &&
23784                                 error "stripes are not evenly distributed"
23785                 fi
23786         done
23787
23788         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23789         do_nodes $mdts $LCTL set_param \
23790                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23791
23792         echo
23793         echo "Check for uneven MDTs: "
23794
23795         local ffree
23796         local bavail
23797         local max
23798         local min
23799         local max_index
23800         local min_index
23801         local tmp
23802
23803         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23804         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23805         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23806
23807         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23808         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23809         max_index=0
23810         min_index=0
23811         for ((i = 1; i < ${#ffree[@]}; i++)); do
23812                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23813                 if [ $tmp -gt $max ]; then
23814                         max=$tmp
23815                         max_index=$i
23816                 fi
23817                 if [ $tmp -lt $min ]; then
23818                         min=$tmp
23819                         min_index=$i
23820                 fi
23821         done
23822
23823         [ ${ffree[min_index]} -eq 0 ] &&
23824                 skip "no free files in MDT$min_index"
23825         [ ${ffree[min_index]} -gt 100000000 ] &&
23826                 skip "too much free files in MDT$min_index"
23827
23828         # Check if we need to generate uneven MDTs
23829         local threshold=50
23830         local diff=$(((max - min) * 100 / min))
23831         local value="$(generate_string 1024)"
23832
23833         while [ $diff -lt $threshold ]; do
23834                 # generate uneven MDTs, create till $threshold% diff
23835                 echo -n "weight diff=$diff% must be > $threshold% ..."
23836                 count=$((${ffree[min_index]} / 10))
23837                 # 50 sec per 10000 files in vm
23838                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23839                         skip "$count files to create"
23840                 echo "Fill MDT$min_index with $count files"
23841                 [ -d $DIR/$tdir-MDT$min_index ] ||
23842                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23843                         error "mkdir $tdir-MDT$min_index failed"
23844                 for i in $(seq $count); do
23845                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23846                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23847                                 error "create f$j_$i failed"
23848                         setfattr -n user.413b -v $value \
23849                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23850                                 error "setfattr f$j_$i failed"
23851                 done
23852
23853                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23854                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23855                 max=$(((${ffree[max_index]} >> 8) * \
23856                         (${bavail[max_index]} * bsize >> 16)))
23857                 min=$(((${ffree[min_index]} >> 8) * \
23858                         (${bavail[min_index]} * bsize >> 16)))
23859                 diff=$(((max - min) * 100 / min))
23860         done
23861
23862         echo "MDT filesfree available: ${ffree[@]}"
23863         echo "MDT blocks available: ${bavail[@]}"
23864         echo "weight diff=$diff%"
23865
23866         echo
23867         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23868
23869         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23870         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23871         # decrease statfs age, so that it can be updated in time
23872         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23873         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23874
23875         sleep 1
23876
23877         testdir=$DIR/$tdir-s$stripe_count/qos
23878
23879         for i in $(seq $((100 * MDSCOUNT))); do
23880                 eval $mkdir_cmd $testdir/subdir$i ||
23881                         error "$mkdir_cmd subdir$i failed"
23882         done
23883
23884         for i in $(seq $MDSCOUNT); do
23885                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23886                         wc -l)
23887                 echo "$count directories created on MDT$((i - 1))"
23888
23889                 if [ $stripe_count -gt 1 ]; then
23890                         count=$($LFS getdirstripe $testdir/* |
23891                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23892                         echo "$count stripes created on MDT$((i - 1))"
23893                 fi
23894         done
23895
23896         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23897         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23898
23899         # D-value should > 10% of averge
23900         [ $((max - min)) -lt 10 ] &&
23901                 error "subdirs shouldn't be evenly distributed"
23902
23903         # ditto
23904         if [ $stripe_count -gt 1 ]; then
23905                 max=$($LFS getdirstripe $testdir/* |
23906                         grep -P "^\s+$max_index\t" | wc -l)
23907                 min=$($LFS getdirstripe $testdir/* |
23908                         grep -P "^\s+$min_index\t" | wc -l)
23909                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23910                         error "stripes shouldn't be evenly distributed"|| true
23911         fi
23912 }
23913
23914 test_413a() {
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                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23928         done
23929 }
23930 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23931
23932 test_413b() {
23933         [ $MDSCOUNT -lt 2 ] &&
23934                 skip "We need at least 2 MDTs for this test"
23935
23936         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23937                 skip "Need server version at least 2.12.52"
23938
23939         local stripe_count
23940
23941         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23942                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23943                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23944                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23945                 $LFS setdirstripe -D -c $stripe_count \
23946                         $DIR/$tdir-s$stripe_count/rr ||
23947                         error "setdirstripe failed"
23948                 $LFS setdirstripe -D -c $stripe_count \
23949                         $DIR/$tdir-s$stripe_count/qos ||
23950                         error "setdirstripe failed"
23951                 test_qos_mkdir "mkdir" $stripe_count
23952         done
23953 }
23954 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23955
23956 test_414() {
23957 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23958         $LCTL set_param fail_loc=0x80000521
23959         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23960         rm -f $DIR/$tfile
23961 }
23962 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23963
23964 test_415() {
23965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23966         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23967                 skip "Need server version at least 2.11.52"
23968
23969         # LU-11102
23970         local total
23971         local setattr_pid
23972         local start_time
23973         local end_time
23974         local duration
23975
23976         total=500
23977         # this test may be slow on ZFS
23978         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23979
23980         # though this test is designed for striped directory, let's test normal
23981         # directory too since lock is always saved as CoS lock.
23982         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23983         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23984
23985         (
23986                 while true; do
23987                         touch $DIR/$tdir
23988                 done
23989         ) &
23990         setattr_pid=$!
23991
23992         start_time=$(date +%s)
23993         for i in $(seq $total); do
23994                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23995                         > /dev/null
23996         done
23997         end_time=$(date +%s)
23998         duration=$((end_time - start_time))
23999
24000         kill -9 $setattr_pid
24001
24002         echo "rename $total files took $duration sec"
24003         [ $duration -lt 100 ] || error "rename took $duration sec"
24004 }
24005 run_test 415 "lock revoke is not missing"
24006
24007 test_416() {
24008         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24009                 skip "Need server version at least 2.11.55"
24010
24011         # define OBD_FAIL_OSD_TXN_START    0x19a
24012         do_facet mds1 lctl set_param fail_loc=0x19a
24013
24014         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24015
24016         true
24017 }
24018 run_test 416 "transaction start failure won't cause system hung"
24019
24020 cleanup_417() {
24021         trap 0
24022         do_nodes $(comma_list $(mdts_nodes)) \
24023                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24024         do_nodes $(comma_list $(mdts_nodes)) \
24025                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24026         do_nodes $(comma_list $(mdts_nodes)) \
24027                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24028 }
24029
24030 test_417() {
24031         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24032         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24033                 skip "Need MDS version at least 2.11.56"
24034
24035         trap cleanup_417 RETURN EXIT
24036
24037         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24038         do_nodes $(comma_list $(mdts_nodes)) \
24039                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24040         $LFS migrate -m 0 $DIR/$tdir.1 &&
24041                 error "migrate dir $tdir.1 should fail"
24042
24043         do_nodes $(comma_list $(mdts_nodes)) \
24044                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24045         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24046                 error "create remote dir $tdir.2 should fail"
24047
24048         do_nodes $(comma_list $(mdts_nodes)) \
24049                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24050         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24051                 error "create striped dir $tdir.3 should fail"
24052         true
24053 }
24054 run_test 417 "disable remote dir, striped dir and dir migration"
24055
24056 # Checks that the outputs of df [-i] and lfs df [-i] match
24057 #
24058 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24059 check_lfs_df() {
24060         local dir=$2
24061         local inodes
24062         local df_out
24063         local lfs_df_out
24064         local count
24065         local passed=false
24066
24067         # blocks or inodes
24068         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24069
24070         for count in {1..100}; do
24071                 cancel_lru_locks
24072                 sync; sleep 0.2
24073
24074                 # read the lines of interest
24075                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24076                         error "df $inodes $dir | tail -n +2 failed"
24077                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24078                         error "lfs df $inodes $dir | grep summary: failed"
24079
24080                 # skip first substrings of each output as they are different
24081                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24082                 # compare the two outputs
24083                 passed=true
24084                 for i in {1..5}; do
24085                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24086                 done
24087                 $passed && break
24088         done
24089
24090         if ! $passed; then
24091                 df -P $inodes $dir
24092                 echo
24093                 lfs df $inodes $dir
24094                 error "df and lfs df $1 output mismatch: "      \
24095                       "df ${inodes}: ${df_out[*]}, "            \
24096                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24097         fi
24098 }
24099
24100 test_418() {
24101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24102
24103         local dir=$DIR/$tdir
24104         local numfiles=$((RANDOM % 4096 + 2))
24105         local numblocks=$((RANDOM % 256 + 1))
24106
24107         wait_delete_completed
24108         test_mkdir $dir
24109
24110         # check block output
24111         check_lfs_df blocks $dir
24112         # check inode output
24113         check_lfs_df inodes $dir
24114
24115         # create a single file and retest
24116         echo "Creating a single file and testing"
24117         createmany -o $dir/$tfile- 1 &>/dev/null ||
24118                 error "creating 1 file in $dir failed"
24119         check_lfs_df blocks $dir
24120         check_lfs_df inodes $dir
24121
24122         # create a random number of files
24123         echo "Creating $((numfiles - 1)) files and testing"
24124         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24125                 error "creating $((numfiles - 1)) files in $dir failed"
24126
24127         # write a random number of blocks to the first test file
24128         echo "Writing $numblocks 4K blocks and testing"
24129         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24130                 count=$numblocks &>/dev/null ||
24131                 error "dd to $dir/${tfile}-0 failed"
24132
24133         # retest
24134         check_lfs_df blocks $dir
24135         check_lfs_df inodes $dir
24136
24137         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24138                 error "unlinking $numfiles files in $dir failed"
24139 }
24140 run_test 418 "df and lfs df outputs match"
24141
24142 test_419()
24143 {
24144         local dir=$DIR/$tdir
24145
24146         mkdir -p $dir
24147         touch $dir/file
24148
24149         cancel_lru_locks mdc
24150
24151         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24152         $LCTL set_param fail_loc=0x1410
24153         cat $dir/file
24154         $LCTL set_param fail_loc=0
24155         rm -rf $dir
24156 }
24157 run_test 419 "Verify open file by name doesn't crash kernel"
24158
24159 test_420()
24160 {
24161         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24162                 skip "Need MDS version at least 2.12.53"
24163
24164         local SAVE_UMASK=$(umask)
24165         local dir=$DIR/$tdir
24166         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24167
24168         mkdir -p $dir
24169         umask 0000
24170         mkdir -m03777 $dir/testdir
24171         ls -dn $dir/testdir
24172         # Need to remove trailing '.' when SELinux is enabled
24173         local dirperms=$(ls -dn $dir/testdir |
24174                          awk '{ sub(/\.$/, "", $1); print $1}')
24175         [ $dirperms == "drwxrwsrwt" ] ||
24176                 error "incorrect perms on $dir/testdir"
24177
24178         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24179                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24180         ls -n $dir/testdir/testfile
24181         local fileperms=$(ls -n $dir/testdir/testfile |
24182                           awk '{ sub(/\.$/, "", $1); print $1}')
24183         [ $fileperms == "-rwxr-xr-x" ] ||
24184                 error "incorrect perms on $dir/testdir/testfile"
24185
24186         umask $SAVE_UMASK
24187 }
24188 run_test 420 "clear SGID bit on non-directories for non-members"
24189
24190 test_421a() {
24191         local cnt
24192         local fid1
24193         local fid2
24194
24195         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24196                 skip "Need MDS version at least 2.12.54"
24197
24198         test_mkdir $DIR/$tdir
24199         createmany -o $DIR/$tdir/f 3
24200         cnt=$(ls -1 $DIR/$tdir | wc -l)
24201         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24202
24203         fid1=$(lfs path2fid $DIR/$tdir/f1)
24204         fid2=$(lfs path2fid $DIR/$tdir/f2)
24205         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
24206
24207         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
24208         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
24209
24210         cnt=$(ls -1 $DIR/$tdir | wc -l)
24211         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24212
24213         rm -f $DIR/$tdir/f3 || error "can't remove f3"
24214         createmany -o $DIR/$tdir/f 3
24215         cnt=$(ls -1 $DIR/$tdir | wc -l)
24216         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24217
24218         fid1=$(lfs path2fid $DIR/$tdir/f1)
24219         fid2=$(lfs path2fid $DIR/$tdir/f2)
24220         echo "remove using fsname $FSNAME"
24221         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
24222
24223         cnt=$(ls -1 $DIR/$tdir | wc -l)
24224         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24225 }
24226 run_test 421a "simple rm by fid"
24227
24228 test_421b() {
24229         local cnt
24230         local FID1
24231         local FID2
24232
24233         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24234                 skip "Need MDS version at least 2.12.54"
24235
24236         test_mkdir $DIR/$tdir
24237         createmany -o $DIR/$tdir/f 3
24238         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
24239         MULTIPID=$!
24240
24241         FID1=$(lfs path2fid $DIR/$tdir/f1)
24242         FID2=$(lfs path2fid $DIR/$tdir/f2)
24243         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
24244
24245         kill -USR1 $MULTIPID
24246         wait
24247
24248         cnt=$(ls $DIR/$tdir | wc -l)
24249         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
24250 }
24251 run_test 421b "rm by fid on open file"
24252
24253 test_421c() {
24254         local cnt
24255         local FIDS
24256
24257         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24258                 skip "Need MDS version at least 2.12.54"
24259
24260         test_mkdir $DIR/$tdir
24261         createmany -o $DIR/$tdir/f 3
24262         touch $DIR/$tdir/$tfile
24263         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
24264         cnt=$(ls -1 $DIR/$tdir | wc -l)
24265         [ $cnt != 184 ] && error "unexpected #files: $cnt"
24266
24267         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
24268         $LFS rmfid $DIR $FID1 || error "rmfid failed"
24269
24270         cnt=$(ls $DIR/$tdir | wc -l)
24271         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
24272 }
24273 run_test 421c "rm by fid against hardlinked files"
24274
24275 test_421d() {
24276         local cnt
24277         local FIDS
24278
24279         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24280                 skip "Need MDS version at least 2.12.54"
24281
24282         test_mkdir $DIR/$tdir
24283         createmany -o $DIR/$tdir/f 4097
24284         cnt=$(ls -1 $DIR/$tdir | wc -l)
24285         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
24286
24287         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
24288         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24289
24290         cnt=$(ls $DIR/$tdir | wc -l)
24291         rm -rf $DIR/$tdir
24292         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24293 }
24294 run_test 421d "rmfid en masse"
24295
24296 test_421e() {
24297         local cnt
24298         local FID
24299
24300         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24301         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24302                 skip "Need MDS version at least 2.12.54"
24303
24304         mkdir -p $DIR/$tdir
24305         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24306         createmany -o $DIR/$tdir/striped_dir/f 512
24307         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24308         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24309
24310         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24311                 sed "s/[/][^:]*://g")
24312         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24313
24314         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24315         rm -rf $DIR/$tdir
24316         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24317 }
24318 run_test 421e "rmfid in DNE"
24319
24320 test_421f() {
24321         local cnt
24322         local FID
24323
24324         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24325                 skip "Need MDS version at least 2.12.54"
24326
24327         test_mkdir $DIR/$tdir
24328         touch $DIR/$tdir/f
24329         cnt=$(ls -1 $DIR/$tdir | wc -l)
24330         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24331
24332         FID=$(lfs path2fid $DIR/$tdir/f)
24333         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24334         # rmfid should fail
24335         cnt=$(ls -1 $DIR/$tdir | wc -l)
24336         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24337
24338         chmod a+rw $DIR/$tdir
24339         ls -la $DIR/$tdir
24340         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24341         # rmfid should fail
24342         cnt=$(ls -1 $DIR/$tdir | wc -l)
24343         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24344
24345         rm -f $DIR/$tdir/f
24346         $RUNAS touch $DIR/$tdir/f
24347         FID=$(lfs path2fid $DIR/$tdir/f)
24348         echo "rmfid as root"
24349         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24350         cnt=$(ls -1 $DIR/$tdir | wc -l)
24351         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24352
24353         rm -f $DIR/$tdir/f
24354         $RUNAS touch $DIR/$tdir/f
24355         cnt=$(ls -1 $DIR/$tdir | wc -l)
24356         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24357         FID=$(lfs path2fid $DIR/$tdir/f)
24358         # rmfid w/o user_fid2path mount option should fail
24359         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24360         cnt=$(ls -1 $DIR/$tdir | wc -l)
24361         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24362
24363         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24364         stack_trap "rmdir $tmpdir"
24365         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24366                 error "failed to mount client'"
24367         stack_trap "umount_client $tmpdir"
24368
24369         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24370         # rmfid should succeed
24371         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24372         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24373
24374         # rmfid shouldn't allow to remove files due to dir's permission
24375         chmod a+rwx $tmpdir/$tdir
24376         touch $tmpdir/$tdir/f
24377         ls -la $tmpdir/$tdir
24378         FID=$(lfs path2fid $tmpdir/$tdir/f)
24379         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24380         return 0
24381 }
24382 run_test 421f "rmfid checks permissions"
24383
24384 test_421g() {
24385         local cnt
24386         local FIDS
24387
24388         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24389         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24390                 skip "Need MDS version at least 2.12.54"
24391
24392         mkdir -p $DIR/$tdir
24393         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24394         createmany -o $DIR/$tdir/striped_dir/f 512
24395         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24396         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24397
24398         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24399                 sed "s/[/][^:]*://g")
24400
24401         rm -f $DIR/$tdir/striped_dir/f1*
24402         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24403         removed=$((512 - cnt))
24404
24405         # few files have been just removed, so we expect
24406         # rmfid to fail on their fids
24407         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24408         [ $removed != $errors ] && error "$errors != $removed"
24409
24410         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24411         rm -rf $DIR/$tdir
24412         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24413 }
24414 run_test 421g "rmfid to return errors properly"
24415
24416 test_422() {
24417         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24418         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24419         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24420         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24421         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24422
24423         local amc=$(at_max_get client)
24424         local amo=$(at_max_get mds1)
24425         local timeout=`lctl get_param -n timeout`
24426
24427         at_max_set 0 client
24428         at_max_set 0 mds1
24429
24430 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24431         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24432                         fail_val=$(((2*timeout + 10)*1000))
24433         touch $DIR/$tdir/d3/file &
24434         sleep 2
24435 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24436         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24437                         fail_val=$((2*timeout + 5))
24438         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24439         local pid=$!
24440         sleep 1
24441         kill -9 $pid
24442         sleep $((2 * timeout))
24443         echo kill $pid
24444         kill -9 $pid
24445         lctl mark touch
24446         touch $DIR/$tdir/d2/file3
24447         touch $DIR/$tdir/d2/file4
24448         touch $DIR/$tdir/d2/file5
24449
24450         wait
24451         at_max_set $amc client
24452         at_max_set $amo mds1
24453
24454         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24455         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24456                 error "Watchdog is always throttled"
24457 }
24458 run_test 422 "kill a process with RPC in progress"
24459
24460 stat_test() {
24461     df -h $MOUNT &
24462     df -h $MOUNT &
24463     df -h $MOUNT &
24464     df -h $MOUNT &
24465     df -h $MOUNT &
24466     df -h $MOUNT &
24467 }
24468
24469 test_423() {
24470     local _stats
24471     # ensure statfs cache is expired
24472     sleep 2;
24473
24474     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24475     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24476
24477     return 0
24478 }
24479 run_test 423 "statfs should return a right data"
24480
24481 test_424() {
24482 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24483         $LCTL set_param fail_loc=0x80000522
24484         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24485         rm -f $DIR/$tfile
24486 }
24487 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24488
24489 test_425() {
24490         test_mkdir -c -1 $DIR/$tdir
24491         $LFS setstripe -c -1 $DIR/$tdir
24492
24493         lru_resize_disable "" 100
24494         stack_trap "lru_resize_enable" EXIT
24495
24496         sleep 5
24497
24498         for i in $(seq $((MDSCOUNT * 125))); do
24499                 local t=$DIR/$tdir/$tfile_$i
24500
24501                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24502                         error_noexit "Create file $t"
24503         done
24504         stack_trap "rm -rf $DIR/$tdir" EXIT
24505
24506         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24507                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24508                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24509
24510                 [ $lock_count -le $lru_size ] ||
24511                         error "osc lock count $lock_count > lru size $lru_size"
24512         done
24513
24514         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24515                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24516                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24517
24518                 [ $lock_count -le $lru_size ] ||
24519                         error "mdc lock count $lock_count > lru size $lru_size"
24520         done
24521 }
24522 run_test 425 "lock count should not exceed lru size"
24523
24524 test_426() {
24525         splice-test -r $DIR/$tfile
24526         splice-test -rd $DIR/$tfile
24527         splice-test $DIR/$tfile
24528         splice-test -d $DIR/$tfile
24529 }
24530 run_test 426 "splice test on Lustre"
24531
24532 test_427() {
24533         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24534         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24535                 skip "Need MDS version at least 2.12.4"
24536         local log
24537
24538         mkdir $DIR/$tdir
24539         mkdir $DIR/$tdir/1
24540         mkdir $DIR/$tdir/2
24541         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24542         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24543
24544         $LFS getdirstripe $DIR/$tdir/1/dir
24545
24546         #first setfattr for creating updatelog
24547         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24548
24549 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24550         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24551         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24552         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24553
24554         sleep 2
24555         fail mds2
24556         wait_recovery_complete mds2 $((2*TIMEOUT))
24557
24558         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24559         echo $log | grep "get update log failed" &&
24560                 error "update log corruption is detected" || true
24561 }
24562 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24563
24564 test_428() {
24565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24566         local cache_limit=$CACHE_MAX
24567
24568         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
24569         $LCTL set_param -n llite.*.max_cached_mb=64
24570
24571         mkdir $DIR/$tdir
24572         $LFS setstripe -c 1 $DIR/$tdir
24573         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
24574         stack_trap "rm -f $DIR/$tdir/$tfile.*"
24575         #test write
24576         for f in $(seq 4); do
24577                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
24578         done
24579         wait
24580
24581         cancel_lru_locks osc
24582         # Test read
24583         for f in $(seq 4); do
24584                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
24585         done
24586         wait
24587 }
24588 run_test 428 "large block size IO should not hang"
24589
24590 lseek_test_430() {
24591         local offset
24592         local file=$1
24593
24594         # data at [200K, 400K)
24595         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24596                 error "256K->512K dd fails"
24597         # data at [2M, 3M)
24598         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24599                 error "2M->3M dd fails"
24600         # data at [4M, 5M)
24601         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24602                 error "4M->5M dd fails"
24603         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24604         # start at first component hole #1
24605         printf "Seeking hole from 1000 ... "
24606         offset=$(lseek_test -l 1000 $file)
24607         echo $offset
24608         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24609         printf "Seeking data from 1000 ... "
24610         offset=$(lseek_test -d 1000 $file)
24611         echo $offset
24612         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24613
24614         # start at first component data block
24615         printf "Seeking hole from 300000 ... "
24616         offset=$(lseek_test -l 300000 $file)
24617         echo $offset
24618         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24619         printf "Seeking data from 300000 ... "
24620         offset=$(lseek_test -d 300000 $file)
24621         echo $offset
24622         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24623
24624         # start at the first component but beyond end of object size
24625         printf "Seeking hole from 1000000 ... "
24626         offset=$(lseek_test -l 1000000 $file)
24627         echo $offset
24628         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24629         printf "Seeking data from 1000000 ... "
24630         offset=$(lseek_test -d 1000000 $file)
24631         echo $offset
24632         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24633
24634         # start at second component stripe 2 (empty file)
24635         printf "Seeking hole from 1500000 ... "
24636         offset=$(lseek_test -l 1500000 $file)
24637         echo $offset
24638         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
24639         printf "Seeking data from 1500000 ... "
24640         offset=$(lseek_test -d 1500000 $file)
24641         echo $offset
24642         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24643
24644         # start at second component stripe 1 (all data)
24645         printf "Seeking hole from 3000000 ... "
24646         offset=$(lseek_test -l 3000000 $file)
24647         echo $offset
24648         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
24649         printf "Seeking data from 3000000 ... "
24650         offset=$(lseek_test -d 3000000 $file)
24651         echo $offset
24652         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
24653
24654         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
24655                 error "2nd dd fails"
24656         echo "Add data block at 640K...1280K"
24657
24658         # start at before new data block, in hole
24659         printf "Seeking hole from 600000 ... "
24660         offset=$(lseek_test -l 600000 $file)
24661         echo $offset
24662         [[ $offset == 600000 ]] || error "offset $offset != 600000"
24663         printf "Seeking data from 600000 ... "
24664         offset=$(lseek_test -d 600000 $file)
24665         echo $offset
24666         [[ $offset == 655360 ]] || error "offset $offset != 655360"
24667
24668         # start at the first component new data block
24669         printf "Seeking hole from 1000000 ... "
24670         offset=$(lseek_test -l 1000000 $file)
24671         echo $offset
24672         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24673         printf "Seeking data from 1000000 ... "
24674         offset=$(lseek_test -d 1000000 $file)
24675         echo $offset
24676         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24677
24678         # start at second component stripe 2, new data
24679         printf "Seeking hole from 1200000 ... "
24680         offset=$(lseek_test -l 1200000 $file)
24681         echo $offset
24682         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24683         printf "Seeking data from 1200000 ... "
24684         offset=$(lseek_test -d 1200000 $file)
24685         echo $offset
24686         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
24687
24688         # start beyond file end
24689         printf "Using offset > filesize ... "
24690         lseek_test -l 4000000 $file && error "lseek should fail"
24691         printf "Using offset > filesize ... "
24692         lseek_test -d 4000000 $file && error "lseek should fail"
24693
24694         printf "Done\n\n"
24695 }
24696
24697 test_430a() {
24698         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
24699                 skip "MDT does not support SEEK_HOLE"
24700
24701         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24702                 skip "OST does not support SEEK_HOLE"
24703
24704         local file=$DIR/$tdir/$tfile
24705
24706         mkdir -p $DIR/$tdir
24707
24708         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
24709         # OST stripe #1 will have continuous data at [1M, 3M)
24710         # OST stripe #2 is empty
24711         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
24712         lseek_test_430 $file
24713         rm $file
24714         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
24715         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
24716         lseek_test_430 $file
24717         rm $file
24718         $LFS setstripe -c2 -S 512K $file
24719         echo "Two stripes, stripe size 512K"
24720         lseek_test_430 $file
24721         rm $file
24722         # FLR with stale mirror
24723         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
24724                        -N -c2 -S 1M $file
24725         echo "Mirrored file:"
24726         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
24727         echo "Plain 2 stripes 1M"
24728         lseek_test_430 $file
24729         rm $file
24730 }
24731 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
24732
24733 test_430b() {
24734         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24735                 skip "OST does not support SEEK_HOLE"
24736
24737         local offset
24738         local file=$DIR/$tdir/$tfile
24739
24740         mkdir -p $DIR/$tdir
24741         # Empty layout lseek should fail
24742         $MCREATE $file
24743         # seek from 0
24744         printf "Seeking hole from 0 ... "
24745         lseek_test -l 0 $file && error "lseek should fail"
24746         printf "Seeking data from 0 ... "
24747         lseek_test -d 0 $file && error "lseek should fail"
24748         rm $file
24749
24750         # 1M-hole file
24751         $LFS setstripe -E 1M -c2 -E eof $file
24752         $TRUNCATE $file 1048576
24753         printf "Seeking hole from 1000000 ... "
24754         offset=$(lseek_test -l 1000000 $file)
24755         echo $offset
24756         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24757         printf "Seeking data from 1000000 ... "
24758         lseek_test -d 1000000 $file && error "lseek should fail"
24759         rm $file
24760
24761         # full component followed by non-inited one
24762         $LFS setstripe -E 1M -c2 -E eof $file
24763         dd if=/dev/urandom of=$file bs=1M count=1
24764         printf "Seeking hole from 1000000 ... "
24765         offset=$(lseek_test -l 1000000 $file)
24766         echo $offset
24767         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24768         printf "Seeking hole from 1048576 ... "
24769         lseek_test -l 1048576 $file && error "lseek should fail"
24770         # init second component and truncate back
24771         echo "123" >> $file
24772         $TRUNCATE $file 1048576
24773         printf "Seeking hole from 1000000 ... "
24774         offset=$(lseek_test -l 1000000 $file)
24775         echo $offset
24776         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24777         printf "Seeking hole from 1048576 ... "
24778         lseek_test -l 1048576 $file && error "lseek should fail"
24779         # boundary checks for big values
24780         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
24781         offset=$(lseek_test -d 0 $file.10g)
24782         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
24783         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
24784         offset=$(lseek_test -d 0 $file.100g)
24785         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
24786         return 0
24787 }
24788 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
24789
24790 test_430c() {
24791         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24792                 skip "OST does not support SEEK_HOLE"
24793
24794         local file=$DIR/$tdir/$tfile
24795         local start
24796
24797         mkdir -p $DIR/$tdir
24798         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
24799
24800         # cp version 8.33+ prefers lseek over fiemap
24801         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
24802                 start=$SECONDS
24803                 time cp $file /dev/null
24804                 (( SECONDS - start < 5 )) ||
24805                         error "cp: too long runtime $((SECONDS - start))"
24806
24807         fi
24808         # tar version 1.29+ supports SEEK_HOLE/DATA
24809         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
24810                 start=$SECONDS
24811                 time tar cS $file - | cat > /dev/null
24812                 (( SECONDS - start < 5 )) ||
24813                         error "tar: too long runtime $((SECONDS - start))"
24814         fi
24815 }
24816 run_test 430c "lseek: external tools check"
24817
24818 test_431() { # LU-14187
24819         local file=$DIR/$tdir/$tfile
24820
24821         mkdir -p $DIR/$tdir
24822         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
24823         dd if=/dev/urandom of=$file bs=4k count=1
24824         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
24825         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
24826         #define OBD_FAIL_OST_RESTART_IO 0x251
24827         do_facet ost1 "$LCTL set_param fail_loc=0x251"
24828         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
24829         cp $file $file.0
24830         cancel_lru_locks
24831         sync_all_data
24832         echo 3 > /proc/sys/vm/drop_caches
24833         diff  $file $file.0 || error "data diff"
24834 }
24835 run_test 431 "Restart transaction for IO"
24836
24837 prep_801() {
24838         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24839         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24840                 skip "Need server version at least 2.9.55"
24841
24842         start_full_debug_logging
24843 }
24844
24845 post_801() {
24846         stop_full_debug_logging
24847 }
24848
24849 barrier_stat() {
24850         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24851                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24852                            awk '/The barrier for/ { print $7 }')
24853                 echo $st
24854         else
24855                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24856                 echo \'$st\'
24857         fi
24858 }
24859
24860 barrier_expired() {
24861         local expired
24862
24863         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24864                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24865                           awk '/will be expired/ { print $7 }')
24866         else
24867                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24868         fi
24869
24870         echo $expired
24871 }
24872
24873 test_801a() {
24874         prep_801
24875
24876         echo "Start barrier_freeze at: $(date)"
24877         #define OBD_FAIL_BARRIER_DELAY          0x2202
24878         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24879         # Do not reduce barrier time - See LU-11873
24880         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24881
24882         sleep 2
24883         local b_status=$(barrier_stat)
24884         echo "Got barrier status at: $(date)"
24885         [ "$b_status" = "'freezing_p1'" ] ||
24886                 error "(1) unexpected barrier status $b_status"
24887
24888         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24889         wait
24890         b_status=$(barrier_stat)
24891         [ "$b_status" = "'frozen'" ] ||
24892                 error "(2) unexpected barrier status $b_status"
24893
24894         local expired=$(barrier_expired)
24895         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24896         sleep $((expired + 3))
24897
24898         b_status=$(barrier_stat)
24899         [ "$b_status" = "'expired'" ] ||
24900                 error "(3) unexpected barrier status $b_status"
24901
24902         # Do not reduce barrier time - See LU-11873
24903         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24904                 error "(4) fail to freeze barrier"
24905
24906         b_status=$(barrier_stat)
24907         [ "$b_status" = "'frozen'" ] ||
24908                 error "(5) unexpected barrier status $b_status"
24909
24910         echo "Start barrier_thaw at: $(date)"
24911         #define OBD_FAIL_BARRIER_DELAY          0x2202
24912         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24913         do_facet mgs $LCTL barrier_thaw $FSNAME &
24914
24915         sleep 2
24916         b_status=$(barrier_stat)
24917         echo "Got barrier status at: $(date)"
24918         [ "$b_status" = "'thawing'" ] ||
24919                 error "(6) unexpected barrier status $b_status"
24920
24921         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24922         wait
24923         b_status=$(barrier_stat)
24924         [ "$b_status" = "'thawed'" ] ||
24925                 error "(7) unexpected barrier status $b_status"
24926
24927         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24928         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24929         do_facet mgs $LCTL barrier_freeze $FSNAME
24930
24931         b_status=$(barrier_stat)
24932         [ "$b_status" = "'failed'" ] ||
24933                 error "(8) unexpected barrier status $b_status"
24934
24935         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24936         do_facet mgs $LCTL barrier_thaw $FSNAME
24937
24938         post_801
24939 }
24940 run_test 801a "write barrier user interfaces and stat machine"
24941
24942 test_801b() {
24943         prep_801
24944
24945         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24946         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24947         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24948         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24949         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24950
24951         cancel_lru_locks mdc
24952
24953         # 180 seconds should be long enough
24954         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24955
24956         local b_status=$(barrier_stat)
24957         [ "$b_status" = "'frozen'" ] ||
24958                 error "(6) unexpected barrier status $b_status"
24959
24960         mkdir $DIR/$tdir/d0/d10 &
24961         mkdir_pid=$!
24962
24963         touch $DIR/$tdir/d1/f13 &
24964         touch_pid=$!
24965
24966         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24967         ln_pid=$!
24968
24969         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24970         mv_pid=$!
24971
24972         rm -f $DIR/$tdir/d4/f12 &
24973         rm_pid=$!
24974
24975         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24976
24977         # To guarantee taht the 'stat' is not blocked
24978         b_status=$(barrier_stat)
24979         [ "$b_status" = "'frozen'" ] ||
24980                 error "(8) unexpected barrier status $b_status"
24981
24982         # let above commands to run at background
24983         sleep 5
24984
24985         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24986         ps -p $touch_pid || error "(10) touch should be blocked"
24987         ps -p $ln_pid || error "(11) link should be blocked"
24988         ps -p $mv_pid || error "(12) rename should be blocked"
24989         ps -p $rm_pid || error "(13) unlink should be blocked"
24990
24991         b_status=$(barrier_stat)
24992         [ "$b_status" = "'frozen'" ] ||
24993                 error "(14) unexpected barrier status $b_status"
24994
24995         do_facet mgs $LCTL barrier_thaw $FSNAME
24996         b_status=$(barrier_stat)
24997         [ "$b_status" = "'thawed'" ] ||
24998                 error "(15) unexpected barrier status $b_status"
24999
25000         wait $mkdir_pid || error "(16) mkdir should succeed"
25001         wait $touch_pid || error "(17) touch should succeed"
25002         wait $ln_pid || error "(18) link should succeed"
25003         wait $mv_pid || error "(19) rename should succeed"
25004         wait $rm_pid || error "(20) unlink should succeed"
25005
25006         post_801
25007 }
25008 run_test 801b "modification will be blocked by write barrier"
25009
25010 test_801c() {
25011         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25012
25013         prep_801
25014
25015         stop mds2 || error "(1) Fail to stop mds2"
25016
25017         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25018
25019         local b_status=$(barrier_stat)
25020         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25021                 do_facet mgs $LCTL barrier_thaw $FSNAME
25022                 error "(2) unexpected barrier status $b_status"
25023         }
25024
25025         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25026                 error "(3) Fail to rescan barrier bitmap"
25027
25028         # Do not reduce barrier time - See LU-11873
25029         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25030
25031         b_status=$(barrier_stat)
25032         [ "$b_status" = "'frozen'" ] ||
25033                 error "(4) unexpected barrier status $b_status"
25034
25035         do_facet mgs $LCTL barrier_thaw $FSNAME
25036         b_status=$(barrier_stat)
25037         [ "$b_status" = "'thawed'" ] ||
25038                 error "(5) unexpected barrier status $b_status"
25039
25040         local devname=$(mdsdevname 2)
25041
25042         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25043
25044         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25045                 error "(7) Fail to rescan barrier bitmap"
25046
25047         post_801
25048 }
25049 run_test 801c "rescan barrier bitmap"
25050
25051 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25052 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25053 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25054 saved_MOUNT_OPTS=$MOUNT_OPTS
25055
25056 cleanup_802a() {
25057         trap 0
25058
25059         stopall
25060         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25061         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25062         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25063         MOUNT_OPTS=$saved_MOUNT_OPTS
25064         setupall
25065 }
25066
25067 test_802a() {
25068         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25069         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25070         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25071                 skip "Need server version at least 2.9.55"
25072
25073         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25074
25075         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25076
25077         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25078                 error "(2) Fail to copy"
25079
25080         trap cleanup_802a EXIT
25081
25082         # sync by force before remount as readonly
25083         sync; sync_all_data; sleep 3; sync_all_data
25084
25085         stopall
25086
25087         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25088         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25089         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25090
25091         echo "Mount the server as read only"
25092         setupall server_only || error "(3) Fail to start servers"
25093
25094         echo "Mount client without ro should fail"
25095         mount_client $MOUNT &&
25096                 error "(4) Mount client without 'ro' should fail"
25097
25098         echo "Mount client with ro should succeed"
25099         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25100         mount_client $MOUNT ||
25101                 error "(5) Mount client with 'ro' should succeed"
25102
25103         echo "Modify should be refused"
25104         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25105
25106         echo "Read should be allowed"
25107         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25108                 error "(7) Read should succeed under ro mode"
25109
25110         cleanup_802a
25111 }
25112 run_test 802a "simulate readonly device"
25113
25114 test_802b() {
25115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25116         remote_mds_nodsh && skip "remote MDS with nodsh"
25117
25118         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25119                 skip "readonly option not available"
25120
25121         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25122
25123         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25124                 error "(2) Fail to copy"
25125
25126         # write back all cached data before setting MDT to readonly
25127         cancel_lru_locks
25128         sync_all_data
25129
25130         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25131         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25132
25133         echo "Modify should be refused"
25134         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25135
25136         echo "Read should be allowed"
25137         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25138                 error "(7) Read should succeed under ro mode"
25139
25140         # disable readonly
25141         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25142 }
25143 run_test 802b "be able to set MDTs to readonly"
25144
25145 test_803a() {
25146         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25147         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25148                 skip "MDS needs to be newer than 2.10.54"
25149
25150         mkdir -p $DIR/$tdir
25151         # Create some objects on all MDTs to trigger related logs objects
25152         for idx in $(seq $MDSCOUNT); do
25153                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
25154                         $DIR/$tdir/dir${idx} ||
25155                         error "Fail to create $DIR/$tdir/dir${idx}"
25156         done
25157
25158         sync; sleep 3
25159         wait_delete_completed # ensure old test cleanups are finished
25160         echo "before create:"
25161         $LFS df -i $MOUNT
25162         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25163
25164         for i in {1..10}; do
25165                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
25166                         error "Fail to create $DIR/$tdir/foo$i"
25167         done
25168
25169         sync; sleep 3
25170         echo "after create:"
25171         $LFS df -i $MOUNT
25172         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25173
25174         # allow for an llog to be cleaned up during the test
25175         [ $after_used -ge $((before_used + 10 - 1)) ] ||
25176                 error "before ($before_used) + 10 > after ($after_used)"
25177
25178         for i in {1..10}; do
25179                 rm -rf $DIR/$tdir/foo$i ||
25180                         error "Fail to remove $DIR/$tdir/foo$i"
25181         done
25182
25183         sleep 3 # avoid MDT return cached statfs
25184         wait_delete_completed
25185         echo "after unlink:"
25186         $LFS df -i $MOUNT
25187         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25188
25189         # allow for an llog to be created during the test
25190         [ $after_used -le $((before_used + 1)) ] ||
25191                 error "after ($after_used) > before ($before_used) + 1"
25192 }
25193 run_test 803a "verify agent object for remote object"
25194
25195 test_803b() {
25196         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25197         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
25198                 skip "MDS needs to be newer than 2.13.56"
25199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25200
25201         for i in $(seq 0 $((MDSCOUNT - 1))); do
25202                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
25203         done
25204
25205         local before=0
25206         local after=0
25207
25208         local tmp
25209
25210         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25211         for i in $(seq 0 $((MDSCOUNT - 1))); do
25212                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25213                         awk '/getattr/ { print $2 }')
25214                 before=$((before + tmp))
25215         done
25216         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25217         for i in $(seq 0 $((MDSCOUNT - 1))); do
25218                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25219                         awk '/getattr/ { print $2 }')
25220                 after=$((after + tmp))
25221         done
25222
25223         [ $before -eq $after ] || error "getattr count $before != $after"
25224 }
25225 run_test 803b "remote object can getattr from cache"
25226
25227 test_804() {
25228         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25229         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25230                 skip "MDS needs to be newer than 2.10.54"
25231         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
25232
25233         mkdir -p $DIR/$tdir
25234         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
25235                 error "Fail to create $DIR/$tdir/dir0"
25236
25237         local fid=$($LFS path2fid $DIR/$tdir/dir0)
25238         local dev=$(mdsdevname 2)
25239
25240         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25241                 grep ${fid} || error "NOT found agent entry for dir0"
25242
25243         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
25244                 error "Fail to create $DIR/$tdir/dir1"
25245
25246         touch $DIR/$tdir/dir1/foo0 ||
25247                 error "Fail to create $DIR/$tdir/dir1/foo0"
25248         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
25249         local rc=0
25250
25251         for idx in $(seq $MDSCOUNT); do
25252                 dev=$(mdsdevname $idx)
25253                 do_facet mds${idx} \
25254                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25255                         grep ${fid} && rc=$idx
25256         done
25257
25258         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
25259                 error "Fail to rename foo0 to foo1"
25260         if [ $rc -eq 0 ]; then
25261                 for idx in $(seq $MDSCOUNT); do
25262                         dev=$(mdsdevname $idx)
25263                         do_facet mds${idx} \
25264                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25265                         grep ${fid} && rc=$idx
25266                 done
25267         fi
25268
25269         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
25270                 error "Fail to rename foo1 to foo2"
25271         if [ $rc -eq 0 ]; then
25272                 for idx in $(seq $MDSCOUNT); do
25273                         dev=$(mdsdevname $idx)
25274                         do_facet mds${idx} \
25275                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25276                         grep ${fid} && rc=$idx
25277                 done
25278         fi
25279
25280         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
25281
25282         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
25283                 error "Fail to link to $DIR/$tdir/dir1/foo2"
25284         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
25285                 error "Fail to rename foo2 to foo0"
25286         unlink $DIR/$tdir/dir1/foo0 ||
25287                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
25288         rm -rf $DIR/$tdir/dir0 ||
25289                 error "Fail to rm $DIR/$tdir/dir0"
25290
25291         for idx in $(seq $MDSCOUNT); do
25292                 dev=$(mdsdevname $idx)
25293                 rc=0
25294
25295                 stop mds${idx}
25296                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25297                         rc=$?
25298                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25299                         error "mount mds$idx failed"
25300                 df $MOUNT > /dev/null 2>&1
25301
25302                 # e2fsck should not return error
25303                 [ $rc -eq 0 ] ||
25304                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25305         done
25306 }
25307 run_test 804 "verify agent entry for remote entry"
25308
25309 cleanup_805() {
25310         do_facet $SINGLEMDS zfs set quota=$old $fsset
25311         unlinkmany $DIR/$tdir/f- 1000000
25312         trap 0
25313 }
25314
25315 test_805() {
25316         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25317         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25318         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25319                 skip "netfree not implemented before 0.7"
25320         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25321                 skip "Need MDS version at least 2.10.57"
25322
25323         local fsset
25324         local freekb
25325         local usedkb
25326         local old
25327         local quota
25328         local pref="osd-zfs.$FSNAME-MDT0000."
25329
25330         # limit available space on MDS dataset to meet nospace issue
25331         # quickly. then ZFS 0.7.2 can use reserved space if asked
25332         # properly (using netfree flag in osd_declare_destroy()
25333         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25334         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25335                 gawk '{print $3}')
25336         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25337         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25338         let "usedkb=usedkb-freekb"
25339         let "freekb=freekb/2"
25340         if let "freekb > 5000"; then
25341                 let "freekb=5000"
25342         fi
25343         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25344         trap cleanup_805 EXIT
25345         mkdir $DIR/$tdir
25346         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25347                 error "Can't set PFL layout"
25348         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25349         rm -rf $DIR/$tdir || error "not able to remove"
25350         do_facet $SINGLEMDS zfs set quota=$old $fsset
25351         trap 0
25352 }
25353 run_test 805 "ZFS can remove from full fs"
25354
25355 # Size-on-MDS test
25356 check_lsom_data()
25357 {
25358         local file=$1
25359         local size=$($LFS getsom -s $file)
25360         local expect=$(stat -c %s $file)
25361
25362         [[ $size == $expect ]] ||
25363                 error "$file expected size: $expect, got: $size"
25364
25365         local blocks=$($LFS getsom -b $file)
25366         expect=$(stat -c %b $file)
25367         [[ $blocks == $expect ]] ||
25368                 error "$file expected blocks: $expect, got: $blocks"
25369 }
25370
25371 check_lsom_size()
25372 {
25373         local size=$($LFS getsom -s $1)
25374         local expect=$2
25375
25376         [[ $size == $expect ]] ||
25377                 error "$file expected size: $expect, got: $size"
25378 }
25379
25380 test_806() {
25381         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25382                 skip "Need MDS version at least 2.11.52"
25383
25384         local bs=1048576
25385
25386         touch $DIR/$tfile || error "touch $tfile failed"
25387
25388         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25389         save_lustre_params client "llite.*.xattr_cache" > $save
25390         lctl set_param llite.*.xattr_cache=0
25391         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25392
25393         # single-threaded write
25394         echo "Test SOM for single-threaded write"
25395         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25396                 error "write $tfile failed"
25397         check_lsom_size $DIR/$tfile $bs
25398
25399         local num=32
25400         local size=$(($num * $bs))
25401         local offset=0
25402         local i
25403
25404         echo "Test SOM for single client multi-threaded($num) write"
25405         $TRUNCATE $DIR/$tfile 0
25406         for ((i = 0; i < $num; i++)); do
25407                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25408                 local pids[$i]=$!
25409                 offset=$((offset + $bs))
25410         done
25411         for (( i=0; i < $num; i++ )); do
25412                 wait ${pids[$i]}
25413         done
25414         check_lsom_size $DIR/$tfile $size
25415
25416         $TRUNCATE $DIR/$tfile 0
25417         for ((i = 0; i < $num; i++)); do
25418                 offset=$((offset - $bs))
25419                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25420                 local pids[$i]=$!
25421         done
25422         for (( i=0; i < $num; i++ )); do
25423                 wait ${pids[$i]}
25424         done
25425         check_lsom_size $DIR/$tfile $size
25426
25427         # multi-client writes
25428         num=$(get_node_count ${CLIENTS//,/ })
25429         size=$(($num * $bs))
25430         offset=0
25431         i=0
25432
25433         echo "Test SOM for multi-client ($num) writes"
25434         $TRUNCATE $DIR/$tfile 0
25435         for client in ${CLIENTS//,/ }; do
25436                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25437                 local pids[$i]=$!
25438                 i=$((i + 1))
25439                 offset=$((offset + $bs))
25440         done
25441         for (( i=0; i < $num; i++ )); do
25442                 wait ${pids[$i]}
25443         done
25444         check_lsom_size $DIR/$tfile $offset
25445
25446         i=0
25447         $TRUNCATE $DIR/$tfile 0
25448         for client in ${CLIENTS//,/ }; do
25449                 offset=$((offset - $bs))
25450                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25451                 local pids[$i]=$!
25452                 i=$((i + 1))
25453         done
25454         for (( i=0; i < $num; i++ )); do
25455                 wait ${pids[$i]}
25456         done
25457         check_lsom_size $DIR/$tfile $size
25458
25459         # verify truncate
25460         echo "Test SOM for truncate"
25461         $TRUNCATE $DIR/$tfile 1048576
25462         check_lsom_size $DIR/$tfile 1048576
25463         $TRUNCATE $DIR/$tfile 1234
25464         check_lsom_size $DIR/$tfile 1234
25465
25466         # verify SOM blocks count
25467         echo "Verify SOM block count"
25468         $TRUNCATE $DIR/$tfile 0
25469         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25470                 error "failed to write file $tfile"
25471         check_lsom_data $DIR/$tfile
25472 }
25473 run_test 806 "Verify Lazy Size on MDS"
25474
25475 test_807() {
25476         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25477         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25478                 skip "Need MDS version at least 2.11.52"
25479
25480         # Registration step
25481         changelog_register || error "changelog_register failed"
25482         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25483         changelog_users $SINGLEMDS | grep -q $cl_user ||
25484                 error "User $cl_user not found in changelog_users"
25485
25486         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25487         save_lustre_params client "llite.*.xattr_cache" > $save
25488         lctl set_param llite.*.xattr_cache=0
25489         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25490
25491         rm -rf $DIR/$tdir || error "rm $tdir failed"
25492         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25493         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25494         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25495         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25496                 error "truncate $tdir/trunc failed"
25497
25498         local bs=1048576
25499         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25500                 error "write $tfile failed"
25501
25502         # multi-client wirtes
25503         local num=$(get_node_count ${CLIENTS//,/ })
25504         local offset=0
25505         local i=0
25506
25507         echo "Test SOM for multi-client ($num) writes"
25508         touch $DIR/$tfile || error "touch $tfile failed"
25509         $TRUNCATE $DIR/$tfile 0
25510         for client in ${CLIENTS//,/ }; do
25511                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25512                 local pids[$i]=$!
25513                 i=$((i + 1))
25514                 offset=$((offset + $bs))
25515         done
25516         for (( i=0; i < $num; i++ )); do
25517                 wait ${pids[$i]}
25518         done
25519
25520         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25521         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25522         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25523         check_lsom_data $DIR/$tdir/trunc
25524         check_lsom_data $DIR/$tdir/single_dd
25525         check_lsom_data $DIR/$tfile
25526
25527         rm -rf $DIR/$tdir
25528         # Deregistration step
25529         changelog_deregister || error "changelog_deregister failed"
25530 }
25531 run_test 807 "verify LSOM syncing tool"
25532
25533 check_som_nologged()
25534 {
25535         local lines=$($LFS changelog $FSNAME-MDT0000 |
25536                 grep 'x=trusted.som' | wc -l)
25537         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25538 }
25539
25540 test_808() {
25541         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25542                 skip "Need MDS version at least 2.11.55"
25543
25544         # Registration step
25545         changelog_register || error "changelog_register failed"
25546
25547         touch $DIR/$tfile || error "touch $tfile failed"
25548         check_som_nologged
25549
25550         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25551                 error "write $tfile failed"
25552         check_som_nologged
25553
25554         $TRUNCATE $DIR/$tfile 1234
25555         check_som_nologged
25556
25557         $TRUNCATE $DIR/$tfile 1048576
25558         check_som_nologged
25559
25560         # Deregistration step
25561         changelog_deregister || error "changelog_deregister failed"
25562 }
25563 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25564
25565 check_som_nodata()
25566 {
25567         $LFS getsom $1
25568         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25569 }
25570
25571 test_809() {
25572         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25573                 skip "Need MDS version at least 2.11.56"
25574
25575         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25576                 error "failed to create DoM-only file $DIR/$tfile"
25577         touch $DIR/$tfile || error "touch $tfile failed"
25578         check_som_nodata $DIR/$tfile
25579
25580         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25581                 error "write $tfile failed"
25582         check_som_nodata $DIR/$tfile
25583
25584         $TRUNCATE $DIR/$tfile 1234
25585         check_som_nodata $DIR/$tfile
25586
25587         $TRUNCATE $DIR/$tfile 4097
25588         check_som_nodata $DIR/$file
25589 }
25590 run_test 809 "Verify no SOM xattr store for DoM-only files"
25591
25592 test_810() {
25593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25594         $GSS && skip_env "could not run with gss"
25595         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25596                 skip "OST < 2.12.58 doesn't align checksum"
25597
25598         set_checksums 1
25599         stack_trap "set_checksums $ORIG_CSUM" EXIT
25600         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25601
25602         local csum
25603         local before
25604         local after
25605         for csum in $CKSUM_TYPES; do
25606                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25607                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25608                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25609                         eval set -- $i
25610                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25611                         before=$(md5sum $DIR/$tfile)
25612                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25613                         after=$(md5sum $DIR/$tfile)
25614                         [ "$before" == "$after" ] ||
25615                                 error "$csum: $before != $after bs=$1 seek=$2"
25616                 done
25617         done
25618 }
25619 run_test 810 "partial page writes on ZFS (LU-11663)"
25620
25621 test_812a() {
25622         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25623                 skip "OST < 2.12.51 doesn't support this fail_loc"
25624
25625         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25626         # ensure ost1 is connected
25627         stat $DIR/$tfile >/dev/null || error "can't stat"
25628         wait_osc_import_state client ost1 FULL
25629         # no locks, no reqs to let the connection idle
25630         cancel_lru_locks osc
25631
25632         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25633 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25634         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25635         wait_osc_import_state client ost1 CONNECTING
25636         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25637
25638         stat $DIR/$tfile >/dev/null || error "can't stat file"
25639 }
25640 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
25641
25642 test_812b() { # LU-12378
25643         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25644                 skip "OST < 2.12.51 doesn't support this fail_loc"
25645
25646         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
25647         # ensure ost1 is connected
25648         stat $DIR/$tfile >/dev/null || error "can't stat"
25649         wait_osc_import_state client ost1 FULL
25650         # no locks, no reqs to let the connection idle
25651         cancel_lru_locks osc
25652
25653         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25654 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25655         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25656         wait_osc_import_state client ost1 CONNECTING
25657         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25658
25659         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
25660         wait_osc_import_state client ost1 IDLE
25661 }
25662 run_test 812b "do not drop no resend request for idle connect"
25663
25664 test_812c() {
25665         local old
25666
25667         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
25668
25669         $LFS setstripe -c 1 -o 0 $DIR/$tfile
25670         $LFS getstripe $DIR/$tfile
25671         $LCTL set_param osc.*.idle_timeout=10
25672         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
25673         # ensure ost1 is connected
25674         stat $DIR/$tfile >/dev/null || error "can't stat"
25675         wait_osc_import_state client ost1 FULL
25676         # no locks, no reqs to let the connection idle
25677         cancel_lru_locks osc
25678
25679 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
25680         $LCTL set_param fail_loc=0x80000533
25681         sleep 15
25682         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
25683 }
25684 run_test 812c "idle import vs lock enqueue race"
25685
25686 test_813() {
25687         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
25688         [ -z "$file_heat_sav" ] && skip "no file heat support"
25689
25690         local readsample
25691         local writesample
25692         local readbyte
25693         local writebyte
25694         local readsample1
25695         local writesample1
25696         local readbyte1
25697         local writebyte1
25698
25699         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
25700         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
25701
25702         $LCTL set_param -n llite.*.file_heat=1
25703         echo "Turn on file heat"
25704         echo "Period second: $period_second, Decay percentage: $decay_pct"
25705
25706         echo "QQQQ" > $DIR/$tfile
25707         echo "QQQQ" > $DIR/$tfile
25708         echo "QQQQ" > $DIR/$tfile
25709         cat $DIR/$tfile > /dev/null
25710         cat $DIR/$tfile > /dev/null
25711         cat $DIR/$tfile > /dev/null
25712         cat $DIR/$tfile > /dev/null
25713
25714         local out=$($LFS heat_get $DIR/$tfile)
25715
25716         $LFS heat_get $DIR/$tfile
25717         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25718         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25719         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25720         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25721
25722         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
25723         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
25724         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
25725         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
25726
25727         sleep $((period_second + 3))
25728         echo "Sleep $((period_second + 3)) seconds..."
25729         # The recursion formula to calculate the heat of the file f is as
25730         # follow:
25731         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
25732         # Where Hi is the heat value in the period between time points i*I and
25733         # (i+1)*I; Ci is the access count in the period; the symbol P refers
25734         # to the weight of Ci.
25735         out=$($LFS heat_get $DIR/$tfile)
25736         $LFS heat_get $DIR/$tfile
25737         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25738         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25739         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25740         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25741
25742         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
25743                 error "read sample ($readsample) is wrong"
25744         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
25745                 error "write sample ($writesample) is wrong"
25746         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
25747                 error "read bytes ($readbyte) is wrong"
25748         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
25749                 error "write bytes ($writebyte) is wrong"
25750
25751         echo "QQQQ" > $DIR/$tfile
25752         echo "QQQQ" > $DIR/$tfile
25753         echo "QQQQ" > $DIR/$tfile
25754         cat $DIR/$tfile > /dev/null
25755         cat $DIR/$tfile > /dev/null
25756         cat $DIR/$tfile > /dev/null
25757         cat $DIR/$tfile > /dev/null
25758
25759         sleep $((period_second + 3))
25760         echo "Sleep $((period_second + 3)) seconds..."
25761
25762         out=$($LFS heat_get $DIR/$tfile)
25763         $LFS heat_get $DIR/$tfile
25764         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25765         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25766         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25767         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25768
25769         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
25770                 4 * $decay_pct) / 100") -eq 1 ] ||
25771                 error "read sample ($readsample1) is wrong"
25772         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
25773                 3 * $decay_pct) / 100") -eq 1 ] ||
25774                 error "write sample ($writesample1) is wrong"
25775         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
25776                 20 * $decay_pct) / 100") -eq 1 ] ||
25777                 error "read bytes ($readbyte1) is wrong"
25778         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
25779                 15 * $decay_pct) / 100") -eq 1 ] ||
25780                 error "write bytes ($writebyte1) is wrong"
25781
25782         echo "Turn off file heat for the file $DIR/$tfile"
25783         $LFS heat_set -o $DIR/$tfile
25784
25785         echo "QQQQ" > $DIR/$tfile
25786         echo "QQQQ" > $DIR/$tfile
25787         echo "QQQQ" > $DIR/$tfile
25788         cat $DIR/$tfile > /dev/null
25789         cat $DIR/$tfile > /dev/null
25790         cat $DIR/$tfile > /dev/null
25791         cat $DIR/$tfile > /dev/null
25792
25793         out=$($LFS heat_get $DIR/$tfile)
25794         $LFS heat_get $DIR/$tfile
25795         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25796         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25797         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25798         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25799
25800         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25801         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25802         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25803         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25804
25805         echo "Trun on file heat for the file $DIR/$tfile"
25806         $LFS heat_set -O $DIR/$tfile
25807
25808         echo "QQQQ" > $DIR/$tfile
25809         echo "QQQQ" > $DIR/$tfile
25810         echo "QQQQ" > $DIR/$tfile
25811         cat $DIR/$tfile > /dev/null
25812         cat $DIR/$tfile > /dev/null
25813         cat $DIR/$tfile > /dev/null
25814         cat $DIR/$tfile > /dev/null
25815
25816         out=$($LFS heat_get $DIR/$tfile)
25817         $LFS heat_get $DIR/$tfile
25818         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25819         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25820         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25821         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25822
25823         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
25824         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
25825         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
25826         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
25827
25828         $LFS heat_set -c $DIR/$tfile
25829         $LCTL set_param -n llite.*.file_heat=0
25830         echo "Turn off file heat support for the Lustre filesystem"
25831
25832         echo "QQQQ" > $DIR/$tfile
25833         echo "QQQQ" > $DIR/$tfile
25834         echo "QQQQ" > $DIR/$tfile
25835         cat $DIR/$tfile > /dev/null
25836         cat $DIR/$tfile > /dev/null
25837         cat $DIR/$tfile > /dev/null
25838         cat $DIR/$tfile > /dev/null
25839
25840         out=$($LFS heat_get $DIR/$tfile)
25841         $LFS heat_get $DIR/$tfile
25842         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25843         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25844         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25845         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25846
25847         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25848         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25849         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25850         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25851
25852         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
25853         rm -f $DIR/$tfile
25854 }
25855 run_test 813 "File heat verfication"
25856
25857 test_814()
25858 {
25859         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25860         echo -n y >> $DIR/$tfile
25861         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25862         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25863 }
25864 run_test 814 "sparse cp works as expected (LU-12361)"
25865
25866 test_815()
25867 {
25868         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25869         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25870 }
25871 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25872
25873 test_816() {
25874         local ost1_imp=$(get_osc_import_name client ost1)
25875         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25876                          cut -d'.' -f2)
25877
25878         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25879         # ensure ost1 is connected
25880
25881         stat $DIR/$tfile >/dev/null || error "can't stat"
25882         wait_osc_import_state client ost1 FULL
25883         # no locks, no reqs to let the connection idle
25884         cancel_lru_locks osc
25885         lru_resize_disable osc
25886         local before
25887         local now
25888         before=$($LCTL get_param -n \
25889                  ldlm.namespaces.$imp_name.lru_size)
25890
25891         wait_osc_import_state client ost1 IDLE
25892         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25893         now=$($LCTL get_param -n \
25894               ldlm.namespaces.$imp_name.lru_size)
25895         [ $before == $now ] || error "lru_size changed $before != $now"
25896 }
25897 run_test 816 "do not reset lru_resize on idle reconnect"
25898
25899 cleanup_817() {
25900         umount $tmpdir
25901         exportfs -u localhost:$DIR/nfsexp
25902         rm -rf $DIR/nfsexp
25903 }
25904
25905 test_817() {
25906         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25907
25908         mkdir -p $DIR/nfsexp
25909         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25910                 error "failed to export nfs"
25911
25912         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25913         stack_trap cleanup_817 EXIT
25914
25915         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25916                 error "failed to mount nfs to $tmpdir"
25917
25918         cp /bin/true $tmpdir
25919         $DIR/nfsexp/true || error "failed to execute 'true' command"
25920 }
25921 run_test 817 "nfsd won't cache write lock for exec file"
25922
25923 test_818() {
25924         mkdir $DIR/$tdir
25925         $LFS setstripe -c1 -i0 $DIR/$tfile
25926         $LFS setstripe -c1 -i1 $DIR/$tfile
25927         stop $SINGLEMDS
25928         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25929         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25930         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25931                 error "start $SINGLEMDS failed"
25932         rm -rf $DIR/$tdir
25933 }
25934 run_test 818 "unlink with failed llog"
25935
25936 test_819a() {
25937         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25938         cancel_lru_locks osc
25939         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25940         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25941         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25942         rm -f $TDIR/$tfile
25943 }
25944 run_test 819a "too big niobuf in read"
25945
25946 test_819b() {
25947         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25948         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25949         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25950         cancel_lru_locks osc
25951         sleep 1
25952         rm -f $TDIR/$tfile
25953 }
25954 run_test 819b "too big niobuf in write"
25955
25956
25957 function test_820_start_ost() {
25958         sleep 5
25959
25960         for num in $(seq $OSTCOUNT); do
25961                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25962         done
25963 }
25964
25965 test_820() {
25966         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25967
25968         mkdir $DIR/$tdir
25969         umount_client $MOUNT || error "umount failed"
25970         for num in $(seq $OSTCOUNT); do
25971                 stop ost$num
25972         done
25973
25974         # mount client with no active OSTs
25975         # so that the client can't initialize max LOV EA size
25976         # from OSC notifications
25977         mount_client $MOUNT || error "mount failed"
25978         # delay OST starting to keep this 0 max EA size for a while
25979         test_820_start_ost &
25980
25981         # create a directory on MDS2
25982         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25983                 error "Failed to create directory"
25984         # open intent should update default EA size
25985         # see mdc_update_max_ea_from_body()
25986         # notice this is the very first RPC to MDS2
25987         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25988         ret=$?
25989         echo $out
25990         # With SSK, this situation can lead to -EPERM being returned.
25991         # In that case, simply retry.
25992         if [ $ret -ne 0 ] && $SHARED_KEY; then
25993                 if echo "$out" | grep -q "not permitted"; then
25994                         cp /etc/services $DIR/$tdir/mds2
25995                         ret=$?
25996                 fi
25997         fi
25998         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25999 }
26000 run_test 820 "update max EA from open intent"
26001
26002 test_822() {
26003         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
26004
26005         save_lustre_params mds1 \
26006                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
26007         do_facet $SINGLEMDS "$LCTL set_param -n \
26008                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
26009         do_facet $SINGLEMDS "$LCTL set_param -n \
26010                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
26011
26012         # wait for statfs update to clear OS_STATFS_NOPRECREATE
26013         local maxage=$(do_facet mds1 $LCTL get_param -n \
26014                        osp.$FSNAME-OST0000*MDT0000.maxage)
26015         sleep $((maxage + 1))
26016
26017         #define OBD_FAIL_NET_ERROR_RPC          0x532
26018         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26019
26020         stack_trap "restore_lustre_params < $p; rm $p"
26021
26022         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26023                       osp.$FSNAME-OST0000*MDT0000.create_count")
26024         for i in $(seq 1 $count); do
26025                 touch $DIR/$tfile.${i} || error "touch failed"
26026         done
26027 }
26028 run_test 822 "test precreate failure"
26029
26030 #
26031 # tests that do cleanup/setup should be run at the end
26032 #
26033
26034 test_900() {
26035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26036         local ls
26037
26038         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26039         $LCTL set_param fail_loc=0x903
26040
26041         cancel_lru_locks MGC
26042
26043         FAIL_ON_ERROR=true cleanup
26044         FAIL_ON_ERROR=true setup
26045 }
26046 run_test 900 "umount should not race with any mgc requeue thread"
26047
26048 # LUS-6253/LU-11185
26049 test_901() {
26050         local oldc
26051         local newc
26052         local olds
26053         local news
26054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26055
26056         # some get_param have a bug to handle dot in param name
26057         cancel_lru_locks MGC
26058         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26059         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26060         umount_client $MOUNT || error "umount failed"
26061         mount_client $MOUNT || error "mount failed"
26062         cancel_lru_locks MGC
26063         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26064         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26065
26066         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26067         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26068
26069         return 0
26070 }
26071 run_test 901 "don't leak a mgc lock on client umount"
26072
26073 # LU-13377
26074 test_902() {
26075         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26076                 skip "client does not have LU-13377 fix"
26077         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26078         $LCTL set_param fail_loc=0x1415
26079         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26080         cancel_lru_locks osc
26081         rm -f $DIR/$tfile
26082 }
26083 run_test 902 "test short write doesn't hang lustre"
26084
26085 complete $SECONDS
26086 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26087 check_and_cleanup_lustre
26088 if [ "$I_MOUNTED" != "yes" ]; then
26089         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26090 fi
26091 exit_status