Whamcloud - gitweb
d49d2441335f9159eb325d747143d3ef0f9e0aad
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5          12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 # Get the SLES distro version
96 #
97 # Returns a version string that should only be used in comparing
98 # strings returned by version_code()
99 sles_version_code()
100 {
101         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
102
103         # All SuSE Linux versions have one decimal. version_code expects two
104         local sles_version=$version.0
105         version_code $sles_version
106 }
107
108 # Check if we are running on Ubuntu or SLES so we can make decisions on
109 # what tests to run
110 if [ -r /etc/SuSE-release ]; then
111         sles_version=$(sles_version_code)
112         [ $sles_version -lt $(version_code 11.4.0) ] &&
113                 # bug number for skipped test: LU-4341
114                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
115         [ $sles_version -lt $(version_code 12.0.0) ] &&
116                 # bug number for skipped test: LU-3703
117                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
118 elif [ -r /etc/os-release ]; then
119         if grep -qi ubuntu /etc/os-release; then
120                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
121                                                 -e 's/^VERSION=//p' \
122                                                 /etc/os-release |
123                                                 awk '{ print $1 }'))
124
125                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
126                         # bug number for skipped test:
127                         #                LU-10334 LU-10366
128                         ALWAYS_EXCEPT+=" 103a     410"
129                 fi
130         fi
131 fi
132
133 build_test_filter
134 FAIL_ON_ERROR=false
135
136 cleanup() {
137         echo -n "cln.."
138         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
139         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
140 }
141 setup() {
142         echo -n "mnt.."
143         load_modules
144         setupall || exit 10
145         echo "done"
146 }
147
148 check_swap_layouts_support()
149 {
150         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
151                 skip "Does not support layout lock."
152 }
153
154 check_swap_layout_no_dom()
155 {
156         local FOLDER=$1
157         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
158         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
159 }
160
161 check_and_setup_lustre
162 DIR=${DIR:-$MOUNT}
163 assert_DIR
164
165 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
166
167 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
168 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
169 rm -rf $DIR/[Rdfs][0-9]*
170
171 # $RUNAS_ID may get set incorrectly somewhere else
172 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
173         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
174
175 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
176
177 if [ "${ONLY}" = "MOUNT" ] ; then
178         echo "Lustre is up, please go on"
179         exit
180 fi
181
182 echo "preparing for tests involving mounts"
183 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
184 touch $EXT2_DEV
185 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
186 echo # add a newline after mke2fs.
187
188 umask 077
189
190 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
191 lctl set_param debug=-1 2> /dev/null || true
192 test_0a() {
193         touch $DIR/$tfile
194         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
195         rm $DIR/$tfile
196         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
197 }
198 run_test 0a "touch; rm ====================="
199
200 test_0b() {
201         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
202         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
203 }
204 run_test 0b "chmod 0755 $DIR ============================="
205
206 test_0c() {
207         $LCTL get_param mdc.*.import | grep "state: FULL" ||
208                 error "import not FULL"
209         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
210                 error "bad target"
211 }
212 run_test 0c "check import proc"
213
214 test_0d() { # LU-3397
215         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
216                 skip "proc exports not supported before 2.10.57"
217
218         local mgs_exp="mgs.MGS.exports"
219         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
220         local exp_client_nid
221         local exp_client_version
222         local exp_val
223         local imp_val
224         local temp_imp=$DIR/$tfile.import
225         local temp_exp=$DIR/$tfile.export
226
227         # save mgc import file to $temp_imp
228         $LCTL get_param mgc.*.import | tee $temp_imp
229         # Check if client uuid is found in MGS export
230         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
231                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
232                         $client_uuid ] &&
233                         break;
234         done
235         # save mgs export file to $temp_exp
236         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
237
238         # Compare the value of field "connect_flags"
239         imp_val=$(grep "connect_flags" $temp_imp)
240         exp_val=$(grep "connect_flags" $temp_exp)
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export flags '$exp_val' != import flags '$imp_val'"
243
244         # Compare client versions.  Only compare top-3 fields for compatibility
245         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
246         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
247         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
248         [ "$exp_val" == "$imp_val" ] ||
249                 error "exp version '$exp_client_version'($exp_val) != " \
250                         "'$(lustre_build_version client)'($imp_val)"
251 }
252 run_test 0d "check export proc ============================="
253
254 test_1() {
255         test_mkdir $DIR/$tdir
256         test_mkdir $DIR/$tdir/d2
257         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
258         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
259         rmdir $DIR/$tdir/d2
260         rmdir $DIR/$tdir
261         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
262 }
263 run_test 1 "mkdir; remkdir; rmdir"
264
265 test_2() {
266         test_mkdir $DIR/$tdir
267         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
268         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
269         rm -r $DIR/$tdir
270         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
271 }
272 run_test 2 "mkdir; touch; rmdir; check file"
273
274 test_3() {
275         test_mkdir $DIR/$tdir
276         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
277         touch $DIR/$tdir/$tfile
278         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
279         rm -r $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
281 }
282 run_test 3 "mkdir; touch; rmdir; check dir"
283
284 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
285 test_4() {
286         test_mkdir -i 1 $DIR/$tdir
287
288         touch $DIR/$tdir/$tfile ||
289                 error "Create file under remote directory failed"
290
291         rmdir $DIR/$tdir &&
292                 error "Expect error removing in-use dir $DIR/$tdir"
293
294         test -d $DIR/$tdir || error "Remote directory disappeared"
295
296         rm -rf $DIR/$tdir || error "remove remote dir error"
297 }
298 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
299
300 test_5() {
301         test_mkdir $DIR/$tdir
302         test_mkdir $DIR/$tdir/d2
303         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
304         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
305         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
306 }
307 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
308
309 test_6a() {
310         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
311         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
312         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
313                 error "$tfile does not have perm 0666 or UID $UID"
314         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
315         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
316                 error "$tfile should be 0666 and owned by UID $UID"
317 }
318 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
319
320 test_6c() {
321         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
322
323         touch $DIR/$tfile
324         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
325         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $RUNAS_ID"
327         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
328         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
329                 error "$tfile should be owned by UID $RUNAS_ID"
330 }
331 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
332
333 test_6e() {
334         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
335
336         touch $DIR/$tfile
337         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
338         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
339                 error "$tfile should be owned by GID $UID"
340         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
341         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
342                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
343 }
344 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
345
346 test_6g() {
347         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
348
349         test_mkdir $DIR/$tdir
350         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
351         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
352         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
353         test_mkdir $DIR/$tdir/d/subdir
354         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
355                 error "$tdir/d/subdir should be GID $RUNAS_GID"
356         if [[ $MDSCOUNT -gt 1 ]]; then
357                 # check remote dir sgid inherite
358                 $LFS mkdir -i 0 $DIR/$tdir.local ||
359                         error "mkdir $tdir.local failed"
360                 chmod g+s $DIR/$tdir.local ||
361                         error "chmod $tdir.local failed"
362                 chgrp $RUNAS_GID $DIR/$tdir.local ||
363                         error "chgrp $tdir.local failed"
364                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
365                         error "mkdir $tdir.remote failed"
366                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
367                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
368                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
369                         error "$tdir.remote should be mode 02755"
370         fi
371 }
372 run_test 6g "verify new dir in sgid dir inherits group"
373
374 test_6h() { # bug 7331
375         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
376
377         touch $DIR/$tfile || error "touch failed"
378         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
379         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
380                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
381         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
382                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
383 }
384 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
385
386 test_7a() {
387         test_mkdir $DIR/$tdir
388         $MCREATE $DIR/$tdir/$tfile
389         chmod 0666 $DIR/$tdir/$tfile
390         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
391                 error "$tdir/$tfile should be mode 0666"
392 }
393 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
394
395 test_7b() {
396         if [ ! -d $DIR/$tdir ]; then
397                 test_mkdir $DIR/$tdir
398         fi
399         $MCREATE $DIR/$tdir/$tfile
400         echo -n foo > $DIR/$tdir/$tfile
401         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
402         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
403 }
404 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
405
406 test_8() {
407         test_mkdir $DIR/$tdir
408         touch $DIR/$tdir/$tfile
409         chmod 0666 $DIR/$tdir/$tfile
410         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
411                 error "$tfile mode not 0666"
412 }
413 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
414
415 test_9() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         test_mkdir $DIR/$tdir/d2/d3
419         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
420 }
421 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
422
423 test_10() {
424         test_mkdir $DIR/$tdir
425         test_mkdir $DIR/$tdir/d2
426         touch $DIR/$tdir/d2/$tfile
427         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
428                 error "$tdir/d2/$tfile not a file"
429 }
430 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
431
432 test_11() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         chmod 0666 $DIR/$tdir/d2
436         chmod 0705 $DIR/$tdir/d2
437         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
438                 error "$tdir/d2 mode not 0705"
439 }
440 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
441
442 test_12() {
443         test_mkdir $DIR/$tdir
444         touch $DIR/$tdir/$tfile
445         chmod 0666 $DIR/$tdir/$tfile
446         chmod 0654 $DIR/$tdir/$tfile
447         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
448                 error "$tdir/d2 mode not 0654"
449 }
450 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
451
452 test_13() {
453         test_mkdir $DIR/$tdir
454         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
455         >  $DIR/$tdir/$tfile
456         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
457                 error "$tdir/$tfile size not 0 after truncate"
458 }
459 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
460
461 test_14() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         rm $DIR/$tdir/$tfile
465         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
466 }
467 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
468
469 test_15() {
470         test_mkdir $DIR/$tdir
471         touch $DIR/$tdir/$tfile
472         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
473         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
474                 error "$tdir/${tfile_2} not a file after rename"
475         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
476 }
477 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
478
479 test_16() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         rm -rf $DIR/$tdir/$tfile
483         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
484 }
485 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
486
487 test_17a() {
488         test_mkdir $DIR/$tdir
489         touch $DIR/$tdir/$tfile
490         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
491         ls -l $DIR/$tdir
492         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
493                 error "$tdir/l-exist not a symlink"
494         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
495                 error "$tdir/l-exist not referencing a file"
496         rm -f $DIR/$tdir/l-exist
497         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
498 }
499 run_test 17a "symlinks: create, remove (real)"
500
501 test_17b() {
502         test_mkdir $DIR/$tdir
503         ln -s no-such-file $DIR/$tdir/l-dangle
504         ls -l $DIR/$tdir
505         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
506                 error "$tdir/l-dangle not referencing no-such-file"
507         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
508                 error "$tdir/l-dangle not referencing non-existent file"
509         rm -f $DIR/$tdir/l-dangle
510         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
511 }
512 run_test 17b "symlinks: create, remove (dangling)"
513
514 test_17c() { # bug 3440 - don't save failed open RPC for replay
515         test_mkdir $DIR/$tdir
516         ln -s foo $DIR/$tdir/$tfile
517         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
518 }
519 run_test 17c "symlinks: open dangling (should return error)"
520
521 test_17d() {
522         test_mkdir $DIR/$tdir
523         ln -s foo $DIR/$tdir/$tfile
524         touch $DIR/$tdir/$tfile || error "creating to new symlink"
525 }
526 run_test 17d "symlinks: create dangling"
527
528 test_17e() {
529         test_mkdir $DIR/$tdir
530         local foo=$DIR/$tdir/$tfile
531         ln -s $foo $foo || error "create symlink failed"
532         ls -l $foo || error "ls -l failed"
533         ls $foo && error "ls not failed" || true
534 }
535 run_test 17e "symlinks: create recursive symlink (should return error)"
536
537 test_17f() {
538         test_mkdir $DIR/$tdir
539         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
540         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
541         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
542         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
543         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
544         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
545         ls -l  $DIR/$tdir
546 }
547 run_test 17f "symlinks: long and very long symlink name"
548
549 # str_repeat(S, N) generate a string that is string S repeated N times
550 str_repeat() {
551         local s=$1
552         local n=$2
553         local ret=''
554         while [ $((n -= 1)) -ge 0 ]; do
555                 ret=$ret$s
556         done
557         echo $ret
558 }
559
560 # Long symlinks and LU-2241
561 test_17g() {
562         test_mkdir $DIR/$tdir
563         local TESTS="59 60 61 4094 4095"
564
565         # Fix for inode size boundary in 2.1.4
566         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
567                 TESTS="4094 4095"
568
569         # Patch not applied to 2.2 or 2.3 branches
570         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
571         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
572                 TESTS="4094 4095"
573
574         for i in $TESTS; do
575                 local SYMNAME=$(str_repeat 'x' $i)
576                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
577                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
578         done
579 }
580 run_test 17g "symlinks: really long symlink name and inode boundaries"
581
582 test_17h() { #bug 17378
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local mdt_idx
587
588         test_mkdir $DIR/$tdir
589         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
590         $LFS setstripe -c -1 $DIR/$tdir
591         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
592         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
593         touch $DIR/$tdir/$tfile || true
594 }
595 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
596
597 test_17i() { #bug 20018
598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
599         remote_mds_nodsh && skip "remote MDS with nodsh"
600
601         local foo=$DIR/$tdir/$tfile
602         local mdt_idx
603
604         test_mkdir -c1 $DIR/$tdir
605         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
606         ln -s $foo $foo || error "create symlink failed"
607 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
608         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
609         ls -l $foo && error "error not detected"
610         return 0
611 }
612 run_test 17i "don't panic on short symlink (should return error)"
613
614 test_17k() { #bug 22301
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         [[ -z "$(which rsync 2>/dev/null)" ]] &&
617                 skip "no rsync command"
618         rsync --help | grep -q xattr ||
619                 skip_env "$(rsync --version | head -n1) does not support xattrs"
620         test_mkdir $DIR/$tdir
621         test_mkdir $DIR/$tdir.new
622         touch $DIR/$tdir/$tfile
623         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
624         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
625                 error "rsync failed with xattrs enabled"
626 }
627 run_test 17k "symlinks: rsync with xattrs enabled"
628
629 test_17l() { # LU-279
630         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
631                 skip "no getfattr command"
632
633         test_mkdir $DIR/$tdir
634         touch $DIR/$tdir/$tfile
635         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
636         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
637                 # -h to not follow symlinks. -m '' to list all the xattrs.
638                 # grep to remove first line: '# file: $path'.
639                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
640                 do
641                         lgetxattr_size_check $path $xattr ||
642                                 error "lgetxattr_size_check $path $xattr failed"
643                 done
644         done
645 }
646 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
647
648 # LU-1540
649 test_17m() {
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
652         remote_mds_nodsh && skip "remote MDS with nodsh"
653         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
654         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
655                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
656
657         local short_sym="0123456789"
658         local wdir=$DIR/$tdir
659         local i
660
661         test_mkdir $wdir
662         long_sym=$short_sym
663         # create a long symlink file
664         for ((i = 0; i < 4; ++i)); do
665                 long_sym=${long_sym}${long_sym}
666         done
667
668         echo "create 512 short and long symlink files under $wdir"
669         for ((i = 0; i < 256; ++i)); do
670                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
671                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
672         done
673
674         echo "erase them"
675         rm -f $wdir/*
676         sync
677         wait_delete_completed
678
679         echo "recreate the 512 symlink files with a shorter string"
680         for ((i = 0; i < 512; ++i)); do
681                 # rewrite the symlink file with a shorter string
682                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
683                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
684         done
685
686         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
687         local devname=$(mdsdevname $mds_index)
688
689         echo "stop and checking mds${mds_index}:"
690         # e2fsck should not return error
691         stop mds${mds_index}
692         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
693         rc=$?
694
695         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
696                 error "start mds${mds_index} failed"
697         df $MOUNT > /dev/null 2>&1
698         [ $rc -eq 0 ] ||
699                 error "e2fsck detected error for short/long symlink: rc=$rc"
700         rm -f $wdir/*
701 }
702 run_test 17m "run e2fsck against MDT which contains short/long symlink"
703
704 check_fs_consistency_17n() {
705         local mdt_index
706         local rc=0
707
708         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
709         # so it only check MDT1/MDT2 instead of all of MDTs.
710         for mdt_index in 1 2; do
711                 local devname=$(mdsdevname $mdt_index)
712                 # e2fsck should not return error
713                 stop mds${mdt_index}
714                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
715                         rc=$((rc + $?))
716
717                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
718                         error "mount mds$mdt_index failed"
719                 df $MOUNT > /dev/null 2>&1
720         done
721         return $rc
722 }
723
724 test_17n() {
725         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
727         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
728         remote_mds_nodsh && skip "remote MDS with nodsh"
729         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
730         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
731                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
732
733         local i
734
735         test_mkdir $DIR/$tdir
736         for ((i=0; i<10; i++)); do
737                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
738                         error "create remote dir error $i"
739                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
740                         error "create files under remote dir failed $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after create files under remote dir"
745
746         for ((i = 0; i < 10; i++)); do
747                 rm -rf $DIR/$tdir/remote_dir_${i} ||
748                         error "destroy remote dir error $i"
749         done
750
751         check_fs_consistency_17n ||
752                 error "e2fsck report error after unlink files under remote dir"
753
754         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
755                 skip "lustre < 2.4.50 does not support migrate mv"
756
757         for ((i = 0; i < 10; i++)); do
758                 mkdir -p $DIR/$tdir/remote_dir_${i}
759                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
760                         error "create files under remote dir failed $i"
761                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
762                         error "migrate remote dir error $i"
763         done
764         check_fs_consistency_17n || error "e2fsck report error after migration"
765
766         for ((i = 0; i < 10; i++)); do
767                 rm -rf $DIR/$tdir/remote_dir_${i} ||
768                         error "destroy remote dir error $i"
769         done
770
771         check_fs_consistency_17n || error "e2fsck report error after unlink"
772 }
773 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
774
775 test_17o() {
776         remote_mds_nodsh && skip "remote MDS with nodsh"
777         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
778                 skip "Need MDS version at least 2.3.64"
779
780         local wdir=$DIR/${tdir}o
781         local mdt_index
782         local rc=0
783
784         test_mkdir $wdir
785         touch $wdir/$tfile
786         mdt_index=$($LFS getstripe -m $wdir/$tfile)
787         mdt_index=$((mdt_index + 1))
788
789         cancel_lru_locks mdc
790         #fail mds will wait the failover finish then set
791         #following fail_loc to avoid interfer the recovery process.
792         fail mds${mdt_index}
793
794         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
795         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
796         ls -l $wdir/$tfile && rc=1
797         do_facet mds${mdt_index} lctl set_param fail_loc=0
798         [[ $rc -eq 0 ]] || error "stat file should fail"
799 }
800 run_test 17o "stat file with incompat LMA feature"
801
802 test_18() {
803         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
804         ls $DIR || error "Failed to ls $DIR: $?"
805 }
806 run_test 18 "touch .../f ; ls ... =============================="
807
808 test_19a() {
809         touch $DIR/$tfile
810         ls -l $DIR
811         rm $DIR/$tfile
812         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
813 }
814 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
815
816 test_19b() {
817         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
818 }
819 run_test 19b "ls -l .../f19 (should return error) =============="
820
821 test_19c() {
822         [ $RUNAS_ID -eq $UID ] &&
823                 skip_env "RUNAS_ID = UID = $UID -- skipping"
824
825         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
826 }
827 run_test 19c "$RUNAS touch .../f19 (should return error) =="
828
829 test_19d() {
830         cat $DIR/f19 && error || true
831 }
832 run_test 19d "cat .../f19 (should return error) =============="
833
834 test_20() {
835         touch $DIR/$tfile
836         rm $DIR/$tfile
837         touch $DIR/$tfile
838         rm $DIR/$tfile
839         touch $DIR/$tfile
840         rm $DIR/$tfile
841         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
842 }
843 run_test 20 "touch .../f ; ls -l ..."
844
845 test_21() {
846         test_mkdir $DIR/$tdir
847         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
848         ln -s dangle $DIR/$tdir/link
849         echo foo >> $DIR/$tdir/link
850         cat $DIR/$tdir/dangle
851         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
852         $CHECKSTAT -f -t file $DIR/$tdir/link ||
853                 error "$tdir/link not linked to a file"
854 }
855 run_test 21 "write to dangling link"
856
857 test_22() {
858         local wdir=$DIR/$tdir
859         test_mkdir $wdir
860         chown $RUNAS_ID:$RUNAS_GID $wdir
861         (cd $wdir || error "cd $wdir failed";
862                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
863                 $RUNAS tar xf -)
864         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
865         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
866         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
867                 error "checkstat -u failed"
868 }
869 run_test 22 "unpack tar archive as non-root user"
870
871 # was test_23
872 test_23a() {
873         test_mkdir $DIR/$tdir
874         local file=$DIR/$tdir/$tfile
875
876         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
877         openfile -f O_CREAT:O_EXCL $file &&
878                 error "$file recreate succeeded" || true
879 }
880 run_test 23a "O_CREAT|O_EXCL in subdir"
881
882 test_23b() { # bug 18988
883         test_mkdir $DIR/$tdir
884         local file=$DIR/$tdir/$tfile
885
886         rm -f $file
887         echo foo > $file || error "write filed"
888         echo bar >> $file || error "append filed"
889         $CHECKSTAT -s 8 $file || error "wrong size"
890         rm $file
891 }
892 run_test 23b "O_APPEND check"
893
894 # LU-9409, size with O_APPEND and tiny writes
895 test_23c() {
896         local file=$DIR/$tfile
897
898         # single dd
899         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
900         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
901         rm -f $file
902
903         # racing tiny writes
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
905         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
906         wait
907         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
908         rm -f $file
909
910         #racing tiny & normal writes
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
912         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
913         wait
914         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
915         rm -f $file
916
917         #racing tiny & normal writes 2, ugly numbers
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
920         wait
921         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
922         rm -f $file
923 }
924 run_test 23c "O_APPEND size checks for tiny writes"
925
926 # LU-11069 file offset is correct after appending writes
927 test_23d() {
928         local file=$DIR/$tfile
929         local offset
930
931         echo CentaurHauls > $file
932         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
933         if ((offset != 26)); then
934                 error "wrong offset, expected 26, got '$offset'"
935         fi
936 }
937 run_test 23d "file offset is correct after appending writes"
938
939 # rename sanity
940 test_24a() {
941         echo '-- same directory rename'
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.1
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
946 }
947 run_test 24a "rename file to non-existent target"
948
949 test_24b() {
950         test_mkdir $DIR/$tdir
951         touch $DIR/$tdir/$tfile.{1,2}
952         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
953         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
954         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
955 }
956 run_test 24b "rename file to existing target"
957
958 test_24c() {
959         test_mkdir $DIR/$tdir
960         test_mkdir $DIR/$tdir/d$testnum.1
961         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
962         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
963         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
964 }
965 run_test 24c "rename directory to non-existent target"
966
967 test_24d() {
968         test_mkdir -c1 $DIR/$tdir
969         test_mkdir -c1 $DIR/$tdir/d$testnum.1
970         test_mkdir -c1 $DIR/$tdir/d$testnum.2
971         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
972         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
973         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
974 }
975 run_test 24d "rename directory to existing target"
976
977 test_24e() {
978         echo '-- cross directory renames --'
979         test_mkdir $DIR/R5a
980         test_mkdir $DIR/R5b
981         touch $DIR/R5a/f
982         mv $DIR/R5a/f $DIR/R5b/g
983         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
984         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
985 }
986 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
987
988 test_24f() {
989         test_mkdir $DIR/R6a
990         test_mkdir $DIR/R6b
991         touch $DIR/R6a/f $DIR/R6b/g
992         mv $DIR/R6a/f $DIR/R6b/g
993         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
994         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
995 }
996 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
997
998 test_24g() {
999         test_mkdir $DIR/R7a
1000         test_mkdir $DIR/R7b
1001         test_mkdir $DIR/R7a/d
1002         mv $DIR/R7a/d $DIR/R7b/e
1003         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1004         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1005 }
1006 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1007
1008 test_24h() {
1009         test_mkdir -c1 $DIR/R8a
1010         test_mkdir -c1 $DIR/R8b
1011         test_mkdir -c1 $DIR/R8a/d
1012         test_mkdir -c1 $DIR/R8b/e
1013         mrename $DIR/R8a/d $DIR/R8b/e
1014         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1015         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1016 }
1017 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1018
1019 test_24i() {
1020         echo "-- rename error cases"
1021         test_mkdir $DIR/R9
1022         test_mkdir $DIR/R9/a
1023         touch $DIR/R9/f
1024         mrename $DIR/R9/f $DIR/R9/a
1025         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1026         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1027         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1028 }
1029 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1030
1031 test_24j() {
1032         test_mkdir $DIR/R10
1033         mrename $DIR/R10/f $DIR/R10/g
1034         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1035         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1036         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1037 }
1038 run_test 24j "source does not exist ============================"
1039
1040 test_24k() {
1041         test_mkdir $DIR/R11a
1042         test_mkdir $DIR/R11a/d
1043         touch $DIR/R11a/f
1044         mv $DIR/R11a/f $DIR/R11a/d
1045         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1046         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1047 }
1048 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1049
1050 # bug 2429 - rename foo foo foo creates invalid file
1051 test_24l() {
1052         f="$DIR/f24l"
1053         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1054 }
1055 run_test 24l "Renaming a file to itself ========================"
1056
1057 test_24m() {
1058         f="$DIR/f24m"
1059         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1060         # on ext3 this does not remove either the source or target files
1061         # though the "expected" operation would be to remove the source
1062         $CHECKSTAT -t file ${f} || error "${f} missing"
1063         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1064 }
1065 run_test 24m "Renaming a file to a hard link to itself ========="
1066
1067 test_24n() {
1068     f="$DIR/f24n"
1069     # this stats the old file after it was renamed, so it should fail
1070     touch ${f}
1071     $CHECKSTAT ${f} || error "${f} missing"
1072     mv ${f} ${f}.rename
1073     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1074     $CHECKSTAT -a ${f} || error "${f} exists"
1075 }
1076 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1077
1078 test_24o() {
1079         test_mkdir $DIR/$tdir
1080         rename_many -s random -v -n 10 $DIR/$tdir
1081 }
1082 run_test 24o "rename of files during htree split"
1083
1084 test_24p() {
1085         test_mkdir $DIR/R12a
1086         test_mkdir $DIR/R12b
1087         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1088         mrename $DIR/R12a $DIR/R12b
1089         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1090         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1091         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1092         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1093 }
1094 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1095
1096 cleanup_multiop_pause() {
1097         trap 0
1098         kill -USR1 $MULTIPID
1099 }
1100
1101 test_24q() {
1102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1103
1104         test_mkdir $DIR/R13a
1105         test_mkdir $DIR/R13b
1106         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1107         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1108         MULTIPID=$!
1109
1110         trap cleanup_multiop_pause EXIT
1111         mrename $DIR/R13a $DIR/R13b
1112         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1113         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1114         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1115         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1116         cleanup_multiop_pause
1117         wait $MULTIPID || error "multiop close failed"
1118 }
1119 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1120
1121 test_24r() { #bug 3789
1122         test_mkdir $DIR/R14a
1123         test_mkdir $DIR/R14a/b
1124         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1125         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1126         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1127 }
1128 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1129
1130 test_24s() {
1131         test_mkdir $DIR/R15a
1132         test_mkdir $DIR/R15a/b
1133         test_mkdir $DIR/R15a/b/c
1134         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1135         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1136         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1137 }
1138 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1139 test_24t() {
1140         test_mkdir $DIR/R16a
1141         test_mkdir $DIR/R16a/b
1142         test_mkdir $DIR/R16a/b/c
1143         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1145         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1146 }
1147 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1148
1149 test_24u() { # bug12192
1150         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1151         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1152 }
1153 run_test 24u "create stripe file"
1154
1155 simple_cleanup_common() {
1156         local rc=0
1157         trap 0
1158         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1159
1160         local start=$SECONDS
1161         rm -rf $DIR/$tdir
1162         rc=$?
1163         wait_delete_completed
1164         echo "cleanup time $((SECONDS - start))"
1165         return $rc
1166 }
1167
1168 max_pages_per_rpc() {
1169         local mdtname="$(printf "MDT%04x" ${1:-0})"
1170         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1171 }
1172
1173 test_24v() {
1174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1175
1176         local nrfiles=${COUNT:-100000}
1177         local fname="$DIR/$tdir/$tfile"
1178
1179         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1180         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1181
1182         test_mkdir "$(dirname $fname)"
1183         # assume MDT0000 has the fewest inodes
1184         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1185         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1186         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1187
1188         trap simple_cleanup_common EXIT
1189
1190         createmany -m "$fname" $nrfiles
1191
1192         cancel_lru_locks mdc
1193         lctl set_param mdc.*.stats clear
1194
1195         # was previously test_24D: LU-6101
1196         # readdir() returns correct number of entries after cursor reload
1197         local num_ls=$(ls $DIR/$tdir | wc -l)
1198         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1199         local num_all=$(ls -a $DIR/$tdir | wc -l)
1200         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1201                 [ $num_all -ne $((nrfiles + 2)) ]; then
1202                         error "Expected $nrfiles files, got $num_ls " \
1203                                 "($num_uniq unique $num_all .&..)"
1204         fi
1205         # LU-5 large readdir
1206         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1207         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1208         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1209         # take into account of overhead in lu_dirpage header and end mark in
1210         # each page, plus one in rpc_num calculation.
1211         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1212         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1213         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1214         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1215         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1216         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1217         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1218         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1219                 error "large readdir doesn't take effect: " \
1220                       "$mds_readpage should be about $rpc_max"
1221
1222         simple_cleanup_common
1223 }
1224 run_test 24v "list large directory (test hash collision, b=17560)"
1225
1226 test_24w() { # bug21506
1227         SZ1=234852
1228         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1229         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1230         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1231         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1232         [[ "$SZ1" -eq "$SZ2" ]] ||
1233                 error "Error reading at the end of the file $tfile"
1234 }
1235 run_test 24w "Reading a file larger than 4Gb"
1236
1237 test_24x() {
1238         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1240         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1241                 skip "Need MDS version at least 2.7.56"
1242
1243         local MDTIDX=1
1244         local remote_dir=$DIR/$tdir/remote_dir
1245
1246         test_mkdir $DIR/$tdir
1247         $LFS mkdir -i $MDTIDX $remote_dir ||
1248                 error "create remote directory failed"
1249
1250         test_mkdir $DIR/$tdir/src_dir
1251         touch $DIR/$tdir/src_file
1252         test_mkdir $remote_dir/tgt_dir
1253         touch $remote_dir/tgt_file
1254
1255         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1256                 error "rename dir cross MDT failed!"
1257
1258         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1259                 error "rename file cross MDT failed!"
1260
1261         touch $DIR/$tdir/ln_file
1262         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1263                 error "ln file cross MDT failed"
1264
1265         rm -rf $DIR/$tdir || error "Can not delete directories"
1266 }
1267 run_test 24x "cross MDT rename/link"
1268
1269 test_24y() {
1270         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1272
1273         local remote_dir=$DIR/$tdir/remote_dir
1274         local mdtidx=1
1275
1276         test_mkdir $DIR/$tdir
1277         $LFS mkdir -i $mdtidx $remote_dir ||
1278                 error "create remote directory failed"
1279
1280         test_mkdir $remote_dir/src_dir
1281         touch $remote_dir/src_file
1282         test_mkdir $remote_dir/tgt_dir
1283         touch $remote_dir/tgt_file
1284
1285         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1286                 error "rename subdir in the same remote dir failed!"
1287
1288         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1289                 error "rename files in the same remote dir failed!"
1290
1291         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1292                 error "link files in the same remote dir failed!"
1293
1294         rm -rf $DIR/$tdir || error "Can not delete directories"
1295 }
1296 run_test 24y "rename/link on the same dir should succeed"
1297
1298 test_24z() {
1299         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1300         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1301                 skip "Need MDS version at least 2.12.51"
1302
1303         local index
1304
1305         for index in 0 1; do
1306                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1307                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1308         done
1309
1310         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1313         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1314
1315         local mdts=$(comma_list $(mdts_nodes))
1316
1317         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1318         stack_trap "do_nodes $mdts $LCTL \
1319                 set_param mdt.*.enable_remote_rename=1" EXIT
1320
1321         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1322
1323         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1324         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1325 }
1326 run_test 24z "cross-MDT rename is done as cp"
1327
1328 test_24A() { # LU-3182
1329         local NFILES=5000
1330
1331         rm -rf $DIR/$tdir
1332         test_mkdir $DIR/$tdir
1333         trap simple_cleanup_common EXIT
1334         createmany -m $DIR/$tdir/$tfile $NFILES
1335         local t=$(ls $DIR/$tdir | wc -l)
1336         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1337         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1338         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1339            [ $v -ne $((NFILES + 2)) ] ; then
1340                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1341         fi
1342
1343         simple_cleanup_common || error "Can not delete directories"
1344 }
1345 run_test 24A "readdir() returns correct number of entries."
1346
1347 test_24B() { # LU-4805
1348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1349
1350         local count
1351
1352         test_mkdir $DIR/$tdir
1353         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1354                 error "create striped dir failed"
1355
1356         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1357         [ $count -eq 2 ] || error "Expected 2, got $count"
1358
1359         touch $DIR/$tdir/striped_dir/a
1360
1361         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1362         [ $count -eq 3 ] || error "Expected 3, got $count"
1363
1364         touch $DIR/$tdir/striped_dir/.f
1365
1366         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1367         [ $count -eq 4 ] || error "Expected 4, got $count"
1368
1369         rm -rf $DIR/$tdir || error "Can not delete directories"
1370 }
1371 run_test 24B "readdir for striped dir return correct number of entries"
1372
1373 test_24C() {
1374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1375
1376         mkdir $DIR/$tdir
1377         mkdir $DIR/$tdir/d0
1378         mkdir $DIR/$tdir/d1
1379
1380         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1381                 error "create striped dir failed"
1382
1383         cd $DIR/$tdir/d0/striped_dir
1384
1385         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1386         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1387         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d0_ino" = "$parent_ino" ] ||
1390                 error ".. wrong, expect $d0_ino, get $parent_ino"
1391
1392         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1393                 error "mv striped dir failed"
1394
1395         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1396
1397         [ "$d1_ino" = "$parent_ino" ] ||
1398                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1399 }
1400 run_test 24C "check .. in striped dir"
1401
1402 test_24E() {
1403         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1405
1406         mkdir -p $DIR/$tdir
1407         mkdir $DIR/$tdir/src_dir
1408         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1409                 error "create remote source failed"
1410
1411         touch $DIR/$tdir/src_dir/src_child/a
1412
1413         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1414                 error "create remote target dir failed"
1415
1416         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1417                 error "create remote target child failed"
1418
1419         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1420                 error "rename dir cross MDT failed!"
1421
1422         find $DIR/$tdir
1423
1424         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1425                 error "src_child still exists after rename"
1426
1427         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1428                 error "missing file(a) after rename"
1429
1430         rm -rf $DIR/$tdir || error "Can not delete directories"
1431 }
1432 run_test 24E "cross MDT rename/link"
1433
1434 test_24F () {
1435         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1436
1437         local repeats=1000
1438         [ "$SLOW" = "no" ] && repeats=100
1439
1440         mkdir -p $DIR/$tdir
1441
1442         echo "$repeats repeats"
1443         for ((i = 0; i < repeats; i++)); do
1444                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1445                 touch $DIR/$tdir/test/a || error "touch fails"
1446                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1447                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1448         done
1449
1450         true
1451 }
1452 run_test 24F "hash order vs readdir (LU-11330)"
1453
1454 test_24G () {
1455         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1456
1457         local ino1
1458         local ino2
1459
1460         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1461         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1462         touch $DIR/$tdir-0/f1 || error "touch f1"
1463         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1464         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1465         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1466         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1467         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1468 }
1469 run_test 24G "migrate symlink in rename"
1470
1471 test_25a() {
1472         echo '== symlink sanity ============================================='
1473
1474         test_mkdir $DIR/d25
1475         ln -s d25 $DIR/s25
1476         touch $DIR/s25/foo ||
1477                 error "File creation in symlinked directory failed"
1478 }
1479 run_test 25a "create file in symlinked directory ==============="
1480
1481 test_25b() {
1482         [ ! -d $DIR/d25 ] && test_25a
1483         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1484 }
1485 run_test 25b "lookup file in symlinked directory ==============="
1486
1487 test_26a() {
1488         test_mkdir $DIR/d26
1489         test_mkdir $DIR/d26/d26-2
1490         ln -s d26/d26-2 $DIR/s26
1491         touch $DIR/s26/foo || error "File creation failed"
1492 }
1493 run_test 26a "multiple component symlink ======================="
1494
1495 test_26b() {
1496         test_mkdir -p $DIR/$tdir/d26-2
1497         ln -s $tdir/d26-2/foo $DIR/s26-2
1498         touch $DIR/s26-2 || error "File creation failed"
1499 }
1500 run_test 26b "multiple component symlink at end of lookup ======"
1501
1502 test_26c() {
1503         test_mkdir $DIR/d26.2
1504         touch $DIR/d26.2/foo
1505         ln -s d26.2 $DIR/s26.2-1
1506         ln -s s26.2-1 $DIR/s26.2-2
1507         ln -s s26.2-2 $DIR/s26.2-3
1508         chmod 0666 $DIR/s26.2-3/foo
1509 }
1510 run_test 26c "chain of symlinks"
1511
1512 # recursive symlinks (bug 439)
1513 test_26d() {
1514         ln -s d26-3/foo $DIR/d26-3
1515 }
1516 run_test 26d "create multiple component recursive symlink"
1517
1518 test_26e() {
1519         [ ! -h $DIR/d26-3 ] && test_26d
1520         rm $DIR/d26-3
1521 }
1522 run_test 26e "unlink multiple component recursive symlink"
1523
1524 # recursive symlinks (bug 7022)
1525 test_26f() {
1526         test_mkdir $DIR/$tdir
1527         test_mkdir $DIR/$tdir/$tfile
1528         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1529         test_mkdir -p lndir/bar1
1530         test_mkdir $DIR/$tdir/$tfile/$tfile
1531         cd $tfile                || error "cd $tfile failed"
1532         ln -s .. dotdot          || error "ln dotdot failed"
1533         ln -s dotdot/lndir lndir || error "ln lndir failed"
1534         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1535         output=`ls $tfile/$tfile/lndir/bar1`
1536         [ "$output" = bar1 ] && error "unexpected output"
1537         rm -r $tfile             || error "rm $tfile failed"
1538         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1539 }
1540 run_test 26f "rm -r of a directory which has recursive symlink"
1541
1542 test_27a() {
1543         test_mkdir $DIR/$tdir
1544         $LFS getstripe $DIR/$tdir
1545         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1546         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1547         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1548 }
1549 run_test 27a "one stripe file"
1550
1551 test_27b() {
1552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1553
1554         test_mkdir $DIR/$tdir
1555         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1556         $LFS getstripe -c $DIR/$tdir/$tfile
1557         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1558                 error "two-stripe file doesn't have two stripes"
1559
1560         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1561 }
1562 run_test 27b "create and write to two stripe file"
1563
1564 # 27c family tests specific striping, setstripe -o
1565 test_27ca() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         test_mkdir -p $DIR/$tdir
1568         local osts="1"
1569
1570         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1571         $LFS getstripe -i $DIR/$tdir/$tfile
1572         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1573                 error "stripe not on specified OST"
1574
1575         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1576 }
1577 run_test 27ca "one stripe on specified OST"
1578
1579 test_27cb() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1581         test_mkdir -p $DIR/$tdir
1582         local osts="1,0"
1583         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1584         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1585         echo "$getstripe"
1586
1587         # Strip getstripe output to a space separated list of OSTs
1588         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1589                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1590         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1591                 error "stripes not on specified OSTs"
1592
1593         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1594 }
1595 run_test 27cb "two stripes on specified OSTs"
1596
1597 test_27cc() {
1598         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1599         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1600                 skip "server does not support overstriping"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts="0,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cc "two stripes on the same OST"
1617
1618 test_27cd() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="0,1,1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cd "four stripes on two OSTs"
1637
1638 test_27ce() {
1639         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1640                 skip_env "too many osts, skipping"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         # We do one more stripe than we have OSTs
1644         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1645                 skip_env "ea_inode feature disabled"
1646
1647         test_mkdir -p $DIR/$tdir
1648         local osts=""
1649         for i in $(seq 0 $OSTCOUNT);
1650         do
1651                 osts=$osts"0"
1652                 if [ $i -ne $OSTCOUNT ]; then
1653                         osts=$osts","
1654                 fi
1655         done
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27ce "more stripes than OSTs with -o"
1669
1670 test_27cf() {
1671         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1672         local pid=0
1673
1674         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1675         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1676         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1677         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1678                 error "failed to set $osp_proc=0"
1679
1680         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1681         pid=$!
1682         sleep 1
1683         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1684         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1685                 error "failed to set $osp_proc=1"
1686         wait $pid
1687         [[ $pid -ne 0 ]] ||
1688                 error "should return error due to $osp_proc=0"
1689 }
1690 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1691
1692 test_27d() {
1693         test_mkdir $DIR/$tdir
1694         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1695                 error "setstripe failed"
1696         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1698 }
1699 run_test 27d "create file with default settings"
1700
1701 test_27e() {
1702         # LU-5839 adds check for existed layout before setting it
1703         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1704                 skip "Need MDS version at least 2.7.56"
1705
1706         test_mkdir $DIR/$tdir
1707         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1708         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1709         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1710 }
1711 run_test 27e "setstripe existing file (should return error)"
1712
1713 test_27f() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1716                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1718                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1719         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1720         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1721 }
1722 run_test 27f "setstripe with bad stripe size (should return error)"
1723
1724 test_27g() {
1725         test_mkdir $DIR/$tdir
1726         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1727         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1728                 error "$DIR/$tdir/$tfile has object"
1729 }
1730 run_test 27g "$LFS getstripe with no objects"
1731
1732 test_27ga() {
1733         test_mkdir $DIR/$tdir
1734         touch $DIR/$tdir/$tfile || error "touch failed"
1735         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1736         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1737         local rc=$?
1738         (( rc == 2 )) || error "getstripe did not return ENOENT"
1739 }
1740 run_test 27ga "$LFS getstripe with missing file (should return error)"
1741
1742 test_27i() {
1743         test_mkdir $DIR/$tdir
1744         touch $DIR/$tdir/$tfile || error "touch failed"
1745         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1746                 error "missing objects"
1747 }
1748 run_test 27i "$LFS getstripe with some objects"
1749
1750 test_27j() {
1751         test_mkdir $DIR/$tdir
1752         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1753                 error "setstripe failed" || true
1754 }
1755 run_test 27j "setstripe with bad stripe offset (should return error)"
1756
1757 test_27k() { # bug 2844
1758         test_mkdir $DIR/$tdir
1759         local file=$DIR/$tdir/$tfile
1760         local ll_max_blksize=$((4 * 1024 * 1024))
1761         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1762         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1763         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1764         dd if=/dev/zero of=$file bs=4k count=1
1765         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1766         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1767 }
1768 run_test 27k "limit i_blksize for broken user apps"
1769
1770 test_27l() {
1771         mcreate $DIR/$tfile || error "creating file"
1772         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1773                 error "setstripe should have failed" || true
1774 }
1775 run_test 27l "check setstripe permissions (should return error)"
1776
1777 test_27m() {
1778         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1779
1780         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1781                 skip_env "multiple clients -- skipping"
1782
1783         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1784                    head -n1)
1785         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1786                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1787         fi
1788         trap simple_cleanup_common EXIT
1789         test_mkdir $DIR/$tdir
1790         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1791         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1792                 error "dd should fill OST0"
1793         i=2
1794         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1795                 i=$((i + 1))
1796                 [ $i -gt 256 ] && break
1797         done
1798         i=$((i + 1))
1799         touch $DIR/$tdir/$tfile.$i
1800         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1801             awk '{print $1}'| grep -w "0") ] &&
1802                 error "OST0 was full but new created file still use it"
1803         i=$((i + 1))
1804         touch $DIR/$tdir/$tfile.$i
1805         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1806             awk '{print $1}'| grep -w "0") ] &&
1807                 error "OST0 was full but new created file still use it"
1808         simple_cleanup_common
1809 }
1810 run_test 27m "create file while OST0 was full"
1811
1812 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1813 # if the OST isn't full anymore.
1814 reset_enospc() {
1815         local ostidx=${1:-""}
1816         local delay
1817         local ready
1818         local get_prealloc
1819
1820         local list=$(comma_list $(osts_nodes))
1821         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1822
1823         do_nodes $list lctl set_param fail_loc=0
1824         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1825         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1826                 awk '{print $1 * 2;exit;}')
1827         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1828                         grep -v \"^0$\""
1829         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1830 }
1831
1832 __exhaust_precreations() {
1833         local OSTIDX=$1
1834         local FAILLOC=$2
1835         local FAILIDX=${3:-$OSTIDX}
1836         local ofacet=ost$((OSTIDX + 1))
1837
1838         test_mkdir -p -c1 $DIR/$tdir
1839         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1840         local mfacet=mds$((mdtidx + 1))
1841         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1842
1843         local OST=$(ostname_from_index $OSTIDX)
1844
1845         # on the mdt's osc
1846         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1847         local last_id=$(do_facet $mfacet lctl get_param -n \
1848                         osp.$mdtosc_proc1.prealloc_last_id)
1849         local next_id=$(do_facet $mfacet lctl get_param -n \
1850                         osp.$mdtosc_proc1.prealloc_next_id)
1851
1852         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1853         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1854
1855         test_mkdir -p $DIR/$tdir/${OST}
1856         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1857 #define OBD_FAIL_OST_ENOSPC              0x215
1858         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1859         echo "Creating to objid $last_id on ost $OST..."
1860         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1861         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1862         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1863 }
1864
1865 exhaust_precreations() {
1866         __exhaust_precreations $1 $2 $3
1867         sleep_maxage
1868 }
1869
1870 exhaust_all_precreations() {
1871         local i
1872         for (( i=0; i < OSTCOUNT; i++ )) ; do
1873                 __exhaust_precreations $i $1 -1
1874         done
1875         sleep_maxage
1876 }
1877
1878 test_27n() {
1879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1881         remote_mds_nodsh && skip "remote MDS with nodsh"
1882         remote_ost_nodsh && skip "remote OST with nodsh"
1883
1884         reset_enospc
1885         rm -f $DIR/$tdir/$tfile
1886         exhaust_precreations 0 0x80000215
1887         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1888         touch $DIR/$tdir/$tfile || error "touch failed"
1889         $LFS getstripe $DIR/$tdir/$tfile
1890         reset_enospc
1891 }
1892 run_test 27n "create file with some full OSTs"
1893
1894 test_27o() {
1895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899
1900         reset_enospc
1901         rm -f $DIR/$tdir/$tfile
1902         exhaust_all_precreations 0x215
1903
1904         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1905
1906         reset_enospc
1907         rm -rf $DIR/$tdir/*
1908 }
1909 run_test 27o "create file with all full OSTs (should error)"
1910
1911 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 -ge 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 -ge 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 -ge 160 ] || large_xattr_enabled ||
2558                 skip_env "ea_inode feature disabled"
2559
2560         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2561                 error "setstripe failed"
2562
2563         echo 1 > $DIR/$tdir/$tfile
2564
2565         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2566         [ $count -eq $setcount ] ||
2567                 error "stripe count $count, should be $setcount"
2568
2569         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2570                 error "overstriped should be set in pattern"
2571
2572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2573                 error "dd failed"
2574
2575         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2576 }
2577 run_test 27Cf "test default inheritance with overstriping"
2578
2579 test_27D() {
2580         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2581         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2582         remote_mds_nodsh && skip "remote MDS with nodsh"
2583
2584         local POOL=${POOL:-testpool}
2585         local first_ost=0
2586         local last_ost=$(($OSTCOUNT - 1))
2587         local ost_step=1
2588         local ost_list=$(seq $first_ost $ost_step $last_ost)
2589         local ost_range="$first_ost $last_ost $ost_step"
2590
2591         test_mkdir $DIR/$tdir
2592         pool_add $POOL || error "pool_add failed"
2593         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2594
2595         local skip27D
2596         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2597                 skip27D+="-s 29"
2598         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2599                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2600                         skip27D+=" -s 30,31"
2601         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2602           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2603                 skip27D+=" -s 32,33"
2604         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2605                 skip27D+=" -s 34"
2606         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2607                 error "llapi_layout_test failed"
2608
2609         destroy_test_pools || error "destroy test pools failed"
2610 }
2611 run_test 27D "validate llapi_layout API"
2612
2613 # Verify that default_easize is increased from its initial value after
2614 # accessing a widely striped file.
2615 test_27E() {
2616         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2617         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2618                 skip "client does not have LU-3338 fix"
2619
2620         # 72 bytes is the minimum space required to store striping
2621         # information for a file striped across one OST:
2622         # (sizeof(struct lov_user_md_v3) +
2623         #  sizeof(struct lov_user_ost_data_v1))
2624         local min_easize=72
2625         $LCTL set_param -n llite.*.default_easize $min_easize ||
2626                 error "lctl set_param failed"
2627         local easize=$($LCTL get_param -n llite.*.default_easize)
2628
2629         [ $easize -eq $min_easize ] ||
2630                 error "failed to set default_easize"
2631
2632         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2633                 error "setstripe failed"
2634         # In order to ensure stat() call actually talks to MDS we need to
2635         # do something drastic to this file to shake off all lock, e.g.
2636         # rename it (kills lookup lock forcing cache cleaning)
2637         mv $DIR/$tfile $DIR/${tfile}-1
2638         ls -l $DIR/${tfile}-1
2639         rm $DIR/${tfile}-1
2640
2641         easize=$($LCTL get_param -n llite.*.default_easize)
2642
2643         [ $easize -gt $min_easize ] ||
2644                 error "default_easize not updated"
2645 }
2646 run_test 27E "check that default extended attribute size properly increases"
2647
2648 test_27F() { # LU-5346/LU-7975
2649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2650         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2651         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2652                 skip "Need MDS version at least 2.8.51"
2653         remote_ost_nodsh && skip "remote OST with nodsh"
2654
2655         test_mkdir $DIR/$tdir
2656         rm -f $DIR/$tdir/f0
2657         $LFS setstripe -c 2 $DIR/$tdir
2658
2659         # stop all OSTs to reproduce situation for LU-7975 ticket
2660         for num in $(seq $OSTCOUNT); do
2661                 stop ost$num
2662         done
2663
2664         # open/create f0 with O_LOV_DELAY_CREATE
2665         # truncate f0 to a non-0 size
2666         # close
2667         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2668
2669         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2670         # open/write it again to force delayed layout creation
2671         cat /etc/hosts > $DIR/$tdir/f0 &
2672         catpid=$!
2673
2674         # restart OSTs
2675         for num in $(seq $OSTCOUNT); do
2676                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2677                         error "ost$num failed to start"
2678         done
2679
2680         wait $catpid || error "cat failed"
2681
2682         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2683         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2684                 error "wrong stripecount"
2685
2686 }
2687 run_test 27F "Client resend delayed layout creation with non-zero size"
2688
2689 test_27G() { #LU-10629
2690         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2691                 skip "Need MDS version at least 2.11.51"
2692         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2693         remote_mds_nodsh && skip "remote MDS with nodsh"
2694         local POOL=${POOL:-testpool}
2695         local ostrange="0 0 1"
2696
2697         test_mkdir $DIR/$tdir
2698         touch $DIR/$tdir/$tfile.nopool
2699         pool_add $POOL || error "pool_add failed"
2700         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2701         $LFS setstripe -p $POOL $DIR/$tdir
2702
2703         local pool=$($LFS getstripe -p $DIR/$tdir)
2704
2705         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2706         touch $DIR/$tdir/$tfile.default
2707         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2708         $LFS find $DIR/$tdir -type f --pool $POOL
2709         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2710         [[ "$found" == "2" ]] ||
2711                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2712
2713         $LFS setstripe -d $DIR/$tdir
2714
2715         pool=$($LFS getstripe -p -d $DIR/$tdir)
2716
2717         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2718 }
2719 run_test 27G "Clear OST pool from stripe"
2720
2721 test_27H() {
2722         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2723                 skip "Need MDS version newer than 2.11.54"
2724         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2725         test_mkdir $DIR/$tdir
2726         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2727         touch $DIR/$tdir/$tfile
2728         $LFS getstripe -c $DIR/$tdir/$tfile
2729         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2730                 error "two-stripe file doesn't have two stripes"
2731
2732         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2733         $LFS getstripe -y $DIR/$tdir/$tfile
2734         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2735              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2736                 error "expected l_ost_idx: [02]$ not matched"
2737
2738         # make sure ost list has been cleared
2739         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2740         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2741                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2742         touch $DIR/$tdir/f3
2743         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2744 }
2745 run_test 27H "Set specific OSTs stripe"
2746
2747 test_27I() {
2748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2750         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2751                 skip "Need MDS version newer than 2.12.52"
2752         local pool=$TESTNAME
2753         local ostrange="1 1 1"
2754
2755         save_layout_restore_at_exit $MOUNT
2756         $LFS setstripe -c 2 -i 0 $MOUNT
2757         pool_add $pool || error "pool_add failed"
2758         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2759         test_mkdir $DIR/$tdir
2760         $LFS setstripe -p $pool $DIR/$tdir
2761         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2762         $LFS getstripe $DIR/$tdir/$tfile
2763 }
2764 run_test 27I "check that root dir striping does not break parent dir one"
2765
2766 test_27J() {
2767         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2768                 skip "Need MDS version newer than 2.12.51"
2769
2770         test_mkdir $DIR/$tdir
2771         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2772         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2773
2774         # create foreign file (raw way)
2775         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2776                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2777
2778         ! $LFS setstripe --foreign --flags foo \
2779                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2780                         error "creating $tfile with '--flags foo' should fail"
2781
2782         ! $LFS setstripe --foreign --flags 0xffffffff \
2783                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2784                         error "creating $tfile w/ 0xffffffff flags should fail"
2785
2786         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2787                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2788
2789         # verify foreign file (raw way)
2790         parse_foreign_file -f $DIR/$tdir/$tfile |
2791                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2792                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2793         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2794                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2795         parse_foreign_file -f $DIR/$tdir/$tfile |
2796                 grep "lov_foreign_size: 73" ||
2797                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2798         parse_foreign_file -f $DIR/$tdir/$tfile |
2799                 grep "lov_foreign_type: 1" ||
2800                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2801         parse_foreign_file -f $DIR/$tdir/$tfile |
2802                 grep "lov_foreign_flags: 0x0000DA08" ||
2803                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2804         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2805                 grep "lov_foreign_value: 0x" |
2806                 sed -e 's/lov_foreign_value: 0x//')
2807         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2808         [[ $lov = ${lov2// /} ]] ||
2809                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2810
2811         # create foreign file (lfs + API)
2812         $LFS setstripe --foreign=none --flags 0xda08 \
2813                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2814                 error "$DIR/$tdir/${tfile}2: create failed"
2815
2816         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2817                 grep "lfm_magic:.*0x0BD70BD0" ||
2818                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2819         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2820         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2821                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2822         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2823                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2824         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2825                 grep "lfm_flags:.*0x0000DA08" ||
2826                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2827         $LFS getstripe $DIR/$tdir/${tfile}2 |
2828                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2829                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2830
2831         # modify striping should fail
2832         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2833                 error "$DIR/$tdir/$tfile: setstripe should fail"
2834         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2835                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2836
2837         # R/W should fail
2838         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2839         cat $DIR/$tdir/${tfile}2 &&
2840                 error "$DIR/$tdir/${tfile}2: read should fail"
2841         cat /etc/passwd > $DIR/$tdir/$tfile &&
2842                 error "$DIR/$tdir/$tfile: write should fail"
2843         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2844                 error "$DIR/$tdir/${tfile}2: write should fail"
2845
2846         # chmod should work
2847         chmod 222 $DIR/$tdir/$tfile ||
2848                 error "$DIR/$tdir/$tfile: chmod failed"
2849         chmod 222 $DIR/$tdir/${tfile}2 ||
2850                 error "$DIR/$tdir/${tfile}2: chmod failed"
2851
2852         # chown should work
2853         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2854                 error "$DIR/$tdir/$tfile: chown failed"
2855         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2856                 error "$DIR/$tdir/${tfile}2: chown failed"
2857
2858         # rename should work
2859         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2860                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2861         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2862                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2863
2864         #remove foreign file
2865         rm $DIR/$tdir/${tfile}.new ||
2866                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2867         rm $DIR/$tdir/${tfile}2.new ||
2868                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2869 }
2870 run_test 27J "basic ops on file with foreign LOV"
2871
2872 test_27K() {
2873         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2874                 skip "Need MDS version newer than 2.12.49"
2875
2876         test_mkdir $DIR/$tdir
2877         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2878         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2879
2880         # create foreign dir (raw way)
2881         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2882                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2883
2884         ! $LFS setdirstripe --foreign --flags foo \
2885                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2886                         error "creating $tdir with '--flags foo' should fail"
2887
2888         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2889                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2890                         error "creating $tdir w/ 0xffffffff flags should fail"
2891
2892         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2893                 error "create_foreign_dir FAILED"
2894
2895         # verify foreign dir (raw way)
2896         parse_foreign_dir -d $DIR/$tdir/$tdir |
2897                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2898                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2899         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2900                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2901         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2902                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2903         parse_foreign_dir -d $DIR/$tdir/$tdir |
2904                 grep "lmv_foreign_flags: 55813$" ||
2905                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2906         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2907                 grep "lmv_foreign_value: 0x" |
2908                 sed 's/lmv_foreign_value: 0x//')
2909         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2910                 sed 's/ //g')
2911         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2912
2913         # create foreign dir (lfs + API)
2914         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2915                 $DIR/$tdir/${tdir}2 ||
2916                 error "$DIR/$tdir/${tdir}2: create failed"
2917
2918         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2919                 grep "lfm_magic:.*0x0CD50CD0" ||
2920                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2921         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2922         # - sizeof(lfm_type) - sizeof(lfm_flags)
2923         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2924                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2925         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2926                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2927         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2928                 grep "lfm_flags:.*0x0000DA05" ||
2929                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2930         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2931                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2932                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2933
2934         # file create in dir should fail
2935         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2936         touch $DIR/$tdir/${tdir}2/$tfile &&
2937                 "$DIR/${tdir}2: file create should fail"
2938
2939         # chmod should work
2940         chmod 777 $DIR/$tdir/$tdir ||
2941                 error "$DIR/$tdir: chmod failed"
2942         chmod 777 $DIR/$tdir/${tdir}2 ||
2943                 error "$DIR/${tdir}2: chmod failed"
2944
2945         # chown should work
2946         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2947                 error "$DIR/$tdir: chown failed"
2948         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2949                 error "$DIR/${tdir}2: chown failed"
2950
2951         # rename should work
2952         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2953                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2954         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2955                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2956
2957         #remove foreign dir
2958         rmdir $DIR/$tdir/${tdir}.new ||
2959                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2960         rmdir $DIR/$tdir/${tdir}2.new ||
2961                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2962 }
2963 run_test 27K "basic ops on dir with foreign LMV"
2964
2965 test_27L() {
2966         remote_mds_nodsh && skip "remote MDS with nodsh"
2967
2968         local POOL=${POOL:-$TESTNAME}
2969
2970         pool_add $POOL || error "pool_add failed"
2971
2972         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2973                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2974                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2975 }
2976 run_test 27L "lfs pool_list gives correct pool name"
2977
2978 test_27M() {
2979         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2980                 skip "Need MDS version >= than 2.12.57"
2981         remote_mds_nodsh && skip "remote MDS with nodsh"
2982         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2983
2984         test_mkdir $DIR/$tdir
2985
2986         # Set default striping on directory
2987         $LFS setstripe -C 4 $DIR/$tdir
2988
2989         echo 1 > $DIR/$tdir/${tfile}.1
2990         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2991         local setcount=4
2992         [ $count -eq $setcount ] ||
2993                 error "(1) stripe count $count, should be $setcount"
2994
2995         # Capture existing append_stripe_count setting for restore
2996         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2997         local mdts=$(comma_list $(mdts_nodes))
2998         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2999
3000         local appendcount=$orig_count
3001         echo 1 >> $DIR/$tdir/${tfile}.2_append
3002         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3003         [ $count -eq $appendcount ] ||
3004                 error "(2)stripe count $count, should be $appendcount for append"
3005
3006         # Disable O_APPEND striping, verify it works
3007         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3008
3009         # Should now get the default striping, which is 4
3010         setcount=4
3011         echo 1 >> $DIR/$tdir/${tfile}.3_append
3012         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3013         [ $count -eq $setcount ] ||
3014                 error "(3) stripe count $count, should be $setcount"
3015
3016         # Try changing the stripe count for append files
3017         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3018
3019         # Append striping is now 2 (directory default is still 4)
3020         appendcount=2
3021         echo 1 >> $DIR/$tdir/${tfile}.4_append
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3023         [ $count -eq $appendcount ] ||
3024                 error "(4) stripe count $count, should be $appendcount for append"
3025
3026         # Test append stripe count of -1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3028         appendcount=$OSTCOUNT
3029         echo 1 >> $DIR/$tdir/${tfile}.5
3030         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3031         [ $count -eq $appendcount ] ||
3032                 error "(5) stripe count $count, should be $appendcount for append"
3033
3034         # Set append striping back to default of 1
3035         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3036
3037         # Try a new default striping, PFL + DOM
3038         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3039
3040         # Create normal DOM file, DOM returns stripe count == 0
3041         setcount=0
3042         touch $DIR/$tdir/${tfile}.6
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3044         [ $count -eq $setcount ] ||
3045                 error "(6) stripe count $count, should be $setcount"
3046
3047         # Show
3048         appendcount=1
3049         echo 1 >> $DIR/$tdir/${tfile}.7_append
3050         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3051         [ $count -eq $appendcount ] ||
3052                 error "(7) stripe count $count, should be $appendcount for append"
3053
3054         # Clean up DOM layout
3055         $LFS setstripe -d $DIR/$tdir
3056
3057         # Now test that append striping works when layout is from root
3058         $LFS setstripe -c 2 $MOUNT
3059         # Make a special directory for this
3060         mkdir $DIR/${tdir}/${tdir}.2
3061         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3062
3063         # Verify for normal file
3064         setcount=2
3065         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3066         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3067         [ $count -eq $setcount ] ||
3068                 error "(8) stripe count $count, should be $setcount"
3069
3070         appendcount=1
3071         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3072         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3073         [ $count -eq $appendcount ] ||
3074                 error "(9) stripe count $count, should be $appendcount for append"
3075
3076         # Now test O_APPEND striping with pools
3077         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3078         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3079
3080         # Create the pool
3081         pool_add $TESTNAME || error "pool creation failed"
3082         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3083
3084         echo 1 >> $DIR/$tdir/${tfile}.10_append
3085
3086         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3087         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3088
3089         # Check that count is still correct
3090         appendcount=1
3091         echo 1 >> $DIR/$tdir/${tfile}.11_append
3092         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3093         [ $count -eq $appendcount ] ||
3094                 error "(11) stripe count $count, should be $appendcount for append"
3095
3096         # Disable O_APPEND stripe count, verify pool works separately
3097         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3098
3099         echo 1 >> $DIR/$tdir/${tfile}.12_append
3100
3101         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3102         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3103
3104         # Remove pool setting, verify it's not applied
3105         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.13_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3110         [ "$pool" = "" ] || error "(13) pool found: $pool"
3111 }
3112 run_test 27M "test O_APPEND striping"
3113
3114 test_27N() {
3115         combined_mgs_mds && skip "needs separate MGS/MDT"
3116
3117         pool_add $TESTNAME || error "pool_add failed"
3118         do_facet mgs "$LCTL pool_list $FSNAME" |
3119                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3120                 error "lctl pool_list on MGS failed"
3121 }
3122 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3123
3124 clean_foreign_symlink() {
3125         trap 0
3126         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3127         for i in $DIR/$tdir/* ; do
3128                 $LFS unlink_foreign $i || true
3129         done
3130 }
3131
3132 test_27O() {
3133         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3134                 skip "Need MDS version newer than 2.12.51"
3135
3136         test_mkdir $DIR/$tdir
3137         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3138         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3139
3140         trap clean_foreign_symlink EXIT
3141
3142         # enable foreign_symlink behaviour
3143         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3144
3145         # foreign symlink LOV format is a partial path by default
3146
3147         # create foreign file (lfs + API)
3148         $LFS setstripe --foreign=symlink --flags 0xda05 \
3149                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3150                 error "$DIR/$tdir/${tfile}: create failed"
3151
3152         $LFS getstripe -v $DIR/$tdir/${tfile} |
3153                 grep "lfm_magic:.*0x0BD70BD0" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3155         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3156                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3157         $LFS getstripe -v $DIR/$tdir/${tfile} |
3158                 grep "lfm_flags:.*0x0000DA05" ||
3159                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3160         $LFS getstripe $DIR/$tdir/${tfile} |
3161                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3163
3164         # modify striping should fail
3165         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3166                 error "$DIR/$tdir/$tfile: setstripe should fail"
3167
3168         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3169         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3170         cat /etc/passwd > $DIR/$tdir/$tfile &&
3171                 error "$DIR/$tdir/$tfile: write should fail"
3172
3173         # rename should succeed
3174         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3175                 error "$DIR/$tdir/$tfile: rename has failed"
3176
3177         #remove foreign_symlink file should fail
3178         rm $DIR/$tdir/${tfile}.new &&
3179                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3180
3181         #test fake symlink
3182         mkdir /tmp/${uuid1} ||
3183                 error "/tmp/${uuid1}: mkdir has failed"
3184         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3185                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3186         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3187         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3188                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3189         #read should succeed now
3190         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3191                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3192         #write should succeed now
3193         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3195         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3197         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3198                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3199
3200         #check that getstripe still works
3201         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3203
3204         # chmod should still succeed
3205         chmod 644 $DIR/$tdir/${tfile}.new ||
3206                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3207
3208         # chown should still succeed
3209         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3211
3212         # rename should still succeed
3213         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3214                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3215
3216         #remove foreign_symlink file should still fail
3217         rm $DIR/$tdir/${tfile} &&
3218                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3219
3220         #use special ioctl() to unlink foreign_symlink file
3221         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3222                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3223
3224 }
3225 run_test 27O "basic ops on foreign file of symlink type"
3226
3227 test_27P() {
3228         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3229                 skip "Need MDS version newer than 2.12.49"
3230
3231         test_mkdir $DIR/$tdir
3232         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3233         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3234
3235         trap clean_foreign_symlink EXIT
3236
3237         # enable foreign_symlink behaviour
3238         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3239
3240         # foreign symlink LMV format is a partial path by default
3241
3242         # create foreign dir (lfs + API)
3243         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3244                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3245                 error "$DIR/$tdir/${tdir}: create failed"
3246
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3248                 grep "lfm_magic:.*0x0CD50CD0" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3250         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3251                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3252         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3253                 grep "lfm_flags:.*0x0000DA05" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3255         $LFS getdirstripe $DIR/$tdir/${tdir} |
3256                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3258
3259         # file create in dir should fail
3260         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3261         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3262
3263         # rename should succeed
3264         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3265                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3266
3267         #remove foreign_symlink dir should fail
3268         rmdir $DIR/$tdir/${tdir}.new &&
3269                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3270
3271         #test fake symlink
3272         mkdir -p /tmp/${uuid1}/${uuid2} ||
3273                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3274         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3275                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3276         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3277         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3278                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3279         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3280                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3281
3282         #check that getstripe fails now that foreign_symlink enabled
3283         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3284                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3285
3286         # file create in dir should work now
3287         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3288                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3289         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3290                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3291         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3292                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3293
3294         # chmod should still succeed
3295         chmod 755 $DIR/$tdir/${tdir}.new ||
3296                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3297
3298         # chown should still succeed
3299         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3300                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3301
3302         # rename should still succeed
3303         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3305
3306         #remove foreign_symlink dir should still fail
3307         rmdir $DIR/$tdir/${tdir} &&
3308                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3309
3310         #use special ioctl() to unlink foreign_symlink file
3311         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3312                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3313
3314         #created file should still exist
3315         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3316                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3317         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3318                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3319 }
3320 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3321
3322 # createtest also checks that device nodes are created and
3323 # then visible correctly (#2091)
3324 test_28() { # bug 2091
3325         test_mkdir $DIR/d28
3326         $CREATETEST $DIR/d28/ct || error "createtest failed"
3327 }
3328 run_test 28 "create/mknod/mkdir with bad file types ============"
3329
3330 test_29() {
3331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3332
3333         sync; sleep 1; sync # flush out any dirty pages from previous tests
3334         cancel_lru_locks
3335         test_mkdir $DIR/d29
3336         touch $DIR/d29/foo
3337         log 'first d29'
3338         ls -l $DIR/d29
3339
3340         declare -i LOCKCOUNTORIG=0
3341         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3342                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3343         done
3344         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3345
3346         declare -i LOCKUNUSEDCOUNTORIG=0
3347         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3348                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3349         done
3350
3351         log 'second d29'
3352         ls -l $DIR/d29
3353         log 'done'
3354
3355         declare -i LOCKCOUNTCURRENT=0
3356         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3357                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3358         done
3359
3360         declare -i LOCKUNUSEDCOUNTCURRENT=0
3361         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3362                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3363         done
3364
3365         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3366                 $LCTL set_param -n ldlm.dump_namespaces ""
3367                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3368                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3369                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3370                 return 2
3371         fi
3372         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3373                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3374                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3375                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3376                 return 3
3377         fi
3378 }
3379 run_test 29 "IT_GETATTR regression  ============================"
3380
3381 test_30a() { # was test_30
3382         cp $(which ls) $DIR || cp /bin/ls $DIR
3383         $DIR/ls / || error "Can't execute binary from lustre"
3384         rm $DIR/ls
3385 }
3386 run_test 30a "execute binary from Lustre (execve) =============="
3387
3388 test_30b() {
3389         cp `which ls` $DIR || cp /bin/ls $DIR
3390         chmod go+rx $DIR/ls
3391         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3392         rm $DIR/ls
3393 }
3394 run_test 30b "execute binary from Lustre as non-root ==========="
3395
3396 test_30c() { # b=22376
3397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3398
3399         cp $(which ls) $DIR || cp /bin/ls $DIR
3400         chmod a-rw $DIR/ls
3401         cancel_lru_locks mdc
3402         cancel_lru_locks osc
3403         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3404         rm -f $DIR/ls
3405 }
3406 run_test 30c "execute binary from Lustre without read perms ===="
3407
3408 test_30d() {
3409         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3410
3411         for i in {1..10}; do
3412                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3413                 local PID=$!
3414                 sleep 1
3415                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3416                 wait $PID || error "executing dd from Lustre failed"
3417                 rm -f $DIR/$tfile
3418         done
3419
3420         rm -f $DIR/dd
3421 }
3422 run_test 30d "execute binary from Lustre while clear locks"
3423
3424 test_31a() {
3425         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3426         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3427 }
3428 run_test 31a "open-unlink file =================================="
3429
3430 test_31b() {
3431         touch $DIR/f31 || error "touch $DIR/f31 failed"
3432         ln $DIR/f31 $DIR/f31b || error "ln failed"
3433         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3434         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3435 }
3436 run_test 31b "unlink file with multiple links while open ======="
3437
3438 test_31c() {
3439         touch $DIR/f31 || error "touch $DIR/f31 failed"
3440         ln $DIR/f31 $DIR/f31c || error "ln failed"
3441         multiop_bg_pause $DIR/f31 O_uc ||
3442                 error "multiop_bg_pause for $DIR/f31 failed"
3443         MULTIPID=$!
3444         $MULTIOP $DIR/f31c Ouc
3445         kill -USR1 $MULTIPID
3446         wait $MULTIPID
3447 }
3448 run_test 31c "open-unlink file with multiple links ============="
3449
3450 test_31d() {
3451         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3452         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3453 }
3454 run_test 31d "remove of open directory ========================="
3455
3456 test_31e() { # bug 2904
3457         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3458 }
3459 run_test 31e "remove of open non-empty directory ==============="
3460
3461 test_31f() { # bug 4554
3462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3463
3464         set -vx
3465         test_mkdir $DIR/d31f
3466         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3467         cp /etc/hosts $DIR/d31f
3468         ls -l $DIR/d31f
3469         $LFS getstripe $DIR/d31f/hosts
3470         multiop_bg_pause $DIR/d31f D_c || return 1
3471         MULTIPID=$!
3472
3473         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3474         test_mkdir $DIR/d31f
3475         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3476         cp /etc/hosts $DIR/d31f
3477         ls -l $DIR/d31f
3478         $LFS getstripe $DIR/d31f/hosts
3479         multiop_bg_pause $DIR/d31f D_c || return 1
3480         MULTIPID2=$!
3481
3482         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3483         wait $MULTIPID || error "first opendir $MULTIPID failed"
3484
3485         sleep 6
3486
3487         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3488         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3489         set +vx
3490 }
3491 run_test 31f "remove of open directory with open-unlink file ==="
3492
3493 test_31g() {
3494         echo "-- cross directory link --"
3495         test_mkdir -c1 $DIR/${tdir}ga
3496         test_mkdir -c1 $DIR/${tdir}gb
3497         touch $DIR/${tdir}ga/f
3498         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3499         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3500         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3501         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3502         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3503 }
3504 run_test 31g "cross directory link==============="
3505
3506 test_31h() {
3507         echo "-- cross directory link --"
3508         test_mkdir -c1 $DIR/${tdir}
3509         test_mkdir -c1 $DIR/${tdir}/dir
3510         touch $DIR/${tdir}/f
3511         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3512         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3513         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3514         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3515         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3516 }
3517 run_test 31h "cross directory link under child==============="
3518
3519 test_31i() {
3520         echo "-- cross directory link --"
3521         test_mkdir -c1 $DIR/$tdir
3522         test_mkdir -c1 $DIR/$tdir/dir
3523         touch $DIR/$tdir/dir/f
3524         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3525         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3526         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3527         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3528         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3529 }
3530 run_test 31i "cross directory link under parent==============="
3531
3532 test_31j() {
3533         test_mkdir -c1 -p $DIR/$tdir
3534         test_mkdir -c1 -p $DIR/$tdir/dir1
3535         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3536         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3537         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3538         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3539         return 0
3540 }
3541 run_test 31j "link for directory==============="
3542
3543 test_31k() {
3544         test_mkdir -c1 -p $DIR/$tdir
3545         touch $DIR/$tdir/s
3546         touch $DIR/$tdir/exist
3547         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3548         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3549         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3550         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3551         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3552         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3553         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3554         return 0
3555 }
3556 run_test 31k "link to file: the same, non-existing, dir==============="
3557
3558 test_31m() {
3559         mkdir $DIR/d31m
3560         touch $DIR/d31m/s
3561         mkdir $DIR/d31m2
3562         touch $DIR/d31m2/exist
3563         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3564         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3565         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3566         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3567         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3568         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3569         return 0
3570 }
3571 run_test 31m "link to file: the same, non-existing, dir==============="
3572
3573 test_31n() {
3574         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3575         nlink=$(stat --format=%h $DIR/$tfile)
3576         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3577         local fd=$(free_fd)
3578         local cmd="exec $fd<$DIR/$tfile"
3579         eval $cmd
3580         cmd="exec $fd<&-"
3581         trap "eval $cmd" EXIT
3582         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3583         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3584         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3585         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3586         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3587         eval $cmd
3588 }
3589 run_test 31n "check link count of unlinked file"
3590
3591 link_one() {
3592         local tempfile=$(mktemp $1_XXXXXX)
3593         mlink $tempfile $1 2> /dev/null &&
3594                 echo "$BASHPID: link $tempfile to $1 succeeded"
3595         munlink $tempfile
3596 }
3597
3598 test_31o() { # LU-2901
3599         test_mkdir $DIR/$tdir
3600         for LOOP in $(seq 100); do
3601                 rm -f $DIR/$tdir/$tfile*
3602                 for THREAD in $(seq 8); do
3603                         link_one $DIR/$tdir/$tfile.$LOOP &
3604                 done
3605                 wait
3606                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3607                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3608                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3609                         break || true
3610         done
3611 }
3612 run_test 31o "duplicate hard links with same filename"
3613
3614 test_31p() {
3615         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3616
3617         test_mkdir $DIR/$tdir
3618         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3619         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3620
3621         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3622                 error "open unlink test1 failed"
3623         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3624                 error "open unlink test2 failed"
3625
3626         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3627                 error "test1 still exists"
3628         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3629                 error "test2 still exists"
3630 }
3631 run_test 31p "remove of open striped directory"
3632
3633 test_31q() {
3634         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3635
3636         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3637         index=$($LFS getdirstripe -i $DIR/$tdir)
3638         [ $index -eq 3 ] || error "first stripe index $index != 3"
3639         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3640         [ $index -eq 1 ] || error "second stripe index $index != 1"
3641
3642         # when "-c <stripe_count>" is set, the number of MDTs specified after
3643         # "-i" should equal to the stripe count
3644         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3645 }
3646 run_test 31q "create striped directory on specific MDTs"
3647
3648 cleanup_test32_mount() {
3649         local rc=0
3650         trap 0
3651         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3652         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3653         losetup -d $loopdev || true
3654         rm -rf $DIR/$tdir
3655         return $rc
3656 }
3657
3658 test_32a() {
3659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3660
3661         echo "== more mountpoints and symlinks ================="
3662         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3663         trap cleanup_test32_mount EXIT
3664         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3665         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3666                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3667         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3668                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3669         cleanup_test32_mount
3670 }
3671 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3672
3673 test_32b() {
3674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3675
3676         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3677         trap cleanup_test32_mount EXIT
3678         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3679         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3680                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3681         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3682                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3683         cleanup_test32_mount
3684 }
3685 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3686
3687 test_32c() {
3688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3689
3690         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3691         trap cleanup_test32_mount EXIT
3692         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3693         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3694                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3695         test_mkdir -p $DIR/$tdir/d2/test_dir
3696         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3697                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3698         cleanup_test32_mount
3699 }
3700 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3701
3702 test_32d() {
3703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3704
3705         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3706         trap cleanup_test32_mount EXIT
3707         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3708         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3709                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3710         test_mkdir -p $DIR/$tdir/d2/test_dir
3711         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3712                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3713         cleanup_test32_mount
3714 }
3715 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3716
3717 test_32e() {
3718         rm -fr $DIR/$tdir
3719         test_mkdir -p $DIR/$tdir/tmp
3720         local tmp_dir=$DIR/$tdir/tmp
3721         ln -s $DIR/$tdir $tmp_dir/symlink11
3722         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3723         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3724         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3725 }
3726 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3727
3728 test_32f() {
3729         rm -fr $DIR/$tdir
3730         test_mkdir -p $DIR/$tdir/tmp
3731         local tmp_dir=$DIR/$tdir/tmp
3732         ln -s $DIR/$tdir $tmp_dir/symlink11
3733         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3734         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3735         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3736 }
3737 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3738
3739 test_32g() {
3740         local tmp_dir=$DIR/$tdir/tmp
3741         test_mkdir -p $tmp_dir
3742         test_mkdir $DIR/${tdir}2
3743         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3744         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3745         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3746         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3747         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3748         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3749 }
3750 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3751
3752 test_32h() {
3753         rm -fr $DIR/$tdir $DIR/${tdir}2
3754         tmp_dir=$DIR/$tdir/tmp
3755         test_mkdir -p $tmp_dir
3756         test_mkdir $DIR/${tdir}2
3757         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3758         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3759         ls $tmp_dir/symlink12 || error "listing symlink12"
3760         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3761 }
3762 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3763
3764 test_32i() {
3765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3766
3767         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3768         trap cleanup_test32_mount EXIT
3769         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3770         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3771                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3772         touch $DIR/$tdir/test_file
3773         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3774                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3775         cleanup_test32_mount
3776 }
3777 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3778
3779 test_32j() {
3780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3781
3782         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3783         trap cleanup_test32_mount EXIT
3784         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3785         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3786                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3787         touch $DIR/$tdir/test_file
3788         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3789                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3790         cleanup_test32_mount
3791 }
3792 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3793
3794 test_32k() {
3795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3796
3797         rm -fr $DIR/$tdir
3798         trap cleanup_test32_mount EXIT
3799         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3800         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3801                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3802         test_mkdir -p $DIR/$tdir/d2
3803         touch $DIR/$tdir/d2/test_file || error "touch failed"
3804         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3805                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3806         cleanup_test32_mount
3807 }
3808 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3809
3810 test_32l() {
3811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3812
3813         rm -fr $DIR/$tdir
3814         trap cleanup_test32_mount EXIT
3815         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3816         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3817                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3818         test_mkdir -p $DIR/$tdir/d2
3819         touch $DIR/$tdir/d2/test_file || error "touch failed"
3820         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3821                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3822         cleanup_test32_mount
3823 }
3824 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3825
3826 test_32m() {
3827         rm -fr $DIR/d32m
3828         test_mkdir -p $DIR/d32m/tmp
3829         TMP_DIR=$DIR/d32m/tmp
3830         ln -s $DIR $TMP_DIR/symlink11
3831         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3832         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3833                 error "symlink11 not a link"
3834         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3835                 error "symlink01 not a link"
3836 }
3837 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3838
3839 test_32n() {
3840         rm -fr $DIR/d32n
3841         test_mkdir -p $DIR/d32n/tmp
3842         TMP_DIR=$DIR/d32n/tmp
3843         ln -s $DIR $TMP_DIR/symlink11
3844         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3845         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3846         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3847 }
3848 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3849
3850 test_32o() {
3851         touch $DIR/$tfile
3852         test_mkdir -p $DIR/d32o/tmp
3853         TMP_DIR=$DIR/d32o/tmp
3854         ln -s $DIR/$tfile $TMP_DIR/symlink12
3855         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3856         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3857                 error "symlink12 not a link"
3858         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3859         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3860                 error "$DIR/d32o/tmp/symlink12 not file type"
3861         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3862                 error "$DIR/d32o/symlink02 not file type"
3863 }
3864 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3865
3866 test_32p() {
3867         log 32p_1
3868         rm -fr $DIR/d32p
3869         log 32p_2
3870         rm -f $DIR/$tfile
3871         log 32p_3
3872         touch $DIR/$tfile
3873         log 32p_4
3874         test_mkdir -p $DIR/d32p/tmp
3875         log 32p_5
3876         TMP_DIR=$DIR/d32p/tmp
3877         log 32p_6
3878         ln -s $DIR/$tfile $TMP_DIR/symlink12
3879         log 32p_7
3880         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3881         log 32p_8
3882         cat $DIR/d32p/tmp/symlink12 ||
3883                 error "Can't open $DIR/d32p/tmp/symlink12"
3884         log 32p_9
3885         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3886         log 32p_10
3887 }
3888 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3889
3890 test_32q() {
3891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3892
3893         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3894         trap cleanup_test32_mount EXIT
3895         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3896         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3897         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3898                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3899         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3900         cleanup_test32_mount
3901 }
3902 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3903
3904 test_32r() {
3905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3906
3907         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3908         trap cleanup_test32_mount EXIT
3909         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3910         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3911         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3912                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3913         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3914         cleanup_test32_mount
3915 }
3916 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3917
3918 test_33aa() {
3919         rm -f $DIR/$tfile
3920         touch $DIR/$tfile
3921         chmod 444 $DIR/$tfile
3922         chown $RUNAS_ID $DIR/$tfile
3923         log 33_1
3924         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3925         log 33_2
3926 }
3927 run_test 33aa "write file with mode 444 (should return error)"
3928
3929 test_33a() {
3930         rm -fr $DIR/$tdir
3931         test_mkdir $DIR/$tdir
3932         chown $RUNAS_ID $DIR/$tdir
3933         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3934                 error "$RUNAS create $tdir/$tfile failed"
3935         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3936                 error "open RDWR" || true
3937 }
3938 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3939
3940 test_33b() {
3941         rm -fr $DIR/$tdir
3942         test_mkdir $DIR/$tdir
3943         chown $RUNAS_ID $DIR/$tdir
3944         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3945 }
3946 run_test 33b "test open file with malformed flags (No panic)"
3947
3948 test_33c() {
3949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3950         remote_ost_nodsh && skip "remote OST with nodsh"
3951
3952         local ostnum
3953         local ostname
3954         local write_bytes
3955         local all_zeros
3956
3957         all_zeros=:
3958         rm -fr $DIR/$tdir
3959         test_mkdir $DIR/$tdir
3960         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3961
3962         sync
3963         for ostnum in $(seq $OSTCOUNT); do
3964                 # test-framework's OST numbering is one-based, while Lustre's
3965                 # is zero-based
3966                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3967                 # Parsing llobdstat's output sucks; we could grep the /proc
3968                 # path, but that's likely to not be as portable as using the
3969                 # llobdstat utility.  So we parse lctl output instead.
3970                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3971                         obdfilter/$ostname/stats |
3972                         awk '/^write_bytes/ {print $7}' )
3973                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3974                 if (( ${write_bytes:-0} > 0 ))
3975                 then
3976                         all_zeros=false
3977                         break;
3978                 fi
3979         done
3980
3981         $all_zeros || return 0
3982
3983         # Write four bytes
3984         echo foo > $DIR/$tdir/bar
3985         # Really write them
3986         sync
3987
3988         # Total up write_bytes after writing.  We'd better find non-zeros.
3989         for ostnum in $(seq $OSTCOUNT); do
3990                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3991                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3992                         obdfilter/$ostname/stats |
3993                         awk '/^write_bytes/ {print $7}' )
3994                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3995                 if (( ${write_bytes:-0} > 0 ))
3996                 then
3997                         all_zeros=false
3998                         break;
3999                 fi
4000         done
4001
4002         if $all_zeros
4003         then
4004                 for ostnum in $(seq $OSTCOUNT); do
4005                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4006                         echo "Check that write_bytes is present in obdfilter/*/stats:"
4007                         do_facet ost$ostnum lctl get_param -n \
4008                                 obdfilter/$ostname/stats
4009                 done
4010                 error "OST not keeping write_bytes stats (b22312)"
4011         fi
4012 }
4013 run_test 33c "test llobdstat and write_bytes"
4014
4015 test_33d() {
4016         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4018
4019         local MDTIDX=1
4020         local remote_dir=$DIR/$tdir/remote_dir
4021
4022         test_mkdir $DIR/$tdir
4023         $LFS mkdir -i $MDTIDX $remote_dir ||
4024                 error "create remote directory failed"
4025
4026         touch $remote_dir/$tfile
4027         chmod 444 $remote_dir/$tfile
4028         chown $RUNAS_ID $remote_dir/$tfile
4029
4030         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4031
4032         chown $RUNAS_ID $remote_dir
4033         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4034                                         error "create" || true
4035         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4036                                     error "open RDWR" || true
4037         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4038 }
4039 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4040
4041 test_33e() {
4042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4043
4044         mkdir $DIR/$tdir
4045
4046         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4047         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4048         mkdir $DIR/$tdir/local_dir
4049
4050         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4051         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4052         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4053
4054         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4055                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4056
4057         rmdir $DIR/$tdir/* || error "rmdir failed"
4058
4059         umask 777
4060         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4061         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4062         mkdir $DIR/$tdir/local_dir
4063
4064         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4065         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4066         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4067
4068         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4069                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4070
4071         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4072
4073         umask 000
4074         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4075         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4076         mkdir $DIR/$tdir/local_dir
4077
4078         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4079         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4080         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4081
4082         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4083                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4084 }
4085 run_test 33e "mkdir and striped directory should have same mode"
4086
4087 cleanup_33f() {
4088         trap 0
4089         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4090 }
4091
4092 test_33f() {
4093         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4094         remote_mds_nodsh && skip "remote MDS with nodsh"
4095
4096         mkdir $DIR/$tdir
4097         chmod go+rwx $DIR/$tdir
4098         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4099         trap cleanup_33f EXIT
4100
4101         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4102                 error "cannot create striped directory"
4103
4104         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4105                 error "cannot create files in striped directory"
4106
4107         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4108                 error "cannot remove files in striped directory"
4109
4110         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4111                 error "cannot remove striped directory"
4112
4113         cleanup_33f
4114 }
4115 run_test 33f "nonroot user can create, access, and remove a striped directory"
4116
4117 test_33g() {
4118         mkdir -p $DIR/$tdir/dir2
4119
4120         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4121         echo $err
4122         [[ $err =~ "exists" ]] || error "Not exists error"
4123 }
4124 run_test 33g "nonroot user create already existing root created file"
4125
4126 test_33h() {
4127         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4128         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4129                 skip "Need MDS version at least 2.13.50"
4130
4131         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4132                 error "mkdir $tdir failed"
4133         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4134
4135         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4136         local index2
4137
4138         for fname in $DIR/$tdir/$tfile.bak \
4139                      $DIR/$tdir/$tfile.SAV \
4140                      $DIR/$tdir/$tfile.orig \
4141                      $DIR/$tdir/$tfile~; do
4142                 touch $fname  || error "touch $fname failed"
4143                 index2=$($LFS getstripe -m $fname)
4144                 [ $index -eq $index2 ] ||
4145                         error "$fname MDT index mismatch $index != $index2"
4146         done
4147
4148         local failed=0
4149         for i in {1..250}; do
4150                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4151                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4152                         touch $fname  || error "touch $fname failed"
4153                         index2=$($LFS getstripe -m $fname)
4154                         if [[ $index != $index2 ]]; then
4155                                 failed=$((failed + 1))
4156                                 echo "$fname MDT index mismatch $index != $index2"
4157                         fi
4158                 done
4159         done
4160         echo "$failed MDT index mismatches"
4161         (( failed < 20 )) || error "MDT index mismatch $failed times"
4162
4163 }
4164 run_test 33h "temp file is located on the same MDT as target"
4165
4166 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4167 test_34a() {
4168         rm -f $DIR/f34
4169         $MCREATE $DIR/f34 || error "mcreate failed"
4170         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4171                 error "getstripe failed"
4172         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4173         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4174                 error "getstripe failed"
4175         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4176                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4177 }
4178 run_test 34a "truncate file that has not been opened ==========="
4179
4180 test_34b() {
4181         [ ! -f $DIR/f34 ] && test_34a
4182         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4183                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4184         $OPENFILE -f O_RDONLY $DIR/f34
4185         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4186                 error "getstripe failed"
4187         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4188                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4189 }
4190 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4191
4192 test_34c() {
4193         [ ! -f $DIR/f34 ] && test_34a
4194         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4195                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4196         $OPENFILE -f O_RDWR $DIR/f34
4197         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4198                 error "$LFS getstripe failed"
4199         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4200                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4201 }
4202 run_test 34c "O_RDWR opening file-with-size works =============="
4203
4204 test_34d() {
4205         [ ! -f $DIR/f34 ] && test_34a
4206         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4207                 error "dd failed"
4208         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4209                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4210         rm $DIR/f34
4211 }
4212 run_test 34d "write to sparse file ============================="
4213
4214 test_34e() {
4215         rm -f $DIR/f34e
4216         $MCREATE $DIR/f34e || error "mcreate failed"
4217         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4218         $CHECKSTAT -s 1000 $DIR/f34e ||
4219                 error "Size of $DIR/f34e not equal to 1000 bytes"
4220         $OPENFILE -f O_RDWR $DIR/f34e
4221         $CHECKSTAT -s 1000 $DIR/f34e ||
4222                 error "Size of $DIR/f34e not equal to 1000 bytes"
4223 }
4224 run_test 34e "create objects, some with size and some without =="
4225
4226 test_34f() { # bug 6242, 6243
4227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4228
4229         SIZE34F=48000
4230         rm -f $DIR/f34f
4231         $MCREATE $DIR/f34f || error "mcreate failed"
4232         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4233         dd if=$DIR/f34f of=$TMP/f34f
4234         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4235         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4236         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4237         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4238         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4239 }
4240 run_test 34f "read from a file with no objects until EOF ======="
4241
4242 test_34g() {
4243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4244
4245         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4246                 error "dd failed"
4247         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4248         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4249                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4250         cancel_lru_locks osc
4251         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4252                 error "wrong size after lock cancel"
4253
4254         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4255         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4256                 error "expanding truncate failed"
4257         cancel_lru_locks osc
4258         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4259                 error "wrong expanded size after lock cancel"
4260 }
4261 run_test 34g "truncate long file ==============================="
4262
4263 test_34h() {
4264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4265
4266         local gid=10
4267         local sz=1000
4268
4269         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4270         sync # Flush the cache so that multiop below does not block on cache
4271              # flush when getting the group lock
4272         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4273         MULTIPID=$!
4274
4275         # Since just timed wait is not good enough, let's do a sync write
4276         # that way we are sure enough time for a roundtrip + processing
4277         # passed + 2 seconds of extra margin.
4278         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4279         rm $DIR/${tfile}-1
4280         sleep 2
4281
4282         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4283                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4284                 kill -9 $MULTIPID
4285         fi
4286         wait $MULTIPID
4287         local nsz=`stat -c %s $DIR/$tfile`
4288         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4289 }
4290 run_test 34h "ftruncate file under grouplock should not block"
4291
4292 test_35a() {
4293         cp /bin/sh $DIR/f35a
4294         chmod 444 $DIR/f35a
4295         chown $RUNAS_ID $DIR/f35a
4296         $RUNAS $DIR/f35a && error || true
4297         rm $DIR/f35a
4298 }
4299 run_test 35a "exec file with mode 444 (should return and not leak)"
4300
4301 test_36a() {
4302         rm -f $DIR/f36
4303         utime $DIR/f36 || error "utime failed for MDS"
4304 }
4305 run_test 36a "MDS utime check (mknod, utime)"
4306
4307 test_36b() {
4308         echo "" > $DIR/f36
4309         utime $DIR/f36 || error "utime failed for OST"
4310 }
4311 run_test 36b "OST utime check (open, utime)"
4312
4313 test_36c() {
4314         rm -f $DIR/d36/f36
4315         test_mkdir $DIR/d36
4316         chown $RUNAS_ID $DIR/d36
4317         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4318 }
4319 run_test 36c "non-root MDS utime check (mknod, utime)"
4320
4321 test_36d() {
4322         [ ! -d $DIR/d36 ] && test_36c
4323         echo "" > $DIR/d36/f36
4324         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4325 }
4326 run_test 36d "non-root OST utime check (open, utime)"
4327
4328 test_36e() {
4329         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4330
4331         test_mkdir $DIR/$tdir
4332         touch $DIR/$tdir/$tfile
4333         $RUNAS utime $DIR/$tdir/$tfile &&
4334                 error "utime worked, expected failure" || true
4335 }
4336 run_test 36e "utime on non-owned file (should return error)"
4337
4338 subr_36fh() {
4339         local fl="$1"
4340         local LANG_SAVE=$LANG
4341         local LC_LANG_SAVE=$LC_LANG
4342         export LANG=C LC_LANG=C # for date language
4343
4344         DATESTR="Dec 20  2000"
4345         test_mkdir $DIR/$tdir
4346         lctl set_param fail_loc=$fl
4347         date; date +%s
4348         cp /etc/hosts $DIR/$tdir/$tfile
4349         sync & # write RPC generated with "current" inode timestamp, but delayed
4350         sleep 1
4351         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4352         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4353         cancel_lru_locks $OSC
4354         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4355         date; date +%s
4356         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4357                 echo "BEFORE: $LS_BEFORE" && \
4358                 echo "AFTER : $LS_AFTER" && \
4359                 echo "WANT  : $DATESTR" && \
4360                 error "$DIR/$tdir/$tfile timestamps changed" || true
4361
4362         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4363 }
4364
4365 test_36f() {
4366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4367
4368         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4369         subr_36fh "0x80000214"
4370 }
4371 run_test 36f "utime on file racing with OST BRW write =========="
4372
4373 test_36g() {
4374         remote_ost_nodsh && skip "remote OST with nodsh"
4375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4376         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4377                 skip "Need MDS version at least 2.12.51"
4378
4379         local fmd_max_age
4380         local fmd
4381         local facet="ost1"
4382         local tgt="obdfilter"
4383
4384         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4385
4386         test_mkdir $DIR/$tdir
4387         fmd_max_age=$(do_facet $facet \
4388                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4389                 head -n 1")
4390
4391         echo "FMD max age: ${fmd_max_age}s"
4392         touch $DIR/$tdir/$tfile
4393         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4394                 gawk '{cnt=cnt+$1}  END{print cnt}')
4395         echo "FMD before: $fmd"
4396         [[ $fmd == 0 ]] &&
4397                 error "FMD wasn't create by touch"
4398         sleep $((fmd_max_age + 12))
4399         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4400                 gawk '{cnt=cnt+$1}  END{print cnt}')
4401         echo "FMD after: $fmd"
4402         [[ $fmd == 0 ]] ||
4403                 error "FMD wasn't expired by ping"
4404 }
4405 run_test 36g "FMD cache expiry ====================="
4406
4407 test_36h() {
4408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4409
4410         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4411         subr_36fh "0x80000227"
4412 }
4413 run_test 36h "utime on file racing with OST BRW write =========="
4414
4415 test_36i() {
4416         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4417
4418         test_mkdir $DIR/$tdir
4419         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4420
4421         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4422         local new_mtime=$((mtime + 200))
4423
4424         #change Modify time of striped dir
4425         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4426                         error "change mtime failed"
4427
4428         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4429
4430         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4431 }
4432 run_test 36i "change mtime on striped directory"
4433
4434 # test_37 - duplicate with tests 32q 32r
4435
4436 test_38() {
4437         local file=$DIR/$tfile
4438         touch $file
4439         openfile -f O_DIRECTORY $file
4440         local RC=$?
4441         local ENOTDIR=20
4442         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4443         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4444 }
4445 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4446
4447 test_39a() { # was test_39
4448         touch $DIR/$tfile
4449         touch $DIR/${tfile}2
4450 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4451 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4452 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4453         sleep 2
4454         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4455         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4456                 echo "mtime"
4457                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4458                 echo "atime"
4459                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4460                 echo "ctime"
4461                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4462                 error "O_TRUNC didn't change timestamps"
4463         fi
4464 }
4465 run_test 39a "mtime changed on create"
4466
4467 test_39b() {
4468         test_mkdir -c1 $DIR/$tdir
4469         cp -p /etc/passwd $DIR/$tdir/fopen
4470         cp -p /etc/passwd $DIR/$tdir/flink
4471         cp -p /etc/passwd $DIR/$tdir/funlink
4472         cp -p /etc/passwd $DIR/$tdir/frename
4473         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4474
4475         sleep 1
4476         echo "aaaaaa" >> $DIR/$tdir/fopen
4477         echo "aaaaaa" >> $DIR/$tdir/flink
4478         echo "aaaaaa" >> $DIR/$tdir/funlink
4479         echo "aaaaaa" >> $DIR/$tdir/frename
4480
4481         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4482         local link_new=`stat -c %Y $DIR/$tdir/flink`
4483         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4484         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4485
4486         cat $DIR/$tdir/fopen > /dev/null
4487         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4488         rm -f $DIR/$tdir/funlink2
4489         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4490
4491         for (( i=0; i < 2; i++ )) ; do
4492                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4493                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4494                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4495                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4496
4497                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4498                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4499                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4500                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4501
4502                 cancel_lru_locks $OSC
4503                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4504         done
4505 }
4506 run_test 39b "mtime change on open, link, unlink, rename  ======"
4507
4508 # this should be set to past
4509 TEST_39_MTIME=`date -d "1 year ago" +%s`
4510
4511 # bug 11063
4512 test_39c() {
4513         touch $DIR1/$tfile
4514         sleep 2
4515         local mtime0=`stat -c %Y $DIR1/$tfile`
4516
4517         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4518         local mtime1=`stat -c %Y $DIR1/$tfile`
4519         [ "$mtime1" = $TEST_39_MTIME ] || \
4520                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4521
4522         local d1=`date +%s`
4523         echo hello >> $DIR1/$tfile
4524         local d2=`date +%s`
4525         local mtime2=`stat -c %Y $DIR1/$tfile`
4526         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4527                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4528
4529         mv $DIR1/$tfile $DIR1/$tfile-1
4530
4531         for (( i=0; i < 2; i++ )) ; do
4532                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4533                 [ "$mtime2" = "$mtime3" ] || \
4534                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4535
4536                 cancel_lru_locks $OSC
4537                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4538         done
4539 }
4540 run_test 39c "mtime change on rename ==========================="
4541
4542 # bug 21114
4543 test_39d() {
4544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4545
4546         touch $DIR1/$tfile
4547         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4548
4549         for (( i=0; i < 2; i++ )) ; do
4550                 local mtime=`stat -c %Y $DIR1/$tfile`
4551                 [ $mtime = $TEST_39_MTIME ] || \
4552                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4553
4554                 cancel_lru_locks $OSC
4555                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4556         done
4557 }
4558 run_test 39d "create, utime, stat =============================="
4559
4560 # bug 21114
4561 test_39e() {
4562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4563
4564         touch $DIR1/$tfile
4565         local mtime1=`stat -c %Y $DIR1/$tfile`
4566
4567         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4568
4569         for (( i=0; i < 2; i++ )) ; do
4570                 local mtime2=`stat -c %Y $DIR1/$tfile`
4571                 [ $mtime2 = $TEST_39_MTIME ] || \
4572                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4573
4574                 cancel_lru_locks $OSC
4575                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4576         done
4577 }
4578 run_test 39e "create, stat, utime, stat ========================"
4579
4580 # bug 21114
4581 test_39f() {
4582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4583
4584         touch $DIR1/$tfile
4585         mtime1=`stat -c %Y $DIR1/$tfile`
4586
4587         sleep 2
4588         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4589
4590         for (( i=0; i < 2; i++ )) ; do
4591                 local mtime2=`stat -c %Y $DIR1/$tfile`
4592                 [ $mtime2 = $TEST_39_MTIME ] || \
4593                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4594
4595                 cancel_lru_locks $OSC
4596                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4597         done
4598 }
4599 run_test 39f "create, stat, sleep, utime, stat ================="
4600
4601 # bug 11063
4602 test_39g() {
4603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4604
4605         echo hello >> $DIR1/$tfile
4606         local mtime1=`stat -c %Y $DIR1/$tfile`
4607
4608         sleep 2
4609         chmod o+r $DIR1/$tfile
4610
4611         for (( i=0; i < 2; i++ )) ; do
4612                 local mtime2=`stat -c %Y $DIR1/$tfile`
4613                 [ "$mtime1" = "$mtime2" ] || \
4614                         error "lost mtime: $mtime2, should be $mtime1"
4615
4616                 cancel_lru_locks $OSC
4617                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4618         done
4619 }
4620 run_test 39g "write, chmod, stat ==============================="
4621
4622 # bug 11063
4623 test_39h() {
4624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4625
4626         touch $DIR1/$tfile
4627         sleep 1
4628
4629         local d1=`date`
4630         echo hello >> $DIR1/$tfile
4631         local mtime1=`stat -c %Y $DIR1/$tfile`
4632
4633         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4634         local d2=`date`
4635         if [ "$d1" != "$d2" ]; then
4636                 echo "write and touch not within one second"
4637         else
4638                 for (( i=0; i < 2; i++ )) ; do
4639                         local mtime2=`stat -c %Y $DIR1/$tfile`
4640                         [ "$mtime2" = $TEST_39_MTIME ] || \
4641                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4642
4643                         cancel_lru_locks $OSC
4644                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4645                 done
4646         fi
4647 }
4648 run_test 39h "write, utime within one second, stat ============="
4649
4650 test_39i() {
4651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4652
4653         touch $DIR1/$tfile
4654         sleep 1
4655
4656         echo hello >> $DIR1/$tfile
4657         local mtime1=`stat -c %Y $DIR1/$tfile`
4658
4659         mv $DIR1/$tfile $DIR1/$tfile-1
4660
4661         for (( i=0; i < 2; i++ )) ; do
4662                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4663
4664                 [ "$mtime1" = "$mtime2" ] || \
4665                         error "lost mtime: $mtime2, should be $mtime1"
4666
4667                 cancel_lru_locks $OSC
4668                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4669         done
4670 }
4671 run_test 39i "write, rename, stat =============================="
4672
4673 test_39j() {
4674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4675
4676         start_full_debug_logging
4677         touch $DIR1/$tfile
4678         sleep 1
4679
4680         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4681         lctl set_param fail_loc=0x80000412
4682         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4683                 error "multiop failed"
4684         local multipid=$!
4685         local mtime1=`stat -c %Y $DIR1/$tfile`
4686
4687         mv $DIR1/$tfile $DIR1/$tfile-1
4688
4689         kill -USR1 $multipid
4690         wait $multipid || error "multiop close failed"
4691
4692         for (( i=0; i < 2; i++ )) ; do
4693                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4694                 [ "$mtime1" = "$mtime2" ] ||
4695                         error "mtime is lost on close: $mtime2, " \
4696                               "should be $mtime1"
4697
4698                 cancel_lru_locks
4699                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4700         done
4701         lctl set_param fail_loc=0
4702         stop_full_debug_logging
4703 }
4704 run_test 39j "write, rename, close, stat ======================="
4705
4706 test_39k() {
4707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4708
4709         touch $DIR1/$tfile
4710         sleep 1
4711
4712         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4713         local multipid=$!
4714         local mtime1=`stat -c %Y $DIR1/$tfile`
4715
4716         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4717
4718         kill -USR1 $multipid
4719         wait $multipid || error "multiop close failed"
4720
4721         for (( i=0; i < 2; i++ )) ; do
4722                 local mtime2=`stat -c %Y $DIR1/$tfile`
4723
4724                 [ "$mtime2" = $TEST_39_MTIME ] || \
4725                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4726
4727                 cancel_lru_locks
4728                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4729         done
4730 }
4731 run_test 39k "write, utime, close, stat ========================"
4732
4733 # this should be set to future
4734 TEST_39_ATIME=`date -d "1 year" +%s`
4735
4736 test_39l() {
4737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4738         remote_mds_nodsh && skip "remote MDS with nodsh"
4739
4740         local atime_diff=$(do_facet $SINGLEMDS \
4741                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4742         rm -rf $DIR/$tdir
4743         mkdir -p $DIR/$tdir
4744
4745         # test setting directory atime to future
4746         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4747         local atime=$(stat -c %X $DIR/$tdir)
4748         [ "$atime" = $TEST_39_ATIME ] ||
4749                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4750
4751         # test setting directory atime from future to now
4752         local now=$(date +%s)
4753         touch -a -d @$now $DIR/$tdir
4754
4755         atime=$(stat -c %X $DIR/$tdir)
4756         [ "$atime" -eq "$now"  ] ||
4757                 error "atime is not updated from future: $atime, $now"
4758
4759         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4760         sleep 3
4761
4762         # test setting directory atime when now > dir atime + atime_diff
4763         local d1=$(date +%s)
4764         ls $DIR/$tdir
4765         local d2=$(date +%s)
4766         cancel_lru_locks mdc
4767         atime=$(stat -c %X $DIR/$tdir)
4768         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4769                 error "atime is not updated  : $atime, should be $d2"
4770
4771         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4772         sleep 3
4773
4774         # test not setting directory atime when now < dir atime + atime_diff
4775         ls $DIR/$tdir
4776         cancel_lru_locks mdc
4777         atime=$(stat -c %X $DIR/$tdir)
4778         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4779                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4780
4781         do_facet $SINGLEMDS \
4782                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4783 }
4784 run_test 39l "directory atime update ==========================="
4785
4786 test_39m() {
4787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4788
4789         touch $DIR1/$tfile
4790         sleep 2
4791         local far_past_mtime=$(date -d "May 29 1953" +%s)
4792         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4793
4794         touch -m -d @$far_past_mtime $DIR1/$tfile
4795         touch -a -d @$far_past_atime $DIR1/$tfile
4796
4797         for (( i=0; i < 2; i++ )) ; do
4798                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4799                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4800                         error "atime or mtime set incorrectly"
4801
4802                 cancel_lru_locks $OSC
4803                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4804         done
4805 }
4806 run_test 39m "test atime and mtime before 1970"
4807
4808 test_39n() { # LU-3832
4809         remote_mds_nodsh && skip "remote MDS with nodsh"
4810
4811         local atime_diff=$(do_facet $SINGLEMDS \
4812                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4813         local atime0
4814         local atime1
4815         local atime2
4816
4817         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4818
4819         rm -rf $DIR/$tfile
4820         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4821         atime0=$(stat -c %X $DIR/$tfile)
4822
4823         sleep 5
4824         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4825         atime1=$(stat -c %X $DIR/$tfile)
4826
4827         sleep 5
4828         cancel_lru_locks mdc
4829         cancel_lru_locks osc
4830         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4831         atime2=$(stat -c %X $DIR/$tfile)
4832
4833         do_facet $SINGLEMDS \
4834                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4835
4836         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4837         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4838 }
4839 run_test 39n "check that O_NOATIME is honored"
4840
4841 test_39o() {
4842         TESTDIR=$DIR/$tdir/$tfile
4843         [ -e $TESTDIR ] && rm -rf $TESTDIR
4844         mkdir -p $TESTDIR
4845         cd $TESTDIR
4846         links1=2
4847         ls
4848         mkdir a b
4849         ls
4850         links2=$(stat -c %h .)
4851         [ $(($links1 + 2)) != $links2 ] &&
4852                 error "wrong links count $(($links1 + 2)) != $links2"
4853         rmdir b
4854         links3=$(stat -c %h .)
4855         [ $(($links1 + 1)) != $links3 ] &&
4856                 error "wrong links count $links1 != $links3"
4857         return 0
4858 }
4859 run_test 39o "directory cached attributes updated after create"
4860
4861 test_39p() {
4862         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4863
4864         local MDTIDX=1
4865         TESTDIR=$DIR/$tdir/$tdir
4866         [ -e $TESTDIR ] && rm -rf $TESTDIR
4867         test_mkdir -p $TESTDIR
4868         cd $TESTDIR
4869         links1=2
4870         ls
4871         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4872         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4873         ls
4874         links2=$(stat -c %h .)
4875         [ $(($links1 + 2)) != $links2 ] &&
4876                 error "wrong links count $(($links1 + 2)) != $links2"
4877         rmdir remote_dir2
4878         links3=$(stat -c %h .)
4879         [ $(($links1 + 1)) != $links3 ] &&
4880                 error "wrong links count $links1 != $links3"
4881         return 0
4882 }
4883 run_test 39p "remote directory cached attributes updated after create ========"
4884
4885 test_39r() {
4886         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4887                 skip "no atime update on old OST"
4888         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4889                 skip_env "ldiskfs only test"
4890         fi
4891
4892         local saved_adiff
4893         saved_adiff=$(do_facet ost1 \
4894                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4895         stack_trap "do_facet ost1 \
4896                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4897
4898         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4899
4900         $LFS setstripe -i 0 $DIR/$tfile
4901         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4902                 error "can't write initial file"
4903         cancel_lru_locks osc
4904
4905         # exceed atime_diff and access file
4906         sleep 6
4907         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4908                 error "can't udpate atime"
4909
4910         local atime_cli=$(stat -c %X $DIR/$tfile)
4911         echo "client atime: $atime_cli"
4912         # allow atime update to be written to device
4913         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4914         sleep 5
4915
4916         local ostdev=$(ostdevname 1)
4917         local fid=($(lfs getstripe -y $DIR/$tfile |
4918                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4919         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4920         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4921
4922         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4923         local atime_ost=$(do_facet ost1 "$cmd" |&
4924                           awk -F'[: ]' '/atime:/ { print $4 }')
4925         (( atime_cli == atime_ost )) ||
4926                 error "atime on client $atime_cli != ost $atime_ost"
4927 }
4928 run_test 39r "lazy atime update on OST"
4929
4930 test_39q() { # LU-8041
4931         local testdir=$DIR/$tdir
4932         mkdir -p $testdir
4933         multiop_bg_pause $testdir D_c || error "multiop failed"
4934         local multipid=$!
4935         cancel_lru_locks mdc
4936         kill -USR1 $multipid
4937         local atime=$(stat -c %X $testdir)
4938         [ "$atime" -ne 0 ] || error "atime is zero"
4939 }
4940 run_test 39q "close won't zero out atime"
4941
4942 test_40() {
4943         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4944         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4945                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4946         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4947                 error "$tfile is not 4096 bytes in size"
4948 }
4949 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4950
4951 test_41() {
4952         # bug 1553
4953         small_write $DIR/f41 18
4954 }
4955 run_test 41 "test small file write + fstat ====================="
4956
4957 count_ost_writes() {
4958         lctl get_param -n ${OSC}.*.stats |
4959                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4960                         END { printf("%0.0f", writes) }'
4961 }
4962
4963 # decent default
4964 WRITEBACK_SAVE=500
4965 DIRTY_RATIO_SAVE=40
4966 MAX_DIRTY_RATIO=50
4967 BG_DIRTY_RATIO_SAVE=10
4968 MAX_BG_DIRTY_RATIO=25
4969
4970 start_writeback() {
4971         trap 0
4972         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4973         # dirty_ratio, dirty_background_ratio
4974         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4975                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4976                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4977                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4978         else
4979                 # if file not here, we are a 2.4 kernel
4980                 kill -CONT `pidof kupdated`
4981         fi
4982 }
4983
4984 stop_writeback() {
4985         # setup the trap first, so someone cannot exit the test at the
4986         # exact wrong time and mess up a machine
4987         trap start_writeback EXIT
4988         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4989         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4990                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4991                 sysctl -w vm.dirty_writeback_centisecs=0
4992                 sysctl -w vm.dirty_writeback_centisecs=0
4993                 # save and increase /proc/sys/vm/dirty_ratio
4994                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4995                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4996                 # save and increase /proc/sys/vm/dirty_background_ratio
4997                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4998                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4999         else
5000                 # if file not here, we are a 2.4 kernel
5001                 kill -STOP `pidof kupdated`
5002         fi
5003 }
5004
5005 # ensure that all stripes have some grant before we test client-side cache
5006 setup_test42() {
5007         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5008                 dd if=/dev/zero of=$i bs=4k count=1
5009                 rm $i
5010         done
5011 }
5012
5013 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5014 # file truncation, and file removal.
5015 test_42a() {
5016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5017
5018         setup_test42
5019         cancel_lru_locks $OSC
5020         stop_writeback
5021         sync; sleep 1; sync # just to be safe
5022         BEFOREWRITES=`count_ost_writes`
5023         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5024         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5025         AFTERWRITES=`count_ost_writes`
5026         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5027                 error "$BEFOREWRITES < $AFTERWRITES"
5028         start_writeback
5029 }
5030 run_test 42a "ensure that we don't flush on close"
5031
5032 test_42b() {
5033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5034
5035         setup_test42
5036         cancel_lru_locks $OSC
5037         stop_writeback
5038         sync
5039         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5040         BEFOREWRITES=$(count_ost_writes)
5041         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5042         AFTERWRITES=$(count_ost_writes)
5043         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5044                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5045         fi
5046         BEFOREWRITES=$(count_ost_writes)
5047         sync || error "sync: $?"
5048         AFTERWRITES=$(count_ost_writes)
5049         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5050                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5051         fi
5052         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5053         start_writeback
5054         return 0
5055 }
5056 run_test 42b "test destroy of file with cached dirty data ======"
5057
5058 # if these tests just want to test the effect of truncation,
5059 # they have to be very careful.  consider:
5060 # - the first open gets a {0,EOF}PR lock
5061 # - the first write conflicts and gets a {0, count-1}PW
5062 # - the rest of the writes are under {count,EOF}PW
5063 # - the open for truncate tries to match a {0,EOF}PR
5064 #   for the filesize and cancels the PWs.
5065 # any number of fixes (don't get {0,EOF} on open, match
5066 # composite locks, do smarter file size management) fix
5067 # this, but for now we want these tests to verify that
5068 # the cancellation with truncate intent works, so we
5069 # start the file with a full-file pw lock to match against
5070 # until the truncate.
5071 trunc_test() {
5072         test=$1
5073         file=$DIR/$test
5074         offset=$2
5075         cancel_lru_locks $OSC
5076         stop_writeback
5077         # prime the file with 0,EOF PW to match
5078         touch $file
5079         $TRUNCATE $file 0
5080         sync; sync
5081         # now the real test..
5082         dd if=/dev/zero of=$file bs=1024 count=100
5083         BEFOREWRITES=`count_ost_writes`
5084         $TRUNCATE $file $offset
5085         cancel_lru_locks $OSC
5086         AFTERWRITES=`count_ost_writes`
5087         start_writeback
5088 }
5089
5090 test_42c() {
5091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5092
5093         trunc_test 42c 1024
5094         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5095                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5096         rm $file
5097 }
5098 run_test 42c "test partial truncate of file with cached dirty data"
5099
5100 test_42d() {
5101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5102
5103         trunc_test 42d 0
5104         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5105                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5106         rm $file
5107 }
5108 run_test 42d "test complete truncate of file with cached dirty data"
5109
5110 test_42e() { # bug22074
5111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5112
5113         local TDIR=$DIR/${tdir}e
5114         local pages=16 # hardcoded 16 pages, don't change it.
5115         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5116         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5117         local max_dirty_mb
5118         local warmup_files
5119
5120         test_mkdir $DIR/${tdir}e
5121         $LFS setstripe -c 1 $TDIR
5122         createmany -o $TDIR/f $files
5123
5124         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5125
5126         # we assume that with $OSTCOUNT files, at least one of them will
5127         # be allocated on OST0.
5128         warmup_files=$((OSTCOUNT * max_dirty_mb))
5129         createmany -o $TDIR/w $warmup_files
5130
5131         # write a large amount of data into one file and sync, to get good
5132         # avail_grant number from OST.
5133         for ((i=0; i<$warmup_files; i++)); do
5134                 idx=$($LFS getstripe -i $TDIR/w$i)
5135                 [ $idx -ne 0 ] && continue
5136                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5137                 break
5138         done
5139         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5140         sync
5141         $LCTL get_param $proc_osc0/cur_dirty_bytes
5142         $LCTL get_param $proc_osc0/cur_grant_bytes
5143
5144         # create as much dirty pages as we can while not to trigger the actual
5145         # RPCs directly. but depends on the env, VFS may trigger flush during this
5146         # period, hopefully we are good.
5147         for ((i=0; i<$warmup_files; i++)); do
5148                 idx=$($LFS getstripe -i $TDIR/w$i)
5149                 [ $idx -ne 0 ] && continue
5150                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5151         done
5152         $LCTL get_param $proc_osc0/cur_dirty_bytes
5153         $LCTL get_param $proc_osc0/cur_grant_bytes
5154
5155         # perform the real test
5156         $LCTL set_param $proc_osc0/rpc_stats 0
5157         for ((;i<$files; i++)); do
5158                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5159                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5160         done
5161         sync
5162         $LCTL get_param $proc_osc0/rpc_stats
5163
5164         local percent=0
5165         local have_ppr=false
5166         $LCTL get_param $proc_osc0/rpc_stats |
5167                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5168                         # skip lines until we are at the RPC histogram data
5169                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5170                         $have_ppr || continue
5171
5172                         # we only want the percent stat for < 16 pages
5173                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5174
5175                         percent=$((percent + WPCT))
5176                         if [[ $percent -gt 15 ]]; then
5177                                 error "less than 16-pages write RPCs" \
5178                                       "$percent% > 15%"
5179                                 break
5180                         fi
5181                 done
5182         rm -rf $TDIR
5183 }
5184 run_test 42e "verify sub-RPC writes are not done synchronously"
5185
5186 test_43A() { # was test_43
5187         test_mkdir $DIR/$tdir
5188         cp -p /bin/ls $DIR/$tdir/$tfile
5189         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5190         pid=$!
5191         # give multiop a chance to open
5192         sleep 1
5193
5194         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5195         kill -USR1 $pid
5196         # Wait for multiop to exit
5197         wait $pid
5198 }
5199 run_test 43A "execution of file opened for write should return -ETXTBSY"
5200
5201 test_43a() {
5202         test_mkdir $DIR/$tdir
5203         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5204         $DIR/$tdir/sleep 60 &
5205         SLEEP_PID=$!
5206         # Make sure exec of $tdir/sleep wins race with truncate
5207         sleep 1
5208         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5209         kill $SLEEP_PID
5210 }
5211 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5212
5213 test_43b() {
5214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5215
5216         test_mkdir $DIR/$tdir
5217         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5218         $DIR/$tdir/sleep 60 &
5219         SLEEP_PID=$!
5220         # Make sure exec of $tdir/sleep wins race with truncate
5221         sleep 1
5222         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5223         kill $SLEEP_PID
5224 }
5225 run_test 43b "truncate of file being executed should return -ETXTBSY"
5226
5227 test_43c() {
5228         local testdir="$DIR/$tdir"
5229         test_mkdir $testdir
5230         cp $SHELL $testdir/
5231         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5232                 ( cd $testdir && md5sum -c )
5233 }
5234 run_test 43c "md5sum of copy into lustre"
5235
5236 test_44A() { # was test_44
5237         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5238
5239         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5240         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5241 }
5242 run_test 44A "zero length read from a sparse stripe"
5243
5244 test_44a() {
5245         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
5246                 awk '{ print $2 }')
5247         [ -z "$nstripe" ] && skip "can't get stripe info"
5248         [[ $nstripe -gt $OSTCOUNT ]] &&
5249                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5250
5251         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
5252                 awk '{ print $2 }')
5253         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5254                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
5255                         awk '{ print $2 }')
5256         fi
5257
5258         OFFSETS="0 $((stride/2)) $((stride-1))"
5259         for offset in $OFFSETS; do
5260                 for i in $(seq 0 $((nstripe-1))); do
5261                         local GLOBALOFFSETS=""
5262                         # size in Bytes
5263                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5264                         local myfn=$DIR/d44a-$size
5265                         echo "--------writing $myfn at $size"
5266                         ll_sparseness_write $myfn $size ||
5267                                 error "ll_sparseness_write"
5268                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5269                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5270                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5271
5272                         for j in $(seq 0 $((nstripe-1))); do
5273                                 # size in Bytes
5274                                 size=$((((j + $nstripe )*$stride + $offset)))
5275                                 ll_sparseness_write $myfn $size ||
5276                                         error "ll_sparseness_write"
5277                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5278                         done
5279                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5280                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5281                         rm -f $myfn
5282                 done
5283         done
5284 }
5285 run_test 44a "test sparse pwrite ==============================="
5286
5287 dirty_osc_total() {
5288         tot=0
5289         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5290                 tot=$(($tot + $d))
5291         done
5292         echo $tot
5293 }
5294 do_dirty_record() {
5295         before=`dirty_osc_total`
5296         echo executing "\"$*\""
5297         eval $*
5298         after=`dirty_osc_total`
5299         echo before $before, after $after
5300 }
5301 test_45() {
5302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5303
5304         f="$DIR/f45"
5305         # Obtain grants from OST if it supports it
5306         echo blah > ${f}_grant
5307         stop_writeback
5308         sync
5309         do_dirty_record "echo blah > $f"
5310         [[ $before -eq $after ]] && error "write wasn't cached"
5311         do_dirty_record "> $f"
5312         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5313         do_dirty_record "echo blah > $f"
5314         [[ $before -eq $after ]] && error "write wasn't cached"
5315         do_dirty_record "sync"
5316         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5317         do_dirty_record "echo blah > $f"
5318         [[ $before -eq $after ]] && error "write wasn't cached"
5319         do_dirty_record "cancel_lru_locks osc"
5320         [[ $before -gt $after ]] ||
5321                 error "lock cancellation didn't lower dirty count"
5322         start_writeback
5323 }
5324 run_test 45 "osc io page accounting ============================"
5325
5326 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5327 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5328 # objects offset and an assert hit when an rpc was built with 1023's mapped
5329 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5330 test_46() {
5331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5332
5333         f="$DIR/f46"
5334         stop_writeback
5335         sync
5336         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5337         sync
5338         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5339         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5340         sync
5341         start_writeback
5342 }
5343 run_test 46 "dirtying a previously written page ================"
5344
5345 # test_47 is removed "Device nodes check" is moved to test_28
5346
5347 test_48a() { # bug 2399
5348         [ "$mds1_FSTYPE" = "zfs" ] &&
5349         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5350                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5351
5352         test_mkdir $DIR/$tdir
5353         cd $DIR/$tdir
5354         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5355         test_mkdir $DIR/$tdir
5356         touch foo || error "'touch foo' failed after recreating cwd"
5357         test_mkdir bar
5358         touch .foo || error "'touch .foo' failed after recreating cwd"
5359         test_mkdir .bar
5360         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5361         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5362         cd . || error "'cd .' failed after recreating cwd"
5363         mkdir . && error "'mkdir .' worked after recreating cwd"
5364         rmdir . && error "'rmdir .' worked after recreating cwd"
5365         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5366         cd .. || error "'cd ..' failed after recreating cwd"
5367 }
5368 run_test 48a "Access renamed working dir (should return errors)="
5369
5370 test_48b() { # bug 2399
5371         rm -rf $DIR/$tdir
5372         test_mkdir $DIR/$tdir
5373         cd $DIR/$tdir
5374         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5375         touch foo && error "'touch foo' worked after removing cwd"
5376         mkdir foo && error "'mkdir foo' worked after removing cwd"
5377         touch .foo && error "'touch .foo' worked after removing cwd"
5378         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5379         ls . > /dev/null && error "'ls .' worked after removing cwd"
5380         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5381         mkdir . && error "'mkdir .' worked after removing cwd"
5382         rmdir . && error "'rmdir .' worked after removing cwd"
5383         ln -s . foo && error "'ln -s .' worked after removing cwd"
5384         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5385 }
5386 run_test 48b "Access removed working dir (should return errors)="
5387
5388 test_48c() { # bug 2350
5389         #lctl set_param debug=-1
5390         #set -vx
5391         rm -rf $DIR/$tdir
5392         test_mkdir -p $DIR/$tdir/dir
5393         cd $DIR/$tdir/dir
5394         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5395         $TRACE touch foo && error "touch foo worked after removing cwd"
5396         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5397         touch .foo && error "touch .foo worked after removing cwd"
5398         mkdir .foo && error "mkdir .foo worked after removing cwd"
5399         $TRACE ls . && error "'ls .' worked after removing cwd"
5400         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5401         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5402         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5403         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5404         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5405 }
5406 run_test 48c "Access removed working subdir (should return errors)"
5407
5408 test_48d() { # bug 2350
5409         #lctl set_param debug=-1
5410         #set -vx
5411         rm -rf $DIR/$tdir
5412         test_mkdir -p $DIR/$tdir/dir
5413         cd $DIR/$tdir/dir
5414         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5415         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5416         $TRACE touch foo && error "'touch foo' worked after removing parent"
5417         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5418         touch .foo && error "'touch .foo' worked after removing parent"
5419         mkdir .foo && error "mkdir .foo worked after removing parent"
5420         $TRACE ls . && error "'ls .' worked after removing parent"
5421         $TRACE ls .. && error "'ls ..' worked after removing parent"
5422         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5423         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5424         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5425         true
5426 }
5427 run_test 48d "Access removed parent subdir (should return errors)"
5428
5429 test_48e() { # bug 4134
5430         #lctl set_param debug=-1
5431         #set -vx
5432         rm -rf $DIR/$tdir
5433         test_mkdir -p $DIR/$tdir/dir
5434         cd $DIR/$tdir/dir
5435         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5436         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5437         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5438         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5439         # On a buggy kernel addition of "touch foo" after cd .. will
5440         # produce kernel oops in lookup_hash_it
5441         touch ../foo && error "'cd ..' worked after recreate parent"
5442         cd $DIR
5443         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5444 }
5445 run_test 48e "Access to recreated parent subdir (should return errors)"
5446
5447 test_48f() {
5448         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5449                 skip "need MDS >= 2.13.55"
5450         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5451         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5452                 skip "needs different host for mdt1 mdt2"
5453         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5454
5455         $LFS mkdir -i0 $DIR/$tdir
5456         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5457
5458         for d in sub1 sub2 sub3; do
5459                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5460                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5461                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5462         done
5463
5464         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5465 }
5466 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5467
5468 test_49() { # LU-1030
5469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5470         remote_ost_nodsh && skip "remote OST with nodsh"
5471
5472         # get ost1 size - $FSNAME-OST0000
5473         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5474                 awk '{ print $4 }')
5475         # write 800M at maximum
5476         [[ $ost1_size -lt 2 ]] && ost1_size=2
5477         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5478
5479         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5480         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5481         local dd_pid=$!
5482
5483         # change max_pages_per_rpc while writing the file
5484         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5485         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5486         # loop until dd process exits
5487         while ps ax -opid | grep -wq $dd_pid; do
5488                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5489                 sleep $((RANDOM % 5 + 1))
5490         done
5491         # restore original max_pages_per_rpc
5492         $LCTL set_param $osc1_mppc=$orig_mppc
5493         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5494 }
5495 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5496
5497 test_50() {
5498         # bug 1485
5499         test_mkdir $DIR/$tdir
5500         cd $DIR/$tdir
5501         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5502 }
5503 run_test 50 "special situations: /proc symlinks  ==============="
5504
5505 test_51a() {    # was test_51
5506         # bug 1516 - create an empty entry right after ".." then split dir
5507         test_mkdir -c1 $DIR/$tdir
5508         touch $DIR/$tdir/foo
5509         $MCREATE $DIR/$tdir/bar
5510         rm $DIR/$tdir/foo
5511         createmany -m $DIR/$tdir/longfile 201
5512         FNUM=202
5513         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5514                 $MCREATE $DIR/$tdir/longfile$FNUM
5515                 FNUM=$(($FNUM + 1))
5516                 echo -n "+"
5517         done
5518         echo
5519         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5520 }
5521 run_test 51a "special situations: split htree with empty entry =="
5522
5523 cleanup_print_lfs_df () {
5524         trap 0
5525         $LFS df
5526         $LFS df -i
5527 }
5528
5529 test_51b() {
5530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5531
5532         local dir=$DIR/$tdir
5533         local nrdirs=$((65536 + 100))
5534
5535         # cleanup the directory
5536         rm -fr $dir
5537
5538         test_mkdir -c1 $dir
5539
5540         $LFS df
5541         $LFS df -i
5542         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5543         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5544         [[ $numfree -lt $nrdirs ]] &&
5545                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5546
5547         # need to check free space for the directories as well
5548         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5549         numfree=$(( blkfree / $(fs_inode_ksize) ))
5550         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5551
5552         trap cleanup_print_lfs_df EXIT
5553
5554         # create files
5555         createmany -d $dir/d $nrdirs || {
5556                 unlinkmany $dir/d $nrdirs
5557                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5558         }
5559
5560         # really created :
5561         nrdirs=$(ls -U $dir | wc -l)
5562
5563         # unlink all but 100 subdirectories, then check it still works
5564         local left=100
5565         local delete=$((nrdirs - left))
5566
5567         $LFS df
5568         $LFS df -i
5569
5570         # for ldiskfs the nlink count should be 1, but this is OSD specific
5571         # and so this is listed for informational purposes only
5572         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5573         unlinkmany -d $dir/d $delete ||
5574                 error "unlink of first $delete subdirs failed"
5575
5576         echo "nlink between: $(stat -c %h $dir)"
5577         local found=$(ls -U $dir | wc -l)
5578         [ $found -ne $left ] &&
5579                 error "can't find subdirs: found only $found, expected $left"
5580
5581         unlinkmany -d $dir/d $delete $left ||
5582                 error "unlink of second $left subdirs failed"
5583         # regardless of whether the backing filesystem tracks nlink accurately
5584         # or not, the nlink count shouldn't be more than "." and ".." here
5585         local after=$(stat -c %h $dir)
5586         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5587                 echo "nlink after: $after"
5588
5589         cleanup_print_lfs_df
5590 }
5591 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5592
5593 test_51d() {
5594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5595         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5596
5597         test_mkdir $DIR/$tdir
5598         createmany -o $DIR/$tdir/t- 1000
5599         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5600         for N in $(seq 0 $((OSTCOUNT - 1))); do
5601                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5602                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5603                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5604                         '($1 == '$N') { objs += 1 } \
5605                         END { printf("%0.0f", objs) }')
5606                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5607         done
5608         unlinkmany $DIR/$tdir/t- 1000
5609
5610         NLAST=0
5611         for N in $(seq 1 $((OSTCOUNT - 1))); do
5612                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5613                         error "OST $N has less objects vs OST $NLAST" \
5614                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5615                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5616                         error "OST $N has less objects vs OST $NLAST" \
5617                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5618
5619                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5620                         error "OST $N has less #0 objects vs OST $NLAST" \
5621                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5622                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5623                         error "OST $N has less #0 objects vs OST $NLAST" \
5624                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5625                 NLAST=$N
5626         done
5627         rm -f $TMP/$tfile
5628 }
5629 run_test 51d "check object distribution"
5630
5631 test_51e() {
5632         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5633                 skip_env "ldiskfs only test"
5634         fi
5635
5636         test_mkdir -c1 $DIR/$tdir
5637         test_mkdir -c1 $DIR/$tdir/d0
5638
5639         touch $DIR/$tdir/d0/foo
5640         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5641                 error "file exceed 65000 nlink limit!"
5642         unlinkmany $DIR/$tdir/d0/f- 65001
5643         return 0
5644 }
5645 run_test 51e "check file nlink limit"
5646
5647 test_51f() {
5648         test_mkdir $DIR/$tdir
5649
5650         local max=100000
5651         local ulimit_old=$(ulimit -n)
5652         local spare=20 # number of spare fd's for scripts/libraries, etc.
5653         local mdt=$($LFS getstripe -m $DIR/$tdir)
5654         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5655
5656         echo "MDT$mdt numfree=$numfree, max=$max"
5657         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5658         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5659                 while ! ulimit -n $((numfree + spare)); do
5660                         numfree=$((numfree * 3 / 4))
5661                 done
5662                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5663         else
5664                 echo "left ulimit at $ulimit_old"
5665         fi
5666
5667         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5668                 unlinkmany $DIR/$tdir/f $numfree
5669                 error "create+open $numfree files in $DIR/$tdir failed"
5670         }
5671         ulimit -n $ulimit_old
5672
5673         # if createmany exits at 120s there will be fewer than $numfree files
5674         unlinkmany $DIR/$tdir/f $numfree || true
5675 }
5676 run_test 51f "check many open files limit"
5677
5678 test_52a() {
5679         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5680         test_mkdir $DIR/$tdir
5681         touch $DIR/$tdir/foo
5682         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5683         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5684         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5685         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5686         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5687                                         error "link worked"
5688         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5689         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5690         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5691                                                      error "lsattr"
5692         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5693         cp -r $DIR/$tdir $TMP/
5694         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5695 }
5696 run_test 52a "append-only flag test (should return errors)"
5697
5698 test_52b() {
5699         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5700         test_mkdir $DIR/$tdir
5701         touch $DIR/$tdir/foo
5702         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5703         cat test > $DIR/$tdir/foo && error "cat test worked"
5704         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5705         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5706         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5707                                         error "link worked"
5708         echo foo >> $DIR/$tdir/foo && error "echo worked"
5709         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5710         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5711         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5712         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5713                                                         error "lsattr"
5714         chattr -i $DIR/$tdir/foo || error "chattr failed"
5715
5716         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5717 }
5718 run_test 52b "immutable flag test (should return errors) ======="
5719
5720 test_53() {
5721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5722         remote_mds_nodsh && skip "remote MDS with nodsh"
5723         remote_ost_nodsh && skip "remote OST with nodsh"
5724
5725         local param
5726         local param_seq
5727         local ostname
5728         local mds_last
5729         local mds_last_seq
5730         local ost_last
5731         local ost_last_seq
5732         local ost_last_id
5733         local ostnum
5734         local node
5735         local found=false
5736         local support_last_seq=true
5737
5738         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5739                 support_last_seq=false
5740
5741         # only test MDT0000
5742         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5743         local value
5744         for value in $(do_facet $SINGLEMDS \
5745                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5746                 param=$(echo ${value[0]} | cut -d "=" -f1)
5747                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5748
5749                 if $support_last_seq; then
5750                         param_seq=$(echo $param |
5751                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5752                         mds_last_seq=$(do_facet $SINGLEMDS \
5753                                        $LCTL get_param -n $param_seq)
5754                 fi
5755                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5756
5757                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5758                 node=$(facet_active_host ost$((ostnum+1)))
5759                 param="obdfilter.$ostname.last_id"
5760                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5761                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5762                         ost_last_id=$ost_last
5763
5764                         if $support_last_seq; then
5765                                 ost_last_id=$(echo $ost_last |
5766                                               awk -F':' '{print $2}' |
5767                                               sed -e "s/^0x//g")
5768                                 ost_last_seq=$(echo $ost_last |
5769                                                awk -F':' '{print $1}')
5770                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5771                         fi
5772
5773                         if [[ $ost_last_id != $mds_last ]]; then
5774                                 error "$ost_last_id != $mds_last"
5775                         else
5776                                 found=true
5777                                 break
5778                         fi
5779                 done
5780         done
5781         $found || error "can not match last_seq/last_id for $mdtosc"
5782         return 0
5783 }
5784 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5785
5786 test_54a() {
5787         perl -MSocket -e ';' || skip "no Socket perl module installed"
5788
5789         $SOCKETSERVER $DIR/socket ||
5790                 error "$SOCKETSERVER $DIR/socket failed: $?"
5791         $SOCKETCLIENT $DIR/socket ||
5792                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5793         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5794 }
5795 run_test 54a "unix domain socket test =========================="
5796
5797 test_54b() {
5798         f="$DIR/f54b"
5799         mknod $f c 1 3
5800         chmod 0666 $f
5801         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5802 }
5803 run_test 54b "char device works in lustre ======================"
5804
5805 find_loop_dev() {
5806         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5807         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5808         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5809
5810         for i in $(seq 3 7); do
5811                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5812                 LOOPDEV=$LOOPBASE$i
5813                 LOOPNUM=$i
5814                 break
5815         done
5816 }
5817
5818 cleanup_54c() {
5819         local rc=0
5820         loopdev="$DIR/loop54c"
5821
5822         trap 0
5823         $UMOUNT $DIR/$tdir || rc=$?
5824         losetup -d $loopdev || true
5825         losetup -d $LOOPDEV || true
5826         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5827         return $rc
5828 }
5829
5830 test_54c() {
5831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5832
5833         loopdev="$DIR/loop54c"
5834
5835         find_loop_dev
5836         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5837         trap cleanup_54c EXIT
5838         mknod $loopdev b 7 $LOOPNUM
5839         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5840         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5841         losetup $loopdev $DIR/$tfile ||
5842                 error "can't set up $loopdev for $DIR/$tfile"
5843         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5844         test_mkdir $DIR/$tdir
5845         mount -t ext2 $loopdev $DIR/$tdir ||
5846                 error "error mounting $loopdev on $DIR/$tdir"
5847         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5848                 error "dd write"
5849         df $DIR/$tdir
5850         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5851                 error "dd read"
5852         cleanup_54c
5853 }
5854 run_test 54c "block device works in lustre ====================="
5855
5856 test_54d() {
5857         f="$DIR/f54d"
5858         string="aaaaaa"
5859         mknod $f p
5860         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5861 }
5862 run_test 54d "fifo device works in lustre ======================"
5863
5864 test_54e() {
5865         f="$DIR/f54e"
5866         string="aaaaaa"
5867         cp -aL /dev/console $f
5868         echo $string > $f || error "echo $string to $f failed"
5869 }
5870 run_test 54e "console/tty device works in lustre ======================"
5871
5872 test_56a() {
5873         local numfiles=3
5874         local dir=$DIR/$tdir
5875
5876         rm -rf $dir
5877         test_mkdir -p $dir/dir
5878         for i in $(seq $numfiles); do
5879                 touch $dir/file$i
5880                 touch $dir/dir/file$i
5881         done
5882
5883         local numcomp=$($LFS getstripe --component-count $dir)
5884
5885         [[ $numcomp == 0 ]] && numcomp=1
5886
5887         # test lfs getstripe with --recursive
5888         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5889
5890         [[ $filenum -eq $((numfiles * 2)) ]] ||
5891                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5892         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5893         [[ $filenum -eq $numfiles ]] ||
5894                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5895         echo "$LFS getstripe showed obdidx or l_ost_idx"
5896
5897         # test lfs getstripe with file instead of dir
5898         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5899         [[ $filenum -eq 1 ]] ||
5900                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5901         echo "$LFS getstripe file1 passed"
5902
5903         #test lfs getstripe with --verbose
5904         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5905         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5906                 error "$LFS getstripe --verbose $dir: "\
5907                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5908         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5909                 error "$LFS getstripe $dir: showed lmm_magic"
5910
5911         #test lfs getstripe with -v prints lmm_fid
5912         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5913         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5914                 error "$LFS getstripe -v $dir: "\
5915                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5916         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5917                 error "$LFS getstripe $dir: showed lmm_fid by default"
5918         echo "$LFS getstripe --verbose passed"
5919
5920         #check for FID information
5921         local fid1=$($LFS getstripe --fid $dir/file1)
5922         local fid2=$($LFS getstripe --verbose $dir/file1 |
5923                      awk '/lmm_fid: / { print $2; exit; }')
5924         local fid3=$($LFS path2fid $dir/file1)
5925
5926         [ "$fid1" != "$fid2" ] &&
5927                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5928         [ "$fid1" != "$fid3" ] &&
5929                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5930         echo "$LFS getstripe --fid passed"
5931
5932         #test lfs getstripe with --obd
5933         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5934                 error "$LFS getstripe --obd wrong_uuid: should return error"
5935
5936         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5937
5938         local ostidx=1
5939         local obduuid=$(ostuuid_from_index $ostidx)
5940         local found=$($LFS getstripe -r --obd $obduuid $dir |
5941                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5942
5943         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5944         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5945                 ((filenum--))
5946         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5947                 ((filenum--))
5948
5949         [[ $found -eq $filenum ]] ||
5950                 error "$LFS getstripe --obd: found $found expect $filenum"
5951         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5952                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5953                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5954                 error "$LFS getstripe --obd: should not show file on other obd"
5955         echo "$LFS getstripe --obd passed"
5956 }
5957 run_test 56a "check $LFS getstripe"
5958
5959 test_56b() {
5960         local dir=$DIR/$tdir
5961         local numdirs=3
5962
5963         test_mkdir $dir
5964         for i in $(seq $numdirs); do
5965                 test_mkdir $dir/dir$i
5966         done
5967
5968         # test lfs getdirstripe default mode is non-recursion, which is
5969         # different from lfs getstripe
5970         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5971
5972         [[ $dircnt -eq 1 ]] ||
5973                 error "$LFS getdirstripe: found $dircnt, not 1"
5974         dircnt=$($LFS getdirstripe --recursive $dir |
5975                 grep -c lmv_stripe_count)
5976         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5977                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5978 }
5979 run_test 56b "check $LFS getdirstripe"
5980
5981 test_56c() {
5982         remote_ost_nodsh && skip "remote OST with nodsh"
5983
5984         local ost_idx=0
5985         local ost_name=$(ostname_from_index $ost_idx)
5986         local old_status=$(ost_dev_status $ost_idx)
5987         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5988
5989         [[ -z "$old_status" ]] ||
5990                 skip_env "OST $ost_name is in $old_status status"
5991
5992         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5993         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5994                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5995         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5996                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5997                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5998         fi
5999
6000         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6001                 error "$LFS df -v showing inactive devices"
6002         sleep_maxage
6003
6004         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6005
6006         [[ "$new_status" =~ "D" ]] ||
6007                 error "$ost_name status is '$new_status', missing 'D'"
6008         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6009                 [[ "$new_status" =~ "N" ]] ||
6010                         error "$ost_name status is '$new_status', missing 'N'"
6011         fi
6012         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6013                 [[ "$new_status" =~ "f" ]] ||
6014                         error "$ost_name status is '$new_status', missing 'f'"
6015         fi
6016
6017         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6018         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6019                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6020         [[ -z "$p" ]] && restore_lustre_params < $p || true
6021         sleep_maxage
6022
6023         new_status=$(ost_dev_status $ost_idx)
6024         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6025                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6026         # can't check 'f' as devices may actually be on flash
6027 }
6028 run_test 56c "check 'lfs df' showing device status"
6029
6030 test_56d() {
6031         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6032         local osts=$($LFS df -v $MOUNT | grep -c OST)
6033
6034         $LFS df $MOUNT
6035
6036         (( mdts == MDSCOUNT )) ||
6037                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6038         (( osts == OSTCOUNT )) ||
6039                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6040 }
6041 run_test 56d "'lfs df -v' prints only configured devices"
6042
6043 NUMFILES=3
6044 NUMDIRS=3
6045 setup_56() {
6046         local local_tdir="$1"
6047         local local_numfiles="$2"
6048         local local_numdirs="$3"
6049         local dir_params="$4"
6050         local dir_stripe_params="$5"
6051
6052         if [ ! -d "$local_tdir" ] ; then
6053                 test_mkdir -p $dir_stripe_params $local_tdir
6054                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6055                 for i in $(seq $local_numfiles) ; do
6056                         touch $local_tdir/file$i
6057                 done
6058                 for i in $(seq $local_numdirs) ; do
6059                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6060                         for j in $(seq $local_numfiles) ; do
6061                                 touch $local_tdir/dir$i/file$j
6062                         done
6063                 done
6064         fi
6065 }
6066
6067 setup_56_special() {
6068         local local_tdir=$1
6069         local local_numfiles=$2
6070         local local_numdirs=$3
6071
6072         setup_56 $local_tdir $local_numfiles $local_numdirs
6073
6074         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6075                 for i in $(seq $local_numfiles) ; do
6076                         mknod $local_tdir/loop${i}b b 7 $i
6077                         mknod $local_tdir/null${i}c c 1 3
6078                         ln -s $local_tdir/file1 $local_tdir/link${i}
6079                 done
6080                 for i in $(seq $local_numdirs) ; do
6081                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6082                         mknod $local_tdir/dir$i/null${i}c c 1 3
6083                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6084                 done
6085         fi
6086 }
6087
6088 test_56g() {
6089         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6090         local expected=$(($NUMDIRS + 2))
6091
6092         setup_56 $dir $NUMFILES $NUMDIRS
6093
6094         # test lfs find with -name
6095         for i in $(seq $NUMFILES) ; do
6096                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6097
6098                 [ $nums -eq $expected ] ||
6099                         error "lfs find -name '*$i' $dir wrong: "\
6100                               "found $nums, expected $expected"
6101         done
6102 }
6103 run_test 56g "check lfs find -name"
6104
6105 test_56h() {
6106         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6107         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6108
6109         setup_56 $dir $NUMFILES $NUMDIRS
6110
6111         # test lfs find with ! -name
6112         for i in $(seq $NUMFILES) ; do
6113                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6114
6115                 [ $nums -eq $expected ] ||
6116                         error "lfs find ! -name '*$i' $dir wrong: "\
6117                               "found $nums, expected $expected"
6118         done
6119 }
6120 run_test 56h "check lfs find ! -name"
6121
6122 test_56i() {
6123         local dir=$DIR/$tdir
6124
6125         test_mkdir $dir
6126
6127         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6128         local out=$($cmd)
6129
6130         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6131 }
6132 run_test 56i "check 'lfs find -ost UUID' skips directories"
6133
6134 test_56j() {
6135         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6136
6137         setup_56_special $dir $NUMFILES $NUMDIRS
6138
6139         local expected=$((NUMDIRS + 1))
6140         local cmd="$LFS find -type d $dir"
6141         local nums=$($cmd | wc -l)
6142
6143         [ $nums -eq $expected ] ||
6144                 error "'$cmd' wrong: found $nums, expected $expected"
6145 }
6146 run_test 56j "check lfs find -type d"
6147
6148 test_56k() {
6149         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6150
6151         setup_56_special $dir $NUMFILES $NUMDIRS
6152
6153         local expected=$(((NUMDIRS + 1) * NUMFILES))
6154         local cmd="$LFS find -type f $dir"
6155         local nums=$($cmd | wc -l)
6156
6157         [ $nums -eq $expected ] ||
6158                 error "'$cmd' wrong: found $nums, expected $expected"
6159 }
6160 run_test 56k "check lfs find -type f"
6161
6162 test_56l() {
6163         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6164
6165         setup_56_special $dir $NUMFILES $NUMDIRS
6166
6167         local expected=$((NUMDIRS + NUMFILES))
6168         local cmd="$LFS find -type b $dir"
6169         local nums=$($cmd | wc -l)
6170
6171         [ $nums -eq $expected ] ||
6172                 error "'$cmd' wrong: found $nums, expected $expected"
6173 }
6174 run_test 56l "check lfs find -type b"
6175
6176 test_56m() {
6177         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6178
6179         setup_56_special $dir $NUMFILES $NUMDIRS
6180
6181         local expected=$((NUMDIRS + NUMFILES))
6182         local cmd="$LFS find -type c $dir"
6183         local nums=$($cmd | wc -l)
6184         [ $nums -eq $expected ] ||
6185                 error "'$cmd' wrong: found $nums, expected $expected"
6186 }
6187 run_test 56m "check lfs find -type c"
6188
6189 test_56n() {
6190         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6191         setup_56_special $dir $NUMFILES $NUMDIRS
6192
6193         local expected=$((NUMDIRS + NUMFILES))
6194         local cmd="$LFS find -type l $dir"
6195         local nums=$($cmd | wc -l)
6196
6197         [ $nums -eq $expected ] ||
6198                 error "'$cmd' wrong: found $nums, expected $expected"
6199 }
6200 run_test 56n "check lfs find -type l"
6201
6202 test_56o() {
6203         local dir=$DIR/$tdir
6204
6205         setup_56 $dir $NUMFILES $NUMDIRS
6206         utime $dir/file1 > /dev/null || error "utime (1)"
6207         utime $dir/file2 > /dev/null || error "utime (2)"
6208         utime $dir/dir1 > /dev/null || error "utime (3)"
6209         utime $dir/dir2 > /dev/null || error "utime (4)"
6210         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6211         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6212
6213         local expected=4
6214         local nums=$($LFS find -mtime +0 $dir | wc -l)
6215
6216         [ $nums -eq $expected ] ||
6217                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6218
6219         expected=12
6220         cmd="$LFS find -mtime 0 $dir"
6221         nums=$($cmd | wc -l)
6222         [ $nums -eq $expected ] ||
6223                 error "'$cmd' wrong: found $nums, expected $expected"
6224 }
6225 run_test 56o "check lfs find -mtime for old files"
6226
6227 test_56ob() {
6228         local dir=$DIR/$tdir
6229         local expected=1
6230         local count=0
6231
6232         # just to make sure there is something that won't be found
6233         test_mkdir $dir
6234         touch $dir/$tfile.now
6235
6236         for age in year week day hour min; do
6237                 count=$((count + 1))
6238
6239                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6240                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6241                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6242
6243                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6244                 local nums=$($cmd | wc -l)
6245                 [ $nums -eq $expected ] ||
6246                         error "'$cmd' wrong: found $nums, expected $expected"
6247
6248                 cmd="$LFS find $dir -atime $count${age:0:1}"
6249                 nums=$($cmd | wc -l)
6250                 [ $nums -eq $expected ] ||
6251                         error "'$cmd' wrong: found $nums, expected $expected"
6252         done
6253
6254         sleep 2
6255         cmd="$LFS find $dir -ctime +1s -type f"
6256         nums=$($cmd | wc -l)
6257         (( $nums == $count * 2 + 1)) ||
6258                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6259 }
6260 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6261
6262 test_newerXY_base() {
6263         local x=$1
6264         local y=$2
6265         local dir=$DIR/$tdir
6266         local ref
6267         local negref
6268
6269         if [ $y == "t" ]; then
6270                 if [ $x == "b" ]; then
6271                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6272                 else
6273                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6274                 fi
6275         else
6276                 ref=$DIR/$tfile.newer.$x$y
6277                 touch $ref || error "touch $ref failed"
6278         fi
6279
6280         echo "before = $ref"
6281         sleep 2
6282         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6283         sleep 2
6284         if [ $y == "t" ]; then
6285                 if [ $x == "b" ]; then
6286                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6287                 else
6288                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6289                 fi
6290         else
6291                 negref=$DIR/$tfile.negnewer.$x$y
6292                 touch $negref || error "touch $negref failed"
6293         fi
6294
6295         echo "after = $negref"
6296         local cmd="$LFS find $dir -newer$x$y $ref"
6297         local nums=$(eval $cmd | wc -l)
6298         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6299
6300         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6301                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6302
6303         cmd="$LFS find $dir ! -newer$x$y $negref"
6304         nums=$(eval $cmd | wc -l)
6305         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6306                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6307
6308         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6309         nums=$(eval $cmd | wc -l)
6310         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6311                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6312
6313         rm -rf $DIR/*
6314 }
6315
6316 test_56oc() {
6317         test_newerXY_base "a" "a"
6318         test_newerXY_base "a" "m"
6319         test_newerXY_base "a" "c"
6320         test_newerXY_base "m" "a"
6321         test_newerXY_base "m" "m"
6322         test_newerXY_base "m" "c"
6323         test_newerXY_base "c" "a"
6324         test_newerXY_base "c" "m"
6325         test_newerXY_base "c" "c"
6326
6327         [[ -n "$sles_version" ]] &&
6328                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6329
6330         test_newerXY_base "a" "t"
6331         test_newerXY_base "m" "t"
6332         test_newerXY_base "c" "t"
6333
6334         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6335            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6336                 ! btime_supported && echo "btime unsupported" && return 0
6337
6338         test_newerXY_base "b" "b"
6339         test_newerXY_base "b" "t"
6340 }
6341 run_test 56oc "check lfs find -newerXY work"
6342
6343 btime_supported() {
6344         local dir=$DIR/$tdir
6345         local rc
6346
6347         mkdir -p $dir
6348         touch $dir/$tfile
6349         $LFS find $dir -btime -1d -type f
6350         rc=$?
6351         rm -rf $dir
6352         return $rc
6353 }
6354
6355 test_56od() {
6356         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6357                 ! btime_supported && skip "btime unsupported on MDS"
6358
6359         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6360                 ! btime_supported && skip "btime unsupported on clients"
6361
6362         local dir=$DIR/$tdir
6363         local ref=$DIR/$tfile.ref
6364         local negref=$DIR/$tfile.negref
6365
6366         mkdir $dir || error "mkdir $dir failed"
6367         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6368         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6369         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6370         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6371         touch $ref || error "touch $ref failed"
6372         # sleep 3 seconds at least
6373         sleep 3
6374
6375         local before=$(do_facet mds1 date +%s)
6376         local skew=$(($(date +%s) - before + 1))
6377
6378         if (( skew < 0 && skew > -5 )); then
6379                 sleep $((0 - skew + 1))
6380                 skew=0
6381         fi
6382
6383         # Set the dir stripe params to limit files all on MDT0,
6384         # otherwise we need to calc the max clock skew between
6385         # the client and MDTs.
6386         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6387         sleep 2
6388         touch $negref || error "touch $negref failed"
6389
6390         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6391         local nums=$($cmd | wc -l)
6392         local expected=$(((NUMFILES + 1) * NUMDIRS))
6393
6394         [ $nums -eq $expected ] ||
6395                 error "'$cmd' wrong: found $nums, expected $expected"
6396
6397         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6398         nums=$($cmd | wc -l)
6399         expected=$((NUMFILES + 1))
6400         [ $nums -eq $expected ] ||
6401                 error "'$cmd' wrong: found $nums, expected $expected"
6402
6403         [ $skew -lt 0 ] && return
6404
6405         local after=$(do_facet mds1 date +%s)
6406         local age=$((after - before + 1 + skew))
6407
6408         cmd="$LFS find $dir -btime -${age}s -type f"
6409         nums=$($cmd | wc -l)
6410         expected=$(((NUMFILES + 1) * NUMDIRS))
6411
6412         echo "Clock skew between client and server: $skew, age:$age"
6413         [ $nums -eq $expected ] ||
6414                 error "'$cmd' wrong: found $nums, expected $expected"
6415
6416         expected=$(($NUMDIRS + 1))
6417         cmd="$LFS find $dir -btime -${age}s -type d"
6418         nums=$($cmd | wc -l)
6419         [ $nums -eq $expected ] ||
6420                 error "'$cmd' wrong: found $nums, expected $expected"
6421         rm -f $ref $negref || error "Failed to remove $ref $negref"
6422 }
6423 run_test 56od "check lfs find -btime with units"
6424
6425 test_56p() {
6426         [ $RUNAS_ID -eq $UID ] &&
6427                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6428
6429         local dir=$DIR/$tdir
6430
6431         setup_56 $dir $NUMFILES $NUMDIRS
6432         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6433
6434         local expected=$NUMFILES
6435         local cmd="$LFS find -uid $RUNAS_ID $dir"
6436         local nums=$($cmd | wc -l)
6437
6438         [ $nums -eq $expected ] ||
6439                 error "'$cmd' wrong: found $nums, expected $expected"
6440
6441         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6442         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6443         nums=$($cmd | wc -l)
6444         [ $nums -eq $expected ] ||
6445                 error "'$cmd' wrong: found $nums, expected $expected"
6446 }
6447 run_test 56p "check lfs find -uid and ! -uid"
6448
6449 test_56q() {
6450         [ $RUNAS_ID -eq $UID ] &&
6451                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6452
6453         local dir=$DIR/$tdir
6454
6455         setup_56 $dir $NUMFILES $NUMDIRS
6456         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6457
6458         local expected=$NUMFILES
6459         local cmd="$LFS find -gid $RUNAS_GID $dir"
6460         local nums=$($cmd | wc -l)
6461
6462         [ $nums -eq $expected ] ||
6463                 error "'$cmd' wrong: found $nums, expected $expected"
6464
6465         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6466         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6467         nums=$($cmd | wc -l)
6468         [ $nums -eq $expected ] ||
6469                 error "'$cmd' wrong: found $nums, expected $expected"
6470 }
6471 run_test 56q "check lfs find -gid and ! -gid"
6472
6473 test_56r() {
6474         local dir=$DIR/$tdir
6475
6476         setup_56 $dir $NUMFILES $NUMDIRS
6477
6478         local expected=12
6479         local cmd="$LFS find -size 0 -type f -lazy $dir"
6480         local nums=$($cmd | wc -l)
6481
6482         [ $nums -eq $expected ] ||
6483                 error "'$cmd' wrong: found $nums, expected $expected"
6484         cmd="$LFS find -size 0 -type f $dir"
6485         nums=$($cmd | wc -l)
6486         [ $nums -eq $expected ] ||
6487                 error "'$cmd' wrong: found $nums, expected $expected"
6488
6489         expected=0
6490         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6491         nums=$($cmd | wc -l)
6492         [ $nums -eq $expected ] ||
6493                 error "'$cmd' wrong: found $nums, expected $expected"
6494         cmd="$LFS find ! -size 0 -type f $dir"
6495         nums=$($cmd | wc -l)
6496         [ $nums -eq $expected ] ||
6497                 error "'$cmd' wrong: found $nums, expected $expected"
6498
6499         echo "test" > $dir/$tfile
6500         echo "test2" > $dir/$tfile.2 && sync
6501         expected=1
6502         cmd="$LFS find -size 5 -type f -lazy $dir"
6503         nums=$($cmd | wc -l)
6504         [ $nums -eq $expected ] ||
6505                 error "'$cmd' wrong: found $nums, expected $expected"
6506         cmd="$LFS find -size 5 -type f $dir"
6507         nums=$($cmd | wc -l)
6508         [ $nums -eq $expected ] ||
6509                 error "'$cmd' wrong: found $nums, expected $expected"
6510
6511         expected=1
6512         cmd="$LFS find -size +5 -type f -lazy $dir"
6513         nums=$($cmd | wc -l)
6514         [ $nums -eq $expected ] ||
6515                 error "'$cmd' wrong: found $nums, expected $expected"
6516         cmd="$LFS find -size +5 -type f $dir"
6517         nums=$($cmd | wc -l)
6518         [ $nums -eq $expected ] ||
6519                 error "'$cmd' wrong: found $nums, expected $expected"
6520
6521         expected=2
6522         cmd="$LFS find -size +0 -type f -lazy $dir"
6523         nums=$($cmd | wc -l)
6524         [ $nums -eq $expected ] ||
6525                 error "'$cmd' wrong: found $nums, expected $expected"
6526         cmd="$LFS find -size +0 -type f $dir"
6527         nums=$($cmd | wc -l)
6528         [ $nums -eq $expected ] ||
6529                 error "'$cmd' wrong: found $nums, expected $expected"
6530
6531         expected=2
6532         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6533         nums=$($cmd | wc -l)
6534         [ $nums -eq $expected ] ||
6535                 error "'$cmd' wrong: found $nums, expected $expected"
6536         cmd="$LFS find ! -size -5 -type f $dir"
6537         nums=$($cmd | wc -l)
6538         [ $nums -eq $expected ] ||
6539                 error "'$cmd' wrong: found $nums, expected $expected"
6540
6541         expected=12
6542         cmd="$LFS find -size -5 -type f -lazy $dir"
6543         nums=$($cmd | wc -l)
6544         [ $nums -eq $expected ] ||
6545                 error "'$cmd' wrong: found $nums, expected $expected"
6546         cmd="$LFS find -size -5 -type f $dir"
6547         nums=$($cmd | wc -l)
6548         [ $nums -eq $expected ] ||
6549                 error "'$cmd' wrong: found $nums, expected $expected"
6550 }
6551 run_test 56r "check lfs find -size works"
6552
6553 test_56ra_sub() {
6554         local expected=$1
6555         local glimpses=$2
6556         local cmd="$3"
6557
6558         cancel_lru_locks $OSC
6559
6560         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6561         local nums=$($cmd | wc -l)
6562
6563         [ $nums -eq $expected ] ||
6564                 error "'$cmd' wrong: found $nums, expected $expected"
6565
6566         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6567
6568         if (( rpcs_before + glimpses != rpcs_after )); then
6569                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6570                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6571
6572                 if [[ $glimpses == 0 ]]; then
6573                         error "'$cmd' should not send glimpse RPCs to OST"
6574                 else
6575                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6576                 fi
6577         fi
6578 }
6579
6580 test_56ra() {
6581         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6582                 skip "MDS < 2.12.58 doesn't return LSOM data"
6583         local dir=$DIR/$tdir
6584         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6585
6586         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6587
6588         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6589         $LCTL set_param -n llite.*.statahead_agl=0
6590         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6591
6592         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6593         # open and close all files to ensure LSOM is updated
6594         cancel_lru_locks $OSC
6595         find $dir -type f | xargs cat > /dev/null
6596
6597         #   expect_found  glimpse_rpcs  command_to_run
6598         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6599         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6600         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6601         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6602
6603         echo "test" > $dir/$tfile
6604         echo "test2" > $dir/$tfile.2 && sync
6605         cancel_lru_locks $OSC
6606         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6607
6608         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6609         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6610         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6611         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6612
6613         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6614         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6615         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6616         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6617         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6618         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6619 }
6620 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6621
6622 test_56rb() {
6623         local dir=$DIR/$tdir
6624         local tmp=$TMP/$tfile.log
6625         local mdt_idx;
6626
6627         test_mkdir -p $dir || error "failed to mkdir $dir"
6628         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6629                 error "failed to setstripe $dir/$tfile"
6630         mdt_idx=$($LFS getdirstripe -i $dir)
6631         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6632
6633         stack_trap "rm -f $tmp" EXIT
6634         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6635         ! grep -q obd_uuid $tmp ||
6636                 error "failed to find --size +100K --ost 0 $dir"
6637         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6638         ! grep -q obd_uuid $tmp ||
6639                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6640 }
6641 run_test 56rb "check lfs find --size --ost/--mdt works"
6642
6643 test_56s() { # LU-611 #LU-9369
6644         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6645
6646         local dir=$DIR/$tdir
6647         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6648
6649         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6650         for i in $(seq $NUMDIRS); do
6651                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6652         done
6653
6654         local expected=$NUMDIRS
6655         local cmd="$LFS find -c $OSTCOUNT $dir"
6656         local nums=$($cmd | wc -l)
6657
6658         [ $nums -eq $expected ] || {
6659                 $LFS getstripe -R $dir
6660                 error "'$cmd' wrong: found $nums, expected $expected"
6661         }
6662
6663         expected=$((NUMDIRS + onestripe))
6664         cmd="$LFS find -stripe-count +0 -type f $dir"
6665         nums=$($cmd | wc -l)
6666         [ $nums -eq $expected ] || {
6667                 $LFS getstripe -R $dir
6668                 error "'$cmd' wrong: found $nums, expected $expected"
6669         }
6670
6671         expected=$onestripe
6672         cmd="$LFS find -stripe-count 1 -type f $dir"
6673         nums=$($cmd | wc -l)
6674         [ $nums -eq $expected ] || {
6675                 $LFS getstripe -R $dir
6676                 error "'$cmd' wrong: found $nums, expected $expected"
6677         }
6678
6679         cmd="$LFS find -stripe-count -2 -type f $dir"
6680         nums=$($cmd | wc -l)
6681         [ $nums -eq $expected ] || {
6682                 $LFS getstripe -R $dir
6683                 error "'$cmd' wrong: found $nums, expected $expected"
6684         }
6685
6686         expected=0
6687         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6688         nums=$($cmd | wc -l)
6689         [ $nums -eq $expected ] || {
6690                 $LFS getstripe -R $dir
6691                 error "'$cmd' wrong: found $nums, expected $expected"
6692         }
6693 }
6694 run_test 56s "check lfs find -stripe-count works"
6695
6696 test_56t() { # LU-611 #LU-9369
6697         local dir=$DIR/$tdir
6698
6699         setup_56 $dir 0 $NUMDIRS
6700         for i in $(seq $NUMDIRS); do
6701                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6702         done
6703
6704         local expected=$NUMDIRS
6705         local cmd="$LFS find -S 8M $dir"
6706         local nums=$($cmd | wc -l)
6707
6708         [ $nums -eq $expected ] || {
6709                 $LFS getstripe -R $dir
6710                 error "'$cmd' wrong: found $nums, expected $expected"
6711         }
6712         rm -rf $dir
6713
6714         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6715
6716         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6717
6718         expected=$(((NUMDIRS + 1) * NUMFILES))
6719         cmd="$LFS find -stripe-size 512k -type f $dir"
6720         nums=$($cmd | wc -l)
6721         [ $nums -eq $expected ] ||
6722                 error "'$cmd' wrong: found $nums, expected $expected"
6723
6724         cmd="$LFS find -stripe-size +320k -type f $dir"
6725         nums=$($cmd | wc -l)
6726         [ $nums -eq $expected ] ||
6727                 error "'$cmd' wrong: found $nums, expected $expected"
6728
6729         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6730         cmd="$LFS find -stripe-size +200k -type f $dir"
6731         nums=$($cmd | wc -l)
6732         [ $nums -eq $expected ] ||
6733                 error "'$cmd' wrong: found $nums, expected $expected"
6734
6735         cmd="$LFS find -stripe-size -640k -type f $dir"
6736         nums=$($cmd | wc -l)
6737         [ $nums -eq $expected ] ||
6738                 error "'$cmd' wrong: found $nums, expected $expected"
6739
6740         expected=4
6741         cmd="$LFS find -stripe-size 256k -type f $dir"
6742         nums=$($cmd | wc -l)
6743         [ $nums -eq $expected ] ||
6744                 error "'$cmd' wrong: found $nums, expected $expected"
6745
6746         cmd="$LFS find -stripe-size -320k -type f $dir"
6747         nums=$($cmd | wc -l)
6748         [ $nums -eq $expected ] ||
6749                 error "'$cmd' wrong: found $nums, expected $expected"
6750
6751         expected=0
6752         cmd="$LFS find -stripe-size 1024k -type f $dir"
6753         nums=$($cmd | wc -l)
6754         [ $nums -eq $expected ] ||
6755                 error "'$cmd' wrong: found $nums, expected $expected"
6756 }
6757 run_test 56t "check lfs find -stripe-size works"
6758
6759 test_56u() { # LU-611
6760         local dir=$DIR/$tdir
6761
6762         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6763
6764         if [[ $OSTCOUNT -gt 1 ]]; then
6765                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6766                 onestripe=4
6767         else
6768                 onestripe=0
6769         fi
6770
6771         local expected=$(((NUMDIRS + 1) * NUMFILES))
6772         local cmd="$LFS find -stripe-index 0 -type f $dir"
6773         local nums=$($cmd | wc -l)
6774
6775         [ $nums -eq $expected ] ||
6776                 error "'$cmd' wrong: found $nums, expected $expected"
6777
6778         expected=$onestripe
6779         cmd="$LFS find -stripe-index 1 -type f $dir"
6780         nums=$($cmd | wc -l)
6781         [ $nums -eq $expected ] ||
6782                 error "'$cmd' wrong: found $nums, expected $expected"
6783
6784         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6785         nums=$($cmd | wc -l)
6786         [ $nums -eq $expected ] ||
6787                 error "'$cmd' wrong: found $nums, expected $expected"
6788
6789         expected=0
6790         # This should produce an error and not return any files
6791         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6792         nums=$($cmd 2>/dev/null | wc -l)
6793         [ $nums -eq $expected ] ||
6794                 error "'$cmd' wrong: found $nums, expected $expected"
6795
6796         if [[ $OSTCOUNT -gt 1 ]]; then
6797                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6798                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6799                 nums=$($cmd | wc -l)
6800                 [ $nums -eq $expected ] ||
6801                         error "'$cmd' wrong: found $nums, expected $expected"
6802         fi
6803 }
6804 run_test 56u "check lfs find -stripe-index works"
6805
6806 test_56v() {
6807         local mdt_idx=0
6808         local dir=$DIR/$tdir
6809
6810         setup_56 $dir $NUMFILES $NUMDIRS
6811
6812         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6813         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6814
6815         for file in $($LFS find -m $UUID $dir); do
6816                 file_midx=$($LFS getstripe -m $file)
6817                 [ $file_midx -eq $mdt_idx ] ||
6818                         error "lfs find -m $UUID != getstripe -m $file_midx"
6819         done
6820 }
6821 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6822
6823 test_56w() {
6824         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6826
6827         local dir=$DIR/$tdir
6828
6829         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6830
6831         local stripe_size=$($LFS getstripe -S -d $dir) ||
6832                 error "$LFS getstripe -S -d $dir failed"
6833         stripe_size=${stripe_size%% *}
6834
6835         local file_size=$((stripe_size * OSTCOUNT))
6836         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6837         local required_space=$((file_num * file_size))
6838         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6839                            head -n1)
6840         [[ $free_space -le $((required_space / 1024)) ]] &&
6841                 skip_env "need $required_space, have $free_space kbytes"
6842
6843         local dd_bs=65536
6844         local dd_count=$((file_size / dd_bs))
6845
6846         # write data into the files
6847         local i
6848         local j
6849         local file
6850
6851         for i in $(seq $NUMFILES); do
6852                 file=$dir/file$i
6853                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6854                         error "write data into $file failed"
6855         done
6856         for i in $(seq $NUMDIRS); do
6857                 for j in $(seq $NUMFILES); do
6858                         file=$dir/dir$i/file$j
6859                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6860                                 error "write data into $file failed"
6861                 done
6862         done
6863
6864         # $LFS_MIGRATE will fail if hard link migration is unsupported
6865         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6866                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6867                         error "creating links to $dir/dir1/file1 failed"
6868         fi
6869
6870         local expected=-1
6871
6872         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6873
6874         # lfs_migrate file
6875         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6876
6877         echo "$cmd"
6878         eval $cmd || error "$cmd failed"
6879
6880         check_stripe_count $dir/file1 $expected
6881
6882         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6883         then
6884                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6885                 # OST 1 if it is on OST 0. This file is small enough to
6886                 # be on only one stripe.
6887                 file=$dir/migr_1_ost
6888                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6889                         error "write data into $file failed"
6890                 local obdidx=$($LFS getstripe -i $file)
6891                 local oldmd5=$(md5sum $file)
6892                 local newobdidx=0
6893
6894                 [[ $obdidx -eq 0 ]] && newobdidx=1
6895                 cmd="$LFS migrate -i $newobdidx $file"
6896                 echo $cmd
6897                 eval $cmd || error "$cmd failed"
6898
6899                 local realobdix=$($LFS getstripe -i $file)
6900                 local newmd5=$(md5sum $file)
6901
6902                 [[ $newobdidx -ne $realobdix ]] &&
6903                         error "new OST is different (was=$obdidx, "\
6904                               "wanted=$newobdidx, got=$realobdix)"
6905                 [[ "$oldmd5" != "$newmd5" ]] &&
6906                         error "md5sum differ: $oldmd5, $newmd5"
6907         fi
6908
6909         # lfs_migrate dir
6910         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6911         echo "$cmd"
6912         eval $cmd || error "$cmd failed"
6913
6914         for j in $(seq $NUMFILES); do
6915                 check_stripe_count $dir/dir1/file$j $expected
6916         done
6917
6918         # lfs_migrate works with lfs find
6919         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6920              $LFS_MIGRATE -y -c $expected"
6921         echo "$cmd"
6922         eval $cmd || error "$cmd failed"
6923
6924         for i in $(seq 2 $NUMFILES); do
6925                 check_stripe_count $dir/file$i $expected
6926         done
6927         for i in $(seq 2 $NUMDIRS); do
6928                 for j in $(seq $NUMFILES); do
6929                 check_stripe_count $dir/dir$i/file$j $expected
6930                 done
6931         done
6932 }
6933 run_test 56w "check lfs_migrate -c stripe_count works"
6934
6935 test_56wb() {
6936         local file1=$DIR/$tdir/file1
6937         local create_pool=false
6938         local initial_pool=$($LFS getstripe -p $DIR)
6939         local pool_list=()
6940         local pool=""
6941
6942         echo -n "Creating test dir..."
6943         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6944         echo "done."
6945
6946         echo -n "Creating test file..."
6947         touch $file1 || error "cannot create file"
6948         echo "done."
6949
6950         echo -n "Detecting existing pools..."
6951         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6952
6953         if [ ${#pool_list[@]} -gt 0 ]; then
6954                 echo "${pool_list[@]}"
6955                 for thispool in "${pool_list[@]}"; do
6956                         if [[ -z "$initial_pool" ||
6957                               "$initial_pool" != "$thispool" ]]; then
6958                                 pool="$thispool"
6959                                 echo "Using existing pool '$pool'"
6960                                 break
6961                         fi
6962                 done
6963         else
6964                 echo "none detected."
6965         fi
6966         if [ -z "$pool" ]; then
6967                 pool=${POOL:-testpool}
6968                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6969                 echo -n "Creating pool '$pool'..."
6970                 create_pool=true
6971                 pool_add $pool &> /dev/null ||
6972                         error "pool_add failed"
6973                 echo "done."
6974
6975                 echo -n "Adding target to pool..."
6976                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6977                         error "pool_add_targets failed"
6978                 echo "done."
6979         fi
6980
6981         echo -n "Setting pool using -p option..."
6982         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6983                 error "migrate failed rc = $?"
6984         echo "done."
6985
6986         echo -n "Verifying test file is in pool after migrating..."
6987         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6988                 error "file was not migrated to pool $pool"
6989         echo "done."
6990
6991         echo -n "Removing test file from pool '$pool'..."
6992         # "lfs migrate $file" won't remove the file from the pool
6993         # until some striping information is changed.
6994         $LFS migrate -c 1 $file1 &> /dev/null ||
6995                 error "cannot remove from pool"
6996         [ "$($LFS getstripe -p $file1)" ] &&
6997                 error "pool still set"
6998         echo "done."
6999
7000         echo -n "Setting pool using --pool option..."
7001         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7002                 error "migrate failed rc = $?"
7003         echo "done."
7004
7005         # Clean up
7006         rm -f $file1
7007         if $create_pool; then
7008                 destroy_test_pools 2> /dev/null ||
7009                         error "destroy test pools failed"
7010         fi
7011 }
7012 run_test 56wb "check lfs_migrate pool support"
7013
7014 test_56wc() {
7015         local file1="$DIR/$tdir/file1"
7016         local parent_ssize
7017         local parent_scount
7018         local cur_ssize
7019         local cur_scount
7020         local orig_ssize
7021
7022         echo -n "Creating test dir..."
7023         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7024         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7025                 error "cannot set stripe by '-S 1M -c 1'"
7026         echo "done"
7027
7028         echo -n "Setting initial stripe for test file..."
7029         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7030                 error "cannot set stripe"
7031         cur_ssize=$($LFS getstripe -S "$file1")
7032         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7033         echo "done."
7034
7035         # File currently set to -S 512K -c 1
7036
7037         # Ensure -c and -S options are rejected when -R is set
7038         echo -n "Verifying incompatible options are detected..."
7039         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7040                 error "incompatible -c and -R options not detected"
7041         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7042                 error "incompatible -S and -R options not detected"
7043         echo "done."
7044
7045         # Ensure unrecognized options are passed through to 'lfs migrate'
7046         echo -n "Verifying -S option is passed through to lfs migrate..."
7047         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7048                 error "migration failed"
7049         cur_ssize=$($LFS getstripe -S "$file1")
7050         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7051         echo "done."
7052
7053         # File currently set to -S 1M -c 1
7054
7055         # Ensure long options are supported
7056         echo -n "Verifying long options supported..."
7057         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7058                 error "long option without argument not supported"
7059         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7060                 error "long option with argument not supported"
7061         cur_ssize=$($LFS getstripe -S "$file1")
7062         [ $cur_ssize -eq 524288 ] ||
7063                 error "migrate --stripe-size $cur_ssize != 524288"
7064         echo "done."
7065
7066         # File currently set to -S 512K -c 1
7067
7068         if [ "$OSTCOUNT" -gt 1 ]; then
7069                 echo -n "Verifying explicit stripe count can be set..."
7070                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7071                         error "migrate failed"
7072                 cur_scount=$($LFS getstripe -c "$file1")
7073                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7074                 echo "done."
7075         fi
7076
7077         # File currently set to -S 512K -c 1 or -S 512K -c 2
7078
7079         # Ensure parent striping is used if -R is set, and no stripe
7080         # count or size is specified
7081         echo -n "Setting stripe for parent directory..."
7082         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7083                 error "cannot set stripe '-S 2M -c 1'"
7084         echo "done."
7085
7086         echo -n "Verifying restripe option uses parent stripe settings..."
7087         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7088         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7089         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7090                 error "migrate failed"
7091         cur_ssize=$($LFS getstripe -S "$file1")
7092         [ $cur_ssize -eq $parent_ssize ] ||
7093                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7094         cur_scount=$($LFS getstripe -c "$file1")
7095         [ $cur_scount -eq $parent_scount ] ||
7096                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7097         echo "done."
7098
7099         # File currently set to -S 1M -c 1
7100
7101         # Ensure striping is preserved if -R is not set, and no stripe
7102         # count or size is specified
7103         echo -n "Verifying striping size preserved when not specified..."
7104         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7105         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7106                 error "cannot set stripe on parent directory"
7107         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7108                 error "migrate failed"
7109         cur_ssize=$($LFS getstripe -S "$file1")
7110         [ $cur_ssize -eq $orig_ssize ] ||
7111                 error "migrate by default $cur_ssize != $orig_ssize"
7112         echo "done."
7113
7114         # Ensure file name properly detected when final option has no argument
7115         echo -n "Verifying file name properly detected..."
7116         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7117                 error "file name interpreted as option argument"
7118         echo "done."
7119
7120         # Clean up
7121         rm -f "$file1"
7122 }
7123 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7124
7125 test_56wd() {
7126         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7127
7128         local file1=$DIR/$tdir/file1
7129
7130         echo -n "Creating test dir..."
7131         test_mkdir $DIR/$tdir || error "cannot create dir"
7132         echo "done."
7133
7134         echo -n "Creating test file..."
7135         touch $file1
7136         echo "done."
7137
7138         # Ensure 'lfs migrate' will fail by using a non-existent option,
7139         # and make sure rsync is not called to recover
7140         echo -n "Make sure --no-rsync option works..."
7141         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7142                 grep -q 'refusing to fall back to rsync' ||
7143                 error "rsync was called with --no-rsync set"
7144         echo "done."
7145
7146         # Ensure rsync is called without trying 'lfs migrate' first
7147         echo -n "Make sure --rsync option works..."
7148         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7149                 grep -q 'falling back to rsync' &&
7150                 error "lfs migrate was called with --rsync set"
7151         echo "done."
7152
7153         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7154         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7155                 grep -q 'at the same time' ||
7156                 error "--rsync and --no-rsync accepted concurrently"
7157         echo "done."
7158
7159         # Clean up
7160         rm -f $file1
7161 }
7162 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7163
7164 test_56we() {
7165         local td=$DIR/$tdir
7166         local tf=$td/$tfile
7167
7168         test_mkdir $td || error "cannot create $td"
7169         touch $tf || error "cannot touch $tf"
7170
7171         echo -n "Make sure --non-direct|-D works..."
7172         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7173                 grep -q "lfs migrate --non-direct" ||
7174                 error "--non-direct option cannot work correctly"
7175         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7176                 grep -q "lfs migrate -D" ||
7177                 error "-D option cannot work correctly"
7178         echo "done."
7179 }
7180 run_test 56we "check lfs_migrate --non-direct|-D support"
7181
7182 test_56x() {
7183         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7184         check_swap_layouts_support
7185
7186         local dir=$DIR/$tdir
7187         local ref1=/etc/passwd
7188         local file1=$dir/file1
7189
7190         test_mkdir $dir || error "creating dir $dir"
7191         $LFS setstripe -c 2 $file1
7192         cp $ref1 $file1
7193         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7194         stripe=$($LFS getstripe -c $file1)
7195         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7196         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7197
7198         # clean up
7199         rm -f $file1
7200 }
7201 run_test 56x "lfs migration support"
7202
7203 test_56xa() {
7204         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7205         check_swap_layouts_support
7206
7207         local dir=$DIR/$tdir/$testnum
7208
7209         test_mkdir -p $dir
7210
7211         local ref1=/etc/passwd
7212         local file1=$dir/file1
7213
7214         $LFS setstripe -c 2 $file1
7215         cp $ref1 $file1
7216         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7217
7218         local stripe=$($LFS getstripe -c $file1)
7219
7220         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7221         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7222
7223         # clean up
7224         rm -f $file1
7225 }
7226 run_test 56xa "lfs migration --block support"
7227
7228 check_migrate_links() {
7229         local dir="$1"
7230         local file1="$dir/file1"
7231         local begin="$2"
7232         local count="$3"
7233         local runas="$4"
7234         local total_count=$(($begin + $count - 1))
7235         local symlink_count=10
7236         local uniq_count=10
7237
7238         if [ ! -f "$file1" ]; then
7239                 echo -n "creating initial file..."
7240                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7241                         error "cannot setstripe initial file"
7242                 echo "done"
7243
7244                 echo -n "creating symlinks..."
7245                 for s in $(seq 1 $symlink_count); do
7246                         ln -s "$file1" "$dir/slink$s" ||
7247                                 error "cannot create symlinks"
7248                 done
7249                 echo "done"
7250
7251                 echo -n "creating nonlinked files..."
7252                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7253                         error "cannot create nonlinked files"
7254                 echo "done"
7255         fi
7256
7257         # create hard links
7258         if [ ! -f "$dir/file$total_count" ]; then
7259                 echo -n "creating hard links $begin:$total_count..."
7260                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7261                         /dev/null || error "cannot create hard links"
7262                 echo "done"
7263         fi
7264
7265         echo -n "checking number of hard links listed in xattrs..."
7266         local fid=$($LFS getstripe -F "$file1")
7267         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7268
7269         echo "${#paths[*]}"
7270         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7271                         skip "hard link list has unexpected size, skipping test"
7272         fi
7273         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7274                         error "link names should exceed xattrs size"
7275         fi
7276
7277         echo -n "migrating files..."
7278         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7279         local rc=$?
7280         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7281         echo "done"
7282
7283         # make sure all links have been properly migrated
7284         echo -n "verifying files..."
7285         fid=$($LFS getstripe -F "$file1") ||
7286                 error "cannot get fid for file $file1"
7287         for i in $(seq 2 $total_count); do
7288                 local fid2=$($LFS getstripe -F $dir/file$i)
7289
7290                 [ "$fid2" == "$fid" ] ||
7291                         error "migrated hard link has mismatched FID"
7292         done
7293
7294         # make sure hard links were properly detected, and migration was
7295         # performed only once for the entire link set; nonlinked files should
7296         # also be migrated
7297         local actual=$(grep -c 'done' <<< "$migrate_out")
7298         local expected=$(($uniq_count + 1))
7299
7300         [ "$actual" -eq  "$expected" ] ||
7301                 error "hard links individually migrated ($actual != $expected)"
7302
7303         # make sure the correct number of hard links are present
7304         local hardlinks=$(stat -c '%h' "$file1")
7305
7306         [ $hardlinks -eq $total_count ] ||
7307                 error "num hard links $hardlinks != $total_count"
7308         echo "done"
7309
7310         return 0
7311 }
7312
7313 test_56xb() {
7314         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7315                 skip "Need MDS version at least 2.10.55"
7316
7317         local dir="$DIR/$tdir"
7318
7319         test_mkdir "$dir" || error "cannot create dir $dir"
7320
7321         echo "testing lfs migrate mode when all links fit within xattrs"
7322         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7323
7324         echo "testing rsync mode when all links fit within xattrs"
7325         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7326
7327         echo "testing lfs migrate mode when all links do not fit within xattrs"
7328         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7329
7330         echo "testing rsync mode when all links do not fit within xattrs"
7331         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7332
7333         chown -R $RUNAS_ID $dir
7334         echo "testing non-root lfs migrate mode when not all links are in xattr"
7335         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7336
7337         # clean up
7338         rm -rf $dir
7339 }
7340 run_test 56xb "lfs migration hard link support"
7341
7342 test_56xc() {
7343         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7344
7345         local dir="$DIR/$tdir"
7346
7347         test_mkdir "$dir" || error "cannot create dir $dir"
7348
7349         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7350         echo -n "Setting initial stripe for 20MB test file..."
7351         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7352                 error "cannot setstripe 20MB file"
7353         echo "done"
7354         echo -n "Sizing 20MB test file..."
7355         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7356         echo "done"
7357         echo -n "Verifying small file autostripe count is 1..."
7358         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7359                 error "cannot migrate 20MB file"
7360         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7361                 error "cannot get stripe for $dir/20mb"
7362         [ $stripe_count -eq 1 ] ||
7363                 error "unexpected stripe count $stripe_count for 20MB file"
7364         rm -f "$dir/20mb"
7365         echo "done"
7366
7367         # Test 2: File is small enough to fit within the available space on
7368         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7369         # have at least an additional 1KB for each desired stripe for test 3
7370         echo -n "Setting stripe for 1GB test file..."
7371         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7372         echo "done"
7373         echo -n "Sizing 1GB test file..."
7374         # File size is 1GB + 3KB
7375         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7376         echo "done"
7377
7378         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7379         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7380         if (( avail > 524288 * OSTCOUNT )); then
7381                 echo -n "Migrating 1GB file..."
7382                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7383                         error "cannot migrate 1GB file"
7384                 echo "done"
7385                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7386                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7387                         error "cannot getstripe for 1GB file"
7388                 [ $stripe_count -eq 2 ] ||
7389                         error "unexpected stripe count $stripe_count != 2"
7390                 echo "done"
7391         fi
7392
7393         # Test 3: File is too large to fit within the available space on
7394         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7395         if [ $OSTCOUNT -ge 3 ]; then
7396                 # The required available space is calculated as
7397                 # file size (1GB + 3KB) / OST count (3).
7398                 local kb_per_ost=349526
7399
7400                 echo -n "Migrating 1GB file with limit..."
7401                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7402                         error "cannot migrate 1GB file with limit"
7403                 echo "done"
7404
7405                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7406                 echo -n "Verifying 1GB autostripe count with limited space..."
7407                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7408                         error "unexpected stripe count $stripe_count (min 3)"
7409                 echo "done"
7410         fi
7411
7412         # clean up
7413         rm -rf $dir
7414 }
7415 run_test 56xc "lfs migration autostripe"
7416
7417 test_56xd() {
7418         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7419
7420         local dir=$DIR/$tdir
7421         local f_mgrt=$dir/$tfile.mgrt
7422         local f_yaml=$dir/$tfile.yaml
7423         local f_copy=$dir/$tfile.copy
7424         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7425         local layout_copy="-c 2 -S 2M -i 1"
7426         local yamlfile=$dir/yamlfile
7427         local layout_before;
7428         local layout_after;
7429
7430         test_mkdir "$dir" || error "cannot create dir $dir"
7431         $LFS setstripe $layout_yaml $f_yaml ||
7432                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7433         $LFS getstripe --yaml $f_yaml > $yamlfile
7434         $LFS setstripe $layout_copy $f_copy ||
7435                 error "cannot setstripe $f_copy with layout $layout_copy"
7436         touch $f_mgrt
7437         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7438
7439         # 1. test option --yaml
7440         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7441                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7442         layout_before=$(get_layout_param $f_yaml)
7443         layout_after=$(get_layout_param $f_mgrt)
7444         [ "$layout_after" == "$layout_before" ] ||
7445                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7446
7447         # 2. test option --copy
7448         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7449                 error "cannot migrate $f_mgrt with --copy $f_copy"
7450         layout_before=$(get_layout_param $f_copy)
7451         layout_after=$(get_layout_param $f_mgrt)
7452         [ "$layout_after" == "$layout_before" ] ||
7453                 error "lfs_migrate --copy: $layout_after != $layout_before"
7454 }
7455 run_test 56xd "check lfs_migrate --yaml and --copy support"
7456
7457 test_56xe() {
7458         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7459
7460         local dir=$DIR/$tdir
7461         local f_comp=$dir/$tfile
7462         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7463         local layout_before=""
7464         local layout_after=""
7465
7466         test_mkdir "$dir" || error "cannot create dir $dir"
7467         $LFS setstripe $layout $f_comp ||
7468                 error "cannot setstripe $f_comp with layout $layout"
7469         layout_before=$(get_layout_param $f_comp)
7470         dd if=/dev/zero of=$f_comp bs=1M count=4
7471
7472         # 1. migrate a comp layout file by lfs_migrate
7473         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7474         layout_after=$(get_layout_param $f_comp)
7475         [ "$layout_before" == "$layout_after" ] ||
7476                 error "lfs_migrate: $layout_before != $layout_after"
7477
7478         # 2. migrate a comp layout file by lfs migrate
7479         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7480         layout_after=$(get_layout_param $f_comp)
7481         [ "$layout_before" == "$layout_after" ] ||
7482                 error "lfs migrate: $layout_before != $layout_after"
7483 }
7484 run_test 56xe "migrate a composite layout file"
7485
7486 test_56xf() {
7487         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7488
7489         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7490                 skip "Need server version at least 2.13.53"
7491
7492         local dir=$DIR/$tdir
7493         local f_comp=$dir/$tfile
7494         local layout="-E 1M -c1 -E -1 -c2"
7495         local fid_before=""
7496         local fid_after=""
7497
7498         test_mkdir "$dir" || error "cannot create dir $dir"
7499         $LFS setstripe $layout $f_comp ||
7500                 error "cannot setstripe $f_comp with layout $layout"
7501         fid_before=$($LFS getstripe --fid $f_comp)
7502         dd if=/dev/zero of=$f_comp bs=1M count=4
7503
7504         # 1. migrate a comp layout file to a comp layout
7505         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7506         fid_after=$($LFS getstripe --fid $f_comp)
7507         [ "$fid_before" == "$fid_after" ] ||
7508                 error "comp-to-comp migrate: $fid_before != $fid_after"
7509
7510         # 2. migrate a comp layout file to a plain layout
7511         $LFS migrate -c2 $f_comp ||
7512                 error "cannot migrate $f_comp by lfs migrate"
7513         fid_after=$($LFS getstripe --fid $f_comp)
7514         [ "$fid_before" == "$fid_after" ] ||
7515                 error "comp-to-plain migrate: $fid_before != $fid_after"
7516
7517         # 3. migrate a plain layout file to a comp layout
7518         $LFS migrate $layout $f_comp ||
7519                 error "cannot migrate $f_comp by lfs migrate"
7520         fid_after=$($LFS getstripe --fid $f_comp)
7521         [ "$fid_before" == "$fid_after" ] ||
7522                 error "plain-to-comp migrate: $fid_before != $fid_after"
7523 }
7524 run_test 56xf "FID is not lost during migration of a composite layout file"
7525
7526 test_56y() {
7527         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7528                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7529
7530         local res=""
7531         local dir=$DIR/$tdir
7532         local f1=$dir/file1
7533         local f2=$dir/file2
7534
7535         test_mkdir -p $dir || error "creating dir $dir"
7536         touch $f1 || error "creating std file $f1"
7537         $MULTIOP $f2 H2c || error "creating released file $f2"
7538
7539         # a directory can be raid0, so ask only for files
7540         res=$($LFS find $dir -L raid0 -type f | wc -l)
7541         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7542
7543         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7544         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7545
7546         # only files can be released, so no need to force file search
7547         res=$($LFS find $dir -L released)
7548         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7549
7550         res=$($LFS find $dir -type f \! -L released)
7551         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7552 }
7553 run_test 56y "lfs find -L raid0|released"
7554
7555 test_56z() { # LU-4824
7556         # This checks to make sure 'lfs find' continues after errors
7557         # There are two classes of errors that should be caught:
7558         # - If multiple paths are provided, all should be searched even if one
7559         #   errors out
7560         # - If errors are encountered during the search, it should not terminate
7561         #   early
7562         local dir=$DIR/$tdir
7563         local i
7564
7565         test_mkdir $dir
7566         for i in d{0..9}; do
7567                 test_mkdir $dir/$i
7568                 touch $dir/$i/$tfile
7569         done
7570         $LFS find $DIR/non_existent_dir $dir &&
7571                 error "$LFS find did not return an error"
7572         # Make a directory unsearchable. This should NOT be the last entry in
7573         # directory order.  Arbitrarily pick the 6th entry
7574         chmod 700 $($LFS find $dir -type d | sed '6!d')
7575
7576         $RUNAS $LFS find $DIR/non_existent $dir
7577         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7578
7579         # The user should be able to see 10 directories and 9 files
7580         (( count == 19 )) ||
7581                 error "$LFS find found $count != 19 entries after error"
7582 }
7583 run_test 56z "lfs find should continue after an error"
7584
7585 test_56aa() { # LU-5937
7586         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7587
7588         local dir=$DIR/$tdir
7589
7590         mkdir $dir
7591         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7592
7593         createmany -o $dir/striped_dir/${tfile}- 1024
7594         local dirs=$($LFS find --size +8k $dir/)
7595
7596         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7597 }
7598 run_test 56aa "lfs find --size under striped dir"
7599
7600 test_56ab() { # LU-10705
7601         test_mkdir $DIR/$tdir
7602         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7603         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7604         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7605         # Flush writes to ensure valid blocks.  Need to be more thorough for
7606         # ZFS, since blocks are not allocated/returned to client immediately.
7607         sync_all_data
7608         wait_zfs_commit ost1 2
7609         cancel_lru_locks osc
7610         ls -ls $DIR/$tdir
7611
7612         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7613
7614         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7615
7616         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7617         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7618
7619         rm -f $DIR/$tdir/$tfile.[123]
7620 }
7621 run_test 56ab "lfs find --blocks"
7622
7623 test_56ba() {
7624         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7625                 skip "Need MDS version at least 2.10.50"
7626
7627         # Create composite files with one component
7628         local dir=$DIR/$tdir
7629
7630         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7631         # Create composite files with three components
7632         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7633         # Create non-composite files
7634         createmany -o $dir/${tfile}- 10
7635
7636         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7637
7638         [[ $nfiles == 10 ]] ||
7639                 error "lfs find -E 1M found $nfiles != 10 files"
7640
7641         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7642         [[ $nfiles == 25 ]] ||
7643                 error "lfs find ! -E 1M found $nfiles != 25 files"
7644
7645         # All files have a component that starts at 0
7646         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7647         [[ $nfiles == 35 ]] ||
7648                 error "lfs find --component-start 0 - $nfiles != 35 files"
7649
7650         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7651         [[ $nfiles == 15 ]] ||
7652                 error "lfs find --component-start 2M - $nfiles != 15 files"
7653
7654         # All files created here have a componenet that does not starts at 2M
7655         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7656         [[ $nfiles == 35 ]] ||
7657                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7658
7659         # Find files with a specified number of components
7660         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7661         [[ $nfiles == 15 ]] ||
7662                 error "lfs find --component-count 3 - $nfiles != 15 files"
7663
7664         # Remember non-composite files have a component count of zero
7665         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7666         [[ $nfiles == 10 ]] ||
7667                 error "lfs find --component-count 0 - $nfiles != 10 files"
7668
7669         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7670         [[ $nfiles == 20 ]] ||
7671                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7672
7673         # All files have a flag called "init"
7674         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7675         [[ $nfiles == 35 ]] ||
7676                 error "lfs find --component-flags init - $nfiles != 35 files"
7677
7678         # Multi-component files will have a component not initialized
7679         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7680         [[ $nfiles == 15 ]] ||
7681                 error "lfs find !--component-flags init - $nfiles != 15 files"
7682
7683         rm -rf $dir
7684
7685 }
7686 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7687
7688 test_56ca() {
7689         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7690                 skip "Need MDS version at least 2.10.57"
7691
7692         local td=$DIR/$tdir
7693         local tf=$td/$tfile
7694         local dir
7695         local nfiles
7696         local cmd
7697         local i
7698         local j
7699
7700         # create mirrored directories and mirrored files
7701         mkdir $td || error "mkdir $td failed"
7702         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7703         createmany -o $tf- 10 || error "create $tf- failed"
7704
7705         for i in $(seq 2); do
7706                 dir=$td/dir$i
7707                 mkdir $dir || error "mkdir $dir failed"
7708                 $LFS mirror create -N$((3 + i)) $dir ||
7709                         error "create mirrored dir $dir failed"
7710                 createmany -o $dir/$tfile- 10 ||
7711                         error "create $dir/$tfile- failed"
7712         done
7713
7714         # change the states of some mirrored files
7715         echo foo > $tf-6
7716         for i in $(seq 2); do
7717                 dir=$td/dir$i
7718                 for j in $(seq 4 9); do
7719                         echo foo > $dir/$tfile-$j
7720                 done
7721         done
7722
7723         # find mirrored files with specific mirror count
7724         cmd="$LFS find --mirror-count 3 --type f $td"
7725         nfiles=$($cmd | wc -l)
7726         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7727
7728         cmd="$LFS find ! --mirror-count 3 --type f $td"
7729         nfiles=$($cmd | wc -l)
7730         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7731
7732         cmd="$LFS find --mirror-count +2 --type f $td"
7733         nfiles=$($cmd | wc -l)
7734         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7735
7736         cmd="$LFS find --mirror-count -6 --type f $td"
7737         nfiles=$($cmd | wc -l)
7738         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7739
7740         # find mirrored files with specific file state
7741         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7742         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7743
7744         cmd="$LFS find --mirror-state=ro --type f $td"
7745         nfiles=$($cmd | wc -l)
7746         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7747
7748         cmd="$LFS find ! --mirror-state=ro --type f $td"
7749         nfiles=$($cmd | wc -l)
7750         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7751
7752         cmd="$LFS find --mirror-state=wp --type f $td"
7753         nfiles=$($cmd | wc -l)
7754         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7755
7756         cmd="$LFS find ! --mirror-state=sp --type f $td"
7757         nfiles=$($cmd | wc -l)
7758         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7759 }
7760 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7761
7762 test_57a() {
7763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7764         # note test will not do anything if MDS is not local
7765         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7766                 skip_env "ldiskfs only test"
7767         fi
7768         remote_mds_nodsh && skip "remote MDS with nodsh"
7769
7770         local MNTDEV="osd*.*MDT*.mntdev"
7771         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7772         [ -z "$DEV" ] && error "can't access $MNTDEV"
7773         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7774                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7775                         error "can't access $DEV"
7776                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7777                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7778                 rm $TMP/t57a.dump
7779         done
7780 }
7781 run_test 57a "verify MDS filesystem created with large inodes =="
7782
7783 test_57b() {
7784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7785         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7786                 skip_env "ldiskfs only test"
7787         fi
7788         remote_mds_nodsh && skip "remote MDS with nodsh"
7789
7790         local dir=$DIR/$tdir
7791         local filecount=100
7792         local file1=$dir/f1
7793         local fileN=$dir/f$filecount
7794
7795         rm -rf $dir || error "removing $dir"
7796         test_mkdir -c1 $dir
7797         local mdtidx=$($LFS getstripe -m $dir)
7798         local mdtname=MDT$(printf %04x $mdtidx)
7799         local facet=mds$((mdtidx + 1))
7800
7801         echo "mcreating $filecount files"
7802         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7803
7804         # verify that files do not have EAs yet
7805         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7806                 error "$file1 has an EA"
7807         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7808                 error "$fileN has an EA"
7809
7810         sync
7811         sleep 1
7812         df $dir  #make sure we get new statfs data
7813         local mdsfree=$(do_facet $facet \
7814                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7815         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7816         local file
7817
7818         echo "opening files to create objects/EAs"
7819         for file in $(seq -f $dir/f%g 1 $filecount); do
7820                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7821                         error "opening $file"
7822         done
7823
7824         # verify that files have EAs now
7825         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7826         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7827
7828         sleep 1  #make sure we get new statfs data
7829         df $dir
7830         local mdsfree2=$(do_facet $facet \
7831                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7832         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7833
7834         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7835                 if [ "$mdsfree" != "$mdsfree2" ]; then
7836                         error "MDC before $mdcfree != after $mdcfree2"
7837                 else
7838                         echo "MDC before $mdcfree != after $mdcfree2"
7839                         echo "unable to confirm if MDS has large inodes"
7840                 fi
7841         fi
7842         rm -rf $dir
7843 }
7844 run_test 57b "default LOV EAs are stored inside large inodes ==="
7845
7846 test_58() {
7847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7848         [ -z "$(which wiretest 2>/dev/null)" ] &&
7849                         skip_env "could not find wiretest"
7850
7851         wiretest
7852 }
7853 run_test 58 "verify cross-platform wire constants =============="
7854
7855 test_59() {
7856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7857
7858         echo "touch 130 files"
7859         createmany -o $DIR/f59- 130
7860         echo "rm 130 files"
7861         unlinkmany $DIR/f59- 130
7862         sync
7863         # wait for commitment of removal
7864         wait_delete_completed
7865 }
7866 run_test 59 "verify cancellation of llog records async ========="
7867
7868 TEST60_HEAD="test_60 run $RANDOM"
7869 test_60a() {
7870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7871         remote_mgs_nodsh && skip "remote MGS with nodsh"
7872         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7873                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7874                         skip_env "missing subtest run-llog.sh"
7875
7876         log "$TEST60_HEAD - from kernel mode"
7877         do_facet mgs "$LCTL dk > /dev/null"
7878         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7879         do_facet mgs $LCTL dk > $TMP/$tfile
7880
7881         # LU-6388: test llog_reader
7882         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7883         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7884         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7885                         skip_env "missing llog_reader"
7886         local fstype=$(facet_fstype mgs)
7887         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7888                 skip_env "Only for ldiskfs or zfs type mgs"
7889
7890         local mntpt=$(facet_mntpt mgs)
7891         local mgsdev=$(mgsdevname 1)
7892         local fid_list
7893         local fid
7894         local rec_list
7895         local rec
7896         local rec_type
7897         local obj_file
7898         local path
7899         local seq
7900         local oid
7901         local pass=true
7902
7903         #get fid and record list
7904         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7905                 tail -n 4))
7906         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7907                 tail -n 4))
7908         #remount mgs as ldiskfs or zfs type
7909         stop mgs || error "stop mgs failed"
7910         mount_fstype mgs || error "remount mgs failed"
7911         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7912                 fid=${fid_list[i]}
7913                 rec=${rec_list[i]}
7914                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7915                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7916                 oid=$((16#$oid))
7917
7918                 case $fstype in
7919                         ldiskfs )
7920                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7921                         zfs )
7922                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7923                 esac
7924                 echo "obj_file is $obj_file"
7925                 do_facet mgs $llog_reader $obj_file
7926
7927                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7928                         awk '{ print $3 }' | sed -e "s/^type=//g")
7929                 if [ $rec_type != $rec ]; then
7930                         echo "FAILED test_60a wrong record type $rec_type," \
7931                               "should be $rec"
7932                         pass=false
7933                         break
7934                 fi
7935
7936                 #check obj path if record type is LLOG_LOGID_MAGIC
7937                 if [ "$rec" == "1064553b" ]; then
7938                         path=$(do_facet mgs $llog_reader $obj_file |
7939                                 grep "path=" | awk '{ print $NF }' |
7940                                 sed -e "s/^path=//g")
7941                         if [ $obj_file != $mntpt/$path ]; then
7942                                 echo "FAILED test_60a wrong obj path" \
7943                                       "$montpt/$path, should be $obj_file"
7944                                 pass=false
7945                                 break
7946                         fi
7947                 fi
7948         done
7949         rm -f $TMP/$tfile
7950         #restart mgs before "error", otherwise it will block the next test
7951         stop mgs || error "stop mgs failed"
7952         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7953         $pass || error "test failed, see FAILED test_60a messages for specifics"
7954 }
7955 run_test 60a "llog_test run from kernel module and test llog_reader"
7956
7957 test_60b() { # bug 6411
7958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7959
7960         dmesg > $DIR/$tfile
7961         LLOG_COUNT=$(do_facet mgs dmesg |
7962                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7963                           /llog_[a-z]*.c:[0-9]/ {
7964                                 if (marker)
7965                                         from_marker++
7966                                 from_begin++
7967                           }
7968                           END {
7969                                 if (marker)
7970                                         print from_marker
7971                                 else
7972                                         print from_begin
7973                           }")
7974
7975         [[ $LLOG_COUNT -gt 120 ]] &&
7976                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7977 }
7978 run_test 60b "limit repeated messages from CERROR/CWARN"
7979
7980 test_60c() {
7981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7982
7983         echo "create 5000 files"
7984         createmany -o $DIR/f60c- 5000
7985 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7986         lctl set_param fail_loc=0x80000137
7987         unlinkmany $DIR/f60c- 5000
7988         lctl set_param fail_loc=0
7989 }
7990 run_test 60c "unlink file when mds full"
7991
7992 test_60d() {
7993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7994
7995         SAVEPRINTK=$(lctl get_param -n printk)
7996         # verify "lctl mark" is even working"
7997         MESSAGE="test message ID $RANDOM $$"
7998         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7999         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8000
8001         lctl set_param printk=0 || error "set lnet.printk failed"
8002         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8003         MESSAGE="new test message ID $RANDOM $$"
8004         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8005         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8006         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8007
8008         lctl set_param -n printk="$SAVEPRINTK"
8009 }
8010 run_test 60d "test printk console message masking"
8011
8012 test_60e() {
8013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8014         remote_mds_nodsh && skip "remote MDS with nodsh"
8015
8016         touch $DIR/$tfile
8017 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8018         do_facet mds1 lctl set_param fail_loc=0x15b
8019         rm $DIR/$tfile
8020 }
8021 run_test 60e "no space while new llog is being created"
8022
8023 test_60g() {
8024         local pid
8025         local i
8026
8027         test_mkdir -c $MDSCOUNT $DIR/$tdir
8028
8029         (
8030                 local index=0
8031                 while true; do
8032                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8033                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8034                                 2>/dev/null
8035                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8036                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8037                         index=$((index + 1))
8038                 done
8039         ) &
8040
8041         pid=$!
8042
8043         for i in {0..100}; do
8044                 # define OBD_FAIL_OSD_TXN_START    0x19a
8045                 local index=$((i % MDSCOUNT + 1))
8046
8047                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8048                         > /dev/null
8049                 sleep 0.01
8050         done
8051
8052         kill -9 $pid
8053
8054         for i in $(seq $MDSCOUNT); do
8055                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8056         done
8057
8058         mkdir $DIR/$tdir/new || error "mkdir failed"
8059         rmdir $DIR/$tdir/new || error "rmdir failed"
8060
8061         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8062                 -t namespace
8063         for i in $(seq $MDSCOUNT); do
8064                 wait_update_facet mds$i "$LCTL get_param -n \
8065                         mdd.$(facet_svc mds$i).lfsck_namespace |
8066                         awk '/^status/ { print \\\$2 }'" "completed"
8067         done
8068
8069         ls -R $DIR/$tdir || error "ls failed"
8070         rm -rf $DIR/$tdir || error "rmdir failed"
8071 }
8072 run_test 60g "transaction abort won't cause MDT hung"
8073
8074 test_60h() {
8075         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8076                 skip "Need MDS version at least 2.12.52"
8077         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8078
8079         local f
8080
8081         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8082         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8083         for fail_loc in 0x80000188 0x80000189; do
8084                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8085                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8086                         error "mkdir $dir-$fail_loc failed"
8087                 for i in {0..10}; do
8088                         # create may fail on missing stripe
8089                         echo $i > $DIR/$tdir-$fail_loc/$i
8090                 done
8091                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8092                         error "getdirstripe $tdir-$fail_loc failed"
8093                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8094                         error "migrate $tdir-$fail_loc failed"
8095                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8096                         error "getdirstripe $tdir-$fail_loc failed"
8097                 pushd $DIR/$tdir-$fail_loc
8098                 for f in *; do
8099                         echo $f | cmp $f - || error "$f data mismatch"
8100                 done
8101                 popd
8102                 rm -rf $DIR/$tdir-$fail_loc
8103         done
8104 }
8105 run_test 60h "striped directory with missing stripes can be accessed"
8106
8107 test_61a() {
8108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8109
8110         f="$DIR/f61"
8111         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8112         cancel_lru_locks osc
8113         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8114         sync
8115 }
8116 run_test 61a "mmap() writes don't make sync hang ================"
8117
8118 test_61b() {
8119         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8120 }
8121 run_test 61b "mmap() of unstriped file is successful"
8122
8123 # bug 2330 - insufficient obd_match error checking causes LBUG
8124 test_62() {
8125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8126
8127         f="$DIR/f62"
8128         echo foo > $f
8129         cancel_lru_locks osc
8130         lctl set_param fail_loc=0x405
8131         cat $f && error "cat succeeded, expect -EIO"
8132         lctl set_param fail_loc=0
8133 }
8134 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8135 # match every page all of the time.
8136 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8137
8138 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8139 # Though this test is irrelevant anymore, it helped to reveal some
8140 # other grant bugs (LU-4482), let's keep it.
8141 test_63a() {   # was test_63
8142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8143
8144         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8145
8146         for i in `seq 10` ; do
8147                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8148                 sleep 5
8149                 kill $!
8150                 sleep 1
8151         done
8152
8153         rm -f $DIR/f63 || true
8154 }
8155 run_test 63a "Verify oig_wait interruption does not crash ======="
8156
8157 # bug 2248 - async write errors didn't return to application on sync
8158 # bug 3677 - async write errors left page locked
8159 test_63b() {
8160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8161
8162         debugsave
8163         lctl set_param debug=-1
8164
8165         # ensure we have a grant to do async writes
8166         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8167         rm $DIR/$tfile
8168
8169         sync    # sync lest earlier test intercept the fail_loc
8170
8171         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8172         lctl set_param fail_loc=0x80000406
8173         $MULTIOP $DIR/$tfile Owy && \
8174                 error "sync didn't return ENOMEM"
8175         sync; sleep 2; sync     # do a real sync this time to flush page
8176         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8177                 error "locked page left in cache after async error" || true
8178         debugrestore
8179 }
8180 run_test 63b "async write errors should be returned to fsync ==="
8181
8182 test_64a () {
8183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8184
8185         lfs df $DIR
8186         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8187 }
8188 run_test 64a "verify filter grant calculations (in kernel) ====="
8189
8190 test_64b () {
8191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8192
8193         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8194 }
8195 run_test 64b "check out-of-space detection on client"
8196
8197 test_64c() {
8198         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8199 }
8200 run_test 64c "verify grant shrink"
8201
8202 import_param() {
8203         local tgt=$1
8204         local param=$2
8205
8206         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8207 }
8208
8209 # this does exactly what osc_request.c:osc_announce_cached() does in
8210 # order to calculate max amount of grants to ask from server
8211 want_grant() {
8212         local tgt=$1
8213
8214         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8215         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8216
8217         ((rpc_in_flight++));
8218         nrpages=$((nrpages * rpc_in_flight))
8219
8220         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8221
8222         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8223
8224         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8225         local undirty=$((nrpages * PAGE_SIZE))
8226
8227         local max_extent_pages
8228         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8229         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8230         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8231         local grant_extent_tax
8232         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8233
8234         undirty=$((undirty + nrextents * grant_extent_tax))
8235
8236         echo $undirty
8237 }
8238
8239 # this is size of unit for grant allocation. It should be equal to
8240 # what tgt_grant.c:tgt_grant_chunk() calculates
8241 grant_chunk() {
8242         local tgt=$1
8243         local max_brw_size
8244         local grant_extent_tax
8245
8246         max_brw_size=$(import_param $tgt max_brw_size)
8247
8248         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8249
8250         echo $(((max_brw_size + grant_extent_tax) * 2))
8251 }
8252
8253 test_64d() {
8254         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8255                 skip "OST < 2.10.55 doesn't limit grants enough"
8256
8257         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8258
8259         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8260                 skip "no grant_param connect flag"
8261
8262         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8263
8264         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8265         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8266
8267
8268         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8269         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8270
8271         $LFS setstripe $DIR/$tfile -i 0 -c 1
8272         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8273         ddpid=$!
8274
8275         while kill -0 $ddpid; do
8276                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8277
8278                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8279                         kill $ddpid
8280                         error "cur_grant $cur_grant > $max_cur_granted"
8281                 fi
8282
8283                 sleep 1
8284         done
8285 }
8286 run_test 64d "check grant limit exceed"
8287
8288 check_grants() {
8289         local tgt=$1
8290         local expected=$2
8291         local msg=$3
8292         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8293
8294         ((cur_grants == expected)) ||
8295                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8296 }
8297
8298 round_up_p2() {
8299         echo $((($1 + $2 - 1) & ~($2 - 1)))
8300 }
8301
8302 test_64e() {
8303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8304         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8305                 skip "Need OSS version at least 2.11.56"
8306
8307         # Remount client to reset grant
8308         remount_client $MOUNT || error "failed to remount client"
8309         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8310
8311         local init_grants=$(import_param $osc_tgt initial_grant)
8312
8313         check_grants $osc_tgt $init_grants "init grants"
8314
8315         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8316         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8317         local gbs=$(import_param $osc_tgt grant_block_size)
8318
8319         # write random number of bytes from max_brw_size / 4 to max_brw_size
8320         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8321         # align for direct io
8322         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8323         # round to grant consumption unit
8324         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8325
8326         local grants=$((wb_round_up + extent_tax))
8327
8328         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8329
8330         # define OBD_FAIL_TGT_NO_GRANT 0x725
8331         # make the server not grant more back
8332         do_facet ost1 $LCTL set_param fail_loc=0x725
8333         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8334
8335         do_facet ost1 $LCTL set_param fail_loc=0
8336
8337         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8338
8339         rm -f $DIR/$tfile || error "rm failed"
8340
8341         # Remount client to reset grant
8342         remount_client $MOUNT || error "failed to remount client"
8343         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8344
8345         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8346
8347         # define OBD_FAIL_TGT_NO_GRANT 0x725
8348         # make the server not grant more back
8349         do_facet ost1 $LCTL set_param fail_loc=0x725
8350         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8351         do_facet ost1 $LCTL set_param fail_loc=0
8352
8353         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8354 }
8355 run_test 64e "check grant consumption (no grant allocation)"
8356
8357 test_64f() {
8358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8359
8360         # Remount client to reset grant
8361         remount_client $MOUNT || error "failed to remount client"
8362         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8363
8364         local init_grants=$(import_param $osc_tgt initial_grant)
8365         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8366         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8367         local gbs=$(import_param $osc_tgt grant_block_size)
8368         local chunk=$(grant_chunk $osc_tgt)
8369
8370         # write random number of bytes from max_brw_size / 4 to max_brw_size
8371         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8372         # align for direct io
8373         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8374         # round to grant consumption unit
8375         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8376
8377         local grants=$((wb_round_up + extent_tax))
8378
8379         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8380         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8381                 error "error writing to $DIR/$tfile"
8382
8383         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8384                 "direct io with grant allocation"
8385
8386         rm -f $DIR/$tfile || error "rm failed"
8387
8388         # Remount client to reset grant
8389         remount_client $MOUNT || error "failed to remount client"
8390         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8391
8392         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8393
8394         local cmd="oO_WRONLY:w${write_bytes}_yc"
8395
8396         $MULTIOP $DIR/$tfile $cmd &
8397         MULTIPID=$!
8398         sleep 1
8399
8400         check_grants $osc_tgt $((init_grants - grants)) \
8401                 "buffered io, not write rpc"
8402
8403         kill -USR1 $MULTIPID
8404         wait
8405
8406         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8407                 "buffered io, one RPC"
8408 }
8409 run_test 64f "check grant consumption (with grant allocation)"
8410
8411 # bug 1414 - set/get directories' stripe info
8412 test_65a() {
8413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8414
8415         test_mkdir $DIR/$tdir
8416         touch $DIR/$tdir/f1
8417         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8418 }
8419 run_test 65a "directory with no stripe info"
8420
8421 test_65b() {
8422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8423
8424         test_mkdir $DIR/$tdir
8425         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8426
8427         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8428                                                 error "setstripe"
8429         touch $DIR/$tdir/f2
8430         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8431 }
8432 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8433
8434 test_65c() {
8435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8436         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8437
8438         test_mkdir $DIR/$tdir
8439         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8440
8441         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8442                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8443         touch $DIR/$tdir/f3
8444         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8445 }
8446 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8447
8448 test_65d() {
8449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8450
8451         test_mkdir $DIR/$tdir
8452         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8453         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8454
8455         if [[ $STRIPECOUNT -le 0 ]]; then
8456                 sc=1
8457         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8458                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8459                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8460         else
8461                 sc=$(($STRIPECOUNT - 1))
8462         fi
8463         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8464         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8465         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8466                 error "lverify failed"
8467 }
8468 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8469
8470 test_65e() {
8471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8472
8473         test_mkdir $DIR/$tdir
8474
8475         $LFS setstripe $DIR/$tdir || error "setstripe"
8476         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8477                                         error "no stripe info failed"
8478         touch $DIR/$tdir/f6
8479         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8480 }
8481 run_test 65e "directory setstripe defaults"
8482
8483 test_65f() {
8484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8485
8486         test_mkdir $DIR/${tdir}f
8487         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8488                 error "setstripe succeeded" || true
8489 }
8490 run_test 65f "dir setstripe permission (should return error) ==="
8491
8492 test_65g() {
8493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8494
8495         test_mkdir $DIR/$tdir
8496         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8497
8498         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8499                 error "setstripe -S failed"
8500         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8501         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8502                 error "delete default stripe failed"
8503 }
8504 run_test 65g "directory setstripe -d"
8505
8506 test_65h() {
8507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8508
8509         test_mkdir $DIR/$tdir
8510         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8511
8512         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8513                 error "setstripe -S failed"
8514         test_mkdir $DIR/$tdir/dd1
8515         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8516                 error "stripe info inherit failed"
8517 }
8518 run_test 65h "directory stripe info inherit ===================="
8519
8520 test_65i() {
8521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8522
8523         save_layout_restore_at_exit $MOUNT
8524
8525         # bug6367: set non-default striping on root directory
8526         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8527
8528         # bug12836: getstripe on -1 default directory striping
8529         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8530
8531         # bug12836: getstripe -v on -1 default directory striping
8532         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8533
8534         # bug12836: new find on -1 default directory striping
8535         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8536 }
8537 run_test 65i "various tests to set root directory striping"
8538
8539 test_65j() { # bug6367
8540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8541
8542         sync; sleep 1
8543
8544         # if we aren't already remounting for each test, do so for this test
8545         if [ "$I_MOUNTED" = "yes" ]; then
8546                 cleanup || error "failed to unmount"
8547                 setup
8548         fi
8549
8550         save_layout_restore_at_exit $MOUNT
8551
8552         $LFS setstripe -d $MOUNT || error "setstripe failed"
8553 }
8554 run_test 65j "set default striping on root directory (bug 6367)="
8555
8556 cleanup_65k() {
8557         rm -rf $DIR/$tdir
8558         wait_delete_completed
8559         do_facet $SINGLEMDS "lctl set_param -n \
8560                 osp.$ost*MDT0000.max_create_count=$max_count"
8561         do_facet $SINGLEMDS "lctl set_param -n \
8562                 osp.$ost*MDT0000.create_count=$count"
8563         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8564         echo $INACTIVE_OSC "is Activate"
8565
8566         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8567 }
8568
8569 test_65k() { # bug11679
8570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8571         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8572         remote_mds_nodsh && skip "remote MDS with nodsh"
8573
8574         local disable_precreate=true
8575         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8576                 disable_precreate=false
8577
8578         echo "Check OST status: "
8579         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8580                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8581
8582         for OSC in $MDS_OSCS; do
8583                 echo $OSC "is active"
8584                 do_facet $SINGLEMDS lctl --device %$OSC activate
8585         done
8586
8587         for INACTIVE_OSC in $MDS_OSCS; do
8588                 local ost=$(osc_to_ost $INACTIVE_OSC)
8589                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8590                                lov.*md*.target_obd |
8591                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8592
8593                 mkdir -p $DIR/$tdir
8594                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8595                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8596
8597                 echo "Deactivate: " $INACTIVE_OSC
8598                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8599
8600                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8601                               osp.$ost*MDT0000.create_count")
8602                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8603                                   osp.$ost*MDT0000.max_create_count")
8604                 $disable_precreate &&
8605                         do_facet $SINGLEMDS "lctl set_param -n \
8606                                 osp.$ost*MDT0000.max_create_count=0"
8607
8608                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8609                         [ -f $DIR/$tdir/$idx ] && continue
8610                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8611                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8612                                 { cleanup_65k;
8613                                   error "setstripe $idx should succeed"; }
8614                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8615                 done
8616                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8617                 rmdir $DIR/$tdir
8618
8619                 do_facet $SINGLEMDS "lctl set_param -n \
8620                         osp.$ost*MDT0000.max_create_count=$max_count"
8621                 do_facet $SINGLEMDS "lctl set_param -n \
8622                         osp.$ost*MDT0000.create_count=$count"
8623                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8624                 echo $INACTIVE_OSC "is Activate"
8625
8626                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8627         done
8628 }
8629 run_test 65k "validate manual striping works properly with deactivated OSCs"
8630
8631 test_65l() { # bug 12836
8632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8633
8634         test_mkdir -p $DIR/$tdir/test_dir
8635         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8636         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8637 }
8638 run_test 65l "lfs find on -1 stripe dir ========================"
8639
8640 test_65m() {
8641         local layout=$(save_layout $MOUNT)
8642         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8643                 restore_layout $MOUNT $layout
8644                 error "setstripe should fail by non-root users"
8645         }
8646         true
8647 }
8648 run_test 65m "normal user can't set filesystem default stripe"
8649
8650 test_65n() {
8651         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8652         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8653                 skip "Need MDS version at least 2.12.50"
8654         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8655
8656         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8657         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8658         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8659
8660         local root_layout=$(save_layout $MOUNT)
8661         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8662
8663         # new subdirectory under root directory should not inherit
8664         # the default layout from root
8665         local dir1=$MOUNT/$tdir-1
8666         mkdir $dir1 || error "mkdir $dir1 failed"
8667         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8668                 error "$dir1 shouldn't have LOV EA"
8669
8670         # delete the default layout on root directory
8671         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8672
8673         local dir2=$MOUNT/$tdir-2
8674         mkdir $dir2 || error "mkdir $dir2 failed"
8675         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8676                 error "$dir2 shouldn't have LOV EA"
8677
8678         # set a new striping pattern on root directory
8679         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8680         local new_def_stripe_size=$((def_stripe_size * 2))
8681         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8682                 error "set stripe size on $MOUNT failed"
8683
8684         # new file created in $dir2 should inherit the new stripe size from
8685         # the filesystem default
8686         local file2=$dir2/$tfile-2
8687         touch $file2 || error "touch $file2 failed"
8688
8689         local file2_stripe_size=$($LFS getstripe -S $file2)
8690         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8691         {
8692                 echo "file2_stripe_size: '$file2_stripe_size'"
8693                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8694                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8695         }
8696
8697         local dir3=$MOUNT/$tdir-3
8698         mkdir $dir3 || error "mkdir $dir3 failed"
8699         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8700         # the root layout, which is the actual default layout that will be used
8701         # when new files are created in $dir3.
8702         local dir3_layout=$(get_layout_param $dir3)
8703         local root_dir_layout=$(get_layout_param $MOUNT)
8704         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8705         {
8706                 echo "dir3_layout: '$dir3_layout'"
8707                 echo "root_dir_layout: '$root_dir_layout'"
8708                 error "$dir3 should show the default layout from $MOUNT"
8709         }
8710
8711         # set OST pool on root directory
8712         local pool=$TESTNAME
8713         pool_add $pool || error "add $pool failed"
8714         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8715                 error "add targets to $pool failed"
8716
8717         $LFS setstripe -p $pool $MOUNT ||
8718                 error "set OST pool on $MOUNT failed"
8719
8720         # new file created in $dir3 should inherit the pool from
8721         # the filesystem default
8722         local file3=$dir3/$tfile-3
8723         touch $file3 || error "touch $file3 failed"
8724
8725         local file3_pool=$($LFS getstripe -p $file3)
8726         [[ "$file3_pool" = "$pool" ]] ||
8727                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8728
8729         local dir4=$MOUNT/$tdir-4
8730         mkdir $dir4 || error "mkdir $dir4 failed"
8731         local dir4_layout=$(get_layout_param $dir4)
8732         root_dir_layout=$(get_layout_param $MOUNT)
8733         echo "$LFS getstripe -d $dir4"
8734         $LFS getstripe -d $dir4
8735         echo "$LFS getstripe -d $MOUNT"
8736         $LFS getstripe -d $MOUNT
8737         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8738         {
8739                 echo "dir4_layout: '$dir4_layout'"
8740                 echo "root_dir_layout: '$root_dir_layout'"
8741                 error "$dir4 should show the default layout from $MOUNT"
8742         }
8743
8744         # new file created in $dir4 should inherit the pool from
8745         # the filesystem default
8746         local file4=$dir4/$tfile-4
8747         touch $file4 || error "touch $file4 failed"
8748
8749         local file4_pool=$($LFS getstripe -p $file4)
8750         [[ "$file4_pool" = "$pool" ]] ||
8751                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8752
8753         # new subdirectory under non-root directory should inherit
8754         # the default layout from its parent directory
8755         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8756                 error "set directory layout on $dir4 failed"
8757
8758         local dir5=$dir4/$tdir-5
8759         mkdir $dir5 || error "mkdir $dir5 failed"
8760
8761         dir4_layout=$(get_layout_param $dir4)
8762         local dir5_layout=$(get_layout_param $dir5)
8763         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8764         {
8765                 echo "dir4_layout: '$dir4_layout'"
8766                 echo "dir5_layout: '$dir5_layout'"
8767                 error "$dir5 should inherit the default layout from $dir4"
8768         }
8769
8770         # though subdir under ROOT doesn't inherit default layout, but
8771         # its sub dir/file should be created with default layout.
8772         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8773         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8774                 skip "Need MDS version at least 2.12.59"
8775
8776         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8777         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8778         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8779
8780         if [ $default_lmv_hash == "none" ]; then
8781                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8782         else
8783                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8784                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8785         fi
8786
8787         $LFS setdirstripe -D -c 2 $MOUNT ||
8788                 error "setdirstripe -D -c 2 failed"
8789         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8790         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8791         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8792 }
8793 run_test 65n "don't inherit default layout from root for new subdirectories"
8794
8795 # bug 2543 - update blocks count on client
8796 test_66() {
8797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8798
8799         COUNT=${COUNT:-8}
8800         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8801         sync; sync_all_data; sync; sync_all_data
8802         cancel_lru_locks osc
8803         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8804         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8805 }
8806 run_test 66 "update inode blocks count on client ==============="
8807
8808 meminfo() {
8809         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8810 }
8811
8812 swap_used() {
8813         swapon -s | awk '($1 == "'$1'") { print $4 }'
8814 }
8815
8816 # bug5265, obdfilter oa2dentry return -ENOENT
8817 # #define OBD_FAIL_SRV_ENOENT 0x217
8818 test_69() {
8819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8820         remote_ost_nodsh && skip "remote OST with nodsh"
8821
8822         f="$DIR/$tfile"
8823         $LFS setstripe -c 1 -i 0 $f
8824
8825         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8826
8827         do_facet ost1 lctl set_param fail_loc=0x217
8828         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8829         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8830
8831         do_facet ost1 lctl set_param fail_loc=0
8832         $DIRECTIO write $f 0 2 || error "write error"
8833
8834         cancel_lru_locks osc
8835         $DIRECTIO read $f 0 1 || error "read error"
8836
8837         do_facet ost1 lctl set_param fail_loc=0x217
8838         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8839
8840         do_facet ost1 lctl set_param fail_loc=0
8841         rm -f $f
8842 }
8843 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8844
8845 test_71() {
8846         test_mkdir $DIR/$tdir
8847         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8848         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8849 }
8850 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8851
8852 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8854         [ "$RUNAS_ID" = "$UID" ] &&
8855                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8856         # Check that testing environment is properly set up. Skip if not
8857         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8858                 skip_env "User $RUNAS_ID does not exist - skipping"
8859
8860         touch $DIR/$tfile
8861         chmod 777 $DIR/$tfile
8862         chmod ug+s $DIR/$tfile
8863         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8864                 error "$RUNAS dd $DIR/$tfile failed"
8865         # See if we are still setuid/sgid
8866         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8867                 error "S/gid is not dropped on write"
8868         # Now test that MDS is updated too
8869         cancel_lru_locks mdc
8870         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8871                 error "S/gid is not dropped on MDS"
8872         rm -f $DIR/$tfile
8873 }
8874 run_test 72a "Test that remove suid works properly (bug5695) ===="
8875
8876 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8877         local perm
8878
8879         [ "$RUNAS_ID" = "$UID" ] &&
8880                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8881         [ "$RUNAS_ID" -eq 0 ] &&
8882                 skip_env "RUNAS_ID = 0 -- skipping"
8883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8884         # Check that testing environment is properly set up. Skip if not
8885         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8886                 skip_env "User $RUNAS_ID does not exist - skipping"
8887
8888         touch $DIR/${tfile}-f{g,u}
8889         test_mkdir $DIR/${tfile}-dg
8890         test_mkdir $DIR/${tfile}-du
8891         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8892         chmod g+s $DIR/${tfile}-{f,d}g
8893         chmod u+s $DIR/${tfile}-{f,d}u
8894         for perm in 777 2777 4777; do
8895                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8896                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8897                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8898                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8899         done
8900         true
8901 }
8902 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8903
8904 # bug 3462 - multiple simultaneous MDC requests
8905 test_73() {
8906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8907
8908         test_mkdir $DIR/d73-1
8909         test_mkdir $DIR/d73-2
8910         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8911         pid1=$!
8912
8913         lctl set_param fail_loc=0x80000129
8914         $MULTIOP $DIR/d73-1/f73-2 Oc &
8915         sleep 1
8916         lctl set_param fail_loc=0
8917
8918         $MULTIOP $DIR/d73-2/f73-3 Oc &
8919         pid3=$!
8920
8921         kill -USR1 $pid1
8922         wait $pid1 || return 1
8923
8924         sleep 25
8925
8926         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8927         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8928         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8929
8930         rm -rf $DIR/d73-*
8931 }
8932 run_test 73 "multiple MDC requests (should not deadlock)"
8933
8934 test_74a() { # bug 6149, 6184
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936
8937         touch $DIR/f74a
8938         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8939         #
8940         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8941         # will spin in a tight reconnection loop
8942         $LCTL set_param fail_loc=0x8000030e
8943         # get any lock that won't be difficult - lookup works.
8944         ls $DIR/f74a
8945         $LCTL set_param fail_loc=0
8946         rm -f $DIR/f74a
8947         true
8948 }
8949 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8950
8951 test_74b() { # bug 13310
8952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8953
8954         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8955         #
8956         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8957         # will spin in a tight reconnection loop
8958         $LCTL set_param fail_loc=0x8000030e
8959         # get a "difficult" lock
8960         touch $DIR/f74b
8961         $LCTL set_param fail_loc=0
8962         rm -f $DIR/f74b
8963         true
8964 }
8965 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8966
8967 test_74c() {
8968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8969
8970         #define OBD_FAIL_LDLM_NEW_LOCK
8971         $LCTL set_param fail_loc=0x319
8972         touch $DIR/$tfile && error "touch successful"
8973         $LCTL set_param fail_loc=0
8974         true
8975 }
8976 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8977
8978 slab_lic=/sys/kernel/slab/lustre_inode_cache
8979 num_objects() {
8980         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8981         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8982                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8983 }
8984
8985 test_76a() { # Now for b=20433, added originally in b=1443
8986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8987
8988         cancel_lru_locks osc
8989         # there may be some slab objects cached per core
8990         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8991         local before=$(num_objects)
8992         local count=$((512 * cpus))
8993         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8994         local margin=$((count / 10))
8995         if [[ -f $slab_lic/aliases ]]; then
8996                 local aliases=$(cat $slab_lic/aliases)
8997                 (( aliases > 0 )) && margin=$((margin * aliases))
8998         fi
8999
9000         echo "before slab objects: $before"
9001         for i in $(seq $count); do
9002                 touch $DIR/$tfile
9003                 rm -f $DIR/$tfile
9004         done
9005         cancel_lru_locks osc
9006         local after=$(num_objects)
9007         echo "created: $count, after slab objects: $after"
9008         # shared slab counts are not very accurate, allow significant margin
9009         # the main goal is that the cache growth is not permanently > $count
9010         while (( after > before + margin )); do
9011                 sleep 1
9012                 after=$(num_objects)
9013                 wait=$((wait + 1))
9014                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9015                 if (( wait > 60 )); then
9016                         error "inode slab grew from $before+$margin to $after"
9017                 fi
9018         done
9019 }
9020 run_test 76a "confirm clients recycle inodes properly ===="
9021
9022 test_76b() {
9023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9024         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9025
9026         local count=512
9027         local before=$(num_objects)
9028
9029         for i in $(seq $count); do
9030                 mkdir $DIR/$tdir
9031                 rmdir $DIR/$tdir
9032         done
9033
9034         local after=$(num_objects)
9035         local wait=0
9036
9037         while (( after > before )); do
9038                 sleep 1
9039                 after=$(num_objects)
9040                 wait=$((wait + 1))
9041                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9042                 if (( wait > 60 )); then
9043                         error "inode slab grew from $before to $after"
9044                 fi
9045         done
9046
9047         echo "slab objects before: $before, after: $after"
9048 }
9049 run_test 76b "confirm clients recycle directory inodes properly ===="
9050
9051 export ORIG_CSUM=""
9052 set_checksums()
9053 {
9054         # Note: in sptlrpc modes which enable its own bulk checksum, the
9055         # original crc32_le bulk checksum will be automatically disabled,
9056         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9057         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9058         # In this case set_checksums() will not be no-op, because sptlrpc
9059         # bulk checksum will be enabled all through the test.
9060
9061         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9062         lctl set_param -n osc.*.checksums $1
9063         return 0
9064 }
9065
9066 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9067                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9068 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9069                              tr -d [] | head -n1)}
9070 set_checksum_type()
9071 {
9072         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9073         rc=$?
9074         log "set checksum type to $1, rc = $rc"
9075         return $rc
9076 }
9077
9078 get_osc_checksum_type()
9079 {
9080         # arugment 1: OST name, like OST0000
9081         ost=$1
9082         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9083                         sed 's/.*\[\(.*\)\].*/\1/g')
9084         rc=$?
9085         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9086         echo $checksum_type
9087 }
9088
9089 F77_TMP=$TMP/f77-temp
9090 F77SZ=8
9091 setup_f77() {
9092         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9093                 error "error writing to $F77_TMP"
9094 }
9095
9096 test_77a() { # bug 10889
9097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9098         $GSS && skip_env "could not run with gss"
9099
9100         [ ! -f $F77_TMP ] && setup_f77
9101         set_checksums 1
9102         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9103         set_checksums 0
9104         rm -f $DIR/$tfile
9105 }
9106 run_test 77a "normal checksum read/write operation"
9107
9108 test_77b() { # bug 10889
9109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9110         $GSS && skip_env "could not run with gss"
9111
9112         [ ! -f $F77_TMP ] && setup_f77
9113         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9114         $LCTL set_param fail_loc=0x80000409
9115         set_checksums 1
9116
9117         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9118                 error "dd error: $?"
9119         $LCTL set_param fail_loc=0
9120
9121         for algo in $CKSUM_TYPES; do
9122                 cancel_lru_locks osc
9123                 set_checksum_type $algo
9124                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9125                 $LCTL set_param fail_loc=0x80000408
9126                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9127                 $LCTL set_param fail_loc=0
9128         done
9129         set_checksums 0
9130         set_checksum_type $ORIG_CSUM_TYPE
9131         rm -f $DIR/$tfile
9132 }
9133 run_test 77b "checksum error on client write, read"
9134
9135 cleanup_77c() {
9136         trap 0
9137         set_checksums 0
9138         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9139         $check_ost &&
9140                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9141         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9142         $check_ost && [ -n "$ost_file_prefix" ] &&
9143                 do_facet ost1 rm -f ${ost_file_prefix}\*
9144 }
9145
9146 test_77c() {
9147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9148         $GSS && skip_env "could not run with gss"
9149         remote_ost_nodsh && skip "remote OST with nodsh"
9150
9151         local bad1
9152         local osc_file_prefix
9153         local osc_file
9154         local check_ost=false
9155         local ost_file_prefix
9156         local ost_file
9157         local orig_cksum
9158         local dump_cksum
9159         local fid
9160
9161         # ensure corruption will occur on first OSS/OST
9162         $LFS setstripe -i 0 $DIR/$tfile
9163
9164         [ ! -f $F77_TMP ] && setup_f77
9165         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9166                 error "dd write error: $?"
9167         fid=$($LFS path2fid $DIR/$tfile)
9168
9169         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9170         then
9171                 check_ost=true
9172                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9173                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9174         else
9175                 echo "OSS do not support bulk pages dump upon error"
9176         fi
9177
9178         osc_file_prefix=$($LCTL get_param -n debug_path)
9179         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9180
9181         trap cleanup_77c EXIT
9182
9183         set_checksums 1
9184         # enable bulk pages dump upon error on Client
9185         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9186         # enable bulk pages dump upon error on OSS
9187         $check_ost &&
9188                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9189
9190         # flush Client cache to allow next read to reach OSS
9191         cancel_lru_locks osc
9192
9193         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9194         $LCTL set_param fail_loc=0x80000408
9195         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9196         $LCTL set_param fail_loc=0
9197
9198         rm -f $DIR/$tfile
9199
9200         # check cksum dump on Client
9201         osc_file=$(ls ${osc_file_prefix}*)
9202         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9203         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9204         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9205         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9206         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9207                      cksum)
9208         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9209         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9210                 error "dump content does not match on Client"
9211
9212         $check_ost || skip "No need to check cksum dump on OSS"
9213
9214         # check cksum dump on OSS
9215         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9216         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9217         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9218         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9219         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9220                 error "dump content does not match on OSS"
9221
9222         cleanup_77c
9223 }
9224 run_test 77c "checksum error on client read with debug"
9225
9226 test_77d() { # bug 10889
9227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9228         $GSS && skip_env "could not run with gss"
9229
9230         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9231         $LCTL set_param fail_loc=0x80000409
9232         set_checksums 1
9233         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9234                 error "direct write: rc=$?"
9235         $LCTL set_param fail_loc=0
9236         set_checksums 0
9237
9238         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9239         $LCTL set_param fail_loc=0x80000408
9240         set_checksums 1
9241         cancel_lru_locks osc
9242         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9243                 error "direct read: rc=$?"
9244         $LCTL set_param fail_loc=0
9245         set_checksums 0
9246 }
9247 run_test 77d "checksum error on OST direct write, read"
9248
9249 test_77f() { # bug 10889
9250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9251         $GSS && skip_env "could not run with gss"
9252
9253         set_checksums 1
9254         for algo in $CKSUM_TYPES; do
9255                 cancel_lru_locks osc
9256                 set_checksum_type $algo
9257                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9258                 $LCTL set_param fail_loc=0x409
9259                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9260                         error "direct write succeeded"
9261                 $LCTL set_param fail_loc=0
9262         done
9263         set_checksum_type $ORIG_CSUM_TYPE
9264         set_checksums 0
9265 }
9266 run_test 77f "repeat checksum error on write (expect error)"
9267
9268 test_77g() { # bug 10889
9269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9270         $GSS && skip_env "could not run with gss"
9271         remote_ost_nodsh && skip "remote OST with nodsh"
9272
9273         [ ! -f $F77_TMP ] && setup_f77
9274
9275         local file=$DIR/$tfile
9276         stack_trap "rm -f $file" EXIT
9277
9278         $LFS setstripe -c 1 -i 0 $file
9279         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9280         do_facet ost1 lctl set_param fail_loc=0x8000021a
9281         set_checksums 1
9282         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9283                 error "write error: rc=$?"
9284         do_facet ost1 lctl set_param fail_loc=0
9285         set_checksums 0
9286
9287         cancel_lru_locks osc
9288         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9289         do_facet ost1 lctl set_param fail_loc=0x8000021b
9290         set_checksums 1
9291         cmp $F77_TMP $file || error "file compare failed"
9292         do_facet ost1 lctl set_param fail_loc=0
9293         set_checksums 0
9294 }
9295 run_test 77g "checksum error on OST write, read"
9296
9297 test_77k() { # LU-10906
9298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9299         $GSS && skip_env "could not run with gss"
9300
9301         local cksum_param="osc.$FSNAME*.checksums"
9302         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9303         local checksum
9304         local i
9305
9306         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9307         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9308         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9309
9310         for i in 0 1; do
9311                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9312                         error "failed to set checksum=$i on MGS"
9313                 wait_update $HOSTNAME "$get_checksum" $i
9314                 #remount
9315                 echo "remount client, checksum should be $i"
9316                 remount_client $MOUNT || error "failed to remount client"
9317                 checksum=$(eval $get_checksum)
9318                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9319         done
9320         # remove persistent param to avoid races with checksum mountopt below
9321         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9322                 error "failed to delete checksum on MGS"
9323
9324         for opt in "checksum" "nochecksum"; do
9325                 #remount with mount option
9326                 echo "remount client with option $opt, checksum should be $i"
9327                 umount_client $MOUNT || error "failed to umount client"
9328                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9329                         error "failed to mount client with option '$opt'"
9330                 checksum=$(eval $get_checksum)
9331                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9332                 i=$((i - 1))
9333         done
9334
9335         remount_client $MOUNT || error "failed to remount client"
9336 }
9337 run_test 77k "enable/disable checksum correctly"
9338
9339 test_77l() {
9340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9341         $GSS && skip_env "could not run with gss"
9342
9343         set_checksums 1
9344         stack_trap "set_checksums $ORIG_CSUM" EXIT
9345         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9346
9347         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9348
9349         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9350         for algo in $CKSUM_TYPES; do
9351                 set_checksum_type $algo || error "fail to set checksum type $algo"
9352                 osc_algo=$(get_osc_checksum_type OST0000)
9353                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9354
9355                 # no locks, no reqs to let the connection idle
9356                 cancel_lru_locks osc
9357                 lru_resize_disable osc
9358                 wait_osc_import_state client ost1 IDLE
9359
9360                 # ensure ost1 is connected
9361                 stat $DIR/$tfile >/dev/null || error "can't stat"
9362                 wait_osc_import_state client ost1 FULL
9363
9364                 osc_algo=$(get_osc_checksum_type OST0000)
9365                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9366         done
9367         return 0
9368 }
9369 run_test 77l "preferred checksum type is remembered after reconnected"
9370
9371 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9372 rm -f $F77_TMP
9373 unset F77_TMP
9374
9375 cleanup_test_78() {
9376         trap 0
9377         rm -f $DIR/$tfile
9378 }
9379
9380 test_78() { # bug 10901
9381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9382         remote_ost || skip_env "local OST"
9383
9384         NSEQ=5
9385         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9386         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9387         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9388         echo "MemTotal: $MEMTOTAL"
9389
9390         # reserve 256MB of memory for the kernel and other running processes,
9391         # and then take 1/2 of the remaining memory for the read/write buffers.
9392         if [ $MEMTOTAL -gt 512 ] ;then
9393                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9394         else
9395                 # for those poor memory-starved high-end clusters...
9396                 MEMTOTAL=$((MEMTOTAL / 2))
9397         fi
9398         echo "Mem to use for directio: $MEMTOTAL"
9399
9400         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9401         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9402         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9403         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9404                 head -n1)
9405         echo "Smallest OST: $SMALLESTOST"
9406         [[ $SMALLESTOST -lt 10240 ]] &&
9407                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9408
9409         trap cleanup_test_78 EXIT
9410
9411         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9412                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9413
9414         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9415         echo "File size: $F78SIZE"
9416         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9417         for i in $(seq 1 $NSEQ); do
9418                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9419                 echo directIO rdwr round $i of $NSEQ
9420                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9421         done
9422
9423         cleanup_test_78
9424 }
9425 run_test 78 "handle large O_DIRECT writes correctly ============"
9426
9427 test_79() { # bug 12743
9428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9429
9430         wait_delete_completed
9431
9432         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9433         BKFREE=$(calc_osc_kbytes kbytesfree)
9434         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9435
9436         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9437         DFTOTAL=`echo $STRING | cut -d, -f1`
9438         DFUSED=`echo $STRING  | cut -d, -f2`
9439         DFAVAIL=`echo $STRING | cut -d, -f3`
9440         DFFREE=$(($DFTOTAL - $DFUSED))
9441
9442         ALLOWANCE=$((64 * $OSTCOUNT))
9443
9444         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9445            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9446                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9447         fi
9448         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9449            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9450                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9451         fi
9452         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9453            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9454                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9455         fi
9456 }
9457 run_test 79 "df report consistency check ======================="
9458
9459 test_80() { # bug 10718
9460         remote_ost_nodsh && skip "remote OST with nodsh"
9461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9462
9463         # relax strong synchronous semantics for slow backends like ZFS
9464         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9465                 local soc="obdfilter.*.sync_lock_cancel"
9466                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9467
9468                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9469                 if [ -z "$save" ]; then
9470                         soc="obdfilter.*.sync_on_lock_cancel"
9471                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9472                 fi
9473
9474                 if [ "$save" != "never" ]; then
9475                         local hosts=$(comma_list $(osts_nodes))
9476
9477                         do_nodes $hosts $LCTL set_param $soc=never
9478                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9479                 fi
9480         fi
9481
9482         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9483         sync; sleep 1; sync
9484         local before=$(date +%s)
9485         cancel_lru_locks osc
9486         local after=$(date +%s)
9487         local diff=$((after - before))
9488         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9489
9490         rm -f $DIR/$tfile
9491 }
9492 run_test 80 "Page eviction is equally fast at high offsets too"
9493
9494 test_81a() { # LU-456
9495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9496         remote_ost_nodsh && skip "remote OST with nodsh"
9497
9498         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9499         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9500         do_facet ost1 lctl set_param fail_loc=0x80000228
9501
9502         # write should trigger a retry and success
9503         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9504         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9505         RC=$?
9506         if [ $RC -ne 0 ] ; then
9507                 error "write should success, but failed for $RC"
9508         fi
9509 }
9510 run_test 81a "OST should retry write when get -ENOSPC ==============="
9511
9512 test_81b() { # LU-456
9513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9514         remote_ost_nodsh && skip "remote OST with nodsh"
9515
9516         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9517         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9518         do_facet ost1 lctl set_param fail_loc=0x228
9519
9520         # write should retry several times and return -ENOSPC finally
9521         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9522         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9523         RC=$?
9524         ENOSPC=28
9525         if [ $RC -ne $ENOSPC ] ; then
9526                 error "dd should fail for -ENOSPC, but succeed."
9527         fi
9528 }
9529 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9530
9531 test_99() {
9532         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9533
9534         test_mkdir $DIR/$tdir.cvsroot
9535         chown $RUNAS_ID $DIR/$tdir.cvsroot
9536
9537         cd $TMP
9538         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9539
9540         cd /etc/init.d
9541         # some versions of cvs import exit(1) when asked to import links or
9542         # files they can't read.  ignore those files.
9543         local toignore=$(find . -type l -printf '-I %f\n' -o \
9544                          ! -perm /4 -printf '-I %f\n')
9545         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9546                 $tdir.reposname vtag rtag
9547
9548         cd $DIR
9549         test_mkdir $DIR/$tdir.reposname
9550         chown $RUNAS_ID $DIR/$tdir.reposname
9551         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9552
9553         cd $DIR/$tdir.reposname
9554         $RUNAS touch foo99
9555         $RUNAS cvs add -m 'addmsg' foo99
9556         $RUNAS cvs update
9557         $RUNAS cvs commit -m 'nomsg' foo99
9558         rm -fr $DIR/$tdir.cvsroot
9559 }
9560 run_test 99 "cvs strange file/directory operations"
9561
9562 test_100() {
9563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9564         [[ "$NETTYPE" =~ tcp ]] ||
9565                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9566         remote_ost_nodsh && skip "remote OST with nodsh"
9567         remote_mds_nodsh && skip "remote MDS with nodsh"
9568         remote_servers ||
9569                 skip "useless for local single node setup"
9570
9571         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9572                 [ "$PROT" != "tcp" ] && continue
9573                 RPORT=$(echo $REMOTE | cut -d: -f2)
9574                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9575
9576                 rc=0
9577                 LPORT=`echo $LOCAL | cut -d: -f2`
9578                 if [ $LPORT -ge 1024 ]; then
9579                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9580                         netstat -tna
9581                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9582                 fi
9583         done
9584         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9585 }
9586 run_test 100 "check local port using privileged port ==========="
9587
9588 function get_named_value()
9589 {
9590     local tag
9591
9592     tag=$1
9593     while read ;do
9594         line=$REPLY
9595         case $line in
9596         $tag*)
9597             echo $line | sed "s/^$tag[ ]*//"
9598             break
9599             ;;
9600         esac
9601     done
9602 }
9603
9604 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9605                    awk '/^max_cached_mb/ { print $2 }')
9606
9607 cleanup_101a() {
9608         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9609         trap 0
9610 }
9611
9612 test_101a() {
9613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9614
9615         local s
9616         local discard
9617         local nreads=10000
9618         local cache_limit=32
9619
9620         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9621         trap cleanup_101a EXIT
9622         $LCTL set_param -n llite.*.read_ahead_stats 0
9623         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9624
9625         #
9626         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9627         #
9628         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9629         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9630
9631         discard=0
9632         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9633                 get_named_value 'read but discarded' | cut -d" " -f1); do
9634                         discard=$(($discard + $s))
9635         done
9636         cleanup_101a
9637
9638         $LCTL get_param osc.*-osc*.rpc_stats
9639         $LCTL get_param llite.*.read_ahead_stats
9640
9641         # Discard is generally zero, but sometimes a few random reads line up
9642         # and trigger larger readahead, which is wasted & leads to discards.
9643         if [[ $(($discard)) -gt $nreads ]]; then
9644                 error "too many ($discard) discarded pages"
9645         fi
9646         rm -f $DIR/$tfile || true
9647 }
9648 run_test 101a "check read-ahead for random reads"
9649
9650 setup_test101bc() {
9651         test_mkdir $DIR/$tdir
9652         local ssize=$1
9653         local FILE_LENGTH=$2
9654         STRIPE_OFFSET=0
9655
9656         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9657
9658         local list=$(comma_list $(osts_nodes))
9659         set_osd_param $list '' read_cache_enable 0
9660         set_osd_param $list '' writethrough_cache_enable 0
9661
9662         trap cleanup_test101bc EXIT
9663         # prepare the read-ahead file
9664         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9665
9666         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9667                                 count=$FILE_SIZE_MB 2> /dev/null
9668
9669 }
9670
9671 cleanup_test101bc() {
9672         trap 0
9673         rm -rf $DIR/$tdir
9674         rm -f $DIR/$tfile
9675
9676         local list=$(comma_list $(osts_nodes))
9677         set_osd_param $list '' read_cache_enable 1
9678         set_osd_param $list '' writethrough_cache_enable 1
9679 }
9680
9681 calc_total() {
9682         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9683 }
9684
9685 ra_check_101() {
9686         local READ_SIZE=$1
9687         local STRIPE_SIZE=$2
9688         local FILE_LENGTH=$3
9689         local RA_INC=1048576
9690         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9691         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9692                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9693         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9694                         get_named_value 'read but discarded' |
9695                         cut -d" " -f1 | calc_total)
9696         if [[ $DISCARD -gt $discard_limit ]]; then
9697                 $LCTL get_param llite.*.read_ahead_stats
9698                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9699         else
9700                 echo "Read-ahead success for size ${READ_SIZE}"
9701         fi
9702 }
9703
9704 test_101b() {
9705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9706         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9707
9708         local STRIPE_SIZE=1048576
9709         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9710
9711         if [ $SLOW == "yes" ]; then
9712                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9713         else
9714                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9715         fi
9716
9717         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9718
9719         # prepare the read-ahead file
9720         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9721         cancel_lru_locks osc
9722         for BIDX in 2 4 8 16 32 64 128 256
9723         do
9724                 local BSIZE=$((BIDX*4096))
9725                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9726                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9727                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9728                 $LCTL set_param -n llite.*.read_ahead_stats 0
9729                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9730                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9731                 cancel_lru_locks osc
9732                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9733         done
9734         cleanup_test101bc
9735         true
9736 }
9737 run_test 101b "check stride-io mode read-ahead ================="
9738
9739 test_101c() {
9740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9741
9742         local STRIPE_SIZE=1048576
9743         local FILE_LENGTH=$((STRIPE_SIZE*100))
9744         local nreads=10000
9745         local rsize=65536
9746         local osc_rpc_stats
9747
9748         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9749
9750         cancel_lru_locks osc
9751         $LCTL set_param osc.*.rpc_stats 0
9752         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9753         $LCTL get_param osc.*.rpc_stats
9754         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9755                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9756                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9757                 local size
9758
9759                 if [ $lines -le 20 ]; then
9760                         echo "continue debug"
9761                         continue
9762                 fi
9763                 for size in 1 2 4 8; do
9764                         local rpc=$(echo "$stats" |
9765                                     awk '($1 == "'$size':") {print $2; exit; }')
9766                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9767                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9768                 done
9769                 echo "$osc_rpc_stats check passed!"
9770         done
9771         cleanup_test101bc
9772         true
9773 }
9774 run_test 101c "check stripe_size aligned read-ahead ================="
9775
9776 test_101d() {
9777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9778
9779         local file=$DIR/$tfile
9780         local sz_MB=${FILESIZE_101d:-80}
9781         local ra_MB=${READAHEAD_MB:-40}
9782
9783         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9784         [ $free_MB -lt $sz_MB ] &&
9785                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9786
9787         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9788         $LFS setstripe -c -1 $file || error "setstripe failed"
9789
9790         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9791         echo Cancel LRU locks on lustre client to flush the client cache
9792         cancel_lru_locks osc
9793
9794         echo Disable read-ahead
9795         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9796         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9797         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9798         $LCTL get_param -n llite.*.max_read_ahead_mb
9799
9800         echo "Reading the test file $file with read-ahead disabled"
9801         local sz_KB=$((sz_MB * 1024 / 4))
9802         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9803         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9804         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9805                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9806
9807         echo "Cancel LRU locks on lustre client to flush the client cache"
9808         cancel_lru_locks osc
9809         echo Enable read-ahead with ${ra_MB}MB
9810         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9811
9812         echo "Reading the test file $file with read-ahead enabled"
9813         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9814                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9815
9816         echo "read-ahead disabled time read $raOFF"
9817         echo "read-ahead enabled time read $raON"
9818
9819         rm -f $file
9820         wait_delete_completed
9821
9822         # use awk for this check instead of bash because it handles decimals
9823         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9824                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9825 }
9826 run_test 101d "file read with and without read-ahead enabled"
9827
9828 test_101e() {
9829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9830
9831         local file=$DIR/$tfile
9832         local size_KB=500  #KB
9833         local count=100
9834         local bsize=1024
9835
9836         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9837         local need_KB=$((count * size_KB))
9838         [[ $free_KB -le $need_KB ]] &&
9839                 skip_env "Need free space $need_KB, have $free_KB"
9840
9841         echo "Creating $count ${size_KB}K test files"
9842         for ((i = 0; i < $count; i++)); do
9843                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9844         done
9845
9846         echo "Cancel LRU locks on lustre client to flush the client cache"
9847         cancel_lru_locks $OSC
9848
9849         echo "Reset readahead stats"
9850         $LCTL set_param -n llite.*.read_ahead_stats 0
9851
9852         for ((i = 0; i < $count; i++)); do
9853                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9854         done
9855
9856         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9857                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9858
9859         for ((i = 0; i < $count; i++)); do
9860                 rm -rf $file.$i 2>/dev/null
9861         done
9862
9863         #10000 means 20% reads are missing in readahead
9864         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9865 }
9866 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9867
9868 test_101f() {
9869         which iozone || skip_env "no iozone installed"
9870
9871         local old_debug=$($LCTL get_param debug)
9872         old_debug=${old_debug#*=}
9873         $LCTL set_param debug="reada mmap"
9874
9875         # create a test file
9876         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
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         echo mmap read the file with small block size
9885         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9886                 > /dev/null 2>&1
9887
9888         echo checking missing pages
9889         $LCTL get_param llite.*.read_ahead_stats
9890         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9891                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9892
9893         $LCTL set_param debug="$old_debug"
9894         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9895         rm -f $DIR/$tfile
9896 }
9897 run_test 101f "check mmap read performance"
9898
9899 test_101g_brw_size_test() {
9900         local mb=$1
9901         local pages=$((mb * 1048576 / PAGE_SIZE))
9902         local file=$DIR/$tfile
9903
9904         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9905                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9906         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9907                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9908                         return 2
9909         done
9910
9911         stack_trap "rm -f $file" EXIT
9912         $LCTL set_param -n osc.*.rpc_stats=0
9913
9914         # 10 RPCs should be enough for the test
9915         local count=10
9916         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9917                 { error "dd write ${mb} MB blocks failed"; return 3; }
9918         cancel_lru_locks osc
9919         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9920                 { error "dd write ${mb} MB blocks failed"; return 4; }
9921
9922         # calculate number of full-sized read and write RPCs
9923         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9924                 sed -n '/pages per rpc/,/^$/p' |
9925                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9926                 END { print reads,writes }'))
9927         # allow one extra full-sized read RPC for async readahead
9928         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9929                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9930         [[ ${rpcs[1]} == $count ]] ||
9931                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9932 }
9933
9934 test_101g() {
9935         remote_ost_nodsh && skip "remote OST with nodsh"
9936
9937         local rpcs
9938         local osts=$(get_facets OST)
9939         local list=$(comma_list $(osts_nodes))
9940         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9941         local brw_size="obdfilter.*.brw_size"
9942
9943         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9944
9945         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9946
9947         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9948                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9949                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9950            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9951                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9952                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9953
9954                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9955                         suffix="M"
9956
9957                 if [[ $orig_mb -lt 16 ]]; then
9958                         save_lustre_params $osts "$brw_size" > $p
9959                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9960                                 error "set 16MB RPC size failed"
9961
9962                         echo "remount client to enable new RPC size"
9963                         remount_client $MOUNT || error "remount_client failed"
9964                 fi
9965
9966                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9967                 # should be able to set brw_size=12, but no rpc_stats for that
9968                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9969         fi
9970
9971         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9972
9973         if [[ $orig_mb -lt 16 ]]; then
9974                 restore_lustre_params < $p
9975                 remount_client $MOUNT || error "remount_client restore failed"
9976         fi
9977
9978         rm -f $p $DIR/$tfile
9979 }
9980 run_test 101g "Big bulk(4/16 MiB) readahead"
9981
9982 test_101h() {
9983         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9984
9985         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9986                 error "dd 70M file failed"
9987         echo Cancel LRU locks on lustre client to flush the client cache
9988         cancel_lru_locks osc
9989
9990         echo "Reset readahead stats"
9991         $LCTL set_param -n llite.*.read_ahead_stats 0
9992
9993         echo "Read 10M of data but cross 64M bundary"
9994         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9995         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9996                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9997         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9998         rm -f $p $DIR/$tfile
9999 }
10000 run_test 101h "Readahead should cover current read window"
10001
10002 test_101i() {
10003         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10004                 error "dd 10M file failed"
10005
10006         local max_per_file_mb=$($LCTL get_param -n \
10007                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10008         cancel_lru_locks osc
10009         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10010         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10011                 error "set max_read_ahead_per_file_mb to 1 failed"
10012
10013         echo "Reset readahead stats"
10014         $LCTL set_param llite.*.read_ahead_stats=0
10015
10016         dd if=$DIR/$tfile of=/dev/null bs=2M
10017
10018         $LCTL get_param llite.*.read_ahead_stats
10019         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10020                      awk '/misses/ { print $2 }')
10021         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10022         rm -f $DIR/$tfile
10023 }
10024 run_test 101i "allow current readahead to exceed reservation"
10025
10026 test_101j() {
10027         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10028                 error "setstripe $DIR/$tfile failed"
10029         local file_size=$((1048576 * 16))
10030         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10031         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10032
10033         echo Disable read-ahead
10034         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10035
10036         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10037         for blk in $PAGE_SIZE 1048576 $file_size; do
10038                 cancel_lru_locks osc
10039                 echo "Reset readahead stats"
10040                 $LCTL set_param -n llite.*.read_ahead_stats=0
10041                 local count=$(($file_size / $blk))
10042                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10043                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10044                              get_named_value 'failed to fast read' |
10045                              cut -d" " -f1 | calc_total)
10046                 $LCTL get_param -n llite.*.read_ahead_stats
10047                 [ $miss -eq $count ] || error "expected $count got $miss"
10048         done
10049
10050         rm -f $p $DIR/$tfile
10051 }
10052 run_test 101j "A complete read block should be submitted when no RA"
10053
10054 setup_test102() {
10055         test_mkdir $DIR/$tdir
10056         chown $RUNAS_ID $DIR/$tdir
10057         STRIPE_SIZE=65536
10058         STRIPE_OFFSET=1
10059         STRIPE_COUNT=$OSTCOUNT
10060         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10061
10062         trap cleanup_test102 EXIT
10063         cd $DIR
10064         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10065         cd $DIR/$tdir
10066         for num in 1 2 3 4; do
10067                 for count in $(seq 1 $STRIPE_COUNT); do
10068                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10069                                 local size=`expr $STRIPE_SIZE \* $num`
10070                                 local file=file"$num-$idx-$count"
10071                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10072                         done
10073                 done
10074         done
10075
10076         cd $DIR
10077         $1 tar cf $TMP/f102.tar $tdir --xattrs
10078 }
10079
10080 cleanup_test102() {
10081         trap 0
10082         rm -f $TMP/f102.tar
10083         rm -rf $DIR/d0.sanity/d102
10084 }
10085
10086 test_102a() {
10087         [ "$UID" != 0 ] && skip "must run as root"
10088         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10089                 skip_env "must have user_xattr"
10090
10091         [ -z "$(which setfattr 2>/dev/null)" ] &&
10092                 skip_env "could not find setfattr"
10093
10094         local testfile=$DIR/$tfile
10095
10096         touch $testfile
10097         echo "set/get xattr..."
10098         setfattr -n trusted.name1 -v value1 $testfile ||
10099                 error "setfattr -n trusted.name1=value1 $testfile failed"
10100         getfattr -n trusted.name1 $testfile 2> /dev/null |
10101           grep "trusted.name1=.value1" ||
10102                 error "$testfile missing trusted.name1=value1"
10103
10104         setfattr -n user.author1 -v author1 $testfile ||
10105                 error "setfattr -n user.author1=author1 $testfile failed"
10106         getfattr -n user.author1 $testfile 2> /dev/null |
10107           grep "user.author1=.author1" ||
10108                 error "$testfile missing trusted.author1=author1"
10109
10110         echo "listxattr..."
10111         setfattr -n trusted.name2 -v value2 $testfile ||
10112                 error "$testfile unable to set trusted.name2"
10113         setfattr -n trusted.name3 -v value3 $testfile ||
10114                 error "$testfile unable to set trusted.name3"
10115         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10116             grep "trusted.name" | wc -l) -eq 3 ] ||
10117                 error "$testfile missing 3 trusted.name xattrs"
10118
10119         setfattr -n user.author2 -v author2 $testfile ||
10120                 error "$testfile unable to set user.author2"
10121         setfattr -n user.author3 -v author3 $testfile ||
10122                 error "$testfile unable to set user.author3"
10123         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10124             grep "user.author" | wc -l) -eq 3 ] ||
10125                 error "$testfile missing 3 user.author xattrs"
10126
10127         echo "remove xattr..."
10128         setfattr -x trusted.name1 $testfile ||
10129                 error "$testfile error deleting trusted.name1"
10130         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10131                 error "$testfile did not delete trusted.name1 xattr"
10132
10133         setfattr -x user.author1 $testfile ||
10134                 error "$testfile error deleting user.author1"
10135         echo "set lustre special xattr ..."
10136         $LFS setstripe -c1 $testfile
10137         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10138                 awk -F "=" '/trusted.lov/ { print $2 }' )
10139         setfattr -n "trusted.lov" -v $lovea $testfile ||
10140                 error "$testfile doesn't ignore setting trusted.lov again"
10141         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10142                 error "$testfile allow setting invalid trusted.lov"
10143         rm -f $testfile
10144 }
10145 run_test 102a "user xattr test =================================="
10146
10147 check_102b_layout() {
10148         local layout="$*"
10149         local testfile=$DIR/$tfile
10150
10151         echo "test layout '$layout'"
10152         $LFS setstripe $layout $testfile || error "setstripe failed"
10153         $LFS getstripe -y $testfile
10154
10155         echo "get/set/list trusted.lov xattr ..." # b=10930
10156         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10157         [[ "$value" =~ "trusted.lov" ]] ||
10158                 error "can't get trusted.lov from $testfile"
10159         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10160                 error "getstripe failed"
10161
10162         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10163
10164         value=$(cut -d= -f2 <<<$value)
10165         # LU-13168: truncated xattr should fail if short lov_user_md header
10166         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10167                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10168         for len in $lens; do
10169                 echo "setfattr $len $testfile.2"
10170                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10171                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10172         done
10173         local stripe_size=$($LFS getstripe -S $testfile.2)
10174         local stripe_count=$($LFS getstripe -c $testfile.2)
10175         [[ $stripe_size -eq 65536 ]] ||
10176                 error "stripe size $stripe_size != 65536"
10177         [[ $stripe_count -eq $stripe_count_orig ]] ||
10178                 error "stripe count $stripe_count != $stripe_count_orig"
10179         rm $testfile $testfile.2
10180 }
10181
10182 test_102b() {
10183         [ -z "$(which setfattr 2>/dev/null)" ] &&
10184                 skip_env "could not find setfattr"
10185         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10186
10187         # check plain layout
10188         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10189
10190         # and also check composite layout
10191         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10192
10193 }
10194 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10195
10196 test_102c() {
10197         [ -z "$(which setfattr 2>/dev/null)" ] &&
10198                 skip_env "could not find setfattr"
10199         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10200
10201         # b10930: get/set/list lustre.lov xattr
10202         echo "get/set/list lustre.lov xattr ..."
10203         test_mkdir $DIR/$tdir
10204         chown $RUNAS_ID $DIR/$tdir
10205         local testfile=$DIR/$tdir/$tfile
10206         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10207                 error "setstripe failed"
10208         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10209                 error "getstripe failed"
10210         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10211         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10212
10213         local testfile2=${testfile}2
10214         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10215                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10216
10217         $RUNAS $MCREATE $testfile2
10218         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10219         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10220         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10221         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10222         [ $stripe_count -eq $STRIPECOUNT ] ||
10223                 error "stripe count $stripe_count != $STRIPECOUNT"
10224 }
10225 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10226
10227 compare_stripe_info1() {
10228         local stripe_index_all_zero=true
10229
10230         for num in 1 2 3 4; do
10231                 for count in $(seq 1 $STRIPE_COUNT); do
10232                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10233                                 local size=$((STRIPE_SIZE * num))
10234                                 local file=file"$num-$offset-$count"
10235                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10236                                 [[ $stripe_size -ne $size ]] &&
10237                                     error "$file: size $stripe_size != $size"
10238                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10239                                 # allow fewer stripes to be created, ORI-601
10240                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10241                                     error "$file: count $stripe_count != $count"
10242                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10243                                 [[ $stripe_index -ne 0 ]] &&
10244                                         stripe_index_all_zero=false
10245                         done
10246                 done
10247         done
10248         $stripe_index_all_zero &&
10249                 error "all files are being extracted starting from OST index 0"
10250         return 0
10251 }
10252
10253 have_xattrs_include() {
10254         tar --help | grep -q xattrs-include &&
10255                 echo --xattrs-include="lustre.*"
10256 }
10257
10258 test_102d() {
10259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10260         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10261
10262         XINC=$(have_xattrs_include)
10263         setup_test102
10264         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10265         cd $DIR/$tdir/$tdir
10266         compare_stripe_info1
10267 }
10268 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10269
10270 test_102f() {
10271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10272         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10273
10274         XINC=$(have_xattrs_include)
10275         setup_test102
10276         test_mkdir $DIR/$tdir.restore
10277         cd $DIR
10278         tar cf - --xattrs $tdir | tar xf - \
10279                 -C $DIR/$tdir.restore --xattrs $XINC
10280         cd $DIR/$tdir.restore/$tdir
10281         compare_stripe_info1
10282 }
10283 run_test 102f "tar copy files, not keep osts"
10284
10285 grow_xattr() {
10286         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10287                 skip "must have user_xattr"
10288         [ -z "$(which setfattr 2>/dev/null)" ] &&
10289                 skip_env "could not find setfattr"
10290         [ -z "$(which getfattr 2>/dev/null)" ] &&
10291                 skip_env "could not find getfattr"
10292
10293         local xsize=${1:-1024}  # in bytes
10294         local file=$DIR/$tfile
10295         local value="$(generate_string $xsize)"
10296         local xbig=trusted.big
10297         local toobig=$2
10298
10299         touch $file
10300         log "save $xbig on $file"
10301         if [ -z "$toobig" ]
10302         then
10303                 setfattr -n $xbig -v $value $file ||
10304                         error "saving $xbig on $file failed"
10305         else
10306                 setfattr -n $xbig -v $value $file &&
10307                         error "saving $xbig on $file succeeded"
10308                 return 0
10309         fi
10310
10311         local orig=$(get_xattr_value $xbig $file)
10312         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10313
10314         local xsml=trusted.sml
10315         log "save $xsml on $file"
10316         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10317
10318         local new=$(get_xattr_value $xbig $file)
10319         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10320
10321         log "grow $xsml on $file"
10322         setfattr -n $xsml -v "$value" $file ||
10323                 error "growing $xsml on $file failed"
10324
10325         new=$(get_xattr_value $xbig $file)
10326         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10327         log "$xbig still valid after growing $xsml"
10328
10329         rm -f $file
10330 }
10331
10332 test_102h() { # bug 15777
10333         grow_xattr 1024
10334 }
10335 run_test 102h "grow xattr from inside inode to external block"
10336
10337 test_102ha() {
10338         large_xattr_enabled || skip_env "ea_inode feature disabled"
10339
10340         echo "setting xattr of max xattr size: $(max_xattr_size)"
10341         grow_xattr $(max_xattr_size)
10342
10343         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10344         echo "This should fail:"
10345         grow_xattr $(($(max_xattr_size) + 10)) 1
10346 }
10347 run_test 102ha "grow xattr from inside inode to external inode"
10348
10349 test_102i() { # bug 17038
10350         [ -z "$(which getfattr 2>/dev/null)" ] &&
10351                 skip "could not find getfattr"
10352
10353         touch $DIR/$tfile
10354         ln -s $DIR/$tfile $DIR/${tfile}link
10355         getfattr -n trusted.lov $DIR/$tfile ||
10356                 error "lgetxattr on $DIR/$tfile failed"
10357         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10358                 grep -i "no such attr" ||
10359                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10360         rm -f $DIR/$tfile $DIR/${tfile}link
10361 }
10362 run_test 102i "lgetxattr test on symbolic link ============"
10363
10364 test_102j() {
10365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10366         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10367
10368         XINC=$(have_xattrs_include)
10369         setup_test102 "$RUNAS"
10370         chown $RUNAS_ID $DIR/$tdir
10371         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10372         cd $DIR/$tdir/$tdir
10373         compare_stripe_info1 "$RUNAS"
10374 }
10375 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10376
10377 test_102k() {
10378         [ -z "$(which setfattr 2>/dev/null)" ] &&
10379                 skip "could not find setfattr"
10380
10381         touch $DIR/$tfile
10382         # b22187 just check that does not crash for regular file.
10383         setfattr -n trusted.lov $DIR/$tfile
10384         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10385         local test_kdir=$DIR/$tdir
10386         test_mkdir $test_kdir
10387         local default_size=$($LFS getstripe -S $test_kdir)
10388         local default_count=$($LFS getstripe -c $test_kdir)
10389         local default_offset=$($LFS getstripe -i $test_kdir)
10390         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10391                 error 'dir setstripe failed'
10392         setfattr -n trusted.lov $test_kdir
10393         local stripe_size=$($LFS getstripe -S $test_kdir)
10394         local stripe_count=$($LFS getstripe -c $test_kdir)
10395         local stripe_offset=$($LFS getstripe -i $test_kdir)
10396         [ $stripe_size -eq $default_size ] ||
10397                 error "stripe size $stripe_size != $default_size"
10398         [ $stripe_count -eq $default_count ] ||
10399                 error "stripe count $stripe_count != $default_count"
10400         [ $stripe_offset -eq $default_offset ] ||
10401                 error "stripe offset $stripe_offset != $default_offset"
10402         rm -rf $DIR/$tfile $test_kdir
10403 }
10404 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10405
10406 test_102l() {
10407         [ -z "$(which getfattr 2>/dev/null)" ] &&
10408                 skip "could not find getfattr"
10409
10410         # LU-532 trusted. xattr is invisible to non-root
10411         local testfile=$DIR/$tfile
10412
10413         touch $testfile
10414
10415         echo "listxattr as user..."
10416         chown $RUNAS_ID $testfile
10417         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10418             grep -q "trusted" &&
10419                 error "$testfile trusted xattrs are user visible"
10420
10421         return 0;
10422 }
10423 run_test 102l "listxattr size test =================================="
10424
10425 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10426         local path=$DIR/$tfile
10427         touch $path
10428
10429         listxattr_size_check $path || error "listattr_size_check $path failed"
10430 }
10431 run_test 102m "Ensure listxattr fails on small bufffer ========"
10432
10433 cleanup_test102
10434
10435 getxattr() { # getxattr path name
10436         # Return the base64 encoding of the value of xattr name on path.
10437         local path=$1
10438         local name=$2
10439
10440         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10441         # file: $path
10442         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10443         #
10444         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10445
10446         getfattr --absolute-names --encoding=base64 --name=$name $path |
10447                 awk -F= -v name=$name '$1 == name {
10448                         print substr($0, index($0, "=") + 1);
10449         }'
10450 }
10451
10452 test_102n() { # LU-4101 mdt: protect internal xattrs
10453         [ -z "$(which setfattr 2>/dev/null)" ] &&
10454                 skip "could not find setfattr"
10455         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10456         then
10457                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10458         fi
10459
10460         local file0=$DIR/$tfile.0
10461         local file1=$DIR/$tfile.1
10462         local xattr0=$TMP/$tfile.0
10463         local xattr1=$TMP/$tfile.1
10464         local namelist="lov lma lmv link fid version som hsm"
10465         local name
10466         local value
10467
10468         rm -rf $file0 $file1 $xattr0 $xattr1
10469         touch $file0 $file1
10470
10471         # Get 'before' xattrs of $file1.
10472         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10473
10474         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10475                 namelist+=" lfsck_namespace"
10476         for name in $namelist; do
10477                 # Try to copy xattr from $file0 to $file1.
10478                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10479
10480                 setfattr --name=trusted.$name --value="$value" $file1 ||
10481                         error "setxattr 'trusted.$name' failed"
10482
10483                 # Try to set a garbage xattr.
10484                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10485
10486                 if [[ x$name == "xlov" ]]; then
10487                         setfattr --name=trusted.lov --value="$value" $file1 &&
10488                         error "setxattr invalid 'trusted.lov' success"
10489                 else
10490                         setfattr --name=trusted.$name --value="$value" $file1 ||
10491                                 error "setxattr invalid 'trusted.$name' failed"
10492                 fi
10493
10494                 # Try to remove the xattr from $file1. We don't care if this
10495                 # appears to succeed or fail, we just don't want there to be
10496                 # any changes or crashes.
10497                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10498         done
10499
10500         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10501         then
10502                 name="lfsck_ns"
10503                 # Try to copy xattr from $file0 to $file1.
10504                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10505
10506                 setfattr --name=trusted.$name --value="$value" $file1 ||
10507                         error "setxattr 'trusted.$name' failed"
10508
10509                 # Try to set a garbage xattr.
10510                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10511
10512                 setfattr --name=trusted.$name --value="$value" $file1 ||
10513                         error "setxattr 'trusted.$name' failed"
10514
10515                 # Try to remove the xattr from $file1. We don't care if this
10516                 # appears to succeed or fail, we just don't want there to be
10517                 # any changes or crashes.
10518                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10519         fi
10520
10521         # Get 'after' xattrs of file1.
10522         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10523
10524         if ! diff $xattr0 $xattr1; then
10525                 error "before and after xattrs of '$file1' differ"
10526         fi
10527
10528         rm -rf $file0 $file1 $xattr0 $xattr1
10529
10530         return 0
10531 }
10532 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10533
10534 test_102p() { # LU-4703 setxattr did not check ownership
10535         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10536                 skip "MDS needs to be at least 2.5.56"
10537
10538         local testfile=$DIR/$tfile
10539
10540         touch $testfile
10541
10542         echo "setfacl as user..."
10543         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10544         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10545
10546         echo "setfattr as user..."
10547         setfacl -m "u:$RUNAS_ID:---" $testfile
10548         $RUNAS setfattr -x system.posix_acl_access $testfile
10549         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10550 }
10551 run_test 102p "check setxattr(2) correctly fails without permission"
10552
10553 test_102q() {
10554         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10555                 skip "MDS needs to be at least 2.6.92"
10556
10557         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10558 }
10559 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10560
10561 test_102r() {
10562         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10563                 skip "MDS needs to be at least 2.6.93"
10564
10565         touch $DIR/$tfile || error "touch"
10566         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10567         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10568         rm $DIR/$tfile || error "rm"
10569
10570         #normal directory
10571         mkdir -p $DIR/$tdir || error "mkdir"
10572         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10573         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10574         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10575                 error "$testfile error deleting user.author1"
10576         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10577                 grep "user.$(basename $tdir)" &&
10578                 error "$tdir did not delete user.$(basename $tdir)"
10579         rmdir $DIR/$tdir || error "rmdir"
10580
10581         #striped directory
10582         test_mkdir $DIR/$tdir
10583         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10584         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10585         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10586                 error "$testfile error deleting user.author1"
10587         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10588                 grep "user.$(basename $tdir)" &&
10589                 error "$tdir did not delete user.$(basename $tdir)"
10590         rmdir $DIR/$tdir || error "rm striped dir"
10591 }
10592 run_test 102r "set EAs with empty values"
10593
10594 test_102s() {
10595         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10596                 skip "MDS needs to be at least 2.11.52"
10597
10598         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10599
10600         save_lustre_params client "llite.*.xattr_cache" > $save
10601
10602         for cache in 0 1; do
10603                 lctl set_param llite.*.xattr_cache=$cache
10604
10605                 rm -f $DIR/$tfile
10606                 touch $DIR/$tfile || error "touch"
10607                 for prefix in lustre security system trusted user; do
10608                         # Note getxattr() may fail with 'Operation not
10609                         # supported' or 'No such attribute' depending
10610                         # on prefix and cache.
10611                         getfattr -n $prefix.n102s $DIR/$tfile &&
10612                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10613                 done
10614         done
10615
10616         restore_lustre_params < $save
10617 }
10618 run_test 102s "getting nonexistent xattrs should fail"
10619
10620 test_102t() {
10621         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10622                 skip "MDS needs to be at least 2.11.52"
10623
10624         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10625
10626         save_lustre_params client "llite.*.xattr_cache" > $save
10627
10628         for cache in 0 1; do
10629                 lctl set_param llite.*.xattr_cache=$cache
10630
10631                 for buf_size in 0 256; do
10632                         rm -f $DIR/$tfile
10633                         touch $DIR/$tfile || error "touch"
10634                         setfattr -n user.multiop $DIR/$tfile
10635                         $MULTIOP $DIR/$tfile oa$buf_size ||
10636                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10637                 done
10638         done
10639
10640         restore_lustre_params < $save
10641 }
10642 run_test 102t "zero length xattr values handled correctly"
10643
10644 run_acl_subtest()
10645 {
10646     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10647     return $?
10648 }
10649
10650 test_103a() {
10651         [ "$UID" != 0 ] && skip "must run as root"
10652         $GSS && skip_env "could not run under gss"
10653         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10654                 skip_env "must have acl enabled"
10655         [ -z "$(which setfacl 2>/dev/null)" ] &&
10656                 skip_env "could not find setfacl"
10657         remote_mds_nodsh && skip "remote MDS with nodsh"
10658
10659         gpasswd -a daemon bin                           # LU-5641
10660         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10661
10662         declare -a identity_old
10663
10664         for num in $(seq $MDSCOUNT); do
10665                 switch_identity $num true || identity_old[$num]=$?
10666         done
10667
10668         SAVE_UMASK=$(umask)
10669         umask 0022
10670         mkdir -p $DIR/$tdir
10671         cd $DIR/$tdir
10672
10673         echo "performing cp ..."
10674         run_acl_subtest cp || error "run_acl_subtest cp failed"
10675         echo "performing getfacl-noacl..."
10676         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10677         echo "performing misc..."
10678         run_acl_subtest misc || error  "misc test failed"
10679         echo "performing permissions..."
10680         run_acl_subtest permissions || error "permissions failed"
10681         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10682         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10683                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10684                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10685         then
10686                 echo "performing permissions xattr..."
10687                 run_acl_subtest permissions_xattr ||
10688                         error "permissions_xattr failed"
10689         fi
10690         echo "performing setfacl..."
10691         run_acl_subtest setfacl || error  "setfacl test failed"
10692
10693         # inheritance test got from HP
10694         echo "performing inheritance..."
10695         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10696         chmod +x make-tree || error "chmod +x failed"
10697         run_acl_subtest inheritance || error "inheritance test failed"
10698         rm -f make-tree
10699
10700         echo "LU-974 ignore umask when acl is enabled..."
10701         run_acl_subtest 974 || error "LU-974 umask test failed"
10702         if [ $MDSCOUNT -ge 2 ]; then
10703                 run_acl_subtest 974_remote ||
10704                         error "LU-974 umask test failed under remote dir"
10705         fi
10706
10707         echo "LU-2561 newly created file is same size as directory..."
10708         if [ "$mds1_FSTYPE" != "zfs" ]; then
10709                 run_acl_subtest 2561 || error "LU-2561 test failed"
10710         else
10711                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10712         fi
10713
10714         run_acl_subtest 4924 || error "LU-4924 test failed"
10715
10716         cd $SAVE_PWD
10717         umask $SAVE_UMASK
10718
10719         for num in $(seq $MDSCOUNT); do
10720                 if [ "${identity_old[$num]}" = 1 ]; then
10721                         switch_identity $num false || identity_old[$num]=$?
10722                 fi
10723         done
10724 }
10725 run_test 103a "acl test"
10726
10727 test_103b() {
10728         declare -a pids
10729         local U
10730
10731         for U in {0..511}; do
10732                 {
10733                 local O=$(printf "%04o" $U)
10734
10735                 umask $(printf "%04o" $((511 ^ $O)))
10736                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10737                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10738
10739                 (( $S == ($O & 0666) )) ||
10740                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10741
10742                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10743                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10744                 (( $S == ($O & 0666) )) ||
10745                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10746
10747                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10748                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10749                 (( $S == ($O & 0666) )) ||
10750                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10751                 rm -f $DIR/$tfile.[smp]$0
10752                 } &
10753                 local pid=$!
10754
10755                 # limit the concurrently running threads to 64. LU-11878
10756                 local idx=$((U % 64))
10757                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10758                 pids[idx]=$pid
10759         done
10760         wait
10761 }
10762 run_test 103b "umask lfs setstripe"
10763
10764 test_103c() {
10765         mkdir -p $DIR/$tdir
10766         cp -rp $DIR/$tdir $DIR/$tdir.bak
10767
10768         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10769                 error "$DIR/$tdir shouldn't contain default ACL"
10770         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10771                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10772         true
10773 }
10774 run_test 103c "'cp -rp' won't set empty acl"
10775
10776 test_103e() {
10777         (( $MDS1_VERSION >= $(version_code 2.13.59) )) ||
10778                 skip "MDS needs to be at least 2.13.59"
10779
10780         mkdir -p $DIR/$tdir
10781         # one default ACL will be created for the file owner
10782         for U in {2..256}; do
10783                 setfacl -m default:user:$U:rwx $DIR/$tdir
10784                 numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10785                 touch $DIR/$tdir/$tfile.$U ||
10786                         error "failed to create $tfile.$U with $numacl ACLs"
10787         done
10788 }
10789 run_test 103e "inheritance of big amount of default ACLs"
10790
10791 test_104a() {
10792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10793
10794         touch $DIR/$tfile
10795         lfs df || error "lfs df failed"
10796         lfs df -ih || error "lfs df -ih failed"
10797         lfs df -h $DIR || error "lfs df -h $DIR failed"
10798         lfs df -i $DIR || error "lfs df -i $DIR failed"
10799         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10800         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10801
10802         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10803         lctl --device %$OSC deactivate
10804         lfs df || error "lfs df with deactivated OSC failed"
10805         lctl --device %$OSC activate
10806         # wait the osc back to normal
10807         wait_osc_import_ready client ost
10808
10809         lfs df || error "lfs df with reactivated OSC failed"
10810         rm -f $DIR/$tfile
10811 }
10812 run_test 104a "lfs df [-ih] [path] test ========================="
10813
10814 test_104b() {
10815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10816         [ $RUNAS_ID -eq $UID ] &&
10817                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10818
10819         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10820                         grep "Permission denied" | wc -l)))
10821         if [ $denied_cnt -ne 0 ]; then
10822                 error "lfs check servers test failed"
10823         fi
10824 }
10825 run_test 104b "$RUNAS lfs check servers test ===================="
10826
10827 test_105a() {
10828         # doesn't work on 2.4 kernels
10829         touch $DIR/$tfile
10830         if $(flock_is_enabled); then
10831                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10832         else
10833                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10834         fi
10835         rm -f $DIR/$tfile
10836 }
10837 run_test 105a "flock when mounted without -o flock test ========"
10838
10839 test_105b() {
10840         touch $DIR/$tfile
10841         if $(flock_is_enabled); then
10842                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10843         else
10844                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10845         fi
10846         rm -f $DIR/$tfile
10847 }
10848 run_test 105b "fcntl when mounted without -o flock test ========"
10849
10850 test_105c() {
10851         touch $DIR/$tfile
10852         if $(flock_is_enabled); then
10853                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10854         else
10855                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10856         fi
10857         rm -f $DIR/$tfile
10858 }
10859 run_test 105c "lockf when mounted without -o flock test"
10860
10861 test_105d() { # bug 15924
10862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10863
10864         test_mkdir $DIR/$tdir
10865         flock_is_enabled || skip_env "mount w/o flock enabled"
10866         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10867         $LCTL set_param fail_loc=0x80000315
10868         flocks_test 2 $DIR/$tdir
10869 }
10870 run_test 105d "flock race (should not freeze) ========"
10871
10872 test_105e() { # bug 22660 && 22040
10873         flock_is_enabled || skip_env "mount w/o flock enabled"
10874
10875         touch $DIR/$tfile
10876         flocks_test 3 $DIR/$tfile
10877 }
10878 run_test 105e "Two conflicting flocks from same process"
10879
10880 test_106() { #bug 10921
10881         test_mkdir $DIR/$tdir
10882         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10883         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10884 }
10885 run_test 106 "attempt exec of dir followed by chown of that dir"
10886
10887 test_107() {
10888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10889
10890         CDIR=`pwd`
10891         local file=core
10892
10893         cd $DIR
10894         rm -f $file
10895
10896         local save_pattern=$(sysctl -n kernel.core_pattern)
10897         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10898         sysctl -w kernel.core_pattern=$file
10899         sysctl -w kernel.core_uses_pid=0
10900
10901         ulimit -c unlimited
10902         sleep 60 &
10903         SLEEPPID=$!
10904
10905         sleep 1
10906
10907         kill -s 11 $SLEEPPID
10908         wait $SLEEPPID
10909         if [ -e $file ]; then
10910                 size=`stat -c%s $file`
10911                 [ $size -eq 0 ] && error "Fail to create core file $file"
10912         else
10913                 error "Fail to create core file $file"
10914         fi
10915         rm -f $file
10916         sysctl -w kernel.core_pattern=$save_pattern
10917         sysctl -w kernel.core_uses_pid=$save_uses_pid
10918         cd $CDIR
10919 }
10920 run_test 107 "Coredump on SIG"
10921
10922 test_110() {
10923         test_mkdir $DIR/$tdir
10924         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10925         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10926                 error "mkdir with 256 char should fail, but did not"
10927         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10928                 error "create with 255 char failed"
10929         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10930                 error "create with 256 char should fail, but did not"
10931
10932         ls -l $DIR/$tdir
10933         rm -rf $DIR/$tdir
10934 }
10935 run_test 110 "filename length checking"
10936
10937 #
10938 # Purpose: To verify dynamic thread (OSS) creation.
10939 #
10940 test_115() {
10941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10942         remote_ost_nodsh && skip "remote OST with nodsh"
10943
10944         # Lustre does not stop service threads once they are started.
10945         # Reset number of running threads to default.
10946         stopall
10947         setupall
10948
10949         local OSTIO_pre
10950         local save_params="$TMP/sanity-$TESTNAME.parameters"
10951
10952         # Get ll_ost_io count before I/O
10953         OSTIO_pre=$(do_facet ost1 \
10954                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10955         # Exit if lustre is not running (ll_ost_io not running).
10956         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10957
10958         echo "Starting with $OSTIO_pre threads"
10959         local thread_max=$((OSTIO_pre * 2))
10960         local rpc_in_flight=$((thread_max * 2))
10961         # Number of I/O Process proposed to be started.
10962         local nfiles
10963         local facets=$(get_facets OST)
10964
10965         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10966         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10967
10968         # Set in_flight to $rpc_in_flight
10969         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10970                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10971         nfiles=${rpc_in_flight}
10972         # Set ost thread_max to $thread_max
10973         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10974
10975         # 5 Minutes should be sufficient for max number of OSS
10976         # threads(thread_max) to be created.
10977         local timeout=300
10978
10979         # Start I/O.
10980         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10981         test_mkdir $DIR/$tdir
10982         for i in $(seq $nfiles); do
10983                 local file=$DIR/$tdir/${tfile}-$i
10984                 $LFS setstripe -c -1 -i 0 $file
10985                 ($WTL $file $timeout)&
10986         done
10987
10988         # I/O Started - Wait for thread_started to reach thread_max or report
10989         # error if thread_started is more than thread_max.
10990         echo "Waiting for thread_started to reach thread_max"
10991         local thread_started=0
10992         local end_time=$((SECONDS + timeout))
10993
10994         while [ $SECONDS -le $end_time ] ; do
10995                 echo -n "."
10996                 # Get ost i/o thread_started count.
10997                 thread_started=$(do_facet ost1 \
10998                         "$LCTL get_param \
10999                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11000                 # Break out if thread_started is equal/greater than thread_max
11001                 if [[ $thread_started -ge $thread_max ]]; then
11002                         echo ll_ost_io thread_started $thread_started, \
11003                                 equal/greater than thread_max $thread_max
11004                         break
11005                 fi
11006                 sleep 1
11007         done
11008
11009         # Cleanup - We have the numbers, Kill i/o jobs if running.
11010         jobcount=($(jobs -p))
11011         for i in $(seq 0 $((${#jobcount[@]}-1)))
11012         do
11013                 kill -9 ${jobcount[$i]}
11014                 if [ $? -ne 0 ] ; then
11015                         echo Warning: \
11016                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11017                 fi
11018         done
11019
11020         # Cleanup files left by WTL binary.
11021         for i in $(seq $nfiles); do
11022                 local file=$DIR/$tdir/${tfile}-$i
11023                 rm -rf $file
11024                 if [ $? -ne 0 ] ; then
11025                         echo "Warning: Failed to delete file $file"
11026                 fi
11027         done
11028
11029         restore_lustre_params <$save_params
11030         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11031
11032         # Error out if no new thread has started or Thread started is greater
11033         # than thread max.
11034         if [[ $thread_started -le $OSTIO_pre ||
11035                         $thread_started -gt $thread_max ]]; then
11036                 error "ll_ost_io: thread_started $thread_started" \
11037                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11038                       "No new thread started or thread started greater " \
11039                       "than thread_max."
11040         fi
11041 }
11042 run_test 115 "verify dynamic thread creation===================="
11043
11044 free_min_max () {
11045         wait_delete_completed
11046         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11047         echo "OST kbytes available: ${AVAIL[@]}"
11048         MAXV=${AVAIL[0]}
11049         MAXI=0
11050         MINV=${AVAIL[0]}
11051         MINI=0
11052         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11053                 #echo OST $i: ${AVAIL[i]}kb
11054                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11055                         MAXV=${AVAIL[i]}
11056                         MAXI=$i
11057                 fi
11058                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11059                         MINV=${AVAIL[i]}
11060                         MINI=$i
11061                 fi
11062         done
11063         echo "Min free space: OST $MINI: $MINV"
11064         echo "Max free space: OST $MAXI: $MAXV"
11065 }
11066
11067 test_116a() { # was previously test_116()
11068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11069         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11070         remote_mds_nodsh && skip "remote MDS with nodsh"
11071
11072         echo -n "Free space priority "
11073         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11074                 head -n1
11075         declare -a AVAIL
11076         free_min_max
11077
11078         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11079         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11080         trap simple_cleanup_common EXIT
11081
11082         # Check if we need to generate uneven OSTs
11083         test_mkdir -p $DIR/$tdir/OST${MINI}
11084         local FILL=$((MINV / 4))
11085         local DIFF=$((MAXV - MINV))
11086         local DIFF2=$((DIFF * 100 / MINV))
11087
11088         local threshold=$(do_facet $SINGLEMDS \
11089                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11090         threshold=${threshold%%%}
11091         echo -n "Check for uneven OSTs: "
11092         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11093
11094         if [[ $DIFF2 -gt $threshold ]]; then
11095                 echo "ok"
11096                 echo "Don't need to fill OST$MINI"
11097         else
11098                 # generate uneven OSTs. Write 2% over the QOS threshold value
11099                 echo "no"
11100                 DIFF=$((threshold - DIFF2 + 2))
11101                 DIFF2=$((MINV * DIFF / 100))
11102                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11103                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11104                         error "setstripe failed"
11105                 DIFF=$((DIFF2 / 2048))
11106                 i=0
11107                 while [ $i -lt $DIFF ]; do
11108                         i=$((i + 1))
11109                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11110                                 bs=2M count=1 2>/dev/null
11111                         echo -n .
11112                 done
11113                 echo .
11114                 sync
11115                 sleep_maxage
11116                 free_min_max
11117         fi
11118
11119         DIFF=$((MAXV - MINV))
11120         DIFF2=$((DIFF * 100 / MINV))
11121         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11122         if [ $DIFF2 -gt $threshold ]; then
11123                 echo "ok"
11124         else
11125                 echo "failed - QOS mode won't be used"
11126                 simple_cleanup_common
11127                 skip "QOS imbalance criteria not met"
11128         fi
11129
11130         MINI1=$MINI
11131         MINV1=$MINV
11132         MAXI1=$MAXI
11133         MAXV1=$MAXV
11134
11135         # now fill using QOS
11136         $LFS setstripe -c 1 $DIR/$tdir
11137         FILL=$((FILL / 200))
11138         if [ $FILL -gt 600 ]; then
11139                 FILL=600
11140         fi
11141         echo "writing $FILL files to QOS-assigned OSTs"
11142         i=0
11143         while [ $i -lt $FILL ]; do
11144                 i=$((i + 1))
11145                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11146                         count=1 2>/dev/null
11147                 echo -n .
11148         done
11149         echo "wrote $i 200k files"
11150         sync
11151         sleep_maxage
11152
11153         echo "Note: free space may not be updated, so measurements might be off"
11154         free_min_max
11155         DIFF2=$((MAXV - MINV))
11156         echo "free space delta: orig $DIFF final $DIFF2"
11157         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11158         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11159         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11160         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11161         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11162         if [[ $DIFF -gt 0 ]]; then
11163                 FILL=$((DIFF2 * 100 / DIFF - 100))
11164                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11165         fi
11166
11167         # Figure out which files were written where
11168         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11169                awk '/'$MINI1': / {print $2; exit}')
11170         echo $UUID
11171         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11172         echo "$MINC files created on smaller OST $MINI1"
11173         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11174                awk '/'$MAXI1': / {print $2; exit}')
11175         echo $UUID
11176         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11177         echo "$MAXC files created on larger OST $MAXI1"
11178         if [[ $MINC -gt 0 ]]; then
11179                 FILL=$((MAXC * 100 / MINC - 100))
11180                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11181         fi
11182         [[ $MAXC -gt $MINC ]] ||
11183                 error_ignore LU-9 "stripe QOS didn't balance free space"
11184         simple_cleanup_common
11185 }
11186 run_test 116a "stripe QOS: free space balance ==================="
11187
11188 test_116b() { # LU-2093
11189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11190         remote_mds_nodsh && skip "remote MDS with nodsh"
11191
11192 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11193         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11194                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11195         [ -z "$old_rr" ] && skip "no QOS"
11196         do_facet $SINGLEMDS lctl set_param \
11197                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11198         mkdir -p $DIR/$tdir
11199         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11200         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11201         do_facet $SINGLEMDS lctl set_param fail_loc=0
11202         rm -rf $DIR/$tdir
11203         do_facet $SINGLEMDS lctl set_param \
11204                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11205 }
11206 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11207
11208 test_117() # bug 10891
11209 {
11210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11211
11212         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11213         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11214         lctl set_param fail_loc=0x21e
11215         > $DIR/$tfile || error "truncate failed"
11216         lctl set_param fail_loc=0
11217         echo "Truncate succeeded."
11218         rm -f $DIR/$tfile
11219 }
11220 run_test 117 "verify osd extend =========="
11221
11222 NO_SLOW_RESENDCOUNT=4
11223 export OLD_RESENDCOUNT=""
11224 set_resend_count () {
11225         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11226         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11227         lctl set_param -n $PROC_RESENDCOUNT $1
11228         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11229 }
11230
11231 # for reduce test_118* time (b=14842)
11232 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11233
11234 # Reset async IO behavior after error case
11235 reset_async() {
11236         FILE=$DIR/reset_async
11237
11238         # Ensure all OSCs are cleared
11239         $LFS setstripe -c -1 $FILE
11240         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11241         sync
11242         rm $FILE
11243 }
11244
11245 test_118a() #bug 11710
11246 {
11247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11248
11249         reset_async
11250
11251         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11252         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11253         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11254
11255         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11256                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11257                 return 1;
11258         fi
11259         rm -f $DIR/$tfile
11260 }
11261 run_test 118a "verify O_SYNC works =========="
11262
11263 test_118b()
11264 {
11265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11266         remote_ost_nodsh && skip "remote OST with nodsh"
11267
11268         reset_async
11269
11270         #define OBD_FAIL_SRV_ENOENT 0x217
11271         set_nodes_failloc "$(osts_nodes)" 0x217
11272         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11273         RC=$?
11274         set_nodes_failloc "$(osts_nodes)" 0
11275         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11276         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11277                     grep -c writeback)
11278
11279         if [[ $RC -eq 0 ]]; then
11280                 error "Must return error due to dropped pages, rc=$RC"
11281                 return 1;
11282         fi
11283
11284         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11285                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11286                 return 1;
11287         fi
11288
11289         echo "Dirty pages not leaked on ENOENT"
11290
11291         # Due to the above error the OSC will issue all RPCs syncronously
11292         # until a subsequent RPC completes successfully without error.
11293         $MULTIOP $DIR/$tfile Ow4096yc
11294         rm -f $DIR/$tfile
11295
11296         return 0
11297 }
11298 run_test 118b "Reclaim dirty pages on fatal error =========="
11299
11300 test_118c()
11301 {
11302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11303
11304         # for 118c, restore the original resend count, LU-1940
11305         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11306                                 set_resend_count $OLD_RESENDCOUNT
11307         remote_ost_nodsh && skip "remote OST with nodsh"
11308
11309         reset_async
11310
11311         #define OBD_FAIL_OST_EROFS               0x216
11312         set_nodes_failloc "$(osts_nodes)" 0x216
11313
11314         # multiop should block due to fsync until pages are written
11315         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11316         MULTIPID=$!
11317         sleep 1
11318
11319         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11320                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11321         fi
11322
11323         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11324                     grep -c writeback)
11325         if [[ $WRITEBACK -eq 0 ]]; then
11326                 error "No page in writeback, writeback=$WRITEBACK"
11327         fi
11328
11329         set_nodes_failloc "$(osts_nodes)" 0
11330         wait $MULTIPID
11331         RC=$?
11332         if [[ $RC -ne 0 ]]; then
11333                 error "Multiop fsync failed, rc=$RC"
11334         fi
11335
11336         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11337         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11338                     grep -c writeback)
11339         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11340                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11341         fi
11342
11343         rm -f $DIR/$tfile
11344         echo "Dirty pages flushed via fsync on EROFS"
11345         return 0
11346 }
11347 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11348
11349 # continue to use small resend count to reduce test_118* time (b=14842)
11350 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11351
11352 test_118d()
11353 {
11354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11355         remote_ost_nodsh && skip "remote OST with nodsh"
11356
11357         reset_async
11358
11359         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11360         set_nodes_failloc "$(osts_nodes)" 0x214
11361         # multiop should block due to fsync until pages are written
11362         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11363         MULTIPID=$!
11364         sleep 1
11365
11366         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11367                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11368         fi
11369
11370         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11371                     grep -c writeback)
11372         if [[ $WRITEBACK -eq 0 ]]; then
11373                 error "No page in writeback, writeback=$WRITEBACK"
11374         fi
11375
11376         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11377         set_nodes_failloc "$(osts_nodes)" 0
11378
11379         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11380         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11381                     grep -c writeback)
11382         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11383                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11384         fi
11385
11386         rm -f $DIR/$tfile
11387         echo "Dirty pages gaurenteed flushed via fsync"
11388         return 0
11389 }
11390 run_test 118d "Fsync validation inject a delay of the bulk =========="
11391
11392 test_118f() {
11393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11394
11395         reset_async
11396
11397         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11398         lctl set_param fail_loc=0x8000040a
11399
11400         # Should simulate EINVAL error which is fatal
11401         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11402         RC=$?
11403         if [[ $RC -eq 0 ]]; then
11404                 error "Must return error due to dropped pages, rc=$RC"
11405         fi
11406
11407         lctl set_param fail_loc=0x0
11408
11409         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11410         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11411         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11412                     grep -c writeback)
11413         if [[ $LOCKED -ne 0 ]]; then
11414                 error "Locked pages remain in cache, locked=$LOCKED"
11415         fi
11416
11417         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11418                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11419         fi
11420
11421         rm -f $DIR/$tfile
11422         echo "No pages locked after fsync"
11423
11424         reset_async
11425         return 0
11426 }
11427 run_test 118f "Simulate unrecoverable OSC side error =========="
11428
11429 test_118g() {
11430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11431
11432         reset_async
11433
11434         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11435         lctl set_param fail_loc=0x406
11436
11437         # simulate local -ENOMEM
11438         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11439         RC=$?
11440
11441         lctl set_param fail_loc=0
11442         if [[ $RC -eq 0 ]]; then
11443                 error "Must return error due to dropped pages, rc=$RC"
11444         fi
11445
11446         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11447         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11448         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11449                         grep -c writeback)
11450         if [[ $LOCKED -ne 0 ]]; then
11451                 error "Locked pages remain in cache, locked=$LOCKED"
11452         fi
11453
11454         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11455                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11456         fi
11457
11458         rm -f $DIR/$tfile
11459         echo "No pages locked after fsync"
11460
11461         reset_async
11462         return 0
11463 }
11464 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11465
11466 test_118h() {
11467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11468         remote_ost_nodsh && skip "remote OST with nodsh"
11469
11470         reset_async
11471
11472         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11473         set_nodes_failloc "$(osts_nodes)" 0x20e
11474         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11475         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11476         RC=$?
11477
11478         set_nodes_failloc "$(osts_nodes)" 0
11479         if [[ $RC -eq 0 ]]; then
11480                 error "Must return error due to dropped pages, rc=$RC"
11481         fi
11482
11483         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11484         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11485         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11486                     grep -c writeback)
11487         if [[ $LOCKED -ne 0 ]]; then
11488                 error "Locked pages remain in cache, locked=$LOCKED"
11489         fi
11490
11491         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11492                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11493         fi
11494
11495         rm -f $DIR/$tfile
11496         echo "No pages locked after fsync"
11497
11498         return 0
11499 }
11500 run_test 118h "Verify timeout in handling recoverables errors  =========="
11501
11502 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11503
11504 test_118i() {
11505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11506         remote_ost_nodsh && skip "remote OST with nodsh"
11507
11508         reset_async
11509
11510         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11511         set_nodes_failloc "$(osts_nodes)" 0x20e
11512
11513         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11514         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11515         PID=$!
11516         sleep 5
11517         set_nodes_failloc "$(osts_nodes)" 0
11518
11519         wait $PID
11520         RC=$?
11521         if [[ $RC -ne 0 ]]; then
11522                 error "got error, but should be not, rc=$RC"
11523         fi
11524
11525         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11526         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11527         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11528         if [[ $LOCKED -ne 0 ]]; then
11529                 error "Locked pages remain in cache, locked=$LOCKED"
11530         fi
11531
11532         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11533                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11534         fi
11535
11536         rm -f $DIR/$tfile
11537         echo "No pages locked after fsync"
11538
11539         return 0
11540 }
11541 run_test 118i "Fix error before timeout in recoverable error  =========="
11542
11543 [ "$SLOW" = "no" ] && set_resend_count 4
11544
11545 test_118j() {
11546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11547         remote_ost_nodsh && skip "remote OST with nodsh"
11548
11549         reset_async
11550
11551         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11552         set_nodes_failloc "$(osts_nodes)" 0x220
11553
11554         # return -EIO from OST
11555         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11556         RC=$?
11557         set_nodes_failloc "$(osts_nodes)" 0x0
11558         if [[ $RC -eq 0 ]]; then
11559                 error "Must return error due to dropped pages, rc=$RC"
11560         fi
11561
11562         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11563         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11564         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11565         if [[ $LOCKED -ne 0 ]]; then
11566                 error "Locked pages remain in cache, locked=$LOCKED"
11567         fi
11568
11569         # in recoverable error on OST we want resend and stay until it finished
11570         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11571                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11572         fi
11573
11574         rm -f $DIR/$tfile
11575         echo "No pages locked after fsync"
11576
11577         return 0
11578 }
11579 run_test 118j "Simulate unrecoverable OST side error =========="
11580
11581 test_118k()
11582 {
11583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11584         remote_ost_nodsh && skip "remote OSTs with nodsh"
11585
11586         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11587         set_nodes_failloc "$(osts_nodes)" 0x20e
11588         test_mkdir $DIR/$tdir
11589
11590         for ((i=0;i<10;i++)); do
11591                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11592                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11593                 SLEEPPID=$!
11594                 sleep 0.500s
11595                 kill $SLEEPPID
11596                 wait $SLEEPPID
11597         done
11598
11599         set_nodes_failloc "$(osts_nodes)" 0
11600         rm -rf $DIR/$tdir
11601 }
11602 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11603
11604 test_118l() # LU-646
11605 {
11606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11607
11608         test_mkdir $DIR/$tdir
11609         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11610         rm -rf $DIR/$tdir
11611 }
11612 run_test 118l "fsync dir"
11613
11614 test_118m() # LU-3066
11615 {
11616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11617
11618         test_mkdir $DIR/$tdir
11619         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11620         rm -rf $DIR/$tdir
11621 }
11622 run_test 118m "fdatasync dir ========="
11623
11624 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11625
11626 test_118n()
11627 {
11628         local begin
11629         local end
11630
11631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11632         remote_ost_nodsh && skip "remote OSTs with nodsh"
11633
11634         # Sleep to avoid a cached response.
11635         #define OBD_STATFS_CACHE_SECONDS 1
11636         sleep 2
11637
11638         # Inject a 10 second delay in the OST_STATFS handler.
11639         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11640         set_nodes_failloc "$(osts_nodes)" 0x242
11641
11642         begin=$SECONDS
11643         stat --file-system $MOUNT > /dev/null
11644         end=$SECONDS
11645
11646         set_nodes_failloc "$(osts_nodes)" 0
11647
11648         if ((end - begin > 20)); then
11649             error "statfs took $((end - begin)) seconds, expected 10"
11650         fi
11651 }
11652 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11653
11654 test_119a() # bug 11737
11655 {
11656         BSIZE=$((512 * 1024))
11657         directio write $DIR/$tfile 0 1 $BSIZE
11658         # We ask to read two blocks, which is more than a file size.
11659         # directio will indicate an error when requested and actual
11660         # sizes aren't equeal (a normal situation in this case) and
11661         # print actual read amount.
11662         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11663         if [ "$NOB" != "$BSIZE" ]; then
11664                 error "read $NOB bytes instead of $BSIZE"
11665         fi
11666         rm -f $DIR/$tfile
11667 }
11668 run_test 119a "Short directIO read must return actual read amount"
11669
11670 test_119b() # bug 11737
11671 {
11672         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11673
11674         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11675         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11676         sync
11677         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11678                 error "direct read failed"
11679         rm -f $DIR/$tfile
11680 }
11681 run_test 119b "Sparse directIO read must return actual read amount"
11682
11683 test_119c() # bug 13099
11684 {
11685         BSIZE=1048576
11686         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11687         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11688         rm -f $DIR/$tfile
11689 }
11690 run_test 119c "Testing for direct read hitting hole"
11691
11692 test_119d() # bug 15950
11693 {
11694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11695
11696         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11697         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11698         BSIZE=1048576
11699         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11700         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11701         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11702         lctl set_param fail_loc=0x40d
11703         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11704         pid_dio=$!
11705         sleep 1
11706         cat $DIR/$tfile > /dev/null &
11707         lctl set_param fail_loc=0
11708         pid_reads=$!
11709         wait $pid_dio
11710         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11711         sleep 2
11712         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11713         error "the read rpcs have not completed in 2s"
11714         rm -f $DIR/$tfile
11715         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11716 }
11717 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11718
11719 test_120a() {
11720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11721         remote_mds_nodsh && skip "remote MDS with nodsh"
11722         test_mkdir -i0 -c1 $DIR/$tdir
11723         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11724                 skip_env "no early lock cancel on server"
11725
11726         lru_resize_disable mdc
11727         lru_resize_disable osc
11728         cancel_lru_locks mdc
11729         # asynchronous object destroy at MDT could cause bl ast to client
11730         cancel_lru_locks osc
11731
11732         stat $DIR/$tdir > /dev/null
11733         can1=$(do_facet mds1 \
11734                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11735                awk '/ldlm_cancel/ {print $2}')
11736         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11737                awk '/ldlm_bl_callback/ {print $2}')
11738         test_mkdir -i0 -c1 $DIR/$tdir/d1
11739         can2=$(do_facet mds1 \
11740                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11741                awk '/ldlm_cancel/ {print $2}')
11742         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11743                awk '/ldlm_bl_callback/ {print $2}')
11744         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11745         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11746         lru_resize_enable mdc
11747         lru_resize_enable osc
11748 }
11749 run_test 120a "Early Lock Cancel: mkdir test"
11750
11751 test_120b() {
11752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11753         remote_mds_nodsh && skip "remote MDS with nodsh"
11754         test_mkdir $DIR/$tdir
11755         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11756                 skip_env "no early lock cancel on server"
11757
11758         lru_resize_disable mdc
11759         lru_resize_disable osc
11760         cancel_lru_locks mdc
11761         stat $DIR/$tdir > /dev/null
11762         can1=$(do_facet $SINGLEMDS \
11763                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11764                awk '/ldlm_cancel/ {print $2}')
11765         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11766                awk '/ldlm_bl_callback/ {print $2}')
11767         touch $DIR/$tdir/f1
11768         can2=$(do_facet $SINGLEMDS \
11769                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11770                awk '/ldlm_cancel/ {print $2}')
11771         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11772                awk '/ldlm_bl_callback/ {print $2}')
11773         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11774         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11775         lru_resize_enable mdc
11776         lru_resize_enable osc
11777 }
11778 run_test 120b "Early Lock Cancel: create test"
11779
11780 test_120c() {
11781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11782         remote_mds_nodsh && skip "remote MDS with nodsh"
11783         test_mkdir -i0 -c1 $DIR/$tdir
11784         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11785                 skip "no early lock cancel on server"
11786
11787         lru_resize_disable mdc
11788         lru_resize_disable osc
11789         test_mkdir -i0 -c1 $DIR/$tdir/d1
11790         test_mkdir -i0 -c1 $DIR/$tdir/d2
11791         touch $DIR/$tdir/d1/f1
11792         cancel_lru_locks mdc
11793         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11794         can1=$(do_facet mds1 \
11795                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11796                awk '/ldlm_cancel/ {print $2}')
11797         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11798                awk '/ldlm_bl_callback/ {print $2}')
11799         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11800         can2=$(do_facet mds1 \
11801                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11802                awk '/ldlm_cancel/ {print $2}')
11803         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11804                awk '/ldlm_bl_callback/ {print $2}')
11805         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11806         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11807         lru_resize_enable mdc
11808         lru_resize_enable osc
11809 }
11810 run_test 120c "Early Lock Cancel: link test"
11811
11812 test_120d() {
11813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11814         remote_mds_nodsh && skip "remote MDS with nodsh"
11815         test_mkdir -i0 -c1 $DIR/$tdir
11816         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11817                 skip_env "no early lock cancel on server"
11818
11819         lru_resize_disable mdc
11820         lru_resize_disable osc
11821         touch $DIR/$tdir
11822         cancel_lru_locks mdc
11823         stat $DIR/$tdir > /dev/null
11824         can1=$(do_facet mds1 \
11825                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11826                awk '/ldlm_cancel/ {print $2}')
11827         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11828                awk '/ldlm_bl_callback/ {print $2}')
11829         chmod a+x $DIR/$tdir
11830         can2=$(do_facet mds1 \
11831                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11832                awk '/ldlm_cancel/ {print $2}')
11833         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11834                awk '/ldlm_bl_callback/ {print $2}')
11835         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11836         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11837         lru_resize_enable mdc
11838         lru_resize_enable osc
11839 }
11840 run_test 120d "Early Lock Cancel: setattr test"
11841
11842 test_120e() {
11843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11844         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11845                 skip_env "no early lock cancel on server"
11846         remote_mds_nodsh && skip "remote MDS with nodsh"
11847
11848         local dlmtrace_set=false
11849
11850         test_mkdir -i0 -c1 $DIR/$tdir
11851         lru_resize_disable mdc
11852         lru_resize_disable osc
11853         ! $LCTL get_param debug | grep -q dlmtrace &&
11854                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11855         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11856         cancel_lru_locks mdc
11857         cancel_lru_locks osc
11858         dd if=$DIR/$tdir/f1 of=/dev/null
11859         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11860         # XXX client can not do early lock cancel of OST lock
11861         # during unlink (LU-4206), so cancel osc lock now.
11862         sleep 2
11863         cancel_lru_locks osc
11864         can1=$(do_facet mds1 \
11865                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11866                awk '/ldlm_cancel/ {print $2}')
11867         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11868                awk '/ldlm_bl_callback/ {print $2}')
11869         unlink $DIR/$tdir/f1
11870         sleep 5
11871         can2=$(do_facet mds1 \
11872                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11873                awk '/ldlm_cancel/ {print $2}')
11874         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11875                awk '/ldlm_bl_callback/ {print $2}')
11876         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11877                 $LCTL dk $TMP/cancel.debug.txt
11878         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11879                 $LCTL dk $TMP/blocking.debug.txt
11880         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11881         lru_resize_enable mdc
11882         lru_resize_enable osc
11883 }
11884 run_test 120e "Early Lock Cancel: unlink test"
11885
11886 test_120f() {
11887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11888         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11889                 skip_env "no early lock cancel on server"
11890         remote_mds_nodsh && skip "remote MDS with nodsh"
11891
11892         test_mkdir -i0 -c1 $DIR/$tdir
11893         lru_resize_disable mdc
11894         lru_resize_disable osc
11895         test_mkdir -i0 -c1 $DIR/$tdir/d1
11896         test_mkdir -i0 -c1 $DIR/$tdir/d2
11897         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11898         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11899         cancel_lru_locks mdc
11900         cancel_lru_locks osc
11901         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11902         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11903         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11904         # XXX client can not do early lock cancel of OST lock
11905         # during rename (LU-4206), so cancel osc lock now.
11906         sleep 2
11907         cancel_lru_locks osc
11908         can1=$(do_facet mds1 \
11909                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11910                awk '/ldlm_cancel/ {print $2}')
11911         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11912                awk '/ldlm_bl_callback/ {print $2}')
11913         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11914         sleep 5
11915         can2=$(do_facet mds1 \
11916                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11917                awk '/ldlm_cancel/ {print $2}')
11918         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11919                awk '/ldlm_bl_callback/ {print $2}')
11920         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11921         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11922         lru_resize_enable mdc
11923         lru_resize_enable osc
11924 }
11925 run_test 120f "Early Lock Cancel: rename test"
11926
11927 test_120g() {
11928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11929         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11930                 skip_env "no early lock cancel on server"
11931         remote_mds_nodsh && skip "remote MDS with nodsh"
11932
11933         lru_resize_disable mdc
11934         lru_resize_disable osc
11935         count=10000
11936         echo create $count files
11937         test_mkdir $DIR/$tdir
11938         cancel_lru_locks mdc
11939         cancel_lru_locks osc
11940         t0=$(date +%s)
11941
11942         can0=$(do_facet $SINGLEMDS \
11943                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11944                awk '/ldlm_cancel/ {print $2}')
11945         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11946                awk '/ldlm_bl_callback/ {print $2}')
11947         createmany -o $DIR/$tdir/f $count
11948         sync
11949         can1=$(do_facet $SINGLEMDS \
11950                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11951                awk '/ldlm_cancel/ {print $2}')
11952         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11953                awk '/ldlm_bl_callback/ {print $2}')
11954         t1=$(date +%s)
11955         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11956         echo rm $count files
11957         rm -r $DIR/$tdir
11958         sync
11959         can2=$(do_facet $SINGLEMDS \
11960                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11961                awk '/ldlm_cancel/ {print $2}')
11962         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11963                awk '/ldlm_bl_callback/ {print $2}')
11964         t2=$(date +%s)
11965         echo total: $count removes in $((t2-t1))
11966         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11967         sleep 2
11968         # wait for commitment of removal
11969         lru_resize_enable mdc
11970         lru_resize_enable osc
11971 }
11972 run_test 120g "Early Lock Cancel: performance test"
11973
11974 test_121() { #bug #10589
11975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11976
11977         rm -rf $DIR/$tfile
11978         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11979 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11980         lctl set_param fail_loc=0x310
11981         cancel_lru_locks osc > /dev/null
11982         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11983         lctl set_param fail_loc=0
11984         [[ $reads -eq $writes ]] ||
11985                 error "read $reads blocks, must be $writes blocks"
11986 }
11987 run_test 121 "read cancel race ========="
11988
11989 test_123a_base() { # was test 123, statahead(bug 11401)
11990         local lsx="$1"
11991
11992         SLOWOK=0
11993         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11994                 log "testing UP system. Performance may be lower than expected."
11995                 SLOWOK=1
11996         fi
11997
11998         rm -rf $DIR/$tdir
11999         test_mkdir $DIR/$tdir
12000         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12001         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12002         MULT=10
12003         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12004                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12005
12006                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12007                 lctl set_param -n llite.*.statahead_max 0
12008                 lctl get_param llite.*.statahead_max
12009                 cancel_lru_locks mdc
12010                 cancel_lru_locks osc
12011                 stime=$(date +%s)
12012                 time $lsx $DIR/$tdir | wc -l
12013                 etime=$(date +%s)
12014                 delta=$((etime - stime))
12015                 log "$lsx $i files without statahead: $delta sec"
12016                 lctl set_param llite.*.statahead_max=$max
12017
12018                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12019                         grep "statahead wrong:" | awk '{print $3}')
12020                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12021                 cancel_lru_locks mdc
12022                 cancel_lru_locks osc
12023                 stime=$(date +%s)
12024                 time $lsx $DIR/$tdir | wc -l
12025                 etime=$(date +%s)
12026                 delta_sa=$((etime - stime))
12027                 log "$lsx $i files with statahead: $delta_sa sec"
12028                 lctl get_param -n llite.*.statahead_stats
12029                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12030                         grep "statahead wrong:" | awk '{print $3}')
12031
12032                 [[ $swrong -lt $ewrong ]] &&
12033                         log "statahead was stopped, maybe too many locks held!"
12034                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12035
12036                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12037                         max=$(lctl get_param -n llite.*.statahead_max |
12038                                 head -n 1)
12039                         lctl set_param -n llite.*.statahead_max 0
12040                         lctl get_param llite.*.statahead_max
12041                         cancel_lru_locks mdc
12042                         cancel_lru_locks osc
12043                         stime=$(date +%s)
12044                         time $lsx $DIR/$tdir | wc -l
12045                         etime=$(date +%s)
12046                         delta=$((etime - stime))
12047                         log "$lsx $i files again without statahead: $delta sec"
12048                         lctl set_param llite.*.statahead_max=$max
12049                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12050                                 if [  $SLOWOK -eq 0 ]; then
12051                                         error "$lsx $i files is slower with statahead!"
12052                                 else
12053                                         log "$lsx $i files is slower with statahead!"
12054                                 fi
12055                                 break
12056                         fi
12057                 fi
12058
12059                 [ $delta -gt 20 ] && break
12060                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12061                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12062         done
12063         log "$lsx done"
12064
12065         stime=$(date +%s)
12066         rm -r $DIR/$tdir
12067         sync
12068         etime=$(date +%s)
12069         delta=$((etime - stime))
12070         log "rm -r $DIR/$tdir/: $delta seconds"
12071         log "rm done"
12072         lctl get_param -n llite.*.statahead_stats
12073 }
12074
12075 test_123aa() {
12076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12077
12078         test_123a_base "ls -l"
12079 }
12080 run_test 123aa "verify statahead work"
12081
12082 test_123ab() {
12083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12084
12085         statx_supported || skip_env "Test must be statx() syscall supported"
12086
12087         test_123a_base "$STATX -l"
12088 }
12089 run_test 123ab "verify statahead work by using statx"
12090
12091 test_123ac() {
12092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12093
12094         statx_supported || skip_env "Test must be statx() syscall supported"
12095
12096         local rpcs_before
12097         local rpcs_after
12098         local agl_before
12099         local agl_after
12100
12101         cancel_lru_locks $OSC
12102         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12103         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12104                 awk '/agl.total:/ {print $3}')
12105         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12106         test_123a_base "$STATX --cached=always -D"
12107         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12108                 awk '/agl.total:/ {print $3}')
12109         [ $agl_before -eq $agl_after ] ||
12110                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12111         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12112         [ $rpcs_after -eq $rpcs_before ] ||
12113                 error "$STATX should not send glimpse RPCs to $OSC"
12114 }
12115 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12116
12117 test_123b () { # statahead(bug 15027)
12118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12119
12120         test_mkdir $DIR/$tdir
12121         createmany -o $DIR/$tdir/$tfile-%d 1000
12122
12123         cancel_lru_locks mdc
12124         cancel_lru_locks osc
12125
12126 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12127         lctl set_param fail_loc=0x80000803
12128         ls -lR $DIR/$tdir > /dev/null
12129         log "ls done"
12130         lctl set_param fail_loc=0x0
12131         lctl get_param -n llite.*.statahead_stats
12132         rm -r $DIR/$tdir
12133         sync
12134
12135 }
12136 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12137
12138 test_123c() {
12139         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12140
12141         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12142         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12143         touch $DIR/$tdir.1/{1..3}
12144         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12145
12146         remount_client $MOUNT
12147
12148         $MULTIOP $DIR/$tdir.0 Q
12149
12150         # let statahead to complete
12151         ls -l $DIR/$tdir.0 > /dev/null
12152
12153         testid=$(echo $TESTNAME | tr '_' ' ')
12154         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12155                 error "statahead warning" || true
12156 }
12157 run_test 123c "Can not initialize inode warning on DNE statahead"
12158
12159 test_124a() {
12160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12161         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12162                 skip_env "no lru resize on server"
12163
12164         local NR=2000
12165
12166         test_mkdir $DIR/$tdir
12167
12168         log "create $NR files at $DIR/$tdir"
12169         createmany -o $DIR/$tdir/f $NR ||
12170                 error "failed to create $NR files in $DIR/$tdir"
12171
12172         cancel_lru_locks mdc
12173         ls -l $DIR/$tdir > /dev/null
12174
12175         local NSDIR=""
12176         local LRU_SIZE=0
12177         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12178                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12179                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12180                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12181                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12182                         log "NSDIR=$NSDIR"
12183                         log "NS=$(basename $NSDIR)"
12184                         break
12185                 fi
12186         done
12187
12188         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12189                 skip "Not enough cached locks created!"
12190         fi
12191         log "LRU=$LRU_SIZE"
12192
12193         local SLEEP=30
12194
12195         # We know that lru resize allows one client to hold $LIMIT locks
12196         # for 10h. After that locks begin to be killed by client.
12197         local MAX_HRS=10
12198         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12199         log "LIMIT=$LIMIT"
12200         if [ $LIMIT -lt $LRU_SIZE ]; then
12201                 skip "Limit is too small $LIMIT"
12202         fi
12203
12204         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12205         # killing locks. Some time was spent for creating locks. This means
12206         # that up to the moment of sleep finish we must have killed some of
12207         # them (10-100 locks). This depends on how fast ther were created.
12208         # Many of them were touched in almost the same moment and thus will
12209         # be killed in groups.
12210         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12211
12212         # Use $LRU_SIZE_B here to take into account real number of locks
12213         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12214         local LRU_SIZE_B=$LRU_SIZE
12215         log "LVF=$LVF"
12216         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12217         log "OLD_LVF=$OLD_LVF"
12218         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12219
12220         # Let's make sure that we really have some margin. Client checks
12221         # cached locks every 10 sec.
12222         SLEEP=$((SLEEP+20))
12223         log "Sleep ${SLEEP} sec"
12224         local SEC=0
12225         while ((SEC<$SLEEP)); do
12226                 echo -n "..."
12227                 sleep 5
12228                 SEC=$((SEC+5))
12229                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12230                 echo -n "$LRU_SIZE"
12231         done
12232         echo ""
12233         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12234         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12235
12236         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12237                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12238                 unlinkmany $DIR/$tdir/f $NR
12239                 return
12240         }
12241
12242         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12243         log "unlink $NR files at $DIR/$tdir"
12244         unlinkmany $DIR/$tdir/f $NR
12245 }
12246 run_test 124a "lru resize ======================================="
12247
12248 get_max_pool_limit()
12249 {
12250         local limit=$($LCTL get_param \
12251                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12252         local max=0
12253         for l in $limit; do
12254                 if [[ $l -gt $max ]]; then
12255                         max=$l
12256                 fi
12257         done
12258         echo $max
12259 }
12260
12261 test_124b() {
12262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12263         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12264                 skip_env "no lru resize on server"
12265
12266         LIMIT=$(get_max_pool_limit)
12267
12268         NR=$(($(default_lru_size)*20))
12269         if [[ $NR -gt $LIMIT ]]; then
12270                 log "Limit lock number by $LIMIT locks"
12271                 NR=$LIMIT
12272         fi
12273
12274         IFree=$(mdsrate_inodes_available)
12275         if [ $IFree -lt $NR ]; then
12276                 log "Limit lock number by $IFree inodes"
12277                 NR=$IFree
12278         fi
12279
12280         lru_resize_disable mdc
12281         test_mkdir -p $DIR/$tdir/disable_lru_resize
12282
12283         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12284         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12285         cancel_lru_locks mdc
12286         stime=`date +%s`
12287         PID=""
12288         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12289         PID="$PID $!"
12290         sleep 2
12291         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12292         PID="$PID $!"
12293         sleep 2
12294         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12295         PID="$PID $!"
12296         wait $PID
12297         etime=`date +%s`
12298         nolruresize_delta=$((etime-stime))
12299         log "ls -la time: $nolruresize_delta seconds"
12300         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12301         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12302
12303         lru_resize_enable mdc
12304         test_mkdir -p $DIR/$tdir/enable_lru_resize
12305
12306         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12307         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12308         cancel_lru_locks mdc
12309         stime=`date +%s`
12310         PID=""
12311         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12312         PID="$PID $!"
12313         sleep 2
12314         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12315         PID="$PID $!"
12316         sleep 2
12317         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12318         PID="$PID $!"
12319         wait $PID
12320         etime=`date +%s`
12321         lruresize_delta=$((etime-stime))
12322         log "ls -la time: $lruresize_delta seconds"
12323         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12324
12325         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12326                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12327         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12328                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12329         else
12330                 log "lru resize performs the same with no lru resize"
12331         fi
12332         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12333 }
12334 run_test 124b "lru resize (performance test) ======================="
12335
12336 test_124c() {
12337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12338         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12339                 skip_env "no lru resize on server"
12340
12341         # cache ununsed locks on client
12342         local nr=100
12343         cancel_lru_locks mdc
12344         test_mkdir $DIR/$tdir
12345         createmany -o $DIR/$tdir/f $nr ||
12346                 error "failed to create $nr files in $DIR/$tdir"
12347         ls -l $DIR/$tdir > /dev/null
12348
12349         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12350         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12351         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12352         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12353         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12354
12355         # set lru_max_age to 1 sec
12356         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12357         echo "sleep $((recalc_p * 2)) seconds..."
12358         sleep $((recalc_p * 2))
12359
12360         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12361         # restore lru_max_age
12362         $LCTL set_param -n $nsdir.lru_max_age $max_age
12363         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12364         unlinkmany $DIR/$tdir/f $nr
12365 }
12366 run_test 124c "LRUR cancel very aged locks"
12367
12368 test_124d() {
12369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12370         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12371                 skip_env "no lru resize on server"
12372
12373         # cache ununsed locks on client
12374         local nr=100
12375
12376         lru_resize_disable mdc
12377         stack_trap "lru_resize_enable mdc" EXIT
12378
12379         cancel_lru_locks mdc
12380
12381         # asynchronous object destroy at MDT could cause bl ast to client
12382         test_mkdir $DIR/$tdir
12383         createmany -o $DIR/$tdir/f $nr ||
12384                 error "failed to create $nr files in $DIR/$tdir"
12385         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12386
12387         ls -l $DIR/$tdir > /dev/null
12388
12389         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12390         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12391         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12392         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12393
12394         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12395
12396         # set lru_max_age to 1 sec
12397         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12398         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12399
12400         echo "sleep $((recalc_p * 2)) seconds..."
12401         sleep $((recalc_p * 2))
12402
12403         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12404
12405         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12406 }
12407 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12408
12409 test_125() { # 13358
12410         $LCTL get_param -n llite.*.client_type | grep -q local ||
12411                 skip "must run as local client"
12412         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12413                 skip_env "must have acl enabled"
12414         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12415
12416         test_mkdir $DIR/$tdir
12417         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12418         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12419         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12420 }
12421 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12422
12423 test_126() { # bug 12829/13455
12424         $GSS && skip_env "must run as gss disabled"
12425         $LCTL get_param -n llite.*.client_type | grep -q local ||
12426                 skip "must run as local client"
12427         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12428
12429         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12430         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12431         rm -f $DIR/$tfile
12432         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12433 }
12434 run_test 126 "check that the fsgid provided by the client is taken into account"
12435
12436 test_127a() { # bug 15521
12437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12438         local name count samp unit min max sum sumsq
12439
12440         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12441         echo "stats before reset"
12442         $LCTL get_param osc.*.stats
12443         $LCTL set_param osc.*.stats=0
12444         local fsize=$((2048 * 1024))
12445
12446         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12447         cancel_lru_locks osc
12448         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12449
12450         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12451         stack_trap "rm -f $TMP/$tfile.tmp"
12452         while read name count samp unit min max sum sumsq; do
12453                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12454                 [ ! $min ] && error "Missing min value for $name proc entry"
12455                 eval $name=$count || error "Wrong proc format"
12456
12457                 case $name in
12458                 read_bytes|write_bytes)
12459                         [[ "$unit" =~ "bytes" ]] ||
12460                                 error "unit is not 'bytes': $unit"
12461                         (( $min >= 4096 )) || error "min is too small: $min"
12462                         (( $min <= $fsize )) || error "min is too big: $min"
12463                         (( $max >= 4096 )) || error "max is too small: $max"
12464                         (( $max <= $fsize )) || error "max is too big: $max"
12465                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12466                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12467                                 error "sumsquare is too small: $sumsq"
12468                         (( $sumsq <= $fsize * $fsize )) ||
12469                                 error "sumsquare is too big: $sumsq"
12470                         ;;
12471                 ost_read|ost_write)
12472                         [[ "$unit" =~ "usec" ]] ||
12473                                 error "unit is not 'usec': $unit"
12474                         ;;
12475                 *)      ;;
12476                 esac
12477         done < $DIR/$tfile.tmp
12478
12479         #check that we actually got some stats
12480         [ "$read_bytes" ] || error "Missing read_bytes stats"
12481         [ "$write_bytes" ] || error "Missing write_bytes stats"
12482         [ "$read_bytes" != 0 ] || error "no read done"
12483         [ "$write_bytes" != 0 ] || error "no write done"
12484 }
12485 run_test 127a "verify the client stats are sane"
12486
12487 test_127b() { # bug LU-333
12488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12489         local name count samp unit min max sum sumsq
12490
12491         echo "stats before reset"
12492         $LCTL get_param llite.*.stats
12493         $LCTL set_param llite.*.stats=0
12494
12495         # perform 2 reads and writes so MAX is different from SUM.
12496         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12497         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12498         cancel_lru_locks osc
12499         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12500         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12501
12502         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12503         stack_trap "rm -f $TMP/$tfile.tmp"
12504         while read name count samp unit min max sum sumsq; do
12505                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12506                 eval $name=$count || error "Wrong proc format"
12507
12508                 case $name in
12509                 read_bytes|write_bytes)
12510                         [[ "$unit" =~ "bytes" ]] ||
12511                                 error "unit is not 'bytes': $unit"
12512                         (( $count == 2 )) || error "count is not 2: $count"
12513                         (( $min == $PAGE_SIZE )) ||
12514                                 error "min is not $PAGE_SIZE: $min"
12515                         (( $max == $PAGE_SIZE )) ||
12516                                 error "max is not $PAGE_SIZE: $max"
12517                         (( $sum == $PAGE_SIZE * 2 )) ||
12518                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12519                         ;;
12520                 read|write)
12521                         [[ "$unit" =~ "usec" ]] ||
12522                                 error "unit is not 'usec': $unit"
12523                         ;;
12524                 *)      ;;
12525                 esac
12526         done < $TMP/$tfile.tmp
12527
12528         #check that we actually got some stats
12529         [ "$read_bytes" ] || error "Missing read_bytes stats"
12530         [ "$write_bytes" ] || error "Missing write_bytes stats"
12531         [ "$read_bytes" != 0 ] || error "no read done"
12532         [ "$write_bytes" != 0 ] || error "no write done"
12533 }
12534 run_test 127b "verify the llite client stats are sane"
12535
12536 test_127c() { # LU-12394
12537         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12538         local size
12539         local bsize
12540         local reads
12541         local writes
12542         local count
12543
12544         $LCTL set_param llite.*.extents_stats=1
12545         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12546
12547         # Use two stripes so there is enough space in default config
12548         $LFS setstripe -c 2 $DIR/$tfile
12549
12550         # Extent stats start at 0-4K and go in power of two buckets
12551         # LL_HIST_START = 12 --> 2^12 = 4K
12552         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12553         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12554         # small configs
12555         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12556                 do
12557                 # Write and read, 2x each, second time at a non-zero offset
12558                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12559                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12560                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12561                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12562                 rm -f $DIR/$tfile
12563         done
12564
12565         $LCTL get_param llite.*.extents_stats
12566
12567         count=2
12568         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12569                 do
12570                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12571                                 grep -m 1 $bsize)
12572                 reads=$(echo $bucket | awk '{print $5}')
12573                 writes=$(echo $bucket | awk '{print $9}')
12574                 [ "$reads" -eq $count ] ||
12575                         error "$reads reads in < $bsize bucket, expect $count"
12576                 [ "$writes" -eq $count ] ||
12577                         error "$writes writes in < $bsize bucket, expect $count"
12578         done
12579
12580         # Test mmap write and read
12581         $LCTL set_param llite.*.extents_stats=c
12582         size=512
12583         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12584         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12585         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12586
12587         $LCTL get_param llite.*.extents_stats
12588
12589         count=$(((size*1024) / PAGE_SIZE))
12590
12591         bsize=$((2 * PAGE_SIZE / 1024))K
12592
12593         bucket=$($LCTL get_param -n llite.*.extents_stats |
12594                         grep -m 1 $bsize)
12595         reads=$(echo $bucket | awk '{print $5}')
12596         writes=$(echo $bucket | awk '{print $9}')
12597         # mmap writes fault in the page first, creating an additonal read
12598         [ "$reads" -eq $((2 * count)) ] ||
12599                 error "$reads reads in < $bsize bucket, expect $count"
12600         [ "$writes" -eq $count ] ||
12601                 error "$writes writes in < $bsize bucket, expect $count"
12602 }
12603 run_test 127c "test llite extent stats with regular & mmap i/o"
12604
12605 test_128() { # bug 15212
12606         touch $DIR/$tfile
12607         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12608                 find $DIR/$tfile
12609                 find $DIR/$tfile
12610         EOF
12611
12612         result=$(grep error $TMP/$tfile.log)
12613         rm -f $DIR/$tfile $TMP/$tfile.log
12614         [ -z "$result" ] ||
12615                 error "consecutive find's under interactive lfs failed"
12616 }
12617 run_test 128 "interactive lfs for 2 consecutive find's"
12618
12619 set_dir_limits () {
12620         local mntdev
12621         local canondev
12622         local node
12623
12624         local ldproc=/proc/fs/ldiskfs
12625         local facets=$(get_facets MDS)
12626
12627         for facet in ${facets//,/ }; do
12628                 canondev=$(ldiskfs_canon \
12629                            *.$(convert_facet2label $facet).mntdev $facet)
12630                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12631                         ldproc=/sys/fs/ldiskfs
12632                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12633                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12634         done
12635 }
12636
12637 check_mds_dmesg() {
12638         local facets=$(get_facets MDS)
12639         for facet in ${facets//,/ }; do
12640                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12641         done
12642         return 1
12643 }
12644
12645 test_129() {
12646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12647         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12648                 skip "Need MDS version with at least 2.5.56"
12649         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12650                 skip_env "ldiskfs only test"
12651         fi
12652         remote_mds_nodsh && skip "remote MDS with nodsh"
12653
12654         local ENOSPC=28
12655         local has_warning=false
12656
12657         rm -rf $DIR/$tdir
12658         mkdir -p $DIR/$tdir
12659
12660         # block size of mds1
12661         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12662         set_dir_limits $maxsize $((maxsize * 6 / 8))
12663         stack_trap "set_dir_limits 0 0"
12664         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12665         local dirsize=$(stat -c%s "$DIR/$tdir")
12666         local nfiles=0
12667         while (( $dirsize <= $maxsize )); do
12668                 $MCREATE $DIR/$tdir/file_base_$nfiles
12669                 rc=$?
12670                 # check two errors:
12671                 # ENOSPC for ext4 max_dir_size, which has been used since
12672                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12673                 if (( rc == ENOSPC )); then
12674                         set_dir_limits 0 0
12675                         echo "rc=$rc returned as expected after $nfiles files"
12676
12677                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12678                                 error "create failed w/o dir size limit"
12679
12680                         # messages may be rate limited if test is run repeatedly
12681                         check_mds_dmesg '"is approaching max"' ||
12682                                 echo "warning message should be output"
12683                         check_mds_dmesg '"has reached max"' ||
12684                                 echo "reached message should be output"
12685
12686                         dirsize=$(stat -c%s "$DIR/$tdir")
12687
12688                         [[ $dirsize -ge $maxsize ]] && return 0
12689                         error "dirsize $dirsize < $maxsize after $nfiles files"
12690                 elif (( rc != 0 )); then
12691                         break
12692                 fi
12693                 nfiles=$((nfiles + 1))
12694                 dirsize=$(stat -c%s "$DIR/$tdir")
12695         done
12696
12697         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12698 }
12699 run_test 129 "test directory size limit ========================"
12700
12701 OLDIFS="$IFS"
12702 cleanup_130() {
12703         trap 0
12704         IFS="$OLDIFS"
12705 }
12706
12707 test_130a() {
12708         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12709         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12710
12711         trap cleanup_130 EXIT RETURN
12712
12713         local fm_file=$DIR/$tfile
12714         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12715         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12716                 error "dd failed for $fm_file"
12717
12718         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12719         filefrag -ves $fm_file
12720         RC=$?
12721         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12722                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12723         [ $RC != 0 ] && error "filefrag $fm_file failed"
12724
12725         filefrag_op=$(filefrag -ve -k $fm_file |
12726                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12727         lun=$($LFS getstripe -i $fm_file)
12728
12729         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12730         IFS=$'\n'
12731         tot_len=0
12732         for line in $filefrag_op
12733         do
12734                 frag_lun=`echo $line | cut -d: -f5`
12735                 ext_len=`echo $line | cut -d: -f4`
12736                 if (( $frag_lun != $lun )); then
12737                         cleanup_130
12738                         error "FIEMAP on 1-stripe file($fm_file) failed"
12739                         return
12740                 fi
12741                 (( tot_len += ext_len ))
12742         done
12743
12744         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12745                 cleanup_130
12746                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12747                 return
12748         fi
12749
12750         cleanup_130
12751
12752         echo "FIEMAP on single striped file succeeded"
12753 }
12754 run_test 130a "FIEMAP (1-stripe file)"
12755
12756 test_130b() {
12757         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12758
12759         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12760         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12761
12762         trap cleanup_130 EXIT RETURN
12763
12764         local fm_file=$DIR/$tfile
12765         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12766                         error "setstripe on $fm_file"
12767         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12768                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12769
12770         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12771                 error "dd failed on $fm_file"
12772
12773         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12774         filefrag_op=$(filefrag -ve -k $fm_file |
12775                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12776
12777         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12778                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12779
12780         IFS=$'\n'
12781         tot_len=0
12782         num_luns=1
12783         for line in $filefrag_op
12784         do
12785                 frag_lun=$(echo $line | cut -d: -f5 |
12786                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12787                 ext_len=$(echo $line | cut -d: -f4)
12788                 if (( $frag_lun != $last_lun )); then
12789                         if (( tot_len != 1024 )); then
12790                                 cleanup_130
12791                                 error "FIEMAP on $fm_file failed; returned " \
12792                                 "len $tot_len for OST $last_lun instead of 1024"
12793                                 return
12794                         else
12795                                 (( num_luns += 1 ))
12796                                 tot_len=0
12797                         fi
12798                 fi
12799                 (( tot_len += ext_len ))
12800                 last_lun=$frag_lun
12801         done
12802         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12803                 cleanup_130
12804                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12805                         "luns or wrong len for OST $last_lun"
12806                 return
12807         fi
12808
12809         cleanup_130
12810
12811         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12812 }
12813 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12814
12815 test_130c() {
12816         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12817
12818         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12819         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12820
12821         trap cleanup_130 EXIT RETURN
12822
12823         local fm_file=$DIR/$tfile
12824         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12825         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12826                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12827
12828         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12829                         error "dd failed on $fm_file"
12830
12831         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12832         filefrag_op=$(filefrag -ve -k $fm_file |
12833                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12834
12835         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12836                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12837
12838         IFS=$'\n'
12839         tot_len=0
12840         num_luns=1
12841         for line in $filefrag_op
12842         do
12843                 frag_lun=$(echo $line | cut -d: -f5 |
12844                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12845                 ext_len=$(echo $line | cut -d: -f4)
12846                 if (( $frag_lun != $last_lun )); then
12847                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12848                         if (( logical != 512 )); then
12849                                 cleanup_130
12850                                 error "FIEMAP on $fm_file failed; returned " \
12851                                 "logical start for lun $logical instead of 512"
12852                                 return
12853                         fi
12854                         if (( tot_len != 512 )); then
12855                                 cleanup_130
12856                                 error "FIEMAP on $fm_file failed; returned " \
12857                                 "len $tot_len for OST $last_lun instead of 1024"
12858                                 return
12859                         else
12860                                 (( num_luns += 1 ))
12861                                 tot_len=0
12862                         fi
12863                 fi
12864                 (( tot_len += ext_len ))
12865                 last_lun=$frag_lun
12866         done
12867         if (( num_luns != 2 || tot_len != 512 )); then
12868                 cleanup_130
12869                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12870                         "luns or wrong len for OST $last_lun"
12871                 return
12872         fi
12873
12874         cleanup_130
12875
12876         echo "FIEMAP on 2-stripe file with hole succeeded"
12877 }
12878 run_test 130c "FIEMAP (2-stripe file with hole)"
12879
12880 test_130d() {
12881         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12882
12883         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12884         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12885
12886         trap cleanup_130 EXIT RETURN
12887
12888         local fm_file=$DIR/$tfile
12889         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12890                         error "setstripe on $fm_file"
12891         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12892                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12893
12894         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12895         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12896                 error "dd failed on $fm_file"
12897
12898         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12899         filefrag_op=$(filefrag -ve -k $fm_file |
12900                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12901
12902         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12903                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12904
12905         IFS=$'\n'
12906         tot_len=0
12907         num_luns=1
12908         for line in $filefrag_op
12909         do
12910                 frag_lun=$(echo $line | cut -d: -f5 |
12911                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12912                 ext_len=$(echo $line | cut -d: -f4)
12913                 if (( $frag_lun != $last_lun )); then
12914                         if (( tot_len != 1024 )); then
12915                                 cleanup_130
12916                                 error "FIEMAP on $fm_file failed; returned " \
12917                                 "len $tot_len for OST $last_lun instead of 1024"
12918                                 return
12919                         else
12920                                 (( num_luns += 1 ))
12921                                 tot_len=0
12922                         fi
12923                 fi
12924                 (( tot_len += ext_len ))
12925                 last_lun=$frag_lun
12926         done
12927         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12928                 cleanup_130
12929                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12930                         "luns or wrong len for OST $last_lun"
12931                 return
12932         fi
12933
12934         cleanup_130
12935
12936         echo "FIEMAP on N-stripe file succeeded"
12937 }
12938 run_test 130d "FIEMAP (N-stripe file)"
12939
12940 test_130e() {
12941         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12942
12943         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12944         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12945
12946         trap cleanup_130 EXIT RETURN
12947
12948         local fm_file=$DIR/$tfile
12949         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12950
12951         NUM_BLKS=512
12952         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12953         for ((i = 0; i < $NUM_BLKS; i++)); do
12954                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
12955                         conv=notrunc > /dev/null 2>&1
12956         done
12957
12958         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12959         filefrag_op=$(filefrag -ve -k $fm_file |
12960                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12961
12962         last_lun=$(echo $filefrag_op | cut -d: -f5)
12963
12964         IFS=$'\n'
12965         tot_len=0
12966         num_luns=1
12967         for line in $filefrag_op; do
12968                 frag_lun=$(echo $line | cut -d: -f5)
12969                 ext_len=$(echo $line | cut -d: -f4)
12970                 if [[ "$frag_lun" != "$last_lun" ]]; then
12971                         if (( tot_len != $EXPECTED_LEN )); then
12972                                 cleanup_130
12973                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
12974                         else
12975                                 (( num_luns += 1 ))
12976                                 tot_len=0
12977                         fi
12978                 fi
12979                 (( tot_len += ext_len ))
12980                 last_lun=$frag_lun
12981         done
12982         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12983                 cleanup_130
12984                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
12985         fi
12986
12987         echo "FIEMAP with continuation calls succeeded"
12988 }
12989 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12990
12991 test_130f() {
12992         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12993         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12994
12995         local fm_file=$DIR/$tfile
12996         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12997                 error "multiop create with lov_delay_create on $fm_file"
12998
12999         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13000         filefrag_extents=$(filefrag -vek $fm_file |
13001                            awk '/extents? found/ { print $2 }')
13002         if [[ "$filefrag_extents" != "0" ]]; then
13003                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13004         fi
13005
13006         rm -f $fm_file
13007 }
13008 run_test 130f "FIEMAP (unstriped file)"
13009
13010 test_130g() {
13011         local file=$DIR/$tfile
13012         local nr=$((OSTCOUNT * 100))
13013
13014         $LFS setstripe -C $nr $file ||
13015                 error "failed to setstripe -C $nr $file"
13016
13017         dd if=/dev/zero of=$file count=$nr bs=1M
13018         sync
13019         nr=$($LFS getstripe -c $file)
13020
13021         local extents=$(filefrag -v $file |
13022                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13023
13024         echo "filefrag list $extents extents in file with stripecount $nr"
13025         if (( extents < nr )); then
13026                 $LFS getstripe $file
13027                 filefrag -v $file
13028                 error "filefrag printed $extents < $nr extents"
13029         fi
13030
13031         rm -f $file
13032 }
13033 run_test 130g "FIEMAP (overstripe file)"
13034
13035 # Test for writev/readv
13036 test_131a() {
13037         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13038                 error "writev test failed"
13039         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13040                 error "readv failed"
13041         rm -f $DIR/$tfile
13042 }
13043 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13044
13045 test_131b() {
13046         local fsize=$((524288 + 1048576 + 1572864))
13047         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13048                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13049                         error "append writev test failed"
13050
13051         ((fsize += 1572864 + 1048576))
13052         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13053                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13054                         error "append writev test failed"
13055         rm -f $DIR/$tfile
13056 }
13057 run_test 131b "test append writev"
13058
13059 test_131c() {
13060         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13061         error "NOT PASS"
13062 }
13063 run_test 131c "test read/write on file w/o objects"
13064
13065 test_131d() {
13066         rwv -f $DIR/$tfile -w -n 1 1572864
13067         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13068         if [ "$NOB" != 1572864 ]; then
13069                 error "Short read filed: read $NOB bytes instead of 1572864"
13070         fi
13071         rm -f $DIR/$tfile
13072 }
13073 run_test 131d "test short read"
13074
13075 test_131e() {
13076         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13077         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13078         error "read hitting hole failed"
13079         rm -f $DIR/$tfile
13080 }
13081 run_test 131e "test read hitting hole"
13082
13083 check_stats() {
13084         local facet=$1
13085         local op=$2
13086         local want=${3:-0}
13087         local res
13088
13089         case $facet in
13090         mds*) res=$(do_facet $facet \
13091                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13092                  ;;
13093         ost*) res=$(do_facet $facet \
13094                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13095                  ;;
13096         *) error "Wrong facet '$facet'" ;;
13097         esac
13098         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13099         # if the argument $3 is zero, it means any stat increment is ok.
13100         if [[ $want -gt 0 ]]; then
13101                 local count=$(echo $res | awk '{ print $2 }')
13102                 [[ $count -ne $want ]] &&
13103                         error "The $op counter on $facet is $count, not $want"
13104         fi
13105 }
13106
13107 test_133a() {
13108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13109         remote_ost_nodsh && skip "remote OST with nodsh"
13110         remote_mds_nodsh && skip "remote MDS with nodsh"
13111         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13112                 skip_env "MDS doesn't support rename stats"
13113
13114         local testdir=$DIR/${tdir}/stats_testdir
13115
13116         mkdir -p $DIR/${tdir}
13117
13118         # clear stats.
13119         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13120         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13121
13122         # verify mdt stats first.
13123         mkdir ${testdir} || error "mkdir failed"
13124         check_stats $SINGLEMDS "mkdir" 1
13125         touch ${testdir}/${tfile} || error "touch failed"
13126         check_stats $SINGLEMDS "open" 1
13127         check_stats $SINGLEMDS "close" 1
13128         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13129                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13130                 check_stats $SINGLEMDS "mknod" 2
13131         }
13132         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13133         check_stats $SINGLEMDS "unlink" 1
13134         rm -f ${testdir}/${tfile} || error "file remove failed"
13135         check_stats $SINGLEMDS "unlink" 2
13136
13137         # remove working dir and check mdt stats again.
13138         rmdir ${testdir} || error "rmdir failed"
13139         check_stats $SINGLEMDS "rmdir" 1
13140
13141         local testdir1=$DIR/${tdir}/stats_testdir1
13142         mkdir -p ${testdir}
13143         mkdir -p ${testdir1}
13144         touch ${testdir1}/test1
13145         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13146         check_stats $SINGLEMDS "crossdir_rename" 1
13147
13148         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13149         check_stats $SINGLEMDS "samedir_rename" 1
13150
13151         rm -rf $DIR/${tdir}
13152 }
13153 run_test 133a "Verifying MDT stats ========================================"
13154
13155 test_133b() {
13156         local res
13157
13158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13159         remote_ost_nodsh && skip "remote OST with nodsh"
13160         remote_mds_nodsh && skip "remote MDS with nodsh"
13161
13162         local testdir=$DIR/${tdir}/stats_testdir
13163
13164         mkdir -p ${testdir} || error "mkdir failed"
13165         touch ${testdir}/${tfile} || error "touch failed"
13166         cancel_lru_locks mdc
13167
13168         # clear stats.
13169         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13170         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13171
13172         # extra mdt stats verification.
13173         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13174         check_stats $SINGLEMDS "setattr" 1
13175         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13176         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13177         then            # LU-1740
13178                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13179                 check_stats $SINGLEMDS "getattr" 1
13180         fi
13181         rm -rf $DIR/${tdir}
13182
13183         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13184         # so the check below is not reliable
13185         [ $MDSCOUNT -eq 1 ] || return 0
13186
13187         # Sleep to avoid a cached response.
13188         #define OBD_STATFS_CACHE_SECONDS 1
13189         sleep 2
13190         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13191         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13192         $LFS df || error "lfs failed"
13193         check_stats $SINGLEMDS "statfs" 1
13194
13195         # check aggregated statfs (LU-10018)
13196         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13197                 return 0
13198         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13199                 return 0
13200         sleep 2
13201         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13202         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13203         df $DIR
13204         check_stats $SINGLEMDS "statfs" 1
13205
13206         # We want to check that the client didn't send OST_STATFS to
13207         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13208         # extra care is needed here.
13209         if remote_mds; then
13210                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13211                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13212
13213                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13214                 [ "$res" ] && error "OST got STATFS"
13215         fi
13216
13217         return 0
13218 }
13219 run_test 133b "Verifying extra MDT stats =================================="
13220
13221 test_133c() {
13222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13223         remote_ost_nodsh && skip "remote OST with nodsh"
13224         remote_mds_nodsh && skip "remote MDS with nodsh"
13225
13226         local testdir=$DIR/$tdir/stats_testdir
13227
13228         test_mkdir -p $testdir
13229
13230         # verify obdfilter stats.
13231         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13232         sync
13233         cancel_lru_locks osc
13234         wait_delete_completed
13235
13236         # clear stats.
13237         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13238         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13239
13240         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13241                 error "dd failed"
13242         sync
13243         cancel_lru_locks osc
13244         check_stats ost1 "write" 1
13245
13246         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13247         check_stats ost1 "read" 1
13248
13249         > $testdir/$tfile || error "truncate failed"
13250         check_stats ost1 "punch" 1
13251
13252         rm -f $testdir/$tfile || error "file remove failed"
13253         wait_delete_completed
13254         check_stats ost1 "destroy" 1
13255
13256         rm -rf $DIR/$tdir
13257 }
13258 run_test 133c "Verifying OST stats ========================================"
13259
13260 order_2() {
13261         local value=$1
13262         local orig=$value
13263         local order=1
13264
13265         while [ $value -ge 2 ]; do
13266                 order=$((order*2))
13267                 value=$((value/2))
13268         done
13269
13270         if [ $orig -gt $order ]; then
13271                 order=$((order*2))
13272         fi
13273         echo $order
13274 }
13275
13276 size_in_KMGT() {
13277     local value=$1
13278     local size=('K' 'M' 'G' 'T');
13279     local i=0
13280     local size_string=$value
13281
13282     while [ $value -ge 1024 ]; do
13283         if [ $i -gt 3 ]; then
13284             #T is the biggest unit we get here, if that is bigger,
13285             #just return XXXT
13286             size_string=${value}T
13287             break
13288         fi
13289         value=$((value >> 10))
13290         if [ $value -lt 1024 ]; then
13291             size_string=${value}${size[$i]}
13292             break
13293         fi
13294         i=$((i + 1))
13295     done
13296
13297     echo $size_string
13298 }
13299
13300 get_rename_size() {
13301         local size=$1
13302         local context=${2:-.}
13303         local sample=$(do_facet $SINGLEMDS $LCTL \
13304                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13305                 grep -A1 $context |
13306                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13307         echo $sample
13308 }
13309
13310 test_133d() {
13311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13312         remote_ost_nodsh && skip "remote OST with nodsh"
13313         remote_mds_nodsh && skip "remote MDS with nodsh"
13314         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13315                 skip_env "MDS doesn't support rename stats"
13316
13317         local testdir1=$DIR/${tdir}/stats_testdir1
13318         local testdir2=$DIR/${tdir}/stats_testdir2
13319         mkdir -p $DIR/${tdir}
13320
13321         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13322
13323         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13324         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13325
13326         createmany -o $testdir1/test 512 || error "createmany failed"
13327
13328         # check samedir rename size
13329         mv ${testdir1}/test0 ${testdir1}/test_0
13330
13331         local testdir1_size=$(ls -l $DIR/${tdir} |
13332                 awk '/stats_testdir1/ {print $5}')
13333         local testdir2_size=$(ls -l $DIR/${tdir} |
13334                 awk '/stats_testdir2/ {print $5}')
13335
13336         testdir1_size=$(order_2 $testdir1_size)
13337         testdir2_size=$(order_2 $testdir2_size)
13338
13339         testdir1_size=$(size_in_KMGT $testdir1_size)
13340         testdir2_size=$(size_in_KMGT $testdir2_size)
13341
13342         echo "source rename dir size: ${testdir1_size}"
13343         echo "target rename dir size: ${testdir2_size}"
13344
13345         local cmd="do_facet $SINGLEMDS $LCTL "
13346         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13347
13348         eval $cmd || error "$cmd failed"
13349         local samedir=$($cmd | grep 'same_dir')
13350         local same_sample=$(get_rename_size $testdir1_size)
13351         [ -z "$samedir" ] && error "samedir_rename_size count error"
13352         [[ $same_sample -eq 1 ]] ||
13353                 error "samedir_rename_size error $same_sample"
13354         echo "Check same dir rename stats success"
13355
13356         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13357
13358         # check crossdir rename size
13359         mv ${testdir1}/test_0 ${testdir2}/test_0
13360
13361         testdir1_size=$(ls -l $DIR/${tdir} |
13362                 awk '/stats_testdir1/ {print $5}')
13363         testdir2_size=$(ls -l $DIR/${tdir} |
13364                 awk '/stats_testdir2/ {print $5}')
13365
13366         testdir1_size=$(order_2 $testdir1_size)
13367         testdir2_size=$(order_2 $testdir2_size)
13368
13369         testdir1_size=$(size_in_KMGT $testdir1_size)
13370         testdir2_size=$(size_in_KMGT $testdir2_size)
13371
13372         echo "source rename dir size: ${testdir1_size}"
13373         echo "target rename dir size: ${testdir2_size}"
13374
13375         eval $cmd || error "$cmd failed"
13376         local crossdir=$($cmd | grep 'crossdir')
13377         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13378         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13379         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13380         [[ $src_sample -eq 1 ]] ||
13381                 error "crossdir_rename_size error $src_sample"
13382         [[ $tgt_sample -eq 1 ]] ||
13383                 error "crossdir_rename_size error $tgt_sample"
13384         echo "Check cross dir rename stats success"
13385         rm -rf $DIR/${tdir}
13386 }
13387 run_test 133d "Verifying rename_stats ========================================"
13388
13389 test_133e() {
13390         remote_mds_nodsh && skip "remote MDS with nodsh"
13391         remote_ost_nodsh && skip "remote OST with nodsh"
13392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13393
13394         local testdir=$DIR/${tdir}/stats_testdir
13395         local ctr f0 f1 bs=32768 count=42 sum
13396
13397         mkdir -p ${testdir} || error "mkdir failed"
13398
13399         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13400
13401         for ctr in {write,read}_bytes; do
13402                 sync
13403                 cancel_lru_locks osc
13404
13405                 do_facet ost1 $LCTL set_param -n \
13406                         "obdfilter.*.exports.clear=clear"
13407
13408                 if [ $ctr = write_bytes ]; then
13409                         f0=/dev/zero
13410                         f1=${testdir}/${tfile}
13411                 else
13412                         f0=${testdir}/${tfile}
13413                         f1=/dev/null
13414                 fi
13415
13416                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13417                         error "dd failed"
13418                 sync
13419                 cancel_lru_locks osc
13420
13421                 sum=$(do_facet ost1 $LCTL get_param \
13422                         "obdfilter.*.exports.*.stats" |
13423                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13424                                 $1 == ctr { sum += $7 }
13425                                 END { printf("%0.0f", sum) }')
13426
13427                 if ((sum != bs * count)); then
13428                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13429                 fi
13430         done
13431
13432         rm -rf $DIR/${tdir}
13433 }
13434 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13435
13436 test_133f() {
13437         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13438                 skip "too old lustre for get_param -R ($facet_ver)"
13439
13440         # verifying readability.
13441         $LCTL get_param -R '*' &> /dev/null
13442
13443         # Verifing writability with badarea_io.
13444         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13445                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13446                 error "client badarea_io failed"
13447
13448         # remount the FS in case writes/reads /proc break the FS
13449         cleanup || error "failed to unmount"
13450         setup || error "failed to setup"
13451 }
13452 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13453
13454 test_133g() {
13455         remote_mds_nodsh && skip "remote MDS with nodsh"
13456         remote_ost_nodsh && skip "remote OST with nodsh"
13457
13458         local facet
13459         for facet in mds1 ost1; do
13460                 local facet_ver=$(lustre_version_code $facet)
13461                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13462                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13463                 else
13464                         log "$facet: too old lustre for get_param -R"
13465                 fi
13466                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13467                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13468                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13469                                 xargs badarea_io" ||
13470                                         error "$facet badarea_io failed"
13471                 else
13472                         skip_noexit "$facet: too old lustre for get_param -R"
13473                 fi
13474         done
13475
13476         # remount the FS in case writes/reads /proc break the FS
13477         cleanup || error "failed to unmount"
13478         setup || error "failed to setup"
13479 }
13480 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13481
13482 test_133h() {
13483         remote_mds_nodsh && skip "remote MDS with nodsh"
13484         remote_ost_nodsh && skip "remote OST with nodsh"
13485         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13486                 skip "Need MDS version at least 2.9.54"
13487
13488         local facet
13489         for facet in client mds1 ost1; do
13490                 # Get the list of files that are missing the terminating newline
13491                 local plist=$(do_facet $facet
13492                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13493                 local ent
13494                 for ent in $plist; do
13495                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13496                                 awk -v FS='\v' -v RS='\v\v' \
13497                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13498                                         print FILENAME}'" 2>/dev/null)
13499                         [ -z $missing ] || {
13500                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13501                                 error "file does not end with newline: $facet-$ent"
13502                         }
13503                 done
13504         done
13505 }
13506 run_test 133h "Proc files should end with newlines"
13507
13508 test_134a() {
13509         remote_mds_nodsh && skip "remote MDS with nodsh"
13510         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13511                 skip "Need MDS version at least 2.7.54"
13512
13513         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13514         cancel_lru_locks mdc
13515
13516         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13517         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13518         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13519
13520         local nr=1000
13521         createmany -o $DIR/$tdir/f $nr ||
13522                 error "failed to create $nr files in $DIR/$tdir"
13523         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13524
13525         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13526         do_facet mds1 $LCTL set_param fail_loc=0x327
13527         do_facet mds1 $LCTL set_param fail_val=500
13528         touch $DIR/$tdir/m
13529
13530         echo "sleep 10 seconds ..."
13531         sleep 10
13532         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13533
13534         do_facet mds1 $LCTL set_param fail_loc=0
13535         do_facet mds1 $LCTL set_param fail_val=0
13536         [ $lck_cnt -lt $unused ] ||
13537                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13538
13539         rm $DIR/$tdir/m
13540         unlinkmany $DIR/$tdir/f $nr
13541 }
13542 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13543
13544 test_134b() {
13545         remote_mds_nodsh && skip "remote MDS with nodsh"
13546         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13547                 skip "Need MDS version at least 2.7.54"
13548
13549         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13550         cancel_lru_locks mdc
13551
13552         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13553                         ldlm.lock_reclaim_threshold_mb)
13554         # disable reclaim temporarily
13555         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13556
13557         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13558         do_facet mds1 $LCTL set_param fail_loc=0x328
13559         do_facet mds1 $LCTL set_param fail_val=500
13560
13561         $LCTL set_param debug=+trace
13562
13563         local nr=600
13564         createmany -o $DIR/$tdir/f $nr &
13565         local create_pid=$!
13566
13567         echo "Sleep $TIMEOUT seconds ..."
13568         sleep $TIMEOUT
13569         if ! ps -p $create_pid  > /dev/null 2>&1; then
13570                 do_facet mds1 $LCTL set_param fail_loc=0
13571                 do_facet mds1 $LCTL set_param fail_val=0
13572                 do_facet mds1 $LCTL set_param \
13573                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13574                 error "createmany finished incorrectly!"
13575         fi
13576         do_facet mds1 $LCTL set_param fail_loc=0
13577         do_facet mds1 $LCTL set_param fail_val=0
13578         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13579         wait $create_pid || return 1
13580
13581         unlinkmany $DIR/$tdir/f $nr
13582 }
13583 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13584
13585 test_135() {
13586         remote_mds_nodsh && skip "remote MDS with nodsh"
13587         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13588                 skip "Need MDS version at least 2.13.50"
13589         local fname
13590
13591         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13592
13593 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13594         #set only one record at plain llog
13595         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13596
13597         #fill already existed plain llog each 64767
13598         #wrapping whole catalog
13599         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13600
13601         createmany -o $DIR/$tdir/$tfile_ 64700
13602         for (( i = 0; i < 64700; i = i + 2 ))
13603         do
13604                 rm $DIR/$tdir/$tfile_$i &
13605                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13606                 local pid=$!
13607                 wait $pid
13608         done
13609
13610         #waiting osp synchronization
13611         wait_delete_completed
13612 }
13613 run_test 135 "Race catalog processing"
13614
13615 test_136() {
13616         remote_mds_nodsh && skip "remote MDS with nodsh"
13617         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13618                 skip "Need MDS version at least 2.13.50"
13619         local fname
13620
13621         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13622         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13623         #set only one record at plain llog
13624 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13625         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13626
13627         #fill already existed 2 plain llogs each 64767
13628         #wrapping whole catalog
13629         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13630         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13631         wait_delete_completed
13632
13633         createmany -o $DIR/$tdir/$tfile_ 10
13634         sleep 25
13635
13636         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13637         for (( i = 0; i < 10; i = i + 3 ))
13638         do
13639                 rm $DIR/$tdir/$tfile_$i &
13640                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13641                 local pid=$!
13642                 wait $pid
13643                 sleep 7
13644                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13645         done
13646
13647         #waiting osp synchronization
13648         wait_delete_completed
13649 }
13650 run_test 136 "Race catalog processing 2"
13651
13652 test_140() { #bug-17379
13653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13654
13655         test_mkdir $DIR/$tdir
13656         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13657         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13658
13659         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13660         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13661         local i=0
13662         while i=$((i + 1)); do
13663                 test_mkdir $i
13664                 cd $i || error "Changing to $i"
13665                 ln -s ../stat stat || error "Creating stat symlink"
13666                 # Read the symlink until ELOOP present,
13667                 # not LBUGing the system is considered success,
13668                 # we didn't overrun the stack.
13669                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13670                 if [ $ret -ne 0 ]; then
13671                         if [ $ret -eq 40 ]; then
13672                                 break  # -ELOOP
13673                         else
13674                                 error "Open stat symlink"
13675                                         return
13676                         fi
13677                 fi
13678         done
13679         i=$((i - 1))
13680         echo "The symlink depth = $i"
13681         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13682                 error "Invalid symlink depth"
13683
13684         # Test recursive symlink
13685         ln -s symlink_self symlink_self
13686         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13687         echo "open symlink_self returns $ret"
13688         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13689 }
13690 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13691
13692 test_150a() {
13693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13694
13695         local TF="$TMP/$tfile"
13696
13697         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13698         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13699         cp $TF $DIR/$tfile
13700         cancel_lru_locks $OSC
13701         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13702         remount_client $MOUNT
13703         df -P $MOUNT
13704         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13705
13706         $TRUNCATE $TF 6000
13707         $TRUNCATE $DIR/$tfile 6000
13708         cancel_lru_locks $OSC
13709         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13710
13711         echo "12345" >>$TF
13712         echo "12345" >>$DIR/$tfile
13713         cancel_lru_locks $OSC
13714         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13715
13716         echo "12345" >>$TF
13717         echo "12345" >>$DIR/$tfile
13718         cancel_lru_locks $OSC
13719         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13720 }
13721 run_test 150a "truncate/append tests"
13722
13723 test_150b() {
13724         check_set_fallocate_or_skip
13725
13726         touch $DIR/$tfile
13727         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13728         check_fallocate $DIR/$tfile || error "fallocate failed"
13729 }
13730 run_test 150b "Verify fallocate (prealloc) functionality"
13731
13732 test_150bb() {
13733         check_set_fallocate_or_skip
13734
13735         touch $DIR/$tfile
13736         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13737         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13738         > $DIR/$tfile
13739         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13740         # precomputed md5sum for 20MB of zeroes
13741         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13742         local sum=($(md5sum $DIR/$tfile))
13743
13744         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13745
13746         check_set_fallocate 1
13747
13748         > $DIR/$tfile
13749         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13750         sum=($(md5sum $DIR/$tfile))
13751
13752         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13753 }
13754 run_test 150bb "Verify fallocate modes both zero space"
13755
13756 test_150c() {
13757         check_set_fallocate_or_skip
13758
13759         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13760         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13761         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13762         sync; sync_all_data
13763         cancel_lru_locks $OSC
13764         sleep 5
13765         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13766         want=$((OSTCOUNT * 1048576))
13767
13768         # Must allocate all requested space, not more than 5% extra
13769         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13770                 error "bytes $bytes is not $want"
13771
13772         rm -f $DIR/$tfile
13773         # verify fallocate on PFL file
13774         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13775                 error "Create $DIR/$tfile failed"
13776         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13777                         error "fallocate failed"
13778         sync; sync_all_data
13779         cancel_lru_locks $OSC
13780         sleep 5
13781         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13782         local want=$((1024 * 1048576))
13783
13784         # Must allocate all requested space, not more than 5% extra
13785         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13786                 error "bytes $bytes is not $want"
13787 }
13788 run_test 150c "Verify fallocate Size and Blocks"
13789
13790 test_150d() {
13791         check_set_fallocate_or_skip
13792
13793         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13794         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13795         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13796         sync; sync_all_data
13797         cancel_lru_locks $OSC
13798         sleep 5
13799         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13800         local want=$((OSTCOUNT * 1048576))
13801
13802         # Must allocate all requested space, not more than 5% extra
13803         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13804                 error "bytes $bytes is not $want"
13805 }
13806 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13807
13808 test_150e() {
13809         check_set_fallocate_or_skip
13810
13811         echo "df before:"
13812         $LFS df
13813         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13814         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13815                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13816
13817         # Find OST with Minimum Size
13818         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13819                        sort -un | head -1)
13820
13821         # Get 100MB per OST of the available space to reduce run time
13822         # else 60% of the available space if we are running SLOW tests
13823         if [ $SLOW == "no" ]; then
13824                 local space=$((1024 * 100 * OSTCOUNT))
13825         else
13826                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
13827         fi
13828
13829         fallocate -l${space}k $DIR/$tfile ||
13830                 error "fallocate ${space}k $DIR/$tfile failed"
13831         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13832
13833         # get size immediately after fallocate. This should be correctly
13834         # updated
13835         local size=$(stat -c '%s' $DIR/$tfile)
13836         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13837
13838         # Sleep for a while for statfs to get updated. And not pull from cache.
13839         sleep 2
13840
13841         echo "df after fallocate:"
13842         $LFS df
13843
13844         (( size / 1024 == space )) || error "size $size != requested $space"
13845         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13846                 error "used $used < space $space"
13847
13848         rm $DIR/$tfile || error "rm failed"
13849         sync
13850         wait_delete_completed
13851
13852         echo "df after unlink:"
13853         $LFS df
13854 }
13855 run_test 150e "Verify 60% of available OST space consumed by fallocate"
13856
13857 #LU-2902 roc_hit was not able to read all values from lproc
13858 function roc_hit_init() {
13859         local list=$(comma_list $(osts_nodes))
13860         local dir=$DIR/$tdir-check
13861         local file=$dir/$tfile
13862         local BEFORE
13863         local AFTER
13864         local idx
13865
13866         test_mkdir $dir
13867         #use setstripe to do a write to every ost
13868         for i in $(seq 0 $((OSTCOUNT-1))); do
13869                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13870                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13871                 idx=$(printf %04x $i)
13872                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13873                         awk '$1 == "cache_access" {sum += $7}
13874                                 END { printf("%0.0f", sum) }')
13875
13876                 cancel_lru_locks osc
13877                 cat $file >/dev/null
13878
13879                 AFTER=$(get_osd_param $list *OST*$idx stats |
13880                         awk '$1 == "cache_access" {sum += $7}
13881                                 END { printf("%0.0f", sum) }')
13882
13883                 echo BEFORE:$BEFORE AFTER:$AFTER
13884                 if ! let "AFTER - BEFORE == 4"; then
13885                         rm -rf $dir
13886                         error "roc_hit is not safe to use"
13887                 fi
13888                 rm $file
13889         done
13890
13891         rm -rf $dir
13892 }
13893
13894 function roc_hit() {
13895         local list=$(comma_list $(osts_nodes))
13896         echo $(get_osd_param $list '' stats |
13897                 awk '$1 == "cache_hit" {sum += $7}
13898                         END { printf("%0.0f", sum) }')
13899 }
13900
13901 function set_cache() {
13902         local on=1
13903
13904         if [ "$2" == "off" ]; then
13905                 on=0;
13906         fi
13907         local list=$(comma_list $(osts_nodes))
13908         set_osd_param $list '' $1_cache_enable $on
13909
13910         cancel_lru_locks osc
13911 }
13912
13913 test_151() {
13914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13915         remote_ost_nodsh && skip "remote OST with nodsh"
13916
13917         local CPAGES=3
13918         local list=$(comma_list $(osts_nodes))
13919
13920         # check whether obdfilter is cache capable at all
13921         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13922                 skip "not cache-capable obdfilter"
13923         fi
13924
13925         # check cache is enabled on all obdfilters
13926         if get_osd_param $list '' read_cache_enable | grep 0; then
13927                 skip "oss cache is disabled"
13928         fi
13929
13930         set_osd_param $list '' writethrough_cache_enable 1
13931
13932         # check write cache is enabled on all obdfilters
13933         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13934                 skip "oss write cache is NOT enabled"
13935         fi
13936
13937         roc_hit_init
13938
13939         #define OBD_FAIL_OBD_NO_LRU  0x609
13940         do_nodes $list $LCTL set_param fail_loc=0x609
13941
13942         # pages should be in the case right after write
13943         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13944                 error "dd failed"
13945
13946         local BEFORE=$(roc_hit)
13947         cancel_lru_locks osc
13948         cat $DIR/$tfile >/dev/null
13949         local AFTER=$(roc_hit)
13950
13951         do_nodes $list $LCTL set_param fail_loc=0
13952
13953         if ! let "AFTER - BEFORE == CPAGES"; then
13954                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13955         fi
13956
13957         cancel_lru_locks osc
13958         # invalidates OST cache
13959         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13960         set_osd_param $list '' read_cache_enable 0
13961         cat $DIR/$tfile >/dev/null
13962
13963         # now data shouldn't be found in the cache
13964         BEFORE=$(roc_hit)
13965         cancel_lru_locks osc
13966         cat $DIR/$tfile >/dev/null
13967         AFTER=$(roc_hit)
13968         if let "AFTER - BEFORE != 0"; then
13969                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13970         fi
13971
13972         set_osd_param $list '' read_cache_enable 1
13973         rm -f $DIR/$tfile
13974 }
13975 run_test 151 "test cache on oss and controls ==============================="
13976
13977 test_152() {
13978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13979
13980         local TF="$TMP/$tfile"
13981
13982         # simulate ENOMEM during write
13983 #define OBD_FAIL_OST_NOMEM      0x226
13984         lctl set_param fail_loc=0x80000226
13985         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13986         cp $TF $DIR/$tfile
13987         sync || error "sync failed"
13988         lctl set_param fail_loc=0
13989
13990         # discard client's cache
13991         cancel_lru_locks osc
13992
13993         # simulate ENOMEM during read
13994         lctl set_param fail_loc=0x80000226
13995         cmp $TF $DIR/$tfile || error "cmp failed"
13996         lctl set_param fail_loc=0
13997
13998         rm -f $TF
13999 }
14000 run_test 152 "test read/write with enomem ============================"
14001
14002 test_153() {
14003         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14004 }
14005 run_test 153 "test if fdatasync does not crash ======================="
14006
14007 dot_lustre_fid_permission_check() {
14008         local fid=$1
14009         local ffid=$MOUNT/.lustre/fid/$fid
14010         local test_dir=$2
14011
14012         echo "stat fid $fid"
14013         stat $ffid > /dev/null || error "stat $ffid failed."
14014         echo "touch fid $fid"
14015         touch $ffid || error "touch $ffid failed."
14016         echo "write to fid $fid"
14017         cat /etc/hosts > $ffid || error "write $ffid failed."
14018         echo "read fid $fid"
14019         diff /etc/hosts $ffid || error "read $ffid failed."
14020         echo "append write to fid $fid"
14021         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14022         echo "rename fid $fid"
14023         mv $ffid $test_dir/$tfile.1 &&
14024                 error "rename $ffid to $tfile.1 should fail."
14025         touch $test_dir/$tfile.1
14026         mv $test_dir/$tfile.1 $ffid &&
14027                 error "rename $tfile.1 to $ffid should fail."
14028         rm -f $test_dir/$tfile.1
14029         echo "truncate fid $fid"
14030         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14031         echo "link fid $fid"
14032         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14033         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14034                 echo "setfacl fid $fid"
14035                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14036                 echo "getfacl fid $fid"
14037                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14038         fi
14039         echo "unlink fid $fid"
14040         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14041         echo "mknod fid $fid"
14042         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14043
14044         fid=[0xf00000400:0x1:0x0]
14045         ffid=$MOUNT/.lustre/fid/$fid
14046
14047         echo "stat non-exist fid $fid"
14048         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14049         echo "write to non-exist fid $fid"
14050         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14051         echo "link new fid $fid"
14052         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14053
14054         mkdir -p $test_dir/$tdir
14055         touch $test_dir/$tdir/$tfile
14056         fid=$($LFS path2fid $test_dir/$tdir)
14057         rc=$?
14058         [ $rc -ne 0 ] &&
14059                 error "error: could not get fid for $test_dir/$dir/$tfile."
14060
14061         ffid=$MOUNT/.lustre/fid/$fid
14062
14063         echo "ls $fid"
14064         ls $ffid > /dev/null || error "ls $ffid failed."
14065         echo "touch $fid/$tfile.1"
14066         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14067
14068         echo "touch $MOUNT/.lustre/fid/$tfile"
14069         touch $MOUNT/.lustre/fid/$tfile && \
14070                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14071
14072         echo "setxattr to $MOUNT/.lustre/fid"
14073         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14074
14075         echo "listxattr for $MOUNT/.lustre/fid"
14076         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14077
14078         echo "delxattr from $MOUNT/.lustre/fid"
14079         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14080
14081         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14082         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14083                 error "touch invalid fid should fail."
14084
14085         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14086         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14087                 error "touch non-normal fid should fail."
14088
14089         echo "rename $tdir to $MOUNT/.lustre/fid"
14090         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14091                 error "rename to $MOUNT/.lustre/fid should fail."
14092
14093         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14094         then            # LU-3547
14095                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14096                 local new_obf_mode=777
14097
14098                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14099                 chmod $new_obf_mode $DIR/.lustre/fid ||
14100                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14101
14102                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14103                 [ $obf_mode -eq $new_obf_mode ] ||
14104                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14105
14106                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14107                 chmod $old_obf_mode $DIR/.lustre/fid ||
14108                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14109         fi
14110
14111         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14112         fid=$($LFS path2fid $test_dir/$tfile-2)
14113
14114         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14115         then # LU-5424
14116                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14117                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14118                         error "create lov data thru .lustre failed"
14119         fi
14120         echo "cp /etc/passwd $test_dir/$tfile-2"
14121         cp /etc/passwd $test_dir/$tfile-2 ||
14122                 error "copy to $test_dir/$tfile-2 failed."
14123         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14124         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14125                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14126
14127         rm -rf $test_dir/tfile.lnk
14128         rm -rf $test_dir/$tfile-2
14129 }
14130
14131 test_154A() {
14132         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14133                 skip "Need MDS version at least 2.4.1"
14134
14135         local tf=$DIR/$tfile
14136         touch $tf
14137
14138         local fid=$($LFS path2fid $tf)
14139         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14140
14141         # check that we get the same pathname back
14142         local rootpath
14143         local found
14144         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14145                 echo "$rootpath $fid"
14146                 found=$($LFS fid2path $rootpath "$fid")
14147                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14148                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14149         done
14150
14151         # check wrong root path format
14152         rootpath=$MOUNT"_wrong"
14153         found=$($LFS fid2path $rootpath "$fid")
14154         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14155 }
14156 run_test 154A "lfs path2fid and fid2path basic checks"
14157
14158 test_154B() {
14159         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14160                 skip "Need MDS version at least 2.4.1"
14161
14162         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14163         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14164         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14165         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14166
14167         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14168         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14169
14170         # check that we get the same pathname
14171         echo "PFID: $PFID, name: $name"
14172         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14173         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14174         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14175                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14176
14177         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14178 }
14179 run_test 154B "verify the ll_decode_linkea tool"
14180
14181 test_154a() {
14182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14183         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14184         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14185                 skip "Need MDS version at least 2.2.51"
14186         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14187
14188         cp /etc/hosts $DIR/$tfile
14189
14190         fid=$($LFS path2fid $DIR/$tfile)
14191         rc=$?
14192         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14193
14194         dot_lustre_fid_permission_check "$fid" $DIR ||
14195                 error "dot lustre permission check $fid failed"
14196
14197         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14198
14199         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14200
14201         touch $MOUNT/.lustre/file &&
14202                 error "creation is not allowed under .lustre"
14203
14204         mkdir $MOUNT/.lustre/dir &&
14205                 error "mkdir is not allowed under .lustre"
14206
14207         rm -rf $DIR/$tfile
14208 }
14209 run_test 154a "Open-by-FID"
14210
14211 test_154b() {
14212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14213         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14214         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14215         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14216                 skip "Need MDS version at least 2.2.51"
14217
14218         local remote_dir=$DIR/$tdir/remote_dir
14219         local MDTIDX=1
14220         local rc=0
14221
14222         mkdir -p $DIR/$tdir
14223         $LFS mkdir -i $MDTIDX $remote_dir ||
14224                 error "create remote directory failed"
14225
14226         cp /etc/hosts $remote_dir/$tfile
14227
14228         fid=$($LFS path2fid $remote_dir/$tfile)
14229         rc=$?
14230         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14231
14232         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14233                 error "dot lustre permission check $fid failed"
14234         rm -rf $DIR/$tdir
14235 }
14236 run_test 154b "Open-by-FID for remote directory"
14237
14238 test_154c() {
14239         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14240                 skip "Need MDS version at least 2.4.1"
14241
14242         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14243         local FID1=$($LFS path2fid $DIR/$tfile.1)
14244         local FID2=$($LFS path2fid $DIR/$tfile.2)
14245         local FID3=$($LFS path2fid $DIR/$tfile.3)
14246
14247         local N=1
14248         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14249                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14250                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14251                 local want=FID$N
14252                 [ "$FID" = "${!want}" ] ||
14253                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14254                 N=$((N + 1))
14255         done
14256
14257         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14258         do
14259                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14260                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14261                 N=$((N + 1))
14262         done
14263 }
14264 run_test 154c "lfs path2fid and fid2path multiple arguments"
14265
14266 test_154d() {
14267         remote_mds_nodsh && skip "remote MDS with nodsh"
14268         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14269                 skip "Need MDS version at least 2.5.53"
14270
14271         if remote_mds; then
14272                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14273         else
14274                 nid="0@lo"
14275         fi
14276         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14277         local fd
14278         local cmd
14279
14280         rm -f $DIR/$tfile
14281         touch $DIR/$tfile
14282
14283         local fid=$($LFS path2fid $DIR/$tfile)
14284         # Open the file
14285         fd=$(free_fd)
14286         cmd="exec $fd<$DIR/$tfile"
14287         eval $cmd
14288         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14289         echo "$fid_list" | grep "$fid"
14290         rc=$?
14291
14292         cmd="exec $fd>/dev/null"
14293         eval $cmd
14294         if [ $rc -ne 0 ]; then
14295                 error "FID $fid not found in open files list $fid_list"
14296         fi
14297 }
14298 run_test 154d "Verify open file fid"
14299
14300 test_154e()
14301 {
14302         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14303                 skip "Need MDS version at least 2.6.50"
14304
14305         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14306                 error ".lustre returned by readdir"
14307         fi
14308 }
14309 run_test 154e ".lustre is not returned by readdir"
14310
14311 test_154f() {
14312         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14313
14314         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14315         test_mkdir -p -c1 $DIR/$tdir/d
14316         # test dirs inherit from its stripe
14317         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14318         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14319         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14320         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14321         touch $DIR/f
14322
14323         # get fid of parents
14324         local FID0=$($LFS path2fid $DIR/$tdir/d)
14325         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14326         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14327         local FID3=$($LFS path2fid $DIR)
14328
14329         # check that path2fid --parents returns expected <parent_fid>/name
14330         # 1) test for a directory (single parent)
14331         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14332         [ "$parent" == "$FID0/foo1" ] ||
14333                 error "expected parent: $FID0/foo1, got: $parent"
14334
14335         # 2) test for a file with nlink > 1 (multiple parents)
14336         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14337         echo "$parent" | grep -F "$FID1/$tfile" ||
14338                 error "$FID1/$tfile not returned in parent list"
14339         echo "$parent" | grep -F "$FID2/link" ||
14340                 error "$FID2/link not returned in parent list"
14341
14342         # 3) get parent by fid
14343         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14344         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14345         echo "$parent" | grep -F "$FID1/$tfile" ||
14346                 error "$FID1/$tfile not returned in parent list (by fid)"
14347         echo "$parent" | grep -F "$FID2/link" ||
14348                 error "$FID2/link not returned in parent list (by fid)"
14349
14350         # 4) test for entry in root directory
14351         parent=$($LFS path2fid --parents $DIR/f)
14352         echo "$parent" | grep -F "$FID3/f" ||
14353                 error "$FID3/f not returned in parent list"
14354
14355         # 5) test it on root directory
14356         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14357                 error "$MOUNT should not have parents"
14358
14359         # enable xattr caching and check that linkea is correctly updated
14360         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14361         save_lustre_params client "llite.*.xattr_cache" > $save
14362         lctl set_param llite.*.xattr_cache 1
14363
14364         # 6.1) linkea update on rename
14365         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14366
14367         # get parents by fid
14368         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14369         # foo1 should no longer be returned in parent list
14370         echo "$parent" | grep -F "$FID1" &&
14371                 error "$FID1 should no longer be in parent list"
14372         # the new path should appear
14373         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14374                 error "$FID2/$tfile.moved is not in parent list"
14375
14376         # 6.2) linkea update on unlink
14377         rm -f $DIR/$tdir/d/foo2/link
14378         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14379         # foo2/link should no longer be returned in parent list
14380         echo "$parent" | grep -F "$FID2/link" &&
14381                 error "$FID2/link should no longer be in parent list"
14382         true
14383
14384         rm -f $DIR/f
14385         restore_lustre_params < $save
14386         rm -f $save
14387 }
14388 run_test 154f "get parent fids by reading link ea"
14389
14390 test_154g()
14391 {
14392         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14393         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14394            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14395                 skip "Need MDS version at least 2.6.92"
14396
14397         mkdir -p $DIR/$tdir
14398         llapi_fid_test -d $DIR/$tdir
14399 }
14400 run_test 154g "various llapi FID tests"
14401
14402 test_155_small_load() {
14403     local temp=$TMP/$tfile
14404     local file=$DIR/$tfile
14405
14406     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14407         error "dd of=$temp bs=6096 count=1 failed"
14408     cp $temp $file
14409     cancel_lru_locks $OSC
14410     cmp $temp $file || error "$temp $file differ"
14411
14412     $TRUNCATE $temp 6000
14413     $TRUNCATE $file 6000
14414     cmp $temp $file || error "$temp $file differ (truncate1)"
14415
14416     echo "12345" >>$temp
14417     echo "12345" >>$file
14418     cmp $temp $file || error "$temp $file differ (append1)"
14419
14420     echo "12345" >>$temp
14421     echo "12345" >>$file
14422     cmp $temp $file || error "$temp $file differ (append2)"
14423
14424     rm -f $temp $file
14425     true
14426 }
14427
14428 test_155_big_load() {
14429         remote_ost_nodsh && skip "remote OST with nodsh"
14430
14431         local temp=$TMP/$tfile
14432         local file=$DIR/$tfile
14433
14434         free_min_max
14435         local cache_size=$(do_facet ost$((MAXI+1)) \
14436                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14437         local large_file_size=$((cache_size * 2))
14438
14439         echo "OSS cache size: $cache_size KB"
14440         echo "Large file size: $large_file_size KB"
14441
14442         [ $MAXV -le $large_file_size ] &&
14443                 skip_env "max available OST size needs > $large_file_size KB"
14444
14445         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14446
14447         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14448                 error "dd of=$temp bs=$large_file_size count=1k failed"
14449         cp $temp $file
14450         ls -lh $temp $file
14451         cancel_lru_locks osc
14452         cmp $temp $file || error "$temp $file differ"
14453
14454         rm -f $temp $file
14455         true
14456 }
14457
14458 save_writethrough() {
14459         local facets=$(get_facets OST)
14460
14461         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14462 }
14463
14464 test_155a() {
14465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14466
14467         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14468
14469         save_writethrough $p
14470
14471         set_cache read on
14472         set_cache writethrough on
14473         test_155_small_load
14474         restore_lustre_params < $p
14475         rm -f $p
14476 }
14477 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14478
14479 test_155b() {
14480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14481
14482         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14483
14484         save_writethrough $p
14485
14486         set_cache read on
14487         set_cache writethrough off
14488         test_155_small_load
14489         restore_lustre_params < $p
14490         rm -f $p
14491 }
14492 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14493
14494 test_155c() {
14495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14496
14497         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14498
14499         save_writethrough $p
14500
14501         set_cache read off
14502         set_cache writethrough on
14503         test_155_small_load
14504         restore_lustre_params < $p
14505         rm -f $p
14506 }
14507 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14508
14509 test_155d() {
14510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14511
14512         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14513
14514         save_writethrough $p
14515
14516         set_cache read off
14517         set_cache writethrough off
14518         test_155_small_load
14519         restore_lustre_params < $p
14520         rm -f $p
14521 }
14522 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14523
14524 test_155e() {
14525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14526
14527         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14528
14529         save_writethrough $p
14530
14531         set_cache read on
14532         set_cache writethrough on
14533         test_155_big_load
14534         restore_lustre_params < $p
14535         rm -f $p
14536 }
14537 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14538
14539 test_155f() {
14540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14541
14542         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14543
14544         save_writethrough $p
14545
14546         set_cache read on
14547         set_cache writethrough off
14548         test_155_big_load
14549         restore_lustre_params < $p
14550         rm -f $p
14551 }
14552 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14553
14554 test_155g() {
14555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14556
14557         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14558
14559         save_writethrough $p
14560
14561         set_cache read off
14562         set_cache writethrough on
14563         test_155_big_load
14564         restore_lustre_params < $p
14565         rm -f $p
14566 }
14567 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14568
14569 test_155h() {
14570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14571
14572         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14573
14574         save_writethrough $p
14575
14576         set_cache read off
14577         set_cache writethrough off
14578         test_155_big_load
14579         restore_lustre_params < $p
14580         rm -f $p
14581 }
14582 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14583
14584 test_156() {
14585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14586         remote_ost_nodsh && skip "remote OST with nodsh"
14587         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14588                 skip "stats not implemented on old servers"
14589         [ "$ost1_FSTYPE" = "zfs" ] &&
14590                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14591
14592         local CPAGES=3
14593         local BEFORE
14594         local AFTER
14595         local file="$DIR/$tfile"
14596         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14597
14598         save_writethrough $p
14599         roc_hit_init
14600
14601         log "Turn on read and write cache"
14602         set_cache read on
14603         set_cache writethrough on
14604
14605         log "Write data and read it back."
14606         log "Read should be satisfied from the cache."
14607         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14608         BEFORE=$(roc_hit)
14609         cancel_lru_locks osc
14610         cat $file >/dev/null
14611         AFTER=$(roc_hit)
14612         if ! let "AFTER - BEFORE == CPAGES"; then
14613                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14614         else
14615                 log "cache hits: before: $BEFORE, after: $AFTER"
14616         fi
14617
14618         log "Read again; it should be satisfied from the cache."
14619         BEFORE=$AFTER
14620         cancel_lru_locks osc
14621         cat $file >/dev/null
14622         AFTER=$(roc_hit)
14623         if ! let "AFTER - BEFORE == CPAGES"; then
14624                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14625         else
14626                 log "cache hits:: before: $BEFORE, after: $AFTER"
14627         fi
14628
14629         log "Turn off the read cache and turn on the write cache"
14630         set_cache read off
14631         set_cache writethrough on
14632
14633         log "Read again; it should be satisfied from the cache."
14634         BEFORE=$(roc_hit)
14635         cancel_lru_locks osc
14636         cat $file >/dev/null
14637         AFTER=$(roc_hit)
14638         if ! let "AFTER - BEFORE == CPAGES"; then
14639                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14640         else
14641                 log "cache hits:: before: $BEFORE, after: $AFTER"
14642         fi
14643
14644         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14645                 # > 2.12.56 uses pagecache if cached
14646                 log "Read again; it should not be satisfied from the cache."
14647                 BEFORE=$AFTER
14648                 cancel_lru_locks osc
14649                 cat $file >/dev/null
14650                 AFTER=$(roc_hit)
14651                 if ! let "AFTER - BEFORE == 0"; then
14652                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14653                 else
14654                         log "cache hits:: before: $BEFORE, after: $AFTER"
14655                 fi
14656         fi
14657
14658         log "Write data and read it back."
14659         log "Read should be satisfied from the cache."
14660         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14661         BEFORE=$(roc_hit)
14662         cancel_lru_locks osc
14663         cat $file >/dev/null
14664         AFTER=$(roc_hit)
14665         if ! let "AFTER - BEFORE == CPAGES"; then
14666                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14667         else
14668                 log "cache hits:: before: $BEFORE, after: $AFTER"
14669         fi
14670
14671         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14672                 # > 2.12.56 uses pagecache if cached
14673                 log "Read again; it should not be satisfied from the cache."
14674                 BEFORE=$AFTER
14675                 cancel_lru_locks osc
14676                 cat $file >/dev/null
14677                 AFTER=$(roc_hit)
14678                 if ! let "AFTER - BEFORE == 0"; then
14679                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14680                 else
14681                         log "cache hits:: before: $BEFORE, after: $AFTER"
14682                 fi
14683         fi
14684
14685         log "Turn off read and write cache"
14686         set_cache read off
14687         set_cache writethrough off
14688
14689         log "Write data and read it back"
14690         log "It should not be satisfied from the cache."
14691         rm -f $file
14692         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14693         cancel_lru_locks osc
14694         BEFORE=$(roc_hit)
14695         cat $file >/dev/null
14696         AFTER=$(roc_hit)
14697         if ! let "AFTER - BEFORE == 0"; then
14698                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14699         else
14700                 log "cache hits:: before: $BEFORE, after: $AFTER"
14701         fi
14702
14703         log "Turn on the read cache and turn off the write cache"
14704         set_cache read on
14705         set_cache writethrough off
14706
14707         log "Write data and read it back"
14708         log "It should not be satisfied from the cache."
14709         rm -f $file
14710         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14711         BEFORE=$(roc_hit)
14712         cancel_lru_locks osc
14713         cat $file >/dev/null
14714         AFTER=$(roc_hit)
14715         if ! let "AFTER - BEFORE == 0"; then
14716                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14717         else
14718                 log "cache hits:: before: $BEFORE, after: $AFTER"
14719         fi
14720
14721         log "Read again; it should be satisfied from the cache."
14722         BEFORE=$(roc_hit)
14723         cancel_lru_locks osc
14724         cat $file >/dev/null
14725         AFTER=$(roc_hit)
14726         if ! let "AFTER - BEFORE == CPAGES"; then
14727                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14728         else
14729                 log "cache hits:: before: $BEFORE, after: $AFTER"
14730         fi
14731
14732         restore_lustre_params < $p
14733         rm -f $p $file
14734 }
14735 run_test 156 "Verification of tunables"
14736
14737 test_160a() {
14738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14739         remote_mds_nodsh && skip "remote MDS with nodsh"
14740         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14741                 skip "Need MDS version at least 2.2.0"
14742
14743         changelog_register || error "changelog_register failed"
14744         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14745         changelog_users $SINGLEMDS | grep -q $cl_user ||
14746                 error "User $cl_user not found in changelog_users"
14747
14748         # change something
14749         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14750         changelog_clear 0 || error "changelog_clear failed"
14751         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14752         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14753         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14754         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14755         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14756         rm $DIR/$tdir/pics/desktop.jpg
14757
14758         changelog_dump | tail -10
14759
14760         echo "verifying changelog mask"
14761         changelog_chmask "-MKDIR"
14762         changelog_chmask "-CLOSE"
14763
14764         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14765         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14766
14767         changelog_chmask "+MKDIR"
14768         changelog_chmask "+CLOSE"
14769
14770         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14771         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14772
14773         changelog_dump | tail -10
14774         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14775         CLOSES=$(changelog_dump | grep -c "CLOSE")
14776         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14777         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14778
14779         # verify contents
14780         echo "verifying target fid"
14781         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14782         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14783         [ "$fidc" == "$fidf" ] ||
14784                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14785         echo "verifying parent fid"
14786         # The FID returned from the Changelog may be the directory shard on
14787         # a different MDT, and not the FID returned by path2fid on the parent.
14788         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14789         # since this is what will matter when recreating this file in the tree.
14790         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14791         local pathp=$($LFS fid2path $MOUNT "$fidp")
14792         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14793                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14794
14795         echo "getting records for $cl_user"
14796         changelog_users $SINGLEMDS
14797         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14798         local nclr=3
14799         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14800                 error "changelog_clear failed"
14801         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14802         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14803         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14804                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14805
14806         local min0_rec=$(changelog_users $SINGLEMDS |
14807                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14808         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14809                           awk '{ print $1; exit; }')
14810
14811         changelog_dump | tail -n 5
14812         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14813         [ $first_rec == $((min0_rec + 1)) ] ||
14814                 error "first index should be $min0_rec + 1 not $first_rec"
14815
14816         # LU-3446 changelog index reset on MDT restart
14817         local cur_rec1=$(changelog_users $SINGLEMDS |
14818                          awk '/^current.index:/ { print $NF }')
14819         changelog_clear 0 ||
14820                 error "clear all changelog records for $cl_user failed"
14821         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14822         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14823                 error "Fail to start $SINGLEMDS"
14824         local cur_rec2=$(changelog_users $SINGLEMDS |
14825                          awk '/^current.index:/ { print $NF }')
14826         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14827         [ $cur_rec1 == $cur_rec2 ] ||
14828                 error "current index should be $cur_rec1 not $cur_rec2"
14829
14830         echo "verifying users from this test are deregistered"
14831         changelog_deregister || error "changelog_deregister failed"
14832         changelog_users $SINGLEMDS | grep -q $cl_user &&
14833                 error "User '$cl_user' still in changelog_users"
14834
14835         # lctl get_param -n mdd.*.changelog_users
14836         # current index: 144
14837         # ID    index (idle seconds)
14838         # cl3   144 (2)
14839         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14840                 # this is the normal case where all users were deregistered
14841                 # make sure no new records are added when no users are present
14842                 local last_rec1=$(changelog_users $SINGLEMDS |
14843                                   awk '/^current.index:/ { print $NF }')
14844                 touch $DIR/$tdir/chloe
14845                 local last_rec2=$(changelog_users $SINGLEMDS |
14846                                   awk '/^current.index:/ { print $NF }')
14847                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14848                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14849         else
14850                 # any changelog users must be leftovers from a previous test
14851                 changelog_users $SINGLEMDS
14852                 echo "other changelog users; can't verify off"
14853         fi
14854 }
14855 run_test 160a "changelog sanity"
14856
14857 test_160b() { # LU-3587
14858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14859         remote_mds_nodsh && skip "remote MDS with nodsh"
14860         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14861                 skip "Need MDS version at least 2.2.0"
14862
14863         changelog_register || error "changelog_register failed"
14864         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14865         changelog_users $SINGLEMDS | grep -q $cl_user ||
14866                 error "User '$cl_user' not found in changelog_users"
14867
14868         local longname1=$(str_repeat a 255)
14869         local longname2=$(str_repeat b 255)
14870
14871         cd $DIR
14872         echo "creating very long named file"
14873         touch $longname1 || error "create of '$longname1' failed"
14874         echo "renaming very long named file"
14875         mv $longname1 $longname2
14876
14877         changelog_dump | grep RENME | tail -n 5
14878         rm -f $longname2
14879 }
14880 run_test 160b "Verify that very long rename doesn't crash in changelog"
14881
14882 test_160c() {
14883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14884         remote_mds_nodsh && skip "remote MDS with nodsh"
14885
14886         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14887                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14888                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14889                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14890
14891         local rc=0
14892
14893         # Registration step
14894         changelog_register || error "changelog_register failed"
14895
14896         rm -rf $DIR/$tdir
14897         mkdir -p $DIR/$tdir
14898         $MCREATE $DIR/$tdir/foo_160c
14899         changelog_chmask "-TRUNC"
14900         $TRUNCATE $DIR/$tdir/foo_160c 200
14901         changelog_chmask "+TRUNC"
14902         $TRUNCATE $DIR/$tdir/foo_160c 199
14903         changelog_dump | tail -n 5
14904         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14905         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14906 }
14907 run_test 160c "verify that changelog log catch the truncate event"
14908
14909 test_160d() {
14910         remote_mds_nodsh && skip "remote MDS with nodsh"
14911         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14913         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14914                 skip "Need MDS version at least 2.7.60"
14915
14916         # Registration step
14917         changelog_register || error "changelog_register failed"
14918
14919         mkdir -p $DIR/$tdir/migrate_dir
14920         changelog_clear 0 || error "changelog_clear failed"
14921
14922         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14923         changelog_dump | tail -n 5
14924         local migrates=$(changelog_dump | grep -c "MIGRT")
14925         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14926 }
14927 run_test 160d "verify that changelog log catch the migrate event"
14928
14929 test_160e() {
14930         remote_mds_nodsh && skip "remote MDS with nodsh"
14931
14932         # Create a user
14933         changelog_register || error "changelog_register failed"
14934
14935         # Delete a future user (expect fail)
14936         local MDT0=$(facet_svc $SINGLEMDS)
14937         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14938         local rc=$?
14939
14940         if [ $rc -eq 0 ]; then
14941                 error "Deleted non-existant user cl77"
14942         elif [ $rc -ne 2 ]; then
14943                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14944         fi
14945
14946         # Clear to a bad index (1 billion should be safe)
14947         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14948         rc=$?
14949
14950         if [ $rc -eq 0 ]; then
14951                 error "Successfully cleared to invalid CL index"
14952         elif [ $rc -ne 22 ]; then
14953                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14954         fi
14955 }
14956 run_test 160e "changelog negative testing (should return errors)"
14957
14958 test_160f() {
14959         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14960         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14961                 skip "Need MDS version at least 2.10.56"
14962
14963         local mdts=$(comma_list $(mdts_nodes))
14964
14965         # Create a user
14966         changelog_register || error "first changelog_register failed"
14967         changelog_register || error "second changelog_register failed"
14968         local cl_users
14969         declare -A cl_user1
14970         declare -A cl_user2
14971         local user_rec1
14972         local user_rec2
14973         local i
14974
14975         # generate some changelog records to accumulate on each MDT
14976         # use all_char because created files should be evenly distributed
14977         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
14978                 error "test_mkdir $tdir failed"
14979         log "$(date +%s): creating first files"
14980         for ((i = 0; i < MDSCOUNT * 2; i++)); do
14981                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
14982                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
14983         done
14984
14985         # check changelogs have been generated
14986         local start=$SECONDS
14987         local idle_time=$((MDSCOUNT * 5 + 5))
14988         local nbcl=$(changelog_dump | wc -l)
14989         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14990
14991         for param in "changelog_max_idle_time=$idle_time" \
14992                      "changelog_gc=1" \
14993                      "changelog_min_gc_interval=2" \
14994                      "changelog_min_free_cat_entries=3"; do
14995                 local MDT0=$(facet_svc $SINGLEMDS)
14996                 local var="${param%=*}"
14997                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14998
14999                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15000                 do_nodes $mdts $LCTL set_param mdd.*.$param
15001         done
15002
15003         # force cl_user2 to be idle (1st part), but also cancel the
15004         # cl_user1 records so that it is not evicted later in the test.
15005         local sleep1=$((idle_time / 2))
15006         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15007         sleep $sleep1
15008
15009         # simulate changelog catalog almost full
15010         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15011         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15012
15013         for i in $(seq $MDSCOUNT); do
15014                 cl_users=(${CL_USERS[mds$i]})
15015                 cl_user1[mds$i]="${cl_users[0]}"
15016                 cl_user2[mds$i]="${cl_users[1]}"
15017
15018                 [ -n "${cl_user1[mds$i]}" ] ||
15019                         error "mds$i: no user registered"
15020                 [ -n "${cl_user2[mds$i]}" ] ||
15021                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15022
15023                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15024                 [ -n "$user_rec1" ] ||
15025                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15026                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15027                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15028                 [ -n "$user_rec2" ] ||
15029                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15030                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15031                      "$user_rec1 + 2 == $user_rec2"
15032                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15033                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15034                               "$user_rec1 + 2, but is $user_rec2"
15035                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15036                 [ -n "$user_rec2" ] ||
15037                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15038                 [ $user_rec1 == $user_rec2 ] ||
15039                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15040                               "$user_rec1, but is $user_rec2"
15041         done
15042
15043         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15044         local sleep2=$((idle_time - (SECONDS - start) + 1))
15045         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15046         sleep $sleep2
15047
15048         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15049         # cl_user1 should be OK because it recently processed records.
15050         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15051         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15052                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15053                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15054         done
15055
15056         # ensure gc thread is done
15057         for i in $(mdts_nodes); do
15058                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15059                         error "$i: GC-thread not done"
15060         done
15061
15062         local first_rec
15063         for (( i = 1; i <= MDSCOUNT; i++ )); do
15064                 # check cl_user1 still registered
15065                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15066                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15067                 # check cl_user2 unregistered
15068                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15069                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15070
15071                 # check changelogs are present and starting at $user_rec1 + 1
15072                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15073                 [ -n "$user_rec1" ] ||
15074                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15075                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15076                             awk '{ print $1; exit; }')
15077
15078                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15079                 [ $((user_rec1 + 1)) == $first_rec ] ||
15080                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15081         done
15082 }
15083 run_test 160f "changelog garbage collect (timestamped users)"
15084
15085 test_160g() {
15086         remote_mds_nodsh && skip "remote MDS with nodsh"
15087         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15088                 skip "Need MDS version at least 2.10.56"
15089
15090         local mdts=$(comma_list $(mdts_nodes))
15091
15092         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15093         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15094
15095         # Create a user
15096         changelog_register || error "first changelog_register failed"
15097         changelog_register || error "second changelog_register failed"
15098         local cl_users
15099         declare -A cl_user1
15100         declare -A cl_user2
15101         local user_rec1
15102         local user_rec2
15103         local i
15104
15105         # generate some changelog records to accumulate on each MDT
15106         # use all_char because created files should be evenly distributed
15107         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15108                 error "test_mkdir $tdir failed"
15109         for ((i = 0; i < MDSCOUNT; i++)); do
15110                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15111                         error "create $DIR/$tdir/d$i.1 failed"
15112         done
15113
15114         # check changelogs have been generated
15115         local nbcl=$(changelog_dump | wc -l)
15116         (( $nbcl > 0 )) || error "no changelogs found"
15117
15118         # reduce the max_idle_indexes value to make sure we exceed it
15119         for param in "changelog_max_idle_indexes=1" \
15120                      "changelog_gc=1" \
15121                      "changelog_min_gc_interval=2" \
15122                      "changelog_min_free_cat_entries=3"; do
15123                 local MDT0=$(facet_svc $SINGLEMDS)
15124                 local var="${param%=*}"
15125                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15126
15127                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15128                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15129                         error "unable to set mdd.*.$param"
15130         done
15131
15132         # simulate changelog catalog almost full
15133         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15134         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15135
15136         local start=$SECONDS
15137         for i in $(seq $MDSCOUNT); do
15138                 cl_users=(${CL_USERS[mds$i]})
15139                 cl_user1[mds$i]="${cl_users[0]}"
15140                 cl_user2[mds$i]="${cl_users[1]}"
15141
15142                 [ -n "${cl_user1[mds$i]}" ] ||
15143                         error "mds$i: no user registered"
15144                 [ -n "${cl_user2[mds$i]}" ] ||
15145                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15146
15147                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15148                 [ -n "$user_rec1" ] ||
15149                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15150                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15151                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15152                 [ -n "$user_rec2" ] ||
15153                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15154                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15155                      "$user_rec1 + 2 == $user_rec2"
15156                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15157                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15158                               "$user_rec1 + 2, but is $user_rec2"
15159                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15160                 [ -n "$user_rec2" ] ||
15161                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15162                 [ $user_rec1 == $user_rec2 ] ||
15163                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15164                               "$user_rec1, but is $user_rec2"
15165         done
15166
15167         # ensure we are past the previous changelog_min_gc_interval set above
15168         local sleep2=$((start + 2 - SECONDS))
15169         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15170
15171         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15172         # cl_user1 should be OK because it recently processed records.
15173         for ((i = 0; i < MDSCOUNT; i++)); do
15174                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15175                         error "create $DIR/$tdir/d$i.3 failed"
15176         done
15177
15178         # ensure gc thread is done
15179         for i in $(mdts_nodes); do
15180                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15181                         error "$i: GC-thread not done"
15182         done
15183
15184         local first_rec
15185         for (( i = 1; i <= MDSCOUNT; i++ )); do
15186                 # check cl_user1 still registered
15187                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15188                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15189                 # check cl_user2 unregistered
15190                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15191                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15192
15193                 # check changelogs are present and starting at $user_rec1 + 1
15194                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15195                 [ -n "$user_rec1" ] ||
15196                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15197                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15198                             awk '{ print $1; exit; }')
15199
15200                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15201                 [ $((user_rec1 + 1)) == $first_rec ] ||
15202                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15203         done
15204 }
15205 run_test 160g "changelog garbage collect (old users)"
15206
15207 test_160h() {
15208         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15209         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15210                 skip "Need MDS version at least 2.10.56"
15211
15212         local mdts=$(comma_list $(mdts_nodes))
15213
15214         # Create a user
15215         changelog_register || error "first changelog_register failed"
15216         changelog_register || error "second changelog_register failed"
15217         local cl_users
15218         declare -A cl_user1
15219         declare -A cl_user2
15220         local user_rec1
15221         local user_rec2
15222         local i
15223
15224         # generate some changelog records to accumulate on each MDT
15225         # use all_char because created files should be evenly distributed
15226         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15227                 error "test_mkdir $tdir failed"
15228         for ((i = 0; i < MDSCOUNT; i++)); do
15229                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15230                         error "create $DIR/$tdir/d$i.1 failed"
15231         done
15232
15233         # check changelogs have been generated
15234         local nbcl=$(changelog_dump | wc -l)
15235         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15236
15237         for param in "changelog_max_idle_time=10" \
15238                      "changelog_gc=1" \
15239                      "changelog_min_gc_interval=2"; do
15240                 local MDT0=$(facet_svc $SINGLEMDS)
15241                 local var="${param%=*}"
15242                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15243
15244                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15245                 do_nodes $mdts $LCTL set_param mdd.*.$param
15246         done
15247
15248         # force cl_user2 to be idle (1st part)
15249         sleep 9
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 to be idle (2nd part) and to reach
15282         # changelog_max_idle_time
15283         sleep 2
15284
15285         # force each GC-thread start and block then
15286         # one per MDT/MDD, set fail_val accordingly
15287         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15288         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15289
15290         # generate more changelogs to trigger fail_loc
15291         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15292                 error "create $DIR/$tdir/${tfile}bis failed"
15293
15294         # stop MDT to stop GC-thread, should be done in back-ground as it will
15295         # block waiting for the thread to be released and exit
15296         declare -A stop_pids
15297         for i in $(seq $MDSCOUNT); do
15298                 stop mds$i &
15299                 stop_pids[mds$i]=$!
15300         done
15301
15302         for i in $(mdts_nodes); do
15303                 local facet
15304                 local nb=0
15305                 local facets=$(facets_up_on_host $i)
15306
15307                 for facet in ${facets//,/ }; do
15308                         if [[ $facet == mds* ]]; then
15309                                 nb=$((nb + 1))
15310                         fi
15311                 done
15312                 # ensure each MDS's gc threads are still present and all in "R"
15313                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15314                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15315                         error "$i: expected $nb GC-thread"
15316                 wait_update $i \
15317                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15318                         "R" 20 ||
15319                         error "$i: GC-thread not found in R-state"
15320                 # check umounts of each MDT on MDS have reached kthread_stop()
15321                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15322                         error "$i: expected $nb umount"
15323                 wait_update $i \
15324                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15325                         error "$i: umount not found in D-state"
15326         done
15327
15328         # release all GC-threads
15329         do_nodes $mdts $LCTL set_param fail_loc=0
15330
15331         # wait for MDT stop to complete
15332         for i in $(seq $MDSCOUNT); do
15333                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15334         done
15335
15336         # XXX
15337         # may try to check if any orphan changelog records are present
15338         # via ldiskfs/zfs and llog_reader...
15339
15340         # re-start/mount MDTs
15341         for i in $(seq $MDSCOUNT); do
15342                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15343                         error "Fail to start mds$i"
15344         done
15345
15346         local first_rec
15347         for i in $(seq $MDSCOUNT); do
15348                 # check cl_user1 still registered
15349                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15350                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15351                 # check cl_user2 unregistered
15352                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15353                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15354
15355                 # check changelogs are present and starting at $user_rec1 + 1
15356                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15357                 [ -n "$user_rec1" ] ||
15358                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15359                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15360                             awk '{ print $1; exit; }')
15361
15362                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15363                 [ $((user_rec1 + 1)) == $first_rec ] ||
15364                         error "mds$i: first index should be $user_rec1 + 1, " \
15365                               "but is $first_rec"
15366         done
15367 }
15368 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15369               "during mount"
15370
15371 test_160i() {
15372
15373         local mdts=$(comma_list $(mdts_nodes))
15374
15375         changelog_register || error "first changelog_register failed"
15376
15377         # generate some changelog records to accumulate on each MDT
15378         # use all_char because created files should be evenly distributed
15379         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15380                 error "test_mkdir $tdir failed"
15381         for ((i = 0; i < MDSCOUNT; i++)); do
15382                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15383                         error "create $DIR/$tdir/d$i.1 failed"
15384         done
15385
15386         # check changelogs have been generated
15387         local nbcl=$(changelog_dump | wc -l)
15388         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15389
15390         # simulate race between register and unregister
15391         # XXX as fail_loc is set per-MDS, with DNE configs the race
15392         # simulation will only occur for one MDT per MDS and for the
15393         # others the normal race scenario will take place
15394         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15395         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15396         do_nodes $mdts $LCTL set_param fail_val=1
15397
15398         # unregister 1st user
15399         changelog_deregister &
15400         local pid1=$!
15401         # wait some time for deregister work to reach race rdv
15402         sleep 2
15403         # register 2nd user
15404         changelog_register || error "2nd user register failed"
15405
15406         wait $pid1 || error "1st user deregister failed"
15407
15408         local i
15409         local last_rec
15410         declare -A LAST_REC
15411         for i in $(seq $MDSCOUNT); do
15412                 if changelog_users mds$i | grep "^cl"; then
15413                         # make sure new records are added with one user present
15414                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15415                                           awk '/^current.index:/ { print $NF }')
15416                 else
15417                         error "mds$i has no user registered"
15418                 fi
15419         done
15420
15421         # generate more changelog records to accumulate on each MDT
15422         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15423                 error "create $DIR/$tdir/${tfile}bis failed"
15424
15425         for i in $(seq $MDSCOUNT); do
15426                 last_rec=$(changelog_users $SINGLEMDS |
15427                            awk '/^current.index:/ { print $NF }')
15428                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15429                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15430                         error "changelogs are off on mds$i"
15431         done
15432 }
15433 run_test 160i "changelog user register/unregister race"
15434
15435 test_160j() {
15436         remote_mds_nodsh && skip "remote MDS with nodsh"
15437         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15438                 skip "Need MDS version at least 2.12.56"
15439
15440         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15441         stack_trap "umount $MOUNT2" EXIT
15442
15443         changelog_register || error "first changelog_register failed"
15444         stack_trap "changelog_deregister" EXIT
15445
15446         # generate some changelog
15447         # use all_char because created files should be evenly distributed
15448         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15449                 error "mkdir $tdir failed"
15450         for ((i = 0; i < MDSCOUNT; i++)); do
15451                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15452                         error "create $DIR/$tdir/d$i.1 failed"
15453         done
15454
15455         # open the changelog device
15456         exec 3>/dev/changelog-$FSNAME-MDT0000
15457         stack_trap "exec 3>&-" EXIT
15458         exec 4</dev/changelog-$FSNAME-MDT0000
15459         stack_trap "exec 4<&-" EXIT
15460
15461         # umount the first lustre mount
15462         umount $MOUNT
15463         stack_trap "mount_client $MOUNT" EXIT
15464
15465         # read changelog, which may or may not fail, but should not crash
15466         cat <&4 >/dev/null
15467
15468         # clear changelog
15469         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15470         changelog_users $SINGLEMDS | grep -q $cl_user ||
15471                 error "User $cl_user not found in changelog_users"
15472
15473         printf 'clear:'$cl_user':0' >&3
15474 }
15475 run_test 160j "client can be umounted while its chanangelog is being used"
15476
15477 test_160k() {
15478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15479         remote_mds_nodsh && skip "remote MDS with nodsh"
15480
15481         mkdir -p $DIR/$tdir/1/1
15482
15483         changelog_register || error "changelog_register failed"
15484         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15485
15486         changelog_users $SINGLEMDS | grep -q $cl_user ||
15487                 error "User '$cl_user' not found in changelog_users"
15488 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15489         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15490         rmdir $DIR/$tdir/1/1 & sleep 1
15491         mkdir $DIR/$tdir/2
15492         touch $DIR/$tdir/2/2
15493         rm -rf $DIR/$tdir/2
15494
15495         wait
15496         sleep 4
15497
15498         changelog_dump | grep rmdir || error "rmdir not recorded"
15499 }
15500 run_test 160k "Verify that changelog records are not lost"
15501
15502 # Verifies that a file passed as a parameter has recently had an operation
15503 # performed on it that has generated an MTIME changelog which contains the
15504 # correct parent FID. As files might reside on a different MDT from the
15505 # parent directory in DNE configurations, the FIDs are translated to paths
15506 # before being compared, which should be identical
15507 compare_mtime_changelog() {
15508         local file="${1}"
15509         local mdtidx
15510         local mtime
15511         local cl_fid
15512         local pdir
15513         local dir
15514
15515         mdtidx=$($LFS getstripe --mdt-index $file)
15516         mdtidx=$(printf "%04x" $mdtidx)
15517
15518         # Obtain the parent FID from the MTIME changelog
15519         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15520         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15521
15522         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15523         [ -z "$cl_fid" ] && error "parent FID not present"
15524
15525         # Verify that the path for the parent FID is the same as the path for
15526         # the test directory
15527         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15528
15529         dir=$(dirname $1)
15530
15531         [[ "${pdir%/}" == "$dir" ]] ||
15532                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15533 }
15534
15535 test_160l() {
15536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15537
15538         remote_mds_nodsh && skip "remote MDS with nodsh"
15539         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15540                 skip "Need MDS version at least 2.13.55"
15541
15542         local cl_user
15543
15544         changelog_register || error "changelog_register failed"
15545         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15546
15547         changelog_users $SINGLEMDS | grep -q $cl_user ||
15548                 error "User '$cl_user' not found in changelog_users"
15549
15550         # Clear some types so that MTIME changelogs are generated
15551         changelog_chmask "-CREAT"
15552         changelog_chmask "-CLOSE"
15553
15554         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15555
15556         # Test CL_MTIME during setattr
15557         touch $DIR/$tdir/$tfile
15558         compare_mtime_changelog $DIR/$tdir/$tfile
15559
15560         # Test CL_MTIME during close
15561         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15562         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15563 }
15564 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15565
15566 test_161a() {
15567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15568
15569         test_mkdir -c1 $DIR/$tdir
15570         cp /etc/hosts $DIR/$tdir/$tfile
15571         test_mkdir -c1 $DIR/$tdir/foo1
15572         test_mkdir -c1 $DIR/$tdir/foo2
15573         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15574         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15575         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15576         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15577         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15578         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15579                 $LFS fid2path $DIR $FID
15580                 error "bad link ea"
15581         fi
15582         # middle
15583         rm $DIR/$tdir/foo2/zachary
15584         # last
15585         rm $DIR/$tdir/foo2/thor
15586         # first
15587         rm $DIR/$tdir/$tfile
15588         # rename
15589         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15590         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15591                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15592         rm $DIR/$tdir/foo2/maggie
15593
15594         # overflow the EA
15595         local longname=$tfile.avg_len_is_thirty_two_
15596         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15597                 error_noexit 'failed to unlink many hardlinks'" EXIT
15598         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15599                 error "failed to hardlink many files"
15600         links=$($LFS fid2path $DIR $FID | wc -l)
15601         echo -n "${links}/1000 links in link EA"
15602         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15603 }
15604 run_test 161a "link ea sanity"
15605
15606 test_161b() {
15607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15608         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15609
15610         local MDTIDX=1
15611         local remote_dir=$DIR/$tdir/remote_dir
15612
15613         mkdir -p $DIR/$tdir
15614         $LFS mkdir -i $MDTIDX $remote_dir ||
15615                 error "create remote directory failed"
15616
15617         cp /etc/hosts $remote_dir/$tfile
15618         mkdir -p $remote_dir/foo1
15619         mkdir -p $remote_dir/foo2
15620         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15621         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15622         ln $remote_dir/$tfile $remote_dir/foo1/luna
15623         ln $remote_dir/$tfile $remote_dir/foo2/thor
15624
15625         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15626                      tr -d ']')
15627         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15628                 $LFS fid2path $DIR $FID
15629                 error "bad link ea"
15630         fi
15631         # middle
15632         rm $remote_dir/foo2/zachary
15633         # last
15634         rm $remote_dir/foo2/thor
15635         # first
15636         rm $remote_dir/$tfile
15637         # rename
15638         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15639         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15640         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15641                 $LFS fid2path $DIR $FID
15642                 error "bad link rename"
15643         fi
15644         rm $remote_dir/foo2/maggie
15645
15646         # overflow the EA
15647         local longname=filename_avg_len_is_thirty_two_
15648         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15649                 error "failed to hardlink many files"
15650         links=$($LFS fid2path $DIR $FID | wc -l)
15651         echo -n "${links}/1000 links in link EA"
15652         [[ ${links} -gt 60 ]] ||
15653                 error "expected at least 60 links in link EA"
15654         unlinkmany $remote_dir/foo2/$longname 1000 ||
15655         error "failed to unlink many hardlinks"
15656 }
15657 run_test 161b "link ea sanity under remote directory"
15658
15659 test_161c() {
15660         remote_mds_nodsh && skip "remote MDS with nodsh"
15661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15662         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15663                 skip "Need MDS version at least 2.1.5"
15664
15665         # define CLF_RENAME_LAST 0x0001
15666         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15667         changelog_register || error "changelog_register failed"
15668
15669         rm -rf $DIR/$tdir
15670         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15671         touch $DIR/$tdir/foo_161c
15672         touch $DIR/$tdir/bar_161c
15673         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15674         changelog_dump | grep RENME | tail -n 5
15675         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15676         changelog_clear 0 || error "changelog_clear failed"
15677         if [ x$flags != "x0x1" ]; then
15678                 error "flag $flags is not 0x1"
15679         fi
15680
15681         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15682         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15683         touch $DIR/$tdir/foo_161c
15684         touch $DIR/$tdir/bar_161c
15685         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15686         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15687         changelog_dump | grep RENME | tail -n 5
15688         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15689         changelog_clear 0 || error "changelog_clear failed"
15690         if [ x$flags != "x0x0" ]; then
15691                 error "flag $flags is not 0x0"
15692         fi
15693         echo "rename overwrite a target having nlink > 1," \
15694                 "changelog record has flags of $flags"
15695
15696         # rename doesn't overwrite a target (changelog flag 0x0)
15697         touch $DIR/$tdir/foo_161c
15698         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15699         changelog_dump | grep RENME | tail -n 5
15700         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15701         changelog_clear 0 || error "changelog_clear failed"
15702         if [ x$flags != "x0x0" ]; then
15703                 error "flag $flags is not 0x0"
15704         fi
15705         echo "rename doesn't overwrite a target," \
15706                 "changelog record has flags of $flags"
15707
15708         # define CLF_UNLINK_LAST 0x0001
15709         # unlink a file having nlink = 1 (changelog flag 0x1)
15710         rm -f $DIR/$tdir/foo2_161c
15711         changelog_dump | grep UNLNK | tail -n 5
15712         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15713         changelog_clear 0 || error "changelog_clear failed"
15714         if [ x$flags != "x0x1" ]; then
15715                 error "flag $flags is not 0x1"
15716         fi
15717         echo "unlink a file having nlink = 1," \
15718                 "changelog record has flags of $flags"
15719
15720         # unlink a file having nlink > 1 (changelog flag 0x0)
15721         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15722         rm -f $DIR/$tdir/foobar_161c
15723         changelog_dump | grep UNLNK | tail -n 5
15724         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15725         changelog_clear 0 || error "changelog_clear failed"
15726         if [ x$flags != "x0x0" ]; then
15727                 error "flag $flags is not 0x0"
15728         fi
15729         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15730 }
15731 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15732
15733 test_161d() {
15734         remote_mds_nodsh && skip "remote MDS with nodsh"
15735         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15736
15737         local pid
15738         local fid
15739
15740         changelog_register || error "changelog_register failed"
15741
15742         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15743         # interfer with $MOUNT/.lustre/fid/ access
15744         mkdir $DIR/$tdir
15745         [[ $? -eq 0 ]] || error "mkdir failed"
15746
15747         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15748         $LCTL set_param fail_loc=0x8000140c
15749         # 5s pause
15750         $LCTL set_param fail_val=5
15751
15752         # create file
15753         echo foofoo > $DIR/$tdir/$tfile &
15754         pid=$!
15755
15756         # wait for create to be delayed
15757         sleep 2
15758
15759         ps -p $pid
15760         [[ $? -eq 0 ]] || error "create should be blocked"
15761
15762         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15763         stack_trap "rm -f $tempfile"
15764         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15765         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15766         # some delay may occur during ChangeLog publishing and file read just
15767         # above, that could allow file write to happen finally
15768         [[ -s $tempfile ]] && echo "file should be empty"
15769
15770         $LCTL set_param fail_loc=0
15771
15772         wait $pid
15773         [[ $? -eq 0 ]] || error "create failed"
15774 }
15775 run_test 161d "create with concurrent .lustre/fid access"
15776
15777 check_path() {
15778         local expected="$1"
15779         shift
15780         local fid="$2"
15781
15782         local path
15783         path=$($LFS fid2path "$@")
15784         local rc=$?
15785
15786         if [ $rc -ne 0 ]; then
15787                 error "path looked up of '$expected' failed: rc=$rc"
15788         elif [ "$path" != "$expected" ]; then
15789                 error "path looked up '$path' instead of '$expected'"
15790         else
15791                 echo "FID '$fid' resolves to path '$path' as expected"
15792         fi
15793 }
15794
15795 test_162a() { # was test_162
15796         test_mkdir -p -c1 $DIR/$tdir/d2
15797         touch $DIR/$tdir/d2/$tfile
15798         touch $DIR/$tdir/d2/x1
15799         touch $DIR/$tdir/d2/x2
15800         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15801         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15802         # regular file
15803         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15804         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15805
15806         # softlink
15807         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15808         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15809         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15810
15811         # softlink to wrong file
15812         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15813         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15814         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15815
15816         # hardlink
15817         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15818         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15819         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15820         # fid2path dir/fsname should both work
15821         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15822         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15823
15824         # hardlink count: check that there are 2 links
15825         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15826         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15827
15828         # hardlink indexing: remove the first link
15829         rm $DIR/$tdir/d2/p/q/r/hlink
15830         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15831 }
15832 run_test 162a "path lookup sanity"
15833
15834 test_162b() {
15835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15836         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15837
15838         mkdir $DIR/$tdir
15839         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15840                                 error "create striped dir failed"
15841
15842         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15843                                         tail -n 1 | awk '{print $2}')
15844         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15845
15846         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15847         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15848
15849         # regular file
15850         for ((i=0;i<5;i++)); do
15851                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15852                         error "get fid for f$i failed"
15853                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15854
15855                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15856                         error "get fid for d$i failed"
15857                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15858         done
15859
15860         return 0
15861 }
15862 run_test 162b "striped directory path lookup sanity"
15863
15864 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15865 test_162c() {
15866         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15867                 skip "Need MDS version at least 2.7.51"
15868
15869         local lpath=$tdir.local
15870         local rpath=$tdir.remote
15871
15872         test_mkdir $DIR/$lpath
15873         test_mkdir $DIR/$rpath
15874
15875         for ((i = 0; i <= 101; i++)); do
15876                 lpath="$lpath/$i"
15877                 mkdir $DIR/$lpath
15878                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15879                         error "get fid for local directory $DIR/$lpath failed"
15880                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15881
15882                 rpath="$rpath/$i"
15883                 test_mkdir $DIR/$rpath
15884                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15885                         error "get fid for remote directory $DIR/$rpath failed"
15886                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15887         done
15888
15889         return 0
15890 }
15891 run_test 162c "fid2path works with paths 100 or more directories deep"
15892
15893 oalr_event_count() {
15894         local event="${1}"
15895         local trace="${2}"
15896
15897         awk -v name="${FSNAME}-OST0000" \
15898             -v event="${event}" \
15899             '$1 == "TRACE" && $2 == event && $3 == name' \
15900             "${trace}" |
15901         wc -l
15902 }
15903
15904 oalr_expect_event_count() {
15905         local event="${1}"
15906         local trace="${2}"
15907         local expect="${3}"
15908         local count
15909
15910         count=$(oalr_event_count "${event}" "${trace}")
15911         if ((count == expect)); then
15912                 return 0
15913         fi
15914
15915         error_noexit "${event} event count was '${count}', expected ${expect}"
15916         cat "${trace}" >&2
15917         exit 1
15918 }
15919
15920 cleanup_165() {
15921         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15922         stop ost1
15923         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15924 }
15925
15926 setup_165() {
15927         sync # Flush previous IOs so we can count log entries.
15928         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15929         stack_trap cleanup_165 EXIT
15930 }
15931
15932 test_165a() {
15933         local trace="/tmp/${tfile}.trace"
15934         local rc
15935         local count
15936
15937         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15938                 skip "OFD access log unsupported"
15939
15940         setup_165
15941         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15942         sleep 5
15943
15944         do_facet ost1 ofd_access_log_reader --list
15945         stop ost1
15946
15947         do_facet ost1 killall -TERM ofd_access_log_reader
15948         wait
15949         rc=$?
15950
15951         if ((rc != 0)); then
15952                 error "ofd_access_log_reader exited with rc = '${rc}'"
15953         fi
15954
15955         # Parse trace file for discovery events:
15956         oalr_expect_event_count alr_log_add "${trace}" 1
15957         oalr_expect_event_count alr_log_eof "${trace}" 1
15958         oalr_expect_event_count alr_log_free "${trace}" 1
15959 }
15960 run_test 165a "ofd access log discovery"
15961
15962 test_165b() {
15963         local trace="/tmp/${tfile}.trace"
15964         local file="${DIR}/${tfile}"
15965         local pfid1
15966         local pfid2
15967         local -a entry
15968         local rc
15969         local count
15970         local size
15971         local flags
15972
15973         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15974                 skip "OFD access log unsupported"
15975
15976         setup_165
15977         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15978         sleep 5
15979
15980         do_facet ost1 ofd_access_log_reader --list
15981
15982         lfs setstripe -c 1 -i 0 "${file}"
15983         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15984                 error "cannot create '${file}'"
15985
15986         sleep 5
15987         do_facet ost1 killall -TERM ofd_access_log_reader
15988         wait
15989         rc=$?
15990
15991         if ((rc != 0)); then
15992                 error "ofd_access_log_reader exited with rc = '${rc}'"
15993         fi
15994
15995         oalr_expect_event_count alr_log_entry "${trace}" 1
15996
15997         pfid1=$($LFS path2fid "${file}")
15998
15999         # 1     2             3   4    5     6   7    8    9     10
16000         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16001         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16002
16003         echo "entry = '${entry[*]}'" >&2
16004
16005         pfid2=${entry[4]}
16006         if [[ "${pfid1}" != "${pfid2}" ]]; then
16007                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16008         fi
16009
16010         size=${entry[8]}
16011         if ((size != 1048576)); then
16012                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16013         fi
16014
16015         flags=${entry[10]}
16016         if [[ "${flags}" != "w" ]]; then
16017                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16018         fi
16019
16020         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16021         sleep 5
16022
16023         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16024                 error "cannot read '${file}'"
16025         sleep 5
16026
16027         do_facet ost1 killall -TERM ofd_access_log_reader
16028         wait
16029         rc=$?
16030
16031         if ((rc != 0)); then
16032                 error "ofd_access_log_reader exited with rc = '${rc}'"
16033         fi
16034
16035         oalr_expect_event_count alr_log_entry "${trace}" 1
16036
16037         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16038         echo "entry = '${entry[*]}'" >&2
16039
16040         pfid2=${entry[4]}
16041         if [[ "${pfid1}" != "${pfid2}" ]]; then
16042                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16043         fi
16044
16045         size=${entry[8]}
16046         if ((size != 524288)); then
16047                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16048         fi
16049
16050         flags=${entry[10]}
16051         if [[ "${flags}" != "r" ]]; then
16052                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16053         fi
16054 }
16055 run_test 165b "ofd access log entries are produced and consumed"
16056
16057 test_165c() {
16058         local trace="/tmp/${tfile}.trace"
16059         local file="${DIR}/${tdir}/${tfile}"
16060
16061         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16062                 skip "OFD access log unsupported"
16063
16064         test_mkdir "${DIR}/${tdir}"
16065
16066         setup_165
16067         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16068         sleep 5
16069
16070         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16071
16072         # 4096 / 64 = 64. Create twice as many entries.
16073         for ((i = 0; i < 128; i++)); do
16074                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16075                         error "cannot create file"
16076         done
16077
16078         sync
16079
16080         do_facet ost1 killall -TERM ofd_access_log_reader
16081         wait
16082         rc=$?
16083         if ((rc != 0)); then
16084                 error "ofd_access_log_reader exited with rc = '${rc}'"
16085         fi
16086
16087         unlinkmany  "${file}-%d" 128
16088 }
16089 run_test 165c "full ofd access logs do not block IOs"
16090
16091 oal_get_read_count() {
16092         local stats="$1"
16093
16094         # STATS lustre-OST0001 alr_read_count 1
16095
16096         do_facet ost1 cat "${stats}" |
16097         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16098              END { print count; }'
16099 }
16100
16101 oal_expect_read_count() {
16102         local stats="$1"
16103         local count
16104         local expect="$2"
16105
16106         # Ask ofd_access_log_reader to write stats.
16107         do_facet ost1 killall -USR1 ofd_access_log_reader
16108
16109         # Allow some time for things to happen.
16110         sleep 1
16111
16112         count=$(oal_get_read_count "${stats}")
16113         if ((count == expect)); then
16114                 return 0
16115         fi
16116
16117         error_noexit "bad read count, got ${count}, expected ${expect}"
16118         do_facet ost1 cat "${stats}" >&2
16119         exit 1
16120 }
16121
16122 test_165d() {
16123         local stats="/tmp/${tfile}.stats"
16124         local file="${DIR}/${tdir}/${tfile}"
16125         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16126
16127         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16128                 skip "OFD access log unsupported"
16129
16130         test_mkdir "${DIR}/${tdir}"
16131
16132         setup_165
16133         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16134         sleep 5
16135
16136         lfs setstripe -c 1 -i 0 "${file}"
16137
16138         do_facet ost1 lctl set_param "${param}=rw"
16139         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16140                 error "cannot create '${file}'"
16141         oal_expect_read_count "${stats}" 1
16142
16143         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16144                 error "cannot read '${file}'"
16145         oal_expect_read_count "${stats}" 2
16146
16147         do_facet ost1 lctl set_param "${param}=r"
16148         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16149                 error "cannot create '${file}'"
16150         oal_expect_read_count "${stats}" 2
16151
16152         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16153                 error "cannot read '${file}'"
16154         oal_expect_read_count "${stats}" 3
16155
16156         do_facet ost1 lctl set_param "${param}=w"
16157         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16158                 error "cannot create '${file}'"
16159         oal_expect_read_count "${stats}" 4
16160
16161         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16162                 error "cannot read '${file}'"
16163         oal_expect_read_count "${stats}" 4
16164
16165         do_facet ost1 lctl set_param "${param}=0"
16166         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16167                 error "cannot create '${file}'"
16168         oal_expect_read_count "${stats}" 4
16169
16170         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16171                 error "cannot read '${file}'"
16172         oal_expect_read_count "${stats}" 4
16173
16174         do_facet ost1 killall -TERM ofd_access_log_reader
16175         wait
16176         rc=$?
16177         if ((rc != 0)); then
16178                 error "ofd_access_log_reader exited with rc = '${rc}'"
16179         fi
16180 }
16181 run_test 165d "ofd_access_log mask works"
16182
16183 test_165e() {
16184         local stats="/tmp/${tfile}.stats"
16185         local file0="${DIR}/${tdir}-0/${tfile}"
16186         local file1="${DIR}/${tdir}-1/${tfile}"
16187
16188         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16189                 skip "OFD access log unsupported"
16190
16191         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16192
16193         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16194         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16195
16196         lfs setstripe -c 1 -i 0 "${file0}"
16197         lfs setstripe -c 1 -i 0 "${file1}"
16198
16199         setup_165
16200         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16201         sleep 5
16202
16203         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16204                 error "cannot create '${file0}'"
16205         sync
16206         oal_expect_read_count "${stats}" 0
16207
16208         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16209                 error "cannot create '${file1}'"
16210         sync
16211         oal_expect_read_count "${stats}" 1
16212
16213         do_facet ost1 killall -TERM ofd_access_log_reader
16214         wait
16215         rc=$?
16216         if ((rc != 0)); then
16217                 error "ofd_access_log_reader exited with rc = '${rc}'"
16218         fi
16219 }
16220 run_test 165e "ofd_access_log MDT index filter works"
16221
16222 test_165f() {
16223         local trace="/tmp/${tfile}.trace"
16224         local rc
16225         local count
16226
16227         setup_165
16228         do_facet ost1 timeout 60 ofd_access_log_reader \
16229                 --exit-on-close --debug=- --trace=- > "${trace}" &
16230         sleep 5
16231         stop ost1
16232
16233         wait
16234         rc=$?
16235
16236         if ((rc != 0)); then
16237                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16238                 cat "${trace}"
16239                 exit 1
16240         fi
16241 }
16242 run_test 165f "ofd_access_log_reader --exit-on-close works"
16243
16244 test_169() {
16245         # do directio so as not to populate the page cache
16246         log "creating a 10 Mb file"
16247         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16248                 error "multiop failed while creating a file"
16249         log "starting reads"
16250         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16251         log "truncating the file"
16252         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16253                 error "multiop failed while truncating the file"
16254         log "killing dd"
16255         kill %+ || true # reads might have finished
16256         echo "wait until dd is finished"
16257         wait
16258         log "removing the temporary file"
16259         rm -rf $DIR/$tfile || error "tmp file removal failed"
16260 }
16261 run_test 169 "parallel read and truncate should not deadlock"
16262
16263 test_170() {
16264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16265
16266         $LCTL clear     # bug 18514
16267         $LCTL debug_daemon start $TMP/${tfile}_log_good
16268         touch $DIR/$tfile
16269         $LCTL debug_daemon stop
16270         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16271                 error "sed failed to read log_good"
16272
16273         $LCTL debug_daemon start $TMP/${tfile}_log_good
16274         rm -rf $DIR/$tfile
16275         $LCTL debug_daemon stop
16276
16277         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16278                error "lctl df log_bad failed"
16279
16280         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16281         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16282
16283         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16284         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16285
16286         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16287                 error "bad_line good_line1 good_line2 are empty"
16288
16289         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16290         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16291         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16292
16293         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16294         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16295         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16296
16297         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16298                 error "bad_line_new good_line_new are empty"
16299
16300         local expected_good=$((good_line1 + good_line2*2))
16301
16302         rm -f $TMP/${tfile}*
16303         # LU-231, short malformed line may not be counted into bad lines
16304         if [ $bad_line -ne $bad_line_new ] &&
16305                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16306                 error "expected $bad_line bad lines, but got $bad_line_new"
16307                 return 1
16308         fi
16309
16310         if [ $expected_good -ne $good_line_new ]; then
16311                 error "expected $expected_good good lines, but got $good_line_new"
16312                 return 2
16313         fi
16314         true
16315 }
16316 run_test 170 "test lctl df to handle corrupted log ====================="
16317
16318 test_171() { # bug20592
16319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16320
16321         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16322         $LCTL set_param fail_loc=0x50e
16323         $LCTL set_param fail_val=3000
16324         multiop_bg_pause $DIR/$tfile O_s || true
16325         local MULTIPID=$!
16326         kill -USR1 $MULTIPID
16327         # cause log dump
16328         sleep 3
16329         wait $MULTIPID
16330         if dmesg | grep "recursive fault"; then
16331                 error "caught a recursive fault"
16332         fi
16333         $LCTL set_param fail_loc=0
16334         true
16335 }
16336 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16337
16338 # it would be good to share it with obdfilter-survey/iokit-libecho code
16339 setup_obdecho_osc () {
16340         local rc=0
16341         local ost_nid=$1
16342         local obdfilter_name=$2
16343         echo "Creating new osc for $obdfilter_name on $ost_nid"
16344         # make sure we can find loopback nid
16345         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16346
16347         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16348                            ${obdfilter_name}_osc_UUID || rc=2; }
16349         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16350                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16351         return $rc
16352 }
16353
16354 cleanup_obdecho_osc () {
16355         local obdfilter_name=$1
16356         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16357         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16358         return 0
16359 }
16360
16361 obdecho_test() {
16362         local OBD=$1
16363         local node=$2
16364         local pages=${3:-64}
16365         local rc=0
16366         local id
16367
16368         local count=10
16369         local obd_size=$(get_obd_size $node $OBD)
16370         local page_size=$(get_page_size $node)
16371         if [[ -n "$obd_size" ]]; then
16372                 local new_count=$((obd_size / (pages * page_size / 1024)))
16373                 [[ $new_count -ge $count ]] || count=$new_count
16374         fi
16375
16376         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16377         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16378                            rc=2; }
16379         if [ $rc -eq 0 ]; then
16380             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16381             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16382         fi
16383         echo "New object id is $id"
16384         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16385                            rc=4; }
16386         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16387                            "test_brw $count w v $pages $id" || rc=4; }
16388         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16389                            rc=4; }
16390         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16391                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16392         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16393                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16394         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16395         return $rc
16396 }
16397
16398 test_180a() {
16399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16400
16401         if ! [ -d /sys/fs/lustre/echo_client ] &&
16402            ! module_loaded obdecho; then
16403                 load_module obdecho/obdecho &&
16404                         stack_trap "rmmod obdecho" EXIT ||
16405                         error "unable to load obdecho on client"
16406         fi
16407
16408         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16409         local host=$($LCTL get_param -n osc.$osc.import |
16410                      awk '/current_connection:/ { print $2 }' )
16411         local target=$($LCTL get_param -n osc.$osc.import |
16412                        awk '/target:/ { print $2 }' )
16413         target=${target%_UUID}
16414
16415         if [ -n "$target" ]; then
16416                 setup_obdecho_osc $host $target &&
16417                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16418                         { error "obdecho setup failed with $?"; return; }
16419
16420                 obdecho_test ${target}_osc client ||
16421                         error "obdecho_test failed on ${target}_osc"
16422         else
16423                 $LCTL get_param osc.$osc.import
16424                 error "there is no osc.$osc.import target"
16425         fi
16426 }
16427 run_test 180a "test obdecho on osc"
16428
16429 test_180b() {
16430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16431         remote_ost_nodsh && skip "remote OST with nodsh"
16432
16433         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16434                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16435                 error "failed to load module obdecho"
16436
16437         local target=$(do_facet ost1 $LCTL dl |
16438                        awk '/obdfilter/ { print $4; exit; }')
16439
16440         if [ -n "$target" ]; then
16441                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16442         else
16443                 do_facet ost1 $LCTL dl
16444                 error "there is no obdfilter target on ost1"
16445         fi
16446 }
16447 run_test 180b "test obdecho directly on obdfilter"
16448
16449 test_180c() { # LU-2598
16450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16451         remote_ost_nodsh && skip "remote OST with nodsh"
16452         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16453                 skip "Need MDS version at least 2.4.0"
16454
16455         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16456                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16457                 error "failed to load module obdecho"
16458
16459         local target=$(do_facet ost1 $LCTL dl |
16460                        awk '/obdfilter/ { print $4; exit; }')
16461
16462         if [ -n "$target" ]; then
16463                 local pages=16384 # 64MB bulk I/O RPC size
16464
16465                 obdecho_test "$target" ost1 "$pages" ||
16466                         error "obdecho_test with pages=$pages failed with $?"
16467         else
16468                 do_facet ost1 $LCTL dl
16469                 error "there is no obdfilter target on ost1"
16470         fi
16471 }
16472 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16473
16474 test_181() { # bug 22177
16475         test_mkdir $DIR/$tdir
16476         # create enough files to index the directory
16477         createmany -o $DIR/$tdir/foobar 4000
16478         # print attributes for debug purpose
16479         lsattr -d .
16480         # open dir
16481         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16482         MULTIPID=$!
16483         # remove the files & current working dir
16484         unlinkmany $DIR/$tdir/foobar 4000
16485         rmdir $DIR/$tdir
16486         kill -USR1 $MULTIPID
16487         wait $MULTIPID
16488         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16489         return 0
16490 }
16491 run_test 181 "Test open-unlinked dir ========================"
16492
16493 test_182() {
16494         local fcount=1000
16495         local tcount=10
16496
16497         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16498
16499         $LCTL set_param mdc.*.rpc_stats=clear
16500
16501         for (( i = 0; i < $tcount; i++ )) ; do
16502                 mkdir $DIR/$tdir/$i
16503         done
16504
16505         for (( i = 0; i < $tcount; i++ )) ; do
16506                 createmany -o $DIR/$tdir/$i/f- $fcount &
16507         done
16508         wait
16509
16510         for (( i = 0; i < $tcount; i++ )) ; do
16511                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16512         done
16513         wait
16514
16515         $LCTL get_param mdc.*.rpc_stats
16516
16517         rm -rf $DIR/$tdir
16518 }
16519 run_test 182 "Test parallel modify metadata operations ================"
16520
16521 test_183() { # LU-2275
16522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16523         remote_mds_nodsh && skip "remote MDS with nodsh"
16524         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16525                 skip "Need MDS version at least 2.3.56"
16526
16527         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16528         echo aaa > $DIR/$tdir/$tfile
16529
16530 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16531         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16532
16533         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16534         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16535
16536         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16537
16538         # Flush negative dentry cache
16539         touch $DIR/$tdir/$tfile
16540
16541         # We are not checking for any leaked references here, they'll
16542         # become evident next time we do cleanup with module unload.
16543         rm -rf $DIR/$tdir
16544 }
16545 run_test 183 "No crash or request leak in case of strange dispositions ========"
16546
16547 # test suite 184 is for LU-2016, LU-2017
16548 test_184a() {
16549         check_swap_layouts_support
16550
16551         dir0=$DIR/$tdir/$testnum
16552         test_mkdir -p -c1 $dir0
16553         ref1=/etc/passwd
16554         ref2=/etc/group
16555         file1=$dir0/f1
16556         file2=$dir0/f2
16557         $LFS setstripe -c1 $file1
16558         cp $ref1 $file1
16559         $LFS setstripe -c2 $file2
16560         cp $ref2 $file2
16561         gen1=$($LFS getstripe -g $file1)
16562         gen2=$($LFS getstripe -g $file2)
16563
16564         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16565         gen=$($LFS getstripe -g $file1)
16566         [[ $gen1 != $gen ]] ||
16567                 "Layout generation on $file1 does not change"
16568         gen=$($LFS getstripe -g $file2)
16569         [[ $gen2 != $gen ]] ||
16570                 "Layout generation on $file2 does not change"
16571
16572         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16573         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16574
16575         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16576 }
16577 run_test 184a "Basic layout swap"
16578
16579 test_184b() {
16580         check_swap_layouts_support
16581
16582         dir0=$DIR/$tdir/$testnum
16583         mkdir -p $dir0 || error "creating dir $dir0"
16584         file1=$dir0/f1
16585         file2=$dir0/f2
16586         file3=$dir0/f3
16587         dir1=$dir0/d1
16588         dir2=$dir0/d2
16589         mkdir $dir1 $dir2
16590         $LFS setstripe -c1 $file1
16591         $LFS setstripe -c2 $file2
16592         $LFS setstripe -c1 $file3
16593         chown $RUNAS_ID $file3
16594         gen1=$($LFS getstripe -g $file1)
16595         gen2=$($LFS getstripe -g $file2)
16596
16597         $LFS swap_layouts $dir1 $dir2 &&
16598                 error "swap of directories layouts should fail"
16599         $LFS swap_layouts $dir1 $file1 &&
16600                 error "swap of directory and file layouts should fail"
16601         $RUNAS $LFS swap_layouts $file1 $file2 &&
16602                 error "swap of file we cannot write should fail"
16603         $LFS swap_layouts $file1 $file3 &&
16604                 error "swap of file with different owner should fail"
16605         /bin/true # to clear error code
16606 }
16607 run_test 184b "Forbidden layout swap (will generate errors)"
16608
16609 test_184c() {
16610         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16611         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16612         check_swap_layouts_support
16613         check_swap_layout_no_dom $DIR
16614
16615         local dir0=$DIR/$tdir/$testnum
16616         mkdir -p $dir0 || error "creating dir $dir0"
16617
16618         local ref1=$dir0/ref1
16619         local ref2=$dir0/ref2
16620         local file1=$dir0/file1
16621         local file2=$dir0/file2
16622         # create a file large enough for the concurrent test
16623         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16624         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16625         echo "ref file size: ref1($(stat -c %s $ref1))," \
16626              "ref2($(stat -c %s $ref2))"
16627
16628         cp $ref2 $file2
16629         dd if=$ref1 of=$file1 bs=16k &
16630         local DD_PID=$!
16631
16632         # Make sure dd starts to copy file, but wait at most 5 seconds
16633         local loops=0
16634         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16635
16636         $LFS swap_layouts $file1 $file2
16637         local rc=$?
16638         wait $DD_PID
16639         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16640         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16641
16642         # how many bytes copied before swapping layout
16643         local copied=$(stat -c %s $file2)
16644         local remaining=$(stat -c %s $ref1)
16645         remaining=$((remaining - copied))
16646         echo "Copied $copied bytes before swapping layout..."
16647
16648         cmp -n $copied $file1 $ref2 | grep differ &&
16649                 error "Content mismatch [0, $copied) of ref2 and file1"
16650         cmp -n $copied $file2 $ref1 ||
16651                 error "Content mismatch [0, $copied) of ref1 and file2"
16652         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16653                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16654
16655         # clean up
16656         rm -f $ref1 $ref2 $file1 $file2
16657 }
16658 run_test 184c "Concurrent write and layout swap"
16659
16660 test_184d() {
16661         check_swap_layouts_support
16662         check_swap_layout_no_dom $DIR
16663         [ -z "$(which getfattr 2>/dev/null)" ] &&
16664                 skip_env "no getfattr command"
16665
16666         local file1=$DIR/$tdir/$tfile-1
16667         local file2=$DIR/$tdir/$tfile-2
16668         local file3=$DIR/$tdir/$tfile-3
16669         local lovea1
16670         local lovea2
16671
16672         mkdir -p $DIR/$tdir
16673         touch $file1 || error "create $file1 failed"
16674         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16675                 error "create $file2 failed"
16676         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16677                 error "create $file3 failed"
16678         lovea1=$(get_layout_param $file1)
16679
16680         $LFS swap_layouts $file2 $file3 ||
16681                 error "swap $file2 $file3 layouts failed"
16682         $LFS swap_layouts $file1 $file2 ||
16683                 error "swap $file1 $file2 layouts failed"
16684
16685         lovea2=$(get_layout_param $file2)
16686         echo "$lovea1"
16687         echo "$lovea2"
16688         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16689
16690         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16691         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16692 }
16693 run_test 184d "allow stripeless layouts swap"
16694
16695 test_184e() {
16696         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16697                 skip "Need MDS version at least 2.6.94"
16698         check_swap_layouts_support
16699         check_swap_layout_no_dom $DIR
16700         [ -z "$(which getfattr 2>/dev/null)" ] &&
16701                 skip_env "no getfattr command"
16702
16703         local file1=$DIR/$tdir/$tfile-1
16704         local file2=$DIR/$tdir/$tfile-2
16705         local file3=$DIR/$tdir/$tfile-3
16706         local lovea
16707
16708         mkdir -p $DIR/$tdir
16709         touch $file1 || error "create $file1 failed"
16710         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16711                 error "create $file2 failed"
16712         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16713                 error "create $file3 failed"
16714
16715         $LFS swap_layouts $file1 $file2 ||
16716                 error "swap $file1 $file2 layouts failed"
16717
16718         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16719         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16720
16721         echo 123 > $file1 || error "Should be able to write into $file1"
16722
16723         $LFS swap_layouts $file1 $file3 ||
16724                 error "swap $file1 $file3 layouts failed"
16725
16726         echo 123 > $file1 || error "Should be able to write into $file1"
16727
16728         rm -rf $file1 $file2 $file3
16729 }
16730 run_test 184e "Recreate layout after stripeless layout swaps"
16731
16732 test_184f() {
16733         # Create a file with name longer than sizeof(struct stat) ==
16734         # 144 to see if we can get chars from the file name to appear
16735         # in the returned striping. Note that 'f' == 0x66.
16736         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16737
16738         mkdir -p $DIR/$tdir
16739         mcreate $DIR/$tdir/$file
16740         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16741                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16742         fi
16743 }
16744 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16745
16746 test_185() { # LU-2441
16747         # LU-3553 - no volatile file support in old servers
16748         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16749                 skip "Need MDS version at least 2.3.60"
16750
16751         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16752         touch $DIR/$tdir/spoo
16753         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16754         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16755                 error "cannot create/write a volatile file"
16756         [ "$FILESET" == "" ] &&
16757         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16758                 error "FID is still valid after close"
16759
16760         multiop_bg_pause $DIR/$tdir vVw4096_c
16761         local multi_pid=$!
16762
16763         local OLD_IFS=$IFS
16764         IFS=":"
16765         local fidv=($fid)
16766         IFS=$OLD_IFS
16767         # assume that the next FID for this client is sequential, since stdout
16768         # is unfortunately eaten by multiop_bg_pause
16769         local n=$((${fidv[1]} + 1))
16770         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16771         if [ "$FILESET" == "" ]; then
16772                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16773                         error "FID is missing before close"
16774         fi
16775         kill -USR1 $multi_pid
16776         # 1 second delay, so if mtime change we will see it
16777         sleep 1
16778         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16779         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16780 }
16781 run_test 185 "Volatile file support"
16782
16783 function create_check_volatile() {
16784         local idx=$1
16785         local tgt
16786
16787         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16788         local PID=$!
16789         sleep 1
16790         local FID=$(cat /tmp/${tfile}.fid)
16791         [ "$FID" == "" ] && error "can't get FID for volatile"
16792         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16793         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16794         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16795         kill -USR1 $PID
16796         wait
16797         sleep 1
16798         cancel_lru_locks mdc # flush opencache
16799         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16800         return 0
16801 }
16802
16803 test_185a(){
16804         # LU-12516 - volatile creation via .lustre
16805         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16806                 skip "Need MDS version at least 2.3.55"
16807
16808         create_check_volatile 0
16809         [ $MDSCOUNT -lt 2 ] && return 0
16810
16811         # DNE case
16812         create_check_volatile 1
16813
16814         return 0
16815 }
16816 run_test 185a "Volatile file creation in .lustre/fid/"
16817
16818 test_187a() {
16819         remote_mds_nodsh && skip "remote MDS with nodsh"
16820         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16821                 skip "Need MDS version at least 2.3.0"
16822
16823         local dir0=$DIR/$tdir/$testnum
16824         mkdir -p $dir0 || error "creating dir $dir0"
16825
16826         local file=$dir0/file1
16827         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16828         local dv1=$($LFS data_version $file)
16829         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16830         local dv2=$($LFS data_version $file)
16831         [[ $dv1 != $dv2 ]] ||
16832                 error "data version did not change on write $dv1 == $dv2"
16833
16834         # clean up
16835         rm -f $file1
16836 }
16837 run_test 187a "Test data version change"
16838
16839 test_187b() {
16840         remote_mds_nodsh && skip "remote MDS with nodsh"
16841         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16842                 skip "Need MDS version at least 2.3.0"
16843
16844         local dir0=$DIR/$tdir/$testnum
16845         mkdir -p $dir0 || error "creating dir $dir0"
16846
16847         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16848         [[ ${DV[0]} != ${DV[1]} ]] ||
16849                 error "data version did not change on write"\
16850                       " ${DV[0]} == ${DV[1]}"
16851
16852         # clean up
16853         rm -f $file1
16854 }
16855 run_test 187b "Test data version change on volatile file"
16856
16857 test_200() {
16858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16859         remote_mgs_nodsh && skip "remote MGS with nodsh"
16860         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16861
16862         local POOL=${POOL:-cea1}
16863         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16864         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16865         # Pool OST targets
16866         local first_ost=0
16867         local last_ost=$(($OSTCOUNT - 1))
16868         local ost_step=2
16869         local ost_list=$(seq $first_ost $ost_step $last_ost)
16870         local ost_range="$first_ost $last_ost $ost_step"
16871         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16872         local file_dir=$POOL_ROOT/file_tst
16873         local subdir=$test_path/subdir
16874         local rc=0
16875
16876         while : ; do
16877                 # former test_200a test_200b
16878                 pool_add $POOL                          || { rc=$? ; break; }
16879                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16880                 # former test_200c test_200d
16881                 mkdir -p $test_path
16882                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16883                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16884                 mkdir -p $subdir
16885                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16886                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16887                                                         || { rc=$? ; break; }
16888                 # former test_200e test_200f
16889                 local files=$((OSTCOUNT*3))
16890                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16891                                                         || { rc=$? ; break; }
16892                 pool_create_files $POOL $file_dir $files "$ost_list" \
16893                                                         || { rc=$? ; break; }
16894                 # former test_200g test_200h
16895                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16896                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16897
16898                 # former test_201a test_201b test_201c
16899                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16900
16901                 local f=$test_path/$tfile
16902                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16903                 pool_remove $POOL $f                    || { rc=$? ; break; }
16904                 break
16905         done
16906
16907         destroy_test_pools
16908
16909         return $rc
16910 }
16911 run_test 200 "OST pools"
16912
16913 # usage: default_attr <count | size | offset>
16914 default_attr() {
16915         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16916 }
16917
16918 # usage: check_default_stripe_attr
16919 check_default_stripe_attr() {
16920         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16921         case $1 in
16922         --stripe-count|-c)
16923                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16924         --stripe-size|-S)
16925                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16926         --stripe-index|-i)
16927                 EXPECTED=-1;;
16928         *)
16929                 error "unknown getstripe attr '$1'"
16930         esac
16931
16932         [ $ACTUAL == $EXPECTED ] ||
16933                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16934 }
16935
16936 test_204a() {
16937         test_mkdir $DIR/$tdir
16938         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16939
16940         check_default_stripe_attr --stripe-count
16941         check_default_stripe_attr --stripe-size
16942         check_default_stripe_attr --stripe-index
16943 }
16944 run_test 204a "Print default stripe attributes"
16945
16946 test_204b() {
16947         test_mkdir $DIR/$tdir
16948         $LFS setstripe --stripe-count 1 $DIR/$tdir
16949
16950         check_default_stripe_attr --stripe-size
16951         check_default_stripe_attr --stripe-index
16952 }
16953 run_test 204b "Print default stripe size and offset"
16954
16955 test_204c() {
16956         test_mkdir $DIR/$tdir
16957         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16958
16959         check_default_stripe_attr --stripe-count
16960         check_default_stripe_attr --stripe-index
16961 }
16962 run_test 204c "Print default stripe count and offset"
16963
16964 test_204d() {
16965         test_mkdir $DIR/$tdir
16966         $LFS setstripe --stripe-index 0 $DIR/$tdir
16967
16968         check_default_stripe_attr --stripe-count
16969         check_default_stripe_attr --stripe-size
16970 }
16971 run_test 204d "Print default stripe count and size"
16972
16973 test_204e() {
16974         test_mkdir $DIR/$tdir
16975         $LFS setstripe -d $DIR/$tdir
16976
16977         check_default_stripe_attr --stripe-count --raw
16978         check_default_stripe_attr --stripe-size --raw
16979         check_default_stripe_attr --stripe-index --raw
16980 }
16981 run_test 204e "Print raw stripe attributes"
16982
16983 test_204f() {
16984         test_mkdir $DIR/$tdir
16985         $LFS setstripe --stripe-count 1 $DIR/$tdir
16986
16987         check_default_stripe_attr --stripe-size --raw
16988         check_default_stripe_attr --stripe-index --raw
16989 }
16990 run_test 204f "Print raw stripe size and offset"
16991
16992 test_204g() {
16993         test_mkdir $DIR/$tdir
16994         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16995
16996         check_default_stripe_attr --stripe-count --raw
16997         check_default_stripe_attr --stripe-index --raw
16998 }
16999 run_test 204g "Print raw stripe count and offset"
17000
17001 test_204h() {
17002         test_mkdir $DIR/$tdir
17003         $LFS setstripe --stripe-index 0 $DIR/$tdir
17004
17005         check_default_stripe_attr --stripe-count --raw
17006         check_default_stripe_attr --stripe-size --raw
17007 }
17008 run_test 204h "Print raw stripe count and size"
17009
17010 # Figure out which job scheduler is being used, if any,
17011 # or use a fake one
17012 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17013         JOBENV=SLURM_JOB_ID
17014 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17015         JOBENV=LSB_JOBID
17016 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17017         JOBENV=PBS_JOBID
17018 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17019         JOBENV=LOADL_STEP_ID
17020 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17021         JOBENV=JOB_ID
17022 else
17023         $LCTL list_param jobid_name > /dev/null 2>&1
17024         if [ $? -eq 0 ]; then
17025                 JOBENV=nodelocal
17026         else
17027                 JOBENV=FAKE_JOBID
17028         fi
17029 fi
17030 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17031
17032 verify_jobstats() {
17033         local cmd=($1)
17034         shift
17035         local facets="$@"
17036
17037 # we don't really need to clear the stats for this test to work, since each
17038 # command has a unique jobid, but it makes debugging easier if needed.
17039 #       for facet in $facets; do
17040 #               local dev=$(convert_facet2label $facet)
17041 #               # clear old jobstats
17042 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17043 #       done
17044
17045         # use a new JobID for each test, or we might see an old one
17046         [ "$JOBENV" = "FAKE_JOBID" ] &&
17047                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17048
17049         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17050
17051         [ "$JOBENV" = "nodelocal" ] && {
17052                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17053                 $LCTL set_param jobid_name=$FAKE_JOBID
17054                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17055         }
17056
17057         log "Test: ${cmd[*]}"
17058         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17059
17060         if [ $JOBENV = "FAKE_JOBID" ]; then
17061                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17062         else
17063                 ${cmd[*]}
17064         fi
17065
17066         # all files are created on OST0000
17067         for facet in $facets; do
17068                 local stats="*.$(convert_facet2label $facet).job_stats"
17069
17070                 # strip out libtool wrappers for in-tree executables
17071                 if [ $(do_facet $facet lctl get_param $stats |
17072                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17073                         do_facet $facet lctl get_param $stats
17074                         error "No jobstats for $JOBVAL found on $facet::$stats"
17075                 fi
17076         done
17077 }
17078
17079 jobstats_set() {
17080         local new_jobenv=$1
17081
17082         set_persistent_param_and_check client "jobid_var" \
17083                 "$FSNAME.sys.jobid_var" $new_jobenv
17084 }
17085
17086 test_205a() { # Job stats
17087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17088         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17089                 skip "Need MDS version with at least 2.7.1"
17090         remote_mgs_nodsh && skip "remote MGS with nodsh"
17091         remote_mds_nodsh && skip "remote MDS with nodsh"
17092         remote_ost_nodsh && skip "remote OST with nodsh"
17093         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17094                 skip "Server doesn't support jobstats"
17095         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17096
17097         local old_jobenv=$($LCTL get_param -n jobid_var)
17098         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17099
17100         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17101                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17102         else
17103                 stack_trap "do_facet mgs $PERM_CMD \
17104                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17105         fi
17106         changelog_register
17107
17108         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17109                                 mdt.*.job_cleanup_interval | head -n 1)
17110         local new_interval=5
17111         do_facet $SINGLEMDS \
17112                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17113         stack_trap "do_facet $SINGLEMDS \
17114                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17115         local start=$SECONDS
17116
17117         local cmd
17118         # mkdir
17119         cmd="mkdir $DIR/$tdir"
17120         verify_jobstats "$cmd" "$SINGLEMDS"
17121         # rmdir
17122         cmd="rmdir $DIR/$tdir"
17123         verify_jobstats "$cmd" "$SINGLEMDS"
17124         # mkdir on secondary MDT
17125         if [ $MDSCOUNT -gt 1 ]; then
17126                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17127                 verify_jobstats "$cmd" "mds2"
17128         fi
17129         # mknod
17130         cmd="mknod $DIR/$tfile c 1 3"
17131         verify_jobstats "$cmd" "$SINGLEMDS"
17132         # unlink
17133         cmd="rm -f $DIR/$tfile"
17134         verify_jobstats "$cmd" "$SINGLEMDS"
17135         # create all files on OST0000 so verify_jobstats can find OST stats
17136         # open & close
17137         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17138         verify_jobstats "$cmd" "$SINGLEMDS"
17139         # setattr
17140         cmd="touch $DIR/$tfile"
17141         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17142         # write
17143         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17144         verify_jobstats "$cmd" "ost1"
17145         # read
17146         cancel_lru_locks osc
17147         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17148         verify_jobstats "$cmd" "ost1"
17149         # truncate
17150         cmd="$TRUNCATE $DIR/$tfile 0"
17151         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17152         # rename
17153         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17154         verify_jobstats "$cmd" "$SINGLEMDS"
17155         # jobstats expiry - sleep until old stats should be expired
17156         local left=$((new_interval + 5 - (SECONDS - start)))
17157         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17158                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17159                         "0" $left
17160         cmd="mkdir $DIR/$tdir.expire"
17161         verify_jobstats "$cmd" "$SINGLEMDS"
17162         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17163             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17164
17165         # Ensure that jobid are present in changelog (if supported by MDS)
17166         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17167                 changelog_dump | tail -10
17168                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17169                 [ $jobids -eq 9 ] ||
17170                         error "Wrong changelog jobid count $jobids != 9"
17171
17172                 # LU-5862
17173                 JOBENV="disable"
17174                 jobstats_set $JOBENV
17175                 touch $DIR/$tfile
17176                 changelog_dump | grep $tfile
17177                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17178                 [ $jobids -eq 0 ] ||
17179                         error "Unexpected jobids when jobid_var=$JOBENV"
17180         fi
17181
17182         # test '%j' access to environment variable - if supported
17183         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17184                 JOBENV="JOBCOMPLEX"
17185                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17186
17187                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17188         fi
17189
17190         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17191                 JOBENV="JOBCOMPLEX"
17192                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17193
17194                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17195         fi
17196
17197         # test '%j' access to per-session jobid - if supported
17198         if lctl list_param jobid_this_session > /dev/null 2>&1
17199         then
17200                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17201                 lctl set_param jobid_this_session=$USER
17202
17203                 JOBENV="JOBCOMPLEX"
17204                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17205
17206                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17207         fi
17208 }
17209 run_test 205a "Verify job stats"
17210
17211 # LU-13117, LU-13597
17212 test_205b() {
17213         job_stats="mdt.*.job_stats"
17214         $LCTL set_param $job_stats=clear
17215         # Setting jobid_var to USER might not be supported
17216         $LCTL set_param jobid_var=USER || true
17217         $LCTL set_param jobid_name="%e.%u"
17218         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17219         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17220                 grep "job_id:.*foolish" &&
17221                         error "Unexpected jobid found"
17222         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17223                 grep "open:.*min.*max.*sum" ||
17224                         error "wrong job_stats format found"
17225 }
17226 run_test 205b "Verify job stats jobid and output format"
17227
17228 # LU-13733
17229 test_205c() {
17230         $LCTL set_param llite.*.stats=0
17231         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17232         $LCTL get_param llite.*.stats
17233         $LCTL get_param llite.*.stats | grep \
17234                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17235                         error "wrong client stats format found"
17236 }
17237 run_test 205c "Verify client stats format"
17238
17239 # LU-1480, LU-1773 and LU-1657
17240 test_206() {
17241         mkdir -p $DIR/$tdir
17242         $LFS setstripe -c -1 $DIR/$tdir
17243 #define OBD_FAIL_LOV_INIT 0x1403
17244         $LCTL set_param fail_loc=0xa0001403
17245         $LCTL set_param fail_val=1
17246         touch $DIR/$tdir/$tfile || true
17247 }
17248 run_test 206 "fail lov_init_raid0() doesn't lbug"
17249
17250 test_207a() {
17251         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17252         local fsz=`stat -c %s $DIR/$tfile`
17253         cancel_lru_locks mdc
17254
17255         # do not return layout in getattr intent
17256 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17257         $LCTL set_param fail_loc=0x170
17258         local sz=`stat -c %s $DIR/$tfile`
17259
17260         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17261
17262         rm -rf $DIR/$tfile
17263 }
17264 run_test 207a "can refresh layout at glimpse"
17265
17266 test_207b() {
17267         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17268         local cksum=`md5sum $DIR/$tfile`
17269         local fsz=`stat -c %s $DIR/$tfile`
17270         cancel_lru_locks mdc
17271         cancel_lru_locks osc
17272
17273         # do not return layout in getattr intent
17274 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17275         $LCTL set_param fail_loc=0x171
17276
17277         # it will refresh layout after the file is opened but before read issues
17278         echo checksum is "$cksum"
17279         echo "$cksum" |md5sum -c --quiet || error "file differs"
17280
17281         rm -rf $DIR/$tfile
17282 }
17283 run_test 207b "can refresh layout at open"
17284
17285 test_208() {
17286         # FIXME: in this test suite, only RD lease is used. This is okay
17287         # for now as only exclusive open is supported. After generic lease
17288         # is done, this test suite should be revised. - Jinshan
17289
17290         remote_mds_nodsh && skip "remote MDS with nodsh"
17291         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17292                 skip "Need MDS version at least 2.4.52"
17293
17294         echo "==== test 1: verify get lease work"
17295         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17296
17297         echo "==== test 2: verify lease can be broken by upcoming open"
17298         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17299         local PID=$!
17300         sleep 1
17301
17302         $MULTIOP $DIR/$tfile oO_RDONLY:c
17303         kill -USR1 $PID && wait $PID || error "break lease error"
17304
17305         echo "==== test 3: verify lease can't be granted if an open already exists"
17306         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17307         local PID=$!
17308         sleep 1
17309
17310         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17311         kill -USR1 $PID && wait $PID || error "open file error"
17312
17313         echo "==== test 4: lease can sustain over recovery"
17314         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17315         PID=$!
17316         sleep 1
17317
17318         fail mds1
17319
17320         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17321
17322         echo "==== test 5: lease broken can't be regained by replay"
17323         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17324         PID=$!
17325         sleep 1
17326
17327         # open file to break lease and then recovery
17328         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17329         fail mds1
17330
17331         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17332
17333         rm -f $DIR/$tfile
17334 }
17335 run_test 208 "Exclusive open"
17336
17337 test_209() {
17338         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17339                 skip_env "must have disp_stripe"
17340
17341         touch $DIR/$tfile
17342         sync; sleep 5; sync;
17343
17344         echo 3 > /proc/sys/vm/drop_caches
17345         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17346                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17347         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17348
17349         # open/close 500 times
17350         for i in $(seq 500); do
17351                 cat $DIR/$tfile
17352         done
17353
17354         echo 3 > /proc/sys/vm/drop_caches
17355         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17356                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17357         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17358
17359         echo "before: $req_before, after: $req_after"
17360         [ $((req_after - req_before)) -ge 300 ] &&
17361                 error "open/close requests are not freed"
17362         return 0
17363 }
17364 run_test 209 "read-only open/close requests should be freed promptly"
17365
17366 test_210() {
17367         local pid
17368
17369         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17370         pid=$!
17371         sleep 1
17372
17373         $LFS getstripe $DIR/$tfile
17374         kill -USR1 $pid
17375         wait $pid || error "multiop failed"
17376
17377         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17378         pid=$!
17379         sleep 1
17380
17381         $LFS getstripe $DIR/$tfile
17382         kill -USR1 $pid
17383         wait $pid || error "multiop failed"
17384 }
17385 run_test 210 "lfs getstripe does not break leases"
17386
17387 test_212() {
17388         size=`date +%s`
17389         size=$((size % 8192 + 1))
17390         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17391         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17392         rm -f $DIR/f212 $DIR/f212.xyz
17393 }
17394 run_test 212 "Sendfile test ============================================"
17395
17396 test_213() {
17397         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17398         cancel_lru_locks osc
17399         lctl set_param fail_loc=0x8000040f
17400         # generate a read lock
17401         cat $DIR/$tfile > /dev/null
17402         # write to the file, it will try to cancel the above read lock.
17403         cat /etc/hosts >> $DIR/$tfile
17404 }
17405 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17406
17407 test_214() { # for bug 20133
17408         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17409         for (( i=0; i < 340; i++ )) ; do
17410                 touch $DIR/$tdir/d214c/a$i
17411         done
17412
17413         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17414         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17415         ls $DIR/d214c || error "ls $DIR/d214c failed"
17416         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17417         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17418 }
17419 run_test 214 "hash-indexed directory test - bug 20133"
17420
17421 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17422 create_lnet_proc_files() {
17423         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17424 }
17425
17426 # counterpart of create_lnet_proc_files
17427 remove_lnet_proc_files() {
17428         rm -f $TMP/lnet_$1.sys
17429 }
17430
17431 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17432 # 3rd arg as regexp for body
17433 check_lnet_proc_stats() {
17434         local l=$(cat "$TMP/lnet_$1" |wc -l)
17435         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17436
17437         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17438 }
17439
17440 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17441 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17442 # optional and can be regexp for 2nd line (lnet.routes case)
17443 check_lnet_proc_entry() {
17444         local blp=2          # blp stands for 'position of 1st line of body'
17445         [ -z "$5" ] || blp=3 # lnet.routes case
17446
17447         local l=$(cat "$TMP/lnet_$1" |wc -l)
17448         # subtracting one from $blp because the body can be empty
17449         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17450
17451         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17452                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17453
17454         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17455                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17456
17457         # bail out if any unexpected line happened
17458         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17459         [ "$?" != 0 ] || error "$2 misformatted"
17460 }
17461
17462 test_215() { # for bugs 18102, 21079, 21517
17463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17464
17465         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17466         local P='[1-9][0-9]*'           # positive numeric
17467         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17468         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17469         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17470         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17471
17472         local L1 # regexp for 1st line
17473         local L2 # regexp for 2nd line (optional)
17474         local BR # regexp for the rest (body)
17475
17476         # lnet.stats should look as 11 space-separated non-negative numerics
17477         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17478         create_lnet_proc_files "stats"
17479         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17480         remove_lnet_proc_files "stats"
17481
17482         # lnet.routes should look like this:
17483         # Routing disabled/enabled
17484         # net hops priority state router
17485         # where net is a string like tcp0, hops > 0, priority >= 0,
17486         # state is up/down,
17487         # router is a string like 192.168.1.1@tcp2
17488         L1="^Routing (disabled|enabled)$"
17489         L2="^net +hops +priority +state +router$"
17490         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17491         create_lnet_proc_files "routes"
17492         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17493         remove_lnet_proc_files "routes"
17494
17495         # lnet.routers should look like this:
17496         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17497         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17498         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17499         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17500         L1="^ref +rtr_ref +alive +router$"
17501         BR="^$P +$P +(up|down) +$NID$"
17502         create_lnet_proc_files "routers"
17503         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17504         remove_lnet_proc_files "routers"
17505
17506         # lnet.peers should look like this:
17507         # nid refs state last max rtr min tx min queue
17508         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17509         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17510         # numeric (0 or >0 or <0), queue >= 0.
17511         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17512         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17513         create_lnet_proc_files "peers"
17514         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17515         remove_lnet_proc_files "peers"
17516
17517         # lnet.buffers  should look like this:
17518         # pages count credits min
17519         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17520         L1="^pages +count +credits +min$"
17521         BR="^ +$N +$N +$I +$I$"
17522         create_lnet_proc_files "buffers"
17523         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17524         remove_lnet_proc_files "buffers"
17525
17526         # lnet.nis should look like this:
17527         # nid status alive refs peer rtr max tx min
17528         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17529         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17530         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17531         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17532         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17533         create_lnet_proc_files "nis"
17534         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17535         remove_lnet_proc_files "nis"
17536
17537         # can we successfully write to lnet.stats?
17538         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17539 }
17540 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17541
17542 test_216() { # bug 20317
17543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17544         remote_ost_nodsh && skip "remote OST with nodsh"
17545
17546         local node
17547         local facets=$(get_facets OST)
17548         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17549
17550         save_lustre_params client "osc.*.contention_seconds" > $p
17551         save_lustre_params $facets \
17552                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17553         save_lustre_params $facets \
17554                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17555         save_lustre_params $facets \
17556                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17557         clear_stats osc.*.osc_stats
17558
17559         # agressive lockless i/o settings
17560         do_nodes $(comma_list $(osts_nodes)) \
17561                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17562                         ldlm.namespaces.filter-*.contended_locks=0 \
17563                         ldlm.namespaces.filter-*.contention_seconds=60"
17564         lctl set_param -n osc.*.contention_seconds=60
17565
17566         $DIRECTIO write $DIR/$tfile 0 10 4096
17567         $CHECKSTAT -s 40960 $DIR/$tfile
17568
17569         # disable lockless i/o
17570         do_nodes $(comma_list $(osts_nodes)) \
17571                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17572                         ldlm.namespaces.filter-*.contended_locks=32 \
17573                         ldlm.namespaces.filter-*.contention_seconds=0"
17574         lctl set_param -n osc.*.contention_seconds=0
17575         clear_stats osc.*.osc_stats
17576
17577         dd if=/dev/zero of=$DIR/$tfile count=0
17578         $CHECKSTAT -s 0 $DIR/$tfile
17579
17580         restore_lustre_params <$p
17581         rm -f $p
17582         rm $DIR/$tfile
17583 }
17584 run_test 216 "check lockless direct write updates file size and kms correctly"
17585
17586 test_217() { # bug 22430
17587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17588
17589         local node
17590         local nid
17591
17592         for node in $(nodes_list); do
17593                 nid=$(host_nids_address $node $NETTYPE)
17594                 if [[ $nid = *-* ]] ; then
17595                         echo "lctl ping $(h2nettype $nid)"
17596                         lctl ping $(h2nettype $nid)
17597                 else
17598                         echo "skipping $node (no hyphen detected)"
17599                 fi
17600         done
17601 }
17602 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17603
17604 test_218() {
17605        # do directio so as not to populate the page cache
17606        log "creating a 10 Mb file"
17607        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17608        log "starting reads"
17609        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17610        log "truncating the file"
17611        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17612        log "killing dd"
17613        kill %+ || true # reads might have finished
17614        echo "wait until dd is finished"
17615        wait
17616        log "removing the temporary file"
17617        rm -rf $DIR/$tfile || error "tmp file removal failed"
17618 }
17619 run_test 218 "parallel read and truncate should not deadlock"
17620
17621 test_219() {
17622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17623
17624         # write one partial page
17625         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17626         # set no grant so vvp_io_commit_write will do sync write
17627         $LCTL set_param fail_loc=0x411
17628         # write a full page at the end of file
17629         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17630
17631         $LCTL set_param fail_loc=0
17632         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17633         $LCTL set_param fail_loc=0x411
17634         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17635
17636         # LU-4201
17637         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17638         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17639 }
17640 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17641
17642 test_220() { #LU-325
17643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17644         remote_ost_nodsh && skip "remote OST with nodsh"
17645         remote_mds_nodsh && skip "remote MDS with nodsh"
17646         remote_mgs_nodsh && skip "remote MGS with nodsh"
17647
17648         local OSTIDX=0
17649
17650         # create on MDT0000 so the last_id and next_id are correct
17651         mkdir $DIR/$tdir
17652         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17653         OST=${OST%_UUID}
17654
17655         # on the mdt's osc
17656         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17657         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17658                         osp.$mdtosc_proc1.prealloc_last_id)
17659         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17660                         osp.$mdtosc_proc1.prealloc_next_id)
17661
17662         $LFS df -i
17663
17664         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17665         #define OBD_FAIL_OST_ENOINO              0x229
17666         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17667         create_pool $FSNAME.$TESTNAME || return 1
17668         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17669
17670         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17671
17672         MDSOBJS=$((last_id - next_id))
17673         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17674
17675         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17676         echo "OST still has $count kbytes free"
17677
17678         echo "create $MDSOBJS files @next_id..."
17679         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17680
17681         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17682                         osp.$mdtosc_proc1.prealloc_last_id)
17683         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17684                         osp.$mdtosc_proc1.prealloc_next_id)
17685
17686         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17687         $LFS df -i
17688
17689         echo "cleanup..."
17690
17691         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17692         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17693
17694         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17695                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17696         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17697                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17698         echo "unlink $MDSOBJS files @$next_id..."
17699         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17700 }
17701 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17702
17703 test_221() {
17704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17705
17706         dd if=`which date` of=$MOUNT/date oflag=sync
17707         chmod +x $MOUNT/date
17708
17709         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17710         $LCTL set_param fail_loc=0x80001401
17711
17712         $MOUNT/date > /dev/null
17713         rm -f $MOUNT/date
17714 }
17715 run_test 221 "make sure fault and truncate race to not cause OOM"
17716
17717 test_222a () {
17718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17719
17720         rm -rf $DIR/$tdir
17721         test_mkdir $DIR/$tdir
17722         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17723         createmany -o $DIR/$tdir/$tfile 10
17724         cancel_lru_locks mdc
17725         cancel_lru_locks osc
17726         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17727         $LCTL set_param fail_loc=0x31a
17728         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17729         $LCTL set_param fail_loc=0
17730         rm -r $DIR/$tdir
17731 }
17732 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17733
17734 test_222b () {
17735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17736
17737         rm -rf $DIR/$tdir
17738         test_mkdir $DIR/$tdir
17739         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17740         createmany -o $DIR/$tdir/$tfile 10
17741         cancel_lru_locks mdc
17742         cancel_lru_locks osc
17743         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17744         $LCTL set_param fail_loc=0x31a
17745         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17746         $LCTL set_param fail_loc=0
17747 }
17748 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17749
17750 test_223 () {
17751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17752
17753         rm -rf $DIR/$tdir
17754         test_mkdir $DIR/$tdir
17755         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17756         createmany -o $DIR/$tdir/$tfile 10
17757         cancel_lru_locks mdc
17758         cancel_lru_locks osc
17759         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17760         $LCTL set_param fail_loc=0x31b
17761         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17762         $LCTL set_param fail_loc=0
17763         rm -r $DIR/$tdir
17764 }
17765 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17766
17767 test_224a() { # LU-1039, MRP-303
17768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17769
17770         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17771         $LCTL set_param fail_loc=0x508
17772         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17773         $LCTL set_param fail_loc=0
17774         df $DIR
17775 }
17776 run_test 224a "Don't panic on bulk IO failure"
17777
17778 test_224b() { # LU-1039, MRP-303
17779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17780
17781         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17782         cancel_lru_locks osc
17783         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17784         $LCTL set_param fail_loc=0x515
17785         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17786         $LCTL set_param fail_loc=0
17787         df $DIR
17788 }
17789 run_test 224b "Don't panic on bulk IO failure"
17790
17791 test_224c() { # LU-6441
17792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17793         remote_mds_nodsh && skip "remote MDS with nodsh"
17794
17795         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17796         save_writethrough $p
17797         set_cache writethrough on
17798
17799         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17800         local at_max=$($LCTL get_param -n at_max)
17801         local timeout=$($LCTL get_param -n timeout)
17802         local test_at="at_max"
17803         local param_at="$FSNAME.sys.at_max"
17804         local test_timeout="timeout"
17805         local param_timeout="$FSNAME.sys.timeout"
17806
17807         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17808
17809         set_persistent_param_and_check client "$test_at" "$param_at" 0
17810         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17811
17812         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17813         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17814         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17815         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17816         sync
17817         do_facet ost1 "$LCTL set_param fail_loc=0"
17818
17819         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17820         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17821                 $timeout
17822
17823         $LCTL set_param -n $pages_per_rpc
17824         restore_lustre_params < $p
17825         rm -f $p
17826 }
17827 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17828
17829 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17830 test_225a () {
17831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17832         if [ -z ${MDSSURVEY} ]; then
17833                 skip_env "mds-survey not found"
17834         fi
17835         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17836                 skip "Need MDS version at least 2.2.51"
17837
17838         local mds=$(facet_host $SINGLEMDS)
17839         local target=$(do_nodes $mds 'lctl dl' |
17840                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17841
17842         local cmd1="file_count=1000 thrhi=4"
17843         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17844         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17845         local cmd="$cmd1 $cmd2 $cmd3"
17846
17847         rm -f ${TMP}/mds_survey*
17848         echo + $cmd
17849         eval $cmd || error "mds-survey with zero-stripe failed"
17850         cat ${TMP}/mds_survey*
17851         rm -f ${TMP}/mds_survey*
17852 }
17853 run_test 225a "Metadata survey sanity with zero-stripe"
17854
17855 test_225b () {
17856         if [ -z ${MDSSURVEY} ]; then
17857                 skip_env "mds-survey not found"
17858         fi
17859         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17860                 skip "Need MDS version at least 2.2.51"
17861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17862         remote_mds_nodsh && skip "remote MDS with nodsh"
17863         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17864                 skip_env "Need to mount OST to test"
17865         fi
17866
17867         local mds=$(facet_host $SINGLEMDS)
17868         local target=$(do_nodes $mds 'lctl dl' |
17869                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17870
17871         local cmd1="file_count=1000 thrhi=4"
17872         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17873         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17874         local cmd="$cmd1 $cmd2 $cmd3"
17875
17876         rm -f ${TMP}/mds_survey*
17877         echo + $cmd
17878         eval $cmd || error "mds-survey with stripe_count failed"
17879         cat ${TMP}/mds_survey*
17880         rm -f ${TMP}/mds_survey*
17881 }
17882 run_test 225b "Metadata survey sanity with stripe_count = 1"
17883
17884 mcreate_path2fid () {
17885         local mode=$1
17886         local major=$2
17887         local minor=$3
17888         local name=$4
17889         local desc=$5
17890         local path=$DIR/$tdir/$name
17891         local fid
17892         local rc
17893         local fid_path
17894
17895         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17896                 error "cannot create $desc"
17897
17898         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17899         rc=$?
17900         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17901
17902         fid_path=$($LFS fid2path $MOUNT $fid)
17903         rc=$?
17904         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17905
17906         [ "$path" == "$fid_path" ] ||
17907                 error "fid2path returned $fid_path, expected $path"
17908
17909         echo "pass with $path and $fid"
17910 }
17911
17912 test_226a () {
17913         rm -rf $DIR/$tdir
17914         mkdir -p $DIR/$tdir
17915
17916         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17917         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17918         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17919         mcreate_path2fid 0040666 0 0 dir "directory"
17920         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17921         mcreate_path2fid 0100666 0 0 file "regular file"
17922         mcreate_path2fid 0120666 0 0 link "symbolic link"
17923         mcreate_path2fid 0140666 0 0 sock "socket"
17924 }
17925 run_test 226a "call path2fid and fid2path on files of all type"
17926
17927 test_226b () {
17928         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17929
17930         local MDTIDX=1
17931
17932         rm -rf $DIR/$tdir
17933         mkdir -p $DIR/$tdir
17934         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17935                 error "create remote directory failed"
17936         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17937         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17938                                 "character special file (null)"
17939         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17940                                 "character special file (no device)"
17941         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17942         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17943                                 "block special file (loop)"
17944         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17945         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17946         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17947 }
17948 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17949
17950 test_226c () {
17951         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17952         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17953                 skip "Need MDS version at least 2.13.55"
17954
17955         local submnt=/mnt/submnt
17956         local srcfile=/etc/passwd
17957         local dstfile=$submnt/passwd
17958         local path
17959         local fid
17960
17961         rm -rf $DIR/$tdir
17962         rm -rf $submnt
17963         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17964                 error "create remote directory failed"
17965         mkdir -p $submnt || error "create $submnt failed"
17966         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17967                 error "mount $submnt failed"
17968         stack_trap "umount $submnt" EXIT
17969
17970         cp $srcfile $dstfile
17971         fid=$($LFS path2fid $dstfile)
17972         path=$($LFS fid2path $submnt "$fid")
17973         [ "$path" = "$dstfile" ] ||
17974                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17975 }
17976 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17977
17978 # LU-1299 Executing or running ldd on a truncated executable does not
17979 # cause an out-of-memory condition.
17980 test_227() {
17981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17982         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17983
17984         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17985         chmod +x $MOUNT/date
17986
17987         $MOUNT/date > /dev/null
17988         ldd $MOUNT/date > /dev/null
17989         rm -f $MOUNT/date
17990 }
17991 run_test 227 "running truncated executable does not cause OOM"
17992
17993 # LU-1512 try to reuse idle OI blocks
17994 test_228a() {
17995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17996         remote_mds_nodsh && skip "remote MDS with nodsh"
17997         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17998
17999         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18000         local myDIR=$DIR/$tdir
18001
18002         mkdir -p $myDIR
18003         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18004         $LCTL set_param fail_loc=0x80001002
18005         createmany -o $myDIR/t- 10000
18006         $LCTL set_param fail_loc=0
18007         # The guard is current the largest FID holder
18008         touch $myDIR/guard
18009         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18010                     tr -d '[')
18011         local IDX=$(($SEQ % 64))
18012
18013         do_facet $SINGLEMDS sync
18014         # Make sure journal flushed.
18015         sleep 6
18016         local blk1=$(do_facet $SINGLEMDS \
18017                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18018                      grep Blockcount | awk '{print $4}')
18019
18020         # Remove old files, some OI blocks will become idle.
18021         unlinkmany $myDIR/t- 10000
18022         # Create new files, idle OI blocks should be reused.
18023         createmany -o $myDIR/t- 2000
18024         do_facet $SINGLEMDS sync
18025         # Make sure journal flushed.
18026         sleep 6
18027         local blk2=$(do_facet $SINGLEMDS \
18028                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18029                      grep Blockcount | awk '{print $4}')
18030
18031         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18032 }
18033 run_test 228a "try to reuse idle OI blocks"
18034
18035 test_228b() {
18036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18037         remote_mds_nodsh && skip "remote MDS with nodsh"
18038         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18039
18040         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18041         local myDIR=$DIR/$tdir
18042
18043         mkdir -p $myDIR
18044         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18045         $LCTL set_param fail_loc=0x80001002
18046         createmany -o $myDIR/t- 10000
18047         $LCTL set_param fail_loc=0
18048         # The guard is current the largest FID holder
18049         touch $myDIR/guard
18050         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18051                     tr -d '[')
18052         local IDX=$(($SEQ % 64))
18053
18054         do_facet $SINGLEMDS sync
18055         # Make sure journal flushed.
18056         sleep 6
18057         local blk1=$(do_facet $SINGLEMDS \
18058                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18059                      grep Blockcount | awk '{print $4}')
18060
18061         # Remove old files, some OI blocks will become idle.
18062         unlinkmany $myDIR/t- 10000
18063
18064         # stop the MDT
18065         stop $SINGLEMDS || error "Fail to stop MDT."
18066         # remount the MDT
18067         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18068
18069         df $MOUNT || error "Fail to df."
18070         # Create new files, idle OI blocks should be reused.
18071         createmany -o $myDIR/t- 2000
18072         do_facet $SINGLEMDS sync
18073         # Make sure journal flushed.
18074         sleep 6
18075         local blk2=$(do_facet $SINGLEMDS \
18076                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18077                      grep Blockcount | awk '{print $4}')
18078
18079         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18080 }
18081 run_test 228b "idle OI blocks can be reused after MDT restart"
18082
18083 #LU-1881
18084 test_228c() {
18085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18086         remote_mds_nodsh && skip "remote MDS with nodsh"
18087         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18088
18089         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18090         local myDIR=$DIR/$tdir
18091
18092         mkdir -p $myDIR
18093         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18094         $LCTL set_param fail_loc=0x80001002
18095         # 20000 files can guarantee there are index nodes in the OI file
18096         createmany -o $myDIR/t- 20000
18097         $LCTL set_param fail_loc=0
18098         # The guard is current the largest FID holder
18099         touch $myDIR/guard
18100         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18101                     tr -d '[')
18102         local IDX=$(($SEQ % 64))
18103
18104         do_facet $SINGLEMDS sync
18105         # Make sure journal flushed.
18106         sleep 6
18107         local blk1=$(do_facet $SINGLEMDS \
18108                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18109                      grep Blockcount | awk '{print $4}')
18110
18111         # Remove old files, some OI blocks will become idle.
18112         unlinkmany $myDIR/t- 20000
18113         rm -f $myDIR/guard
18114         # The OI file should become empty now
18115
18116         # Create new files, idle OI blocks should be reused.
18117         createmany -o $myDIR/t- 2000
18118         do_facet $SINGLEMDS sync
18119         # Make sure journal flushed.
18120         sleep 6
18121         local blk2=$(do_facet $SINGLEMDS \
18122                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18123                      grep Blockcount | awk '{print $4}')
18124
18125         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18126 }
18127 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18128
18129 test_229() { # LU-2482, LU-3448
18130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18131         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18132         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18133                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18134
18135         rm -f $DIR/$tfile
18136
18137         # Create a file with a released layout and stripe count 2.
18138         $MULTIOP $DIR/$tfile H2c ||
18139                 error "failed to create file with released layout"
18140
18141         $LFS getstripe -v $DIR/$tfile
18142
18143         local pattern=$($LFS getstripe -L $DIR/$tfile)
18144         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18145
18146         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18147                 error "getstripe"
18148         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18149         stat $DIR/$tfile || error "failed to stat released file"
18150
18151         chown $RUNAS_ID $DIR/$tfile ||
18152                 error "chown $RUNAS_ID $DIR/$tfile failed"
18153
18154         chgrp $RUNAS_ID $DIR/$tfile ||
18155                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18156
18157         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18158         rm $DIR/$tfile || error "failed to remove released file"
18159 }
18160 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18161
18162 test_230a() {
18163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18164         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18165         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18166                 skip "Need MDS version at least 2.11.52"
18167
18168         local MDTIDX=1
18169
18170         test_mkdir $DIR/$tdir
18171         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18172         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18173         [ $mdt_idx -ne 0 ] &&
18174                 error "create local directory on wrong MDT $mdt_idx"
18175
18176         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18177                         error "create remote directory failed"
18178         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18179         [ $mdt_idx -ne $MDTIDX ] &&
18180                 error "create remote directory on wrong MDT $mdt_idx"
18181
18182         createmany -o $DIR/$tdir/test_230/t- 10 ||
18183                 error "create files on remote directory failed"
18184         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18185         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18186         rm -r $DIR/$tdir || error "unlink remote directory failed"
18187 }
18188 run_test 230a "Create remote directory and files under the remote directory"
18189
18190 test_230b() {
18191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18192         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18193         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18194                 skip "Need MDS version at least 2.11.52"
18195
18196         local MDTIDX=1
18197         local mdt_index
18198         local i
18199         local file
18200         local pid
18201         local stripe_count
18202         local migrate_dir=$DIR/$tdir/migrate_dir
18203         local other_dir=$DIR/$tdir/other_dir
18204
18205         test_mkdir $DIR/$tdir
18206         test_mkdir -i0 -c1 $migrate_dir
18207         test_mkdir -i0 -c1 $other_dir
18208         for ((i=0; i<10; i++)); do
18209                 mkdir -p $migrate_dir/dir_${i}
18210                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18211                         error "create files under remote dir failed $i"
18212         done
18213
18214         cp /etc/passwd $migrate_dir/$tfile
18215         cp /etc/passwd $other_dir/$tfile
18216         chattr +SAD $migrate_dir
18217         chattr +SAD $migrate_dir/$tfile
18218
18219         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18220         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18221         local old_dir_mode=$(stat -c%f $migrate_dir)
18222         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18223
18224         mkdir -p $migrate_dir/dir_default_stripe2
18225         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18226         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18227
18228         mkdir -p $other_dir
18229         ln $migrate_dir/$tfile $other_dir/luna
18230         ln $migrate_dir/$tfile $migrate_dir/sofia
18231         ln $other_dir/$tfile $migrate_dir/david
18232         ln -s $migrate_dir/$tfile $other_dir/zachary
18233         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18234         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18235
18236         local len
18237         local lnktgt
18238
18239         # inline symlink
18240         for len in 58 59 60; do
18241                 lnktgt=$(str_repeat 'l' $len)
18242                 touch $migrate_dir/$lnktgt
18243                 ln -s $lnktgt $migrate_dir/${len}char_ln
18244         done
18245
18246         # PATH_MAX
18247         for len in 4094 4095; do
18248                 lnktgt=$(str_repeat 'l' $len)
18249                 ln -s $lnktgt $migrate_dir/${len}char_ln
18250         done
18251
18252         # NAME_MAX
18253         for len in 254 255; do
18254                 touch $migrate_dir/$(str_repeat 'l' $len)
18255         done
18256
18257         $LFS migrate -m $MDTIDX $migrate_dir ||
18258                 error "fails on migrating remote dir to MDT1"
18259
18260         echo "migratate to MDT1, then checking.."
18261         for ((i = 0; i < 10; i++)); do
18262                 for file in $(find $migrate_dir/dir_${i}); do
18263                         mdt_index=$($LFS getstripe -m $file)
18264                         # broken symlink getstripe will fail
18265                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18266                                 error "$file is not on MDT${MDTIDX}"
18267                 done
18268         done
18269
18270         # the multiple link file should still in MDT0
18271         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18272         [ $mdt_index == 0 ] ||
18273                 error "$file is not on MDT${MDTIDX}"
18274
18275         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18276         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18277                 error " expect $old_dir_flag get $new_dir_flag"
18278
18279         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18280         [ "$old_file_flag" = "$new_file_flag" ] ||
18281                 error " expect $old_file_flag get $new_file_flag"
18282
18283         local new_dir_mode=$(stat -c%f $migrate_dir)
18284         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18285                 error "expect mode $old_dir_mode get $new_dir_mode"
18286
18287         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18288         [ "$old_file_mode" = "$new_file_mode" ] ||
18289                 error "expect mode $old_file_mode get $new_file_mode"
18290
18291         diff /etc/passwd $migrate_dir/$tfile ||
18292                 error "$tfile different after migration"
18293
18294         diff /etc/passwd $other_dir/luna ||
18295                 error "luna different after migration"
18296
18297         diff /etc/passwd $migrate_dir/sofia ||
18298                 error "sofia different after migration"
18299
18300         diff /etc/passwd $migrate_dir/david ||
18301                 error "david different after migration"
18302
18303         diff /etc/passwd $other_dir/zachary ||
18304                 error "zachary different after migration"
18305
18306         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18307                 error "${tfile}_ln different after migration"
18308
18309         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18310                 error "${tfile}_ln_other different after migration"
18311
18312         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18313         [ $stripe_count = 2 ] ||
18314                 error "dir strpe_count $d != 2 after migration."
18315
18316         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18317         [ $stripe_count = 2 ] ||
18318                 error "file strpe_count $d != 2 after migration."
18319
18320         #migrate back to MDT0
18321         MDTIDX=0
18322
18323         $LFS migrate -m $MDTIDX $migrate_dir ||
18324                 error "fails on migrating remote dir to MDT0"
18325
18326         echo "migrate back to MDT0, checking.."
18327         for file in $(find $migrate_dir); do
18328                 mdt_index=$($LFS getstripe -m $file)
18329                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18330                         error "$file is not on MDT${MDTIDX}"
18331         done
18332
18333         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18334         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18335                 error " expect $old_dir_flag get $new_dir_flag"
18336
18337         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18338         [ "$old_file_flag" = "$new_file_flag" ] ||
18339                 error " expect $old_file_flag get $new_file_flag"
18340
18341         local new_dir_mode=$(stat -c%f $migrate_dir)
18342         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18343                 error "expect mode $old_dir_mode get $new_dir_mode"
18344
18345         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18346         [ "$old_file_mode" = "$new_file_mode" ] ||
18347                 error "expect mode $old_file_mode get $new_file_mode"
18348
18349         diff /etc/passwd ${migrate_dir}/$tfile ||
18350                 error "$tfile different after migration"
18351
18352         diff /etc/passwd ${other_dir}/luna ||
18353                 error "luna different after migration"
18354
18355         diff /etc/passwd ${migrate_dir}/sofia ||
18356                 error "sofia different after migration"
18357
18358         diff /etc/passwd ${other_dir}/zachary ||
18359                 error "zachary different after migration"
18360
18361         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18362                 error "${tfile}_ln different after migration"
18363
18364         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18365                 error "${tfile}_ln_other different after migration"
18366
18367         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18368         [ $stripe_count = 2 ] ||
18369                 error "dir strpe_count $d != 2 after migration."
18370
18371         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18372         [ $stripe_count = 2 ] ||
18373                 error "file strpe_count $d != 2 after migration."
18374
18375         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18376 }
18377 run_test 230b "migrate directory"
18378
18379 test_230c() {
18380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18381         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18382         remote_mds_nodsh && skip "remote MDS with nodsh"
18383         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18384                 skip "Need MDS version at least 2.11.52"
18385
18386         local MDTIDX=1
18387         local total=3
18388         local mdt_index
18389         local file
18390         local migrate_dir=$DIR/$tdir/migrate_dir
18391
18392         #If migrating directory fails in the middle, all entries of
18393         #the directory is still accessiable.
18394         test_mkdir $DIR/$tdir
18395         test_mkdir -i0 -c1 $migrate_dir
18396         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18397         stat $migrate_dir
18398         createmany -o $migrate_dir/f $total ||
18399                 error "create files under ${migrate_dir} failed"
18400
18401         # fail after migrating top dir, and this will fail only once, so the
18402         # first sub file migration will fail (currently f3), others succeed.
18403         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18404         do_facet mds1 lctl set_param fail_loc=0x1801
18405         local t=$(ls $migrate_dir | wc -l)
18406         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18407                 error "migrate should fail"
18408         local u=$(ls $migrate_dir | wc -l)
18409         [ "$u" == "$t" ] || error "$u != $t during migration"
18410
18411         # add new dir/file should succeed
18412         mkdir $migrate_dir/dir ||
18413                 error "mkdir failed under migrating directory"
18414         touch $migrate_dir/file ||
18415                 error "create file failed under migrating directory"
18416
18417         # add file with existing name should fail
18418         for file in $migrate_dir/f*; do
18419                 stat $file > /dev/null || error "stat $file failed"
18420                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18421                         error "open(O_CREAT|O_EXCL) $file should fail"
18422                 $MULTIOP $file m && error "create $file should fail"
18423                 touch $DIR/$tdir/remote_dir/$tfile ||
18424                         error "touch $tfile failed"
18425                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18426                         error "link $file should fail"
18427                 mdt_index=$($LFS getstripe -m $file)
18428                 if [ $mdt_index == 0 ]; then
18429                         # file failed to migrate is not allowed to rename to
18430                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18431                                 error "rename to $file should fail"
18432                 else
18433                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18434                                 error "rename to $file failed"
18435                 fi
18436                 echo hello >> $file || error "write $file failed"
18437         done
18438
18439         # resume migration with different options should fail
18440         $LFS migrate -m 0 $migrate_dir &&
18441                 error "migrate -m 0 $migrate_dir should fail"
18442
18443         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18444                 error "migrate -c 2 $migrate_dir should fail"
18445
18446         # resume migration should succeed
18447         $LFS migrate -m $MDTIDX $migrate_dir ||
18448                 error "migrate $migrate_dir failed"
18449
18450         echo "Finish migration, then checking.."
18451         for file in $(find $migrate_dir); do
18452                 mdt_index=$($LFS getstripe -m $file)
18453                 [ $mdt_index == $MDTIDX ] ||
18454                         error "$file is not on MDT${MDTIDX}"
18455         done
18456
18457         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18458 }
18459 run_test 230c "check directory accessiblity if migration failed"
18460
18461 test_230d() {
18462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18463         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18464         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18465                 skip "Need MDS version at least 2.11.52"
18466         # LU-11235
18467         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18468
18469         local migrate_dir=$DIR/$tdir/migrate_dir
18470         local old_index
18471         local new_index
18472         local old_count
18473         local new_count
18474         local new_hash
18475         local mdt_index
18476         local i
18477         local j
18478
18479         old_index=$((RANDOM % MDSCOUNT))
18480         old_count=$((MDSCOUNT - old_index))
18481         new_index=$((RANDOM % MDSCOUNT))
18482         new_count=$((MDSCOUNT - new_index))
18483         new_hash=1 # for all_char
18484
18485         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18486         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18487
18488         test_mkdir $DIR/$tdir
18489         test_mkdir -i $old_index -c $old_count $migrate_dir
18490
18491         for ((i=0; i<100; i++)); do
18492                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18493                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18494                         error "create files under remote dir failed $i"
18495         done
18496
18497         echo -n "Migrate from MDT$old_index "
18498         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18499         echo -n "to MDT$new_index"
18500         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18501         echo
18502
18503         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18504         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18505                 error "migrate remote dir error"
18506
18507         echo "Finish migration, then checking.."
18508         for file in $(find $migrate_dir); do
18509                 mdt_index=$($LFS getstripe -m $file)
18510                 if [ $mdt_index -lt $new_index ] ||
18511                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18512                         error "$file is on MDT$mdt_index"
18513                 fi
18514         done
18515
18516         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18517 }
18518 run_test 230d "check migrate big directory"
18519
18520 test_230e() {
18521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18522         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18523         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18524                 skip "Need MDS version at least 2.11.52"
18525
18526         local i
18527         local j
18528         local a_fid
18529         local b_fid
18530
18531         mkdir -p $DIR/$tdir
18532         mkdir $DIR/$tdir/migrate_dir
18533         mkdir $DIR/$tdir/other_dir
18534         touch $DIR/$tdir/migrate_dir/a
18535         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18536         ls $DIR/$tdir/other_dir
18537
18538         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18539                 error "migrate dir fails"
18540
18541         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18542         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18543
18544         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18545         [ $mdt_index == 0 ] || error "a is not on MDT0"
18546
18547         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18548                 error "migrate dir fails"
18549
18550         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18551         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18552
18553         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18554         [ $mdt_index == 1 ] || error "a is not on MDT1"
18555
18556         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18557         [ $mdt_index == 1 ] || error "b is not on MDT1"
18558
18559         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18560         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18561
18562         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18563
18564         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18565 }
18566 run_test 230e "migrate mulitple local link files"
18567
18568 test_230f() {
18569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18570         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18571         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18572                 skip "Need MDS version at least 2.11.52"
18573
18574         local a_fid
18575         local ln_fid
18576
18577         mkdir -p $DIR/$tdir
18578         mkdir $DIR/$tdir/migrate_dir
18579         $LFS mkdir -i1 $DIR/$tdir/other_dir
18580         touch $DIR/$tdir/migrate_dir/a
18581         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18582         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18583         ls $DIR/$tdir/other_dir
18584
18585         # a should be migrated to MDT1, since no other links on MDT0
18586         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18587                 error "#1 migrate dir fails"
18588         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18589         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18590         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18591         [ $mdt_index == 1 ] || error "a is not on MDT1"
18592
18593         # a should stay on MDT1, because it is a mulitple link file
18594         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18595                 error "#2 migrate dir fails"
18596         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18597         [ $mdt_index == 1 ] || error "a is not on MDT1"
18598
18599         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18600                 error "#3 migrate dir fails"
18601
18602         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18603         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18604         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18605
18606         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18607         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18608
18609         # a should be migrated to MDT0, since no other links on MDT1
18610         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18611                 error "#4 migrate dir fails"
18612         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18613         [ $mdt_index == 0 ] || error "a is not on MDT0"
18614
18615         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18616 }
18617 run_test 230f "migrate mulitple remote link files"
18618
18619 test_230g() {
18620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18621         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18622         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18623                 skip "Need MDS version at least 2.11.52"
18624
18625         mkdir -p $DIR/$tdir/migrate_dir
18626
18627         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18628                 error "migrating dir to non-exist MDT succeeds"
18629         true
18630 }
18631 run_test 230g "migrate dir to non-exist MDT"
18632
18633 test_230h() {
18634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18635         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18636         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18637                 skip "Need MDS version at least 2.11.52"
18638
18639         local mdt_index
18640
18641         mkdir -p $DIR/$tdir/migrate_dir
18642
18643         $LFS migrate -m1 $DIR &&
18644                 error "migrating mountpoint1 should fail"
18645
18646         $LFS migrate -m1 $DIR/$tdir/.. &&
18647                 error "migrating mountpoint2 should fail"
18648
18649         # same as mv
18650         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18651                 error "migrating $tdir/migrate_dir/.. should fail"
18652
18653         true
18654 }
18655 run_test 230h "migrate .. and root"
18656
18657 test_230i() {
18658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18659         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18660         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18661                 skip "Need MDS version at least 2.11.52"
18662
18663         mkdir -p $DIR/$tdir/migrate_dir
18664
18665         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18666                 error "migration fails with a tailing slash"
18667
18668         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18669                 error "migration fails with two tailing slashes"
18670 }
18671 run_test 230i "lfs migrate -m tolerates trailing slashes"
18672
18673 test_230j() {
18674         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18675         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18676                 skip "Need MDS version at least 2.11.52"
18677
18678         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18679         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18680                 error "create $tfile failed"
18681         cat /etc/passwd > $DIR/$tdir/$tfile
18682
18683         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18684
18685         cmp /etc/passwd $DIR/$tdir/$tfile ||
18686                 error "DoM file mismatch after migration"
18687 }
18688 run_test 230j "DoM file data not changed after dir migration"
18689
18690 test_230k() {
18691         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18692         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18693                 skip "Need MDS version at least 2.11.56"
18694
18695         local total=20
18696         local files_on_starting_mdt=0
18697
18698         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18699         $LFS getdirstripe $DIR/$tdir
18700         for i in $(seq $total); do
18701                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18702                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18703                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18704         done
18705
18706         echo "$files_on_starting_mdt files on MDT0"
18707
18708         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18709         $LFS getdirstripe $DIR/$tdir
18710
18711         files_on_starting_mdt=0
18712         for i in $(seq $total); do
18713                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18714                         error "file $tfile.$i mismatch after migration"
18715                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18716                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18717         done
18718
18719         echo "$files_on_starting_mdt files on MDT1 after migration"
18720         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18721
18722         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18723         $LFS getdirstripe $DIR/$tdir
18724
18725         files_on_starting_mdt=0
18726         for i in $(seq $total); do
18727                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18728                         error "file $tfile.$i mismatch after 2nd migration"
18729                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18730                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18731         done
18732
18733         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18734         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18735
18736         true
18737 }
18738 run_test 230k "file data not changed after dir migration"
18739
18740 test_230l() {
18741         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18742         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18743                 skip "Need MDS version at least 2.11.56"
18744
18745         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18746         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18747                 error "create files under remote dir failed $i"
18748         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18749 }
18750 run_test 230l "readdir between MDTs won't crash"
18751
18752 test_230m() {
18753         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18754         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18755                 skip "Need MDS version at least 2.11.56"
18756
18757         local MDTIDX=1
18758         local mig_dir=$DIR/$tdir/migrate_dir
18759         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18760         local shortstr="b"
18761         local val
18762
18763         echo "Creating files and dirs with xattrs"
18764         test_mkdir $DIR/$tdir
18765         test_mkdir -i0 -c1 $mig_dir
18766         mkdir $mig_dir/dir
18767         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18768                 error "cannot set xattr attr1 on dir"
18769         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18770                 error "cannot set xattr attr2 on dir"
18771         touch $mig_dir/dir/f0
18772         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18773                 error "cannot set xattr attr1 on file"
18774         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18775                 error "cannot set xattr attr2 on file"
18776         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18777         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18778         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18779         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18780         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18781         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18782         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18783         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18784         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18785
18786         echo "Migrating to MDT1"
18787         $LFS migrate -m $MDTIDX $mig_dir ||
18788                 error "fails on migrating dir to MDT1"
18789
18790         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18791         echo "Checking xattrs"
18792         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18793         [ "$val" = $longstr ] ||
18794                 error "expecting xattr1 $longstr on dir, found $val"
18795         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18796         [ "$val" = $shortstr ] ||
18797                 error "expecting xattr2 $shortstr on dir, found $val"
18798         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18799         [ "$val" = $longstr ] ||
18800                 error "expecting xattr1 $longstr on file, found $val"
18801         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18802         [ "$val" = $shortstr ] ||
18803                 error "expecting xattr2 $shortstr on file, found $val"
18804 }
18805 run_test 230m "xattrs not changed after dir migration"
18806
18807 test_230n() {
18808         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18809         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18810                 skip "Need MDS version at least 2.13.53"
18811
18812         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18813         cat /etc/hosts > $DIR/$tdir/$tfile
18814         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18815         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18816
18817         cmp /etc/hosts $DIR/$tdir/$tfile ||
18818                 error "File data mismatch after migration"
18819 }
18820 run_test 230n "Dir migration with mirrored file"
18821
18822 test_230o() {
18823         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18824         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18825                 skip "Need MDS version at least 2.13.52"
18826
18827         local mdts=$(comma_list $(mdts_nodes))
18828         local timeout=100
18829         local restripe_status
18830         local delta
18831         local i
18832
18833         [[ $mds1_FSTYPE == zfs ]] && timeout=300
18834
18835         # in case "crush" hash type is not set
18836         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18837
18838         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18839                            mdt.*MDT0000.enable_dir_restripe)
18840         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18841         stack_trap "do_nodes $mdts $LCTL set_param \
18842                     mdt.*.enable_dir_restripe=$restripe_status"
18843
18844         mkdir $DIR/$tdir
18845         createmany -m $DIR/$tdir/f 100 ||
18846                 error "create files under remote dir failed $i"
18847         createmany -d $DIR/$tdir/d 100 ||
18848                 error "create dirs under remote dir failed $i"
18849
18850         for i in $(seq 2 $MDSCOUNT); do
18851                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
18852                 $LFS setdirstripe -c $i $DIR/$tdir ||
18853                         error "split -c $i $tdir failed"
18854                 wait_update $HOSTNAME \
18855                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18856                         error "dir split not finished"
18857                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18858                         awk '/migrate/ {sum += $2} END { print sum }')
18859                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
18860                 # delta is around total_files/stripe_count
18861                 (( $delta < 200 / (i - 1) + 4 )) ||
18862                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
18863         done
18864 }
18865 run_test 230o "dir split"
18866
18867 test_230p() {
18868         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18869         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18870                 skip "Need MDS version at least 2.13.52"
18871
18872         local mdts=$(comma_list $(mdts_nodes))
18873         local timeout=100
18874         local restripe_status
18875         local delta
18876         local i
18877
18878         [[ $mds1_FSTYPE == zfs ]] && timeout=300
18879
18880         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18881
18882         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18883                            mdt.*MDT0000.enable_dir_restripe)
18884         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18885         stack_trap "do_nodes $mdts $LCTL set_param \
18886                     mdt.*.enable_dir_restripe=$restripe_status"
18887
18888         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18889         createmany -m $DIR/$tdir/f 100 ||
18890                 error "create files under remote dir failed $i"
18891         createmany -d $DIR/$tdir/d 100 ||
18892                 error "create dirs under remote dir failed $i"
18893
18894         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18895                 local mdt_hash="crush"
18896
18897                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
18898                 $LFS setdirstripe -c $i $DIR/$tdir ||
18899                         error "split -c $i $tdir failed"
18900                 [ $i -eq 1 ] && mdt_hash="none"
18901                 wait_update $HOSTNAME \
18902                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18903                         error "dir merge not finished"
18904                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18905                         awk '/migrate/ {sum += $2} END { print sum }')
18906                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
18907                 # delta is around total_files/stripe_count
18908                 (( $delta < 200 / i + 4 )) ||
18909                         error "$delta files migrated >= $((200 / i + 4))"
18910         done
18911 }
18912 run_test 230p "dir merge"
18913
18914 test_230q() {
18915         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18916         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18917                 skip "Need MDS version at least 2.13.52"
18918
18919         local mdts=$(comma_list $(mdts_nodes))
18920         local saved_threshold=$(do_facet mds1 \
18921                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18922         local saved_delta=$(do_facet mds1 \
18923                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18924         local threshold=100
18925         local delta=2
18926         local total=0
18927         local stripe_count=0
18928         local stripe_index
18929         local nr_files
18930         local create
18931
18932         # test with fewer files on ZFS
18933         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18934
18935         stack_trap "do_nodes $mdts $LCTL set_param \
18936                     mdt.*.dir_split_count=$saved_threshold"
18937         stack_trap "do_nodes $mdts $LCTL set_param \
18938                     mdt.*.dir_split_delta=$saved_delta"
18939         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18940         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18941         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18942         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18943         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18944         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18945
18946         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18947         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18948
18949         create=$((threshold * 3 / 2))
18950         while [ $stripe_count -lt $MDSCOUNT ]; do
18951                 createmany -m $DIR/$tdir/f $total $create ||
18952                         error "create sub files failed"
18953                 stat $DIR/$tdir > /dev/null
18954                 total=$((total + create))
18955                 stripe_count=$((stripe_count + delta))
18956                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18957
18958                 wait_update $HOSTNAME \
18959                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18960                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18961
18962                 wait_update $HOSTNAME \
18963                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18964                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18965
18966                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
18967                 echo "$nr_files/$total files on MDT$stripe_index after split"
18968                 # allow 10% margin of imbalance with crush hash
18969                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
18970                         error "$nr_files files on MDT$stripe_index after split"
18971
18972                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
18973                 [ $nr_files -eq $total ] ||
18974                         error "total sub files $nr_files != $total"
18975         done
18976 }
18977 run_test 230q "dir auto split"
18978
18979 test_230r() {
18980         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18981         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18982         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18983                 skip "Need MDS version at least 2.13.54"
18984
18985         # maximum amount of local locks:
18986         # parent striped dir - 2 locks
18987         # new stripe in parent to migrate to - 1 lock
18988         # source and target - 2 locks
18989         # Total 5 locks for regular file
18990         mkdir -p $DIR/$tdir
18991         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18992         touch $DIR/$tdir/dir1/eee
18993
18994         # create 4 hardlink for 4 more locks
18995         # Total: 9 locks > RS_MAX_LOCKS (8)
18996         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18997         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18998         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18999         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19000         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19001         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19002         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19003         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19004
19005         cancel_lru_locks mdc
19006
19007         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19008                 error "migrate dir fails"
19009
19010         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19011 }
19012 run_test 230r "migrate with too many local locks"
19013
19014 test_231a()
19015 {
19016         # For simplicity this test assumes that max_pages_per_rpc
19017         # is the same across all OSCs
19018         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19019         local bulk_size=$((max_pages * PAGE_SIZE))
19020         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19021                                        head -n 1)
19022
19023         mkdir -p $DIR/$tdir
19024         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19025                 error "failed to set stripe with -S ${brw_size}M option"
19026
19027         # clear the OSC stats
19028         $LCTL set_param osc.*.stats=0 &>/dev/null
19029         stop_writeback
19030
19031         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19032         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19033                 oflag=direct &>/dev/null || error "dd failed"
19034
19035         sync; sleep 1; sync # just to be safe
19036         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19037         if [ x$nrpcs != "x1" ]; then
19038                 $LCTL get_param osc.*.stats
19039                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19040         fi
19041
19042         start_writeback
19043         # Drop the OSC cache, otherwise we will read from it
19044         cancel_lru_locks osc
19045
19046         # clear the OSC stats
19047         $LCTL set_param osc.*.stats=0 &>/dev/null
19048
19049         # Client reads $bulk_size.
19050         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19051                 iflag=direct &>/dev/null || error "dd failed"
19052
19053         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19054         if [ x$nrpcs != "x1" ]; then
19055                 $LCTL get_param osc.*.stats
19056                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19057         fi
19058 }
19059 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19060
19061 test_231b() {
19062         mkdir -p $DIR/$tdir
19063         local i
19064         for i in {0..1023}; do
19065                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19066                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19067                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19068         done
19069         sync
19070 }
19071 run_test 231b "must not assert on fully utilized OST request buffer"
19072
19073 test_232a() {
19074         mkdir -p $DIR/$tdir
19075         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19076
19077         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19078         do_facet ost1 $LCTL set_param fail_loc=0x31c
19079
19080         # ignore dd failure
19081         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19082
19083         do_facet ost1 $LCTL set_param fail_loc=0
19084         umount_client $MOUNT || error "umount failed"
19085         mount_client $MOUNT || error "mount failed"
19086         stop ost1 || error "cannot stop ost1"
19087         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19088 }
19089 run_test 232a "failed lock should not block umount"
19090
19091 test_232b() {
19092         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19093                 skip "Need MDS version at least 2.10.58"
19094
19095         mkdir -p $DIR/$tdir
19096         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19097         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19098         sync
19099         cancel_lru_locks osc
19100
19101         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19102         do_facet ost1 $LCTL set_param fail_loc=0x31c
19103
19104         # ignore failure
19105         $LFS data_version $DIR/$tdir/$tfile || true
19106
19107         do_facet ost1 $LCTL set_param fail_loc=0
19108         umount_client $MOUNT || error "umount failed"
19109         mount_client $MOUNT || error "mount failed"
19110         stop ost1 || error "cannot stop ost1"
19111         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19112 }
19113 run_test 232b "failed data version lock should not block umount"
19114
19115 test_233a() {
19116         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19117                 skip "Need MDS version at least 2.3.64"
19118         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19119
19120         local fid=$($LFS path2fid $MOUNT)
19121
19122         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19123                 error "cannot access $MOUNT using its FID '$fid'"
19124 }
19125 run_test 233a "checking that OBF of the FS root succeeds"
19126
19127 test_233b() {
19128         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19129                 skip "Need MDS version at least 2.5.90"
19130         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19131
19132         local fid=$($LFS path2fid $MOUNT/.lustre)
19133
19134         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19135                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19136
19137         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19138         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19139                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19140 }
19141 run_test 233b "checking that OBF of the FS .lustre succeeds"
19142
19143 test_234() {
19144         local p="$TMP/sanityN-$TESTNAME.parameters"
19145         save_lustre_params client "llite.*.xattr_cache" > $p
19146         lctl set_param llite.*.xattr_cache 1 ||
19147                 skip_env "xattr cache is not supported"
19148
19149         mkdir -p $DIR/$tdir || error "mkdir failed"
19150         touch $DIR/$tdir/$tfile || error "touch failed"
19151         # OBD_FAIL_LLITE_XATTR_ENOMEM
19152         $LCTL set_param fail_loc=0x1405
19153         getfattr -n user.attr $DIR/$tdir/$tfile &&
19154                 error "getfattr should have failed with ENOMEM"
19155         $LCTL set_param fail_loc=0x0
19156         rm -rf $DIR/$tdir
19157
19158         restore_lustre_params < $p
19159         rm -f $p
19160 }
19161 run_test 234 "xattr cache should not crash on ENOMEM"
19162
19163 test_235() {
19164         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19165                 skip "Need MDS version at least 2.4.52"
19166
19167         flock_deadlock $DIR/$tfile
19168         local RC=$?
19169         case $RC in
19170                 0)
19171                 ;;
19172                 124) error "process hangs on a deadlock"
19173                 ;;
19174                 *) error "error executing flock_deadlock $DIR/$tfile"
19175                 ;;
19176         esac
19177 }
19178 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19179
19180 #LU-2935
19181 test_236() {
19182         check_swap_layouts_support
19183
19184         local ref1=/etc/passwd
19185         local ref2=/etc/group
19186         local file1=$DIR/$tdir/f1
19187         local file2=$DIR/$tdir/f2
19188
19189         test_mkdir -c1 $DIR/$tdir
19190         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19191         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19192         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19193         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19194         local fd=$(free_fd)
19195         local cmd="exec $fd<>$file2"
19196         eval $cmd
19197         rm $file2
19198         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19199                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19200         cmd="exec $fd>&-"
19201         eval $cmd
19202         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19203
19204         #cleanup
19205         rm -rf $DIR/$tdir
19206 }
19207 run_test 236 "Layout swap on open unlinked file"
19208
19209 # LU-4659 linkea consistency
19210 test_238() {
19211         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19212                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19213                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19214                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19215
19216         touch $DIR/$tfile
19217         ln $DIR/$tfile $DIR/$tfile.lnk
19218         touch $DIR/$tfile.new
19219         mv $DIR/$tfile.new $DIR/$tfile
19220         local fid1=$($LFS path2fid $DIR/$tfile)
19221         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19222         local path1=$($LFS fid2path $FSNAME "$fid1")
19223         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19224         local path2=$($LFS fid2path $FSNAME "$fid2")
19225         [ $tfile.lnk == $path2 ] ||
19226                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19227         rm -f $DIR/$tfile*
19228 }
19229 run_test 238 "Verify linkea consistency"
19230
19231 test_239A() { # was test_239
19232         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19233                 skip "Need MDS version at least 2.5.60"
19234
19235         local list=$(comma_list $(mdts_nodes))
19236
19237         mkdir -p $DIR/$tdir
19238         createmany -o $DIR/$tdir/f- 5000
19239         unlinkmany $DIR/$tdir/f- 5000
19240         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19241                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19242         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19243                         osp.*MDT*.sync_in_flight" | calc_sum)
19244         [ "$changes" -eq 0 ] || error "$changes not synced"
19245 }
19246 run_test 239A "osp_sync test"
19247
19248 test_239a() { #LU-5297
19249         remote_mds_nodsh && skip "remote MDS with nodsh"
19250
19251         touch $DIR/$tfile
19252         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19253         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19254         chgrp $RUNAS_GID $DIR/$tfile
19255         wait_delete_completed
19256 }
19257 run_test 239a "process invalid osp sync record correctly"
19258
19259 test_239b() { #LU-5297
19260         remote_mds_nodsh && skip "remote MDS with nodsh"
19261
19262         touch $DIR/$tfile1
19263         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19264         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19265         chgrp $RUNAS_GID $DIR/$tfile1
19266         wait_delete_completed
19267         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19268         touch $DIR/$tfile2
19269         chgrp $RUNAS_GID $DIR/$tfile2
19270         wait_delete_completed
19271 }
19272 run_test 239b "process osp sync record with ENOMEM error correctly"
19273
19274 test_240() {
19275         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19276         remote_mds_nodsh && skip "remote MDS with nodsh"
19277
19278         mkdir -p $DIR/$tdir
19279
19280         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19281                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19282         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19283                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19284
19285         umount_client $MOUNT || error "umount failed"
19286         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19287         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19288         mount_client $MOUNT || error "failed to mount client"
19289
19290         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19291         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19292 }
19293 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19294
19295 test_241_bio() {
19296         local count=$1
19297         local bsize=$2
19298
19299         for LOOP in $(seq $count); do
19300                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19301                 cancel_lru_locks $OSC || true
19302         done
19303 }
19304
19305 test_241_dio() {
19306         local count=$1
19307         local bsize=$2
19308
19309         for LOOP in $(seq $1); do
19310                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19311                         2>/dev/null
19312         done
19313 }
19314
19315 test_241a() { # was test_241
19316         local bsize=$PAGE_SIZE
19317
19318         (( bsize < 40960 )) && bsize=40960
19319         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19320         ls -la $DIR/$tfile
19321         cancel_lru_locks $OSC
19322         test_241_bio 1000 $bsize &
19323         PID=$!
19324         test_241_dio 1000 $bsize
19325         wait $PID
19326 }
19327 run_test 241a "bio vs dio"
19328
19329 test_241b() {
19330         local bsize=$PAGE_SIZE
19331
19332         (( bsize < 40960 )) && bsize=40960
19333         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19334         ls -la $DIR/$tfile
19335         test_241_dio 1000 $bsize &
19336         PID=$!
19337         test_241_dio 1000 $bsize
19338         wait $PID
19339 }
19340 run_test 241b "dio vs dio"
19341
19342 test_242() {
19343         remote_mds_nodsh && skip "remote MDS with nodsh"
19344
19345         mkdir -p $DIR/$tdir
19346         touch $DIR/$tdir/$tfile
19347
19348         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19349         do_facet mds1 lctl set_param fail_loc=0x105
19350         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19351
19352         do_facet mds1 lctl set_param fail_loc=0
19353         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19354 }
19355 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19356
19357 test_243()
19358 {
19359         test_mkdir $DIR/$tdir
19360         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19361 }
19362 run_test 243 "various group lock tests"
19363
19364 test_244a()
19365 {
19366         test_mkdir $DIR/$tdir
19367         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19368         sendfile_grouplock $DIR/$tdir/$tfile || \
19369                 error "sendfile+grouplock failed"
19370         rm -rf $DIR/$tdir
19371 }
19372 run_test 244a "sendfile with group lock tests"
19373
19374 test_244b()
19375 {
19376         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19377
19378         local threads=50
19379         local size=$((1024*1024))
19380
19381         test_mkdir $DIR/$tdir
19382         for i in $(seq 1 $threads); do
19383                 local file=$DIR/$tdir/file_$((i / 10))
19384                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19385                 local pids[$i]=$!
19386         done
19387         for i in $(seq 1 $threads); do
19388                 wait ${pids[$i]}
19389         done
19390 }
19391 run_test 244b "multi-threaded write with group lock"
19392
19393 test_245() {
19394         local flagname="multi_mod_rpcs"
19395         local connect_data_name="max_mod_rpcs"
19396         local out
19397
19398         # check if multiple modify RPCs flag is set
19399         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19400                 grep "connect_flags:")
19401         echo "$out"
19402
19403         echo "$out" | grep -qw $flagname
19404         if [ $? -ne 0 ]; then
19405                 echo "connect flag $flagname is not set"
19406                 return
19407         fi
19408
19409         # check if multiple modify RPCs data is set
19410         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19411         echo "$out"
19412
19413         echo "$out" | grep -qw $connect_data_name ||
19414                 error "import should have connect data $connect_data_name"
19415 }
19416 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19417
19418 cleanup_247() {
19419         local submount=$1
19420
19421         trap 0
19422         umount_client $submount
19423         rmdir $submount
19424 }
19425
19426 test_247a() {
19427         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19428                 grep -q subtree ||
19429                 skip_env "Fileset feature is not supported"
19430
19431         local submount=${MOUNT}_$tdir
19432
19433         mkdir $MOUNT/$tdir
19434         mkdir -p $submount || error "mkdir $submount failed"
19435         FILESET="$FILESET/$tdir" mount_client $submount ||
19436                 error "mount $submount failed"
19437         trap "cleanup_247 $submount" EXIT
19438         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19439         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19440                 error "read $MOUNT/$tdir/$tfile failed"
19441         cleanup_247 $submount
19442 }
19443 run_test 247a "mount subdir as fileset"
19444
19445 test_247b() {
19446         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19447                 skip_env "Fileset feature is not supported"
19448
19449         local submount=${MOUNT}_$tdir
19450
19451         rm -rf $MOUNT/$tdir
19452         mkdir -p $submount || error "mkdir $submount failed"
19453         SKIP_FILESET=1
19454         FILESET="$FILESET/$tdir" mount_client $submount &&
19455                 error "mount $submount should fail"
19456         rmdir $submount
19457 }
19458 run_test 247b "mount subdir that dose not exist"
19459
19460 test_247c() {
19461         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19462                 skip_env "Fileset feature is not supported"
19463
19464         local submount=${MOUNT}_$tdir
19465
19466         mkdir -p $MOUNT/$tdir/dir1
19467         mkdir -p $submount || error "mkdir $submount failed"
19468         trap "cleanup_247 $submount" EXIT
19469         FILESET="$FILESET/$tdir" mount_client $submount ||
19470                 error "mount $submount failed"
19471         local fid=$($LFS path2fid $MOUNT/)
19472         $LFS fid2path $submount $fid && error "fid2path should fail"
19473         cleanup_247 $submount
19474 }
19475 run_test 247c "running fid2path outside subdirectory root"
19476
19477 test_247d() {
19478         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19479                 skip "Fileset feature is not supported"
19480
19481         local submount=${MOUNT}_$tdir
19482
19483         mkdir -p $MOUNT/$tdir/dir1
19484         mkdir -p $submount || error "mkdir $submount failed"
19485         FILESET="$FILESET/$tdir" mount_client $submount ||
19486                 error "mount $submount failed"
19487         trap "cleanup_247 $submount" EXIT
19488
19489         local td=$submount/dir1
19490         local fid=$($LFS path2fid $td)
19491         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19492
19493         # check that we get the same pathname back
19494         local rootpath
19495         local found
19496         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19497                 echo "$rootpath $fid"
19498                 found=$($LFS fid2path $rootpath "$fid")
19499                 [ -n "found" ] || error "fid2path should succeed"
19500                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19501         done
19502         # check wrong root path format
19503         rootpath=$submount"_wrong"
19504         found=$($LFS fid2path $rootpath "$fid")
19505         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19506
19507         cleanup_247 $submount
19508 }
19509 run_test 247d "running fid2path inside subdirectory root"
19510
19511 # LU-8037
19512 test_247e() {
19513         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19514                 grep -q subtree ||
19515                 skip "Fileset feature is not supported"
19516
19517         local submount=${MOUNT}_$tdir
19518
19519         mkdir $MOUNT/$tdir
19520         mkdir -p $submount || error "mkdir $submount failed"
19521         FILESET="$FILESET/.." mount_client $submount &&
19522                 error "mount $submount should fail"
19523         rmdir $submount
19524 }
19525 run_test 247e "mount .. as fileset"
19526
19527 test_247f() {
19528         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19529         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19530                 skip "Need at least version 2.13.52"
19531         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19532                 grep -q subtree ||
19533                 skip "Fileset feature is not supported"
19534
19535         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19536         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19537                 error "mkdir remote failed"
19538         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19539         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19540                 error "mkdir striped failed"
19541         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19542
19543         local submount=${MOUNT}_$tdir
19544
19545         mkdir -p $submount || error "mkdir $submount failed"
19546
19547         local dir
19548         local fileset=$FILESET
19549
19550         for dir in $tdir/remote $tdir/remote/subdir \
19551                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19552                 FILESET="$fileset/$dir" mount_client $submount ||
19553                         error "mount $dir failed"
19554                 umount_client $submount
19555         done
19556 }
19557 run_test 247f "mount striped or remote directory as fileset"
19558
19559 test_248a() {
19560         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19561         [ -z "$fast_read_sav" ] && skip "no fast read support"
19562
19563         # create a large file for fast read verification
19564         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19565
19566         # make sure the file is created correctly
19567         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19568                 { rm -f $DIR/$tfile; skip "file creation error"; }
19569
19570         echo "Test 1: verify that fast read is 4 times faster on cache read"
19571
19572         # small read with fast read enabled
19573         $LCTL set_param -n llite.*.fast_read=1
19574         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19575                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19576                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19577         # small read with fast read disabled
19578         $LCTL set_param -n llite.*.fast_read=0
19579         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19580                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19581                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19582
19583         # verify that fast read is 4 times faster for cache read
19584         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19585                 error_not_in_vm "fast read was not 4 times faster: " \
19586                            "$t_fast vs $t_slow"
19587
19588         echo "Test 2: verify the performance between big and small read"
19589         $LCTL set_param -n llite.*.fast_read=1
19590
19591         # 1k non-cache read
19592         cancel_lru_locks osc
19593         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19594                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19595                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19596
19597         # 1M non-cache read
19598         cancel_lru_locks osc
19599         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19600                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19601                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19602
19603         # verify that big IO is not 4 times faster than small IO
19604         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19605                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19606
19607         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19608         rm -f $DIR/$tfile
19609 }
19610 run_test 248a "fast read verification"
19611
19612 test_248b() {
19613         # Default short_io_bytes=16384, try both smaller and larger sizes.
19614         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19615         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19616         echo "bs=53248 count=113 normal buffered write"
19617         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19618                 error "dd of initial data file failed"
19619         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19620
19621         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19622         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19623                 error "dd with sync normal writes failed"
19624         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19625
19626         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19627         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19628                 error "dd with sync small writes failed"
19629         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19630
19631         cancel_lru_locks osc
19632
19633         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19634         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19635         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19636         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19637                 iflag=direct || error "dd with O_DIRECT small read failed"
19638         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19639         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19640                 error "compare $TMP/$tfile.1 failed"
19641
19642         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19643         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19644
19645         # just to see what the maximum tunable value is, and test parsing
19646         echo "test invalid parameter 2MB"
19647         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19648                 error "too-large short_io_bytes allowed"
19649         echo "test maximum parameter 512KB"
19650         # if we can set a larger short_io_bytes, run test regardless of version
19651         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19652                 # older clients may not allow setting it this large, that's OK
19653                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19654                         skip "Need at least client version 2.13.50"
19655                 error "medium short_io_bytes failed"
19656         fi
19657         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19658         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19659
19660         echo "test large parameter 64KB"
19661         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19662         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19663
19664         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19665         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19666                 error "dd with sync large writes failed"
19667         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19668
19669         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19670         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19671         num=$((113 * 4096 / PAGE_SIZE))
19672         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19673         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19674                 error "dd with O_DIRECT large writes failed"
19675         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19676                 error "compare $DIR/$tfile.3 failed"
19677
19678         cancel_lru_locks osc
19679
19680         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19681         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19682                 error "dd with O_DIRECT large read failed"
19683         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19684                 error "compare $TMP/$tfile.2 failed"
19685
19686         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19687         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19688                 error "dd with O_DIRECT large read failed"
19689         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19690                 error "compare $TMP/$tfile.3 failed"
19691 }
19692 run_test 248b "test short_io read and write for both small and large sizes"
19693
19694 test_249() { # LU-7890
19695         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19696                 skip "Need at least version 2.8.54"
19697
19698         rm -f $DIR/$tfile
19699         $LFS setstripe -c 1 $DIR/$tfile
19700         # Offset 2T == 4k * 512M
19701         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19702                 error "dd to 2T offset failed"
19703 }
19704 run_test 249 "Write above 2T file size"
19705
19706 test_250() {
19707         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19708          && skip "no 16TB file size limit on ZFS"
19709
19710         $LFS setstripe -c 1 $DIR/$tfile
19711         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19712         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19713         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19714         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19715                 conv=notrunc,fsync && error "append succeeded"
19716         return 0
19717 }
19718 run_test 250 "Write above 16T limit"
19719
19720 test_251() {
19721         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19722
19723         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19724         #Skip once - writing the first stripe will succeed
19725         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19726         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19727                 error "short write happened"
19728
19729         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19730         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19731                 error "short read happened"
19732
19733         rm -f $DIR/$tfile
19734 }
19735 run_test 251 "Handling short read and write correctly"
19736
19737 test_252() {
19738         remote_mds_nodsh && skip "remote MDS with nodsh"
19739         remote_ost_nodsh && skip "remote OST with nodsh"
19740         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19741                 skip_env "ldiskfs only test"
19742         fi
19743
19744         local tgt
19745         local dev
19746         local out
19747         local uuid
19748         local num
19749         local gen
19750
19751         # check lr_reader on OST0000
19752         tgt=ost1
19753         dev=$(facet_device $tgt)
19754         out=$(do_facet $tgt $LR_READER $dev)
19755         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19756         echo "$out"
19757         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19758         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19759                 error "Invalid uuid returned by $LR_READER on target $tgt"
19760         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19761
19762         # check lr_reader -c on MDT0000
19763         tgt=mds1
19764         dev=$(facet_device $tgt)
19765         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19766                 skip "$LR_READER does not support additional options"
19767         fi
19768         out=$(do_facet $tgt $LR_READER -c $dev)
19769         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19770         echo "$out"
19771         num=$(echo "$out" | grep -c "mdtlov")
19772         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19773                 error "Invalid number of mdtlov clients returned by $LR_READER"
19774         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19775
19776         # check lr_reader -cr on MDT0000
19777         out=$(do_facet $tgt $LR_READER -cr $dev)
19778         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19779         echo "$out"
19780         echo "$out" | grep -q "^reply_data:$" ||
19781                 error "$LR_READER should have returned 'reply_data' section"
19782         num=$(echo "$out" | grep -c "client_generation")
19783         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19784 }
19785 run_test 252 "check lr_reader tool"
19786
19787 test_253() {
19788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19789         remote_mds_nodsh && skip "remote MDS with nodsh"
19790         remote_mgs_nodsh && skip "remote MGS with nodsh"
19791
19792         local ostidx=0
19793         local rc=0
19794         local ost_name=$(ostname_from_index $ostidx)
19795
19796         # on the mdt's osc
19797         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19798         do_facet $SINGLEMDS $LCTL get_param -n \
19799                 osp.$mdtosc_proc1.reserved_mb_high ||
19800                 skip  "remote MDS does not support reserved_mb_high"
19801
19802         rm -rf $DIR/$tdir
19803         wait_mds_ost_sync
19804         wait_delete_completed
19805         mkdir $DIR/$tdir
19806
19807         pool_add $TESTNAME || error "Pool creation failed"
19808         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19809
19810         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19811                 error "Setstripe failed"
19812
19813         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19814
19815         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19816                     grep "watermarks")
19817         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19818
19819         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19820                         osp.$mdtosc_proc1.prealloc_status)
19821         echo "prealloc_status $oa_status"
19822
19823         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19824                 error "File creation should fail"
19825
19826         #object allocation was stopped, but we still able to append files
19827         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19828                 oflag=append || error "Append failed"
19829
19830         rm -f $DIR/$tdir/$tfile.0
19831
19832         # For this test, we want to delete the files we created to go out of
19833         # space but leave the watermark, so we remain nearly out of space
19834         ost_watermarks_enospc_delete_files $tfile $ostidx
19835
19836         wait_delete_completed
19837
19838         sleep_maxage
19839
19840         for i in $(seq 10 12); do
19841                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19842                         2>/dev/null || error "File creation failed after rm"
19843         done
19844
19845         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19846                         osp.$mdtosc_proc1.prealloc_status)
19847         echo "prealloc_status $oa_status"
19848
19849         if (( oa_status != 0 )); then
19850                 error "Object allocation still disable after rm"
19851         fi
19852 }
19853 run_test 253 "Check object allocation limit"
19854
19855 test_254() {
19856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19857         remote_mds_nodsh && skip "remote MDS with nodsh"
19858         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19859                 skip "MDS does not support changelog_size"
19860
19861         local cl_user
19862         local MDT0=$(facet_svc $SINGLEMDS)
19863
19864         changelog_register || error "changelog_register failed"
19865
19866         changelog_clear 0 || error "changelog_clear failed"
19867
19868         local size1=$(do_facet $SINGLEMDS \
19869                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19870         echo "Changelog size $size1"
19871
19872         rm -rf $DIR/$tdir
19873         $LFS mkdir -i 0 $DIR/$tdir
19874         # change something
19875         mkdir -p $DIR/$tdir/pics/2008/zachy
19876         touch $DIR/$tdir/pics/2008/zachy/timestamp
19877         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19878         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19879         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19880         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19881         rm $DIR/$tdir/pics/desktop.jpg
19882
19883         local size2=$(do_facet $SINGLEMDS \
19884                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19885         echo "Changelog size after work $size2"
19886
19887         (( $size2 > $size1 )) ||
19888                 error "new Changelog size=$size2 less than old size=$size1"
19889 }
19890 run_test 254 "Check changelog size"
19891
19892 ladvise_no_type()
19893 {
19894         local type=$1
19895         local file=$2
19896
19897         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19898                 awk -F: '{print $2}' | grep $type > /dev/null
19899         if [ $? -ne 0 ]; then
19900                 return 0
19901         fi
19902         return 1
19903 }
19904
19905 ladvise_no_ioctl()
19906 {
19907         local file=$1
19908
19909         lfs ladvise -a willread $file > /dev/null 2>&1
19910         if [ $? -eq 0 ]; then
19911                 return 1
19912         fi
19913
19914         lfs ladvise -a willread $file 2>&1 |
19915                 grep "Inappropriate ioctl for device" > /dev/null
19916         if [ $? -eq 0 ]; then
19917                 return 0
19918         fi
19919         return 1
19920 }
19921
19922 percent() {
19923         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19924 }
19925
19926 # run a random read IO workload
19927 # usage: random_read_iops <filename> <filesize> <iosize>
19928 random_read_iops() {
19929         local file=$1
19930         local fsize=$2
19931         local iosize=${3:-4096}
19932
19933         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19934                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19935 }
19936
19937 drop_file_oss_cache() {
19938         local file="$1"
19939         local nodes="$2"
19940
19941         $LFS ladvise -a dontneed $file 2>/dev/null ||
19942                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19943 }
19944
19945 ladvise_willread_performance()
19946 {
19947         local repeat=10
19948         local average_origin=0
19949         local average_cache=0
19950         local average_ladvise=0
19951
19952         for ((i = 1; i <= $repeat; i++)); do
19953                 echo "Iter $i/$repeat: reading without willread hint"
19954                 cancel_lru_locks osc
19955                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19956                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19957                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19958                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19959
19960                 cancel_lru_locks osc
19961                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19962                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19963                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19964
19965                 cancel_lru_locks osc
19966                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19967                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19968                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19969                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19970                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19971         done
19972         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19973         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19974         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19975
19976         speedup_cache=$(percent $average_cache $average_origin)
19977         speedup_ladvise=$(percent $average_ladvise $average_origin)
19978
19979         echo "Average uncached read: $average_origin"
19980         echo "Average speedup with OSS cached read: " \
19981                 "$average_cache = +$speedup_cache%"
19982         echo "Average speedup with ladvise willread: " \
19983                 "$average_ladvise = +$speedup_ladvise%"
19984
19985         local lowest_speedup=20
19986         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19987                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19988                         "got $average_cache%. Skipping ladvise willread check."
19989                 return 0
19990         fi
19991
19992         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19993         # it is still good to run until then to exercise 'ladvise willread'
19994         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19995                 [ "$ost1_FSTYPE" = "zfs" ] &&
19996                 echo "osd-zfs does not support dontneed or drop_caches" &&
19997                 return 0
19998
19999         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20000         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20001                 error_not_in_vm "Speedup with willread is less than " \
20002                         "$lowest_speedup%, got $average_ladvise%"
20003 }
20004
20005 test_255a() {
20006         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20007                 skip "lustre < 2.8.54 does not support ladvise "
20008         remote_ost_nodsh && skip "remote OST with nodsh"
20009
20010         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20011
20012         ladvise_no_type willread $DIR/$tfile &&
20013                 skip "willread ladvise is not supported"
20014
20015         ladvise_no_ioctl $DIR/$tfile &&
20016                 skip "ladvise ioctl is not supported"
20017
20018         local size_mb=100
20019         local size=$((size_mb * 1048576))
20020         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20021                 error "dd to $DIR/$tfile failed"
20022
20023         lfs ladvise -a willread $DIR/$tfile ||
20024                 error "Ladvise failed with no range argument"
20025
20026         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20027                 error "Ladvise failed with no -l or -e argument"
20028
20029         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20030                 error "Ladvise failed with only -e argument"
20031
20032         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20033                 error "Ladvise failed with only -l argument"
20034
20035         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20036                 error "End offset should not be smaller than start offset"
20037
20038         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20039                 error "End offset should not be equal to start offset"
20040
20041         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20042                 error "Ladvise failed with overflowing -s argument"
20043
20044         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20045                 error "Ladvise failed with overflowing -e argument"
20046
20047         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20048                 error "Ladvise failed with overflowing -l argument"
20049
20050         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20051                 error "Ladvise succeeded with conflicting -l and -e arguments"
20052
20053         echo "Synchronous ladvise should wait"
20054         local delay=4
20055 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20056         do_nodes $(comma_list $(osts_nodes)) \
20057                 $LCTL set_param fail_val=$delay fail_loc=0x237
20058
20059         local start_ts=$SECONDS
20060         lfs ladvise -a willread $DIR/$tfile ||
20061                 error "Ladvise failed with no range argument"
20062         local end_ts=$SECONDS
20063         local inteval_ts=$((end_ts - start_ts))
20064
20065         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20066                 error "Synchronous advice didn't wait reply"
20067         fi
20068
20069         echo "Asynchronous ladvise shouldn't wait"
20070         local start_ts=$SECONDS
20071         lfs ladvise -a willread -b $DIR/$tfile ||
20072                 error "Ladvise failed with no range argument"
20073         local end_ts=$SECONDS
20074         local inteval_ts=$((end_ts - start_ts))
20075
20076         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20077                 error "Asynchronous advice blocked"
20078         fi
20079
20080         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20081         ladvise_willread_performance
20082 }
20083 run_test 255a "check 'lfs ladvise -a willread'"
20084
20085 facet_meminfo() {
20086         local facet=$1
20087         local info=$2
20088
20089         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20090 }
20091
20092 test_255b() {
20093         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20094                 skip "lustre < 2.8.54 does not support ladvise "
20095         remote_ost_nodsh && skip "remote OST with nodsh"
20096
20097         lfs setstripe -c 1 -i 0 $DIR/$tfile
20098
20099         ladvise_no_type dontneed $DIR/$tfile &&
20100                 skip "dontneed ladvise is not supported"
20101
20102         ladvise_no_ioctl $DIR/$tfile &&
20103                 skip "ladvise ioctl is not supported"
20104
20105         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20106                 [ "$ost1_FSTYPE" = "zfs" ] &&
20107                 skip "zfs-osd does not support 'ladvise dontneed'"
20108
20109         local size_mb=100
20110         local size=$((size_mb * 1048576))
20111         # In order to prevent disturbance of other processes, only check 3/4
20112         # of the memory usage
20113         local kibibytes=$((size_mb * 1024 * 3 / 4))
20114
20115         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20116                 error "dd to $DIR/$tfile failed"
20117
20118         #force write to complete before dropping OST cache & checking memory
20119         sync
20120
20121         local total=$(facet_meminfo ost1 MemTotal)
20122         echo "Total memory: $total KiB"
20123
20124         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20125         local before_read=$(facet_meminfo ost1 Cached)
20126         echo "Cache used before read: $before_read KiB"
20127
20128         lfs ladvise -a willread $DIR/$tfile ||
20129                 error "Ladvise willread failed"
20130         local after_read=$(facet_meminfo ost1 Cached)
20131         echo "Cache used after read: $after_read KiB"
20132
20133         lfs ladvise -a dontneed $DIR/$tfile ||
20134                 error "Ladvise dontneed again failed"
20135         local no_read=$(facet_meminfo ost1 Cached)
20136         echo "Cache used after dontneed ladvise: $no_read KiB"
20137
20138         if [ $total -lt $((before_read + kibibytes)) ]; then
20139                 echo "Memory is too small, abort checking"
20140                 return 0
20141         fi
20142
20143         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20144                 error "Ladvise willread should use more memory" \
20145                         "than $kibibytes KiB"
20146         fi
20147
20148         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20149                 error "Ladvise dontneed should release more memory" \
20150                         "than $kibibytes KiB"
20151         fi
20152 }
20153 run_test 255b "check 'lfs ladvise -a dontneed'"
20154
20155 test_255c() {
20156         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20157                 skip "lustre < 2.10.50 does not support lockahead"
20158
20159         local ost1_imp=$(get_osc_import_name client ost1)
20160         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20161                          cut -d'.' -f2)
20162         local count
20163         local new_count
20164         local difference
20165         local i
20166         local rc
20167
20168         test_mkdir -p $DIR/$tdir
20169         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20170
20171         #test 10 returns only success/failure
20172         i=10
20173         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20174         rc=$?
20175         if [ $rc -eq 255 ]; then
20176                 error "Ladvise test${i} failed, ${rc}"
20177         fi
20178
20179         #test 11 counts lock enqueue requests, all others count new locks
20180         i=11
20181         count=$(do_facet ost1 \
20182                 $LCTL get_param -n ost.OSS.ost.stats)
20183         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20184
20185         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20186         rc=$?
20187         if [ $rc -eq 255 ]; then
20188                 error "Ladvise test${i} failed, ${rc}"
20189         fi
20190
20191         new_count=$(do_facet ost1 \
20192                 $LCTL get_param -n ost.OSS.ost.stats)
20193         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20194                    awk '{ print $2 }')
20195
20196         difference="$((new_count - count))"
20197         if [ $difference -ne $rc ]; then
20198                 error "Ladvise test${i}, bad enqueue count, returned " \
20199                       "${rc}, actual ${difference}"
20200         fi
20201
20202         for i in $(seq 12 21); do
20203                 # If we do not do this, we run the risk of having too many
20204                 # locks and starting lock cancellation while we are checking
20205                 # lock counts.
20206                 cancel_lru_locks osc
20207
20208                 count=$($LCTL get_param -n \
20209                        ldlm.namespaces.$imp_name.lock_unused_count)
20210
20211                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20212                 rc=$?
20213                 if [ $rc -eq 255 ]; then
20214                         error "Ladvise test ${i} failed, ${rc}"
20215                 fi
20216
20217                 new_count=$($LCTL get_param -n \
20218                        ldlm.namespaces.$imp_name.lock_unused_count)
20219                 difference="$((new_count - count))"
20220
20221                 # Test 15 output is divided by 100 to map down to valid return
20222                 if [ $i -eq 15 ]; then
20223                         rc="$((rc * 100))"
20224                 fi
20225
20226                 if [ $difference -ne $rc ]; then
20227                         error "Ladvise test ${i}, bad lock count, returned " \
20228                               "${rc}, actual ${difference}"
20229                 fi
20230         done
20231
20232         #test 22 returns only success/failure
20233         i=22
20234         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20235         rc=$?
20236         if [ $rc -eq 255 ]; then
20237                 error "Ladvise test${i} failed, ${rc}"
20238         fi
20239 }
20240 run_test 255c "suite of ladvise lockahead tests"
20241
20242 test_256() {
20243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20244         remote_mds_nodsh && skip "remote MDS with nodsh"
20245         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20246         changelog_users $SINGLEMDS | grep "^cl" &&
20247                 skip "active changelog user"
20248
20249         local cl_user
20250         local cat_sl
20251         local mdt_dev
20252
20253         mdt_dev=$(mdsdevname 1)
20254         echo $mdt_dev
20255
20256         changelog_register || error "changelog_register failed"
20257
20258         rm -rf $DIR/$tdir
20259         mkdir -p $DIR/$tdir
20260
20261         changelog_clear 0 || error "changelog_clear failed"
20262
20263         # change something
20264         touch $DIR/$tdir/{1..10}
20265
20266         # stop the MDT
20267         stop $SINGLEMDS || error "Fail to stop MDT"
20268
20269         # remount the MDT
20270
20271         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20272
20273         #after mount new plainllog is used
20274         touch $DIR/$tdir/{11..19}
20275         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20276         stack_trap "rm -f $tmpfile"
20277         cat_sl=$(do_facet $SINGLEMDS "sync; \
20278                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20279                  llog_reader $tmpfile | grep -c type=1064553b")
20280         do_facet $SINGLEMDS llog_reader $tmpfile
20281
20282         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20283
20284         changelog_clear 0 || error "changelog_clear failed"
20285
20286         cat_sl=$(do_facet $SINGLEMDS "sync; \
20287                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20288                  llog_reader $tmpfile | grep -c type=1064553b")
20289
20290         if (( cat_sl == 2 )); then
20291                 error "Empty plain llog was not deleted from changelog catalog"
20292         elif (( cat_sl != 1 )); then
20293                 error "Active plain llog shouldn't be deleted from catalog"
20294         fi
20295 }
20296 run_test 256 "Check llog delete for empty and not full state"
20297
20298 test_257() {
20299         remote_mds_nodsh && skip "remote MDS with nodsh"
20300         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20301                 skip "Need MDS version at least 2.8.55"
20302
20303         test_mkdir $DIR/$tdir
20304
20305         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20306                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20307         stat $DIR/$tdir
20308
20309 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20310         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20311         local facet=mds$((mdtidx + 1))
20312         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20313         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20314
20315         stop $facet || error "stop MDS failed"
20316         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20317                 error "start MDS fail"
20318         wait_recovery_complete $facet
20319 }
20320 run_test 257 "xattr locks are not lost"
20321
20322 # Verify we take the i_mutex when security requires it
20323 test_258a() {
20324 #define OBD_FAIL_IMUTEX_SEC 0x141c
20325         $LCTL set_param fail_loc=0x141c
20326         touch $DIR/$tfile
20327         chmod u+s $DIR/$tfile
20328         chmod a+rwx $DIR/$tfile
20329         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20330         RC=$?
20331         if [ $RC -ne 0 ]; then
20332                 error "error, failed to take i_mutex, rc=$?"
20333         fi
20334         rm -f $DIR/$tfile
20335 }
20336 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20337
20338 # Verify we do NOT take the i_mutex in the normal case
20339 test_258b() {
20340 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20341         $LCTL set_param fail_loc=0x141d
20342         touch $DIR/$tfile
20343         chmod a+rwx $DIR
20344         chmod a+rw $DIR/$tfile
20345         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20346         RC=$?
20347         if [ $RC -ne 0 ]; then
20348                 error "error, took i_mutex unnecessarily, rc=$?"
20349         fi
20350         rm -f $DIR/$tfile
20351
20352 }
20353 run_test 258b "verify i_mutex security behavior"
20354
20355 test_259() {
20356         local file=$DIR/$tfile
20357         local before
20358         local after
20359
20360         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20361
20362         stack_trap "rm -f $file" EXIT
20363
20364         wait_delete_completed
20365         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20366         echo "before: $before"
20367
20368         $LFS setstripe -i 0 -c 1 $file
20369         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20370         sync_all_data
20371         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20372         echo "after write: $after"
20373
20374 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20375         do_facet ost1 $LCTL set_param fail_loc=0x2301
20376         $TRUNCATE $file 0
20377         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20378         echo "after truncate: $after"
20379
20380         stop ost1
20381         do_facet ost1 $LCTL set_param fail_loc=0
20382         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20383         sleep 2
20384         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20385         echo "after restart: $after"
20386         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20387                 error "missing truncate?"
20388
20389         return 0
20390 }
20391 run_test 259 "crash at delayed truncate"
20392
20393 test_260() {
20394 #define OBD_FAIL_MDC_CLOSE               0x806
20395         $LCTL set_param fail_loc=0x80000806
20396         touch $DIR/$tfile
20397
20398 }
20399 run_test 260 "Check mdc_close fail"
20400
20401 ### Data-on-MDT sanity tests ###
20402 test_270a() {
20403         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20404                 skip "Need MDS version at least 2.10.55 for DoM"
20405
20406         # create DoM file
20407         local dom=$DIR/$tdir/dom_file
20408         local tmp=$DIR/$tdir/tmp_file
20409
20410         mkdir -p $DIR/$tdir
20411
20412         # basic checks for DoM component creation
20413         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20414                 error "Can set MDT layout to non-first entry"
20415
20416         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20417                 error "Can define multiple entries as MDT layout"
20418
20419         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20420
20421         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20422         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20423         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20424
20425         local mdtidx=$($LFS getstripe -m $dom)
20426         local mdtname=MDT$(printf %04x $mdtidx)
20427         local facet=mds$((mdtidx + 1))
20428         local space_check=1
20429
20430         # Skip free space checks with ZFS
20431         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20432
20433         # write
20434         sync
20435         local size_tmp=$((65536 * 3))
20436         local mdtfree1=$(do_facet $facet \
20437                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20438
20439         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20440         # check also direct IO along write
20441         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20442         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20443         sync
20444         cmp $tmp $dom || error "file data is different"
20445         [ $(stat -c%s $dom) == $size_tmp ] ||
20446                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20447         if [ $space_check == 1 ]; then
20448                 local mdtfree2=$(do_facet $facet \
20449                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20450
20451                 # increase in usage from by $size_tmp
20452                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20453                         error "MDT free space wrong after write: " \
20454                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20455         fi
20456
20457         # truncate
20458         local size_dom=10000
20459
20460         $TRUNCATE $dom $size_dom
20461         [ $(stat -c%s $dom) == $size_dom ] ||
20462                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20463         if [ $space_check == 1 ]; then
20464                 mdtfree1=$(do_facet $facet \
20465                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20466                 # decrease in usage from $size_tmp to new $size_dom
20467                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20468                   $(((size_tmp - size_dom) / 1024)) ] ||
20469                         error "MDT free space is wrong after truncate: " \
20470                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20471         fi
20472
20473         # append
20474         cat $tmp >> $dom
20475         sync
20476         size_dom=$((size_dom + size_tmp))
20477         [ $(stat -c%s $dom) == $size_dom ] ||
20478                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20479         if [ $space_check == 1 ]; then
20480                 mdtfree2=$(do_facet $facet \
20481                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20482                 # increase in usage by $size_tmp from previous
20483                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20484                         error "MDT free space is wrong after append: " \
20485                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20486         fi
20487
20488         # delete
20489         rm $dom
20490         if [ $space_check == 1 ]; then
20491                 mdtfree1=$(do_facet $facet \
20492                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20493                 # decrease in usage by $size_dom from previous
20494                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20495                         error "MDT free space is wrong after removal: " \
20496                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20497         fi
20498
20499         # combined striping
20500         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20501                 error "Can't create DoM + OST striping"
20502
20503         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20504         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20505         # check also direct IO along write
20506         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20507         sync
20508         cmp $tmp $dom || error "file data is different"
20509         [ $(stat -c%s $dom) == $size_tmp ] ||
20510                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20511         rm $dom $tmp
20512
20513         return 0
20514 }
20515 run_test 270a "DoM: basic functionality tests"
20516
20517 test_270b() {
20518         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20519                 skip "Need MDS version at least 2.10.55"
20520
20521         local dom=$DIR/$tdir/dom_file
20522         local max_size=1048576
20523
20524         mkdir -p $DIR/$tdir
20525         $LFS setstripe -E $max_size -L mdt $dom
20526
20527         # truncate over the limit
20528         $TRUNCATE $dom $(($max_size + 1)) &&
20529                 error "successful truncate over the maximum size"
20530         # write over the limit
20531         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20532                 error "successful write over the maximum size"
20533         # append over the limit
20534         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20535         echo "12345" >> $dom && error "successful append over the maximum size"
20536         rm $dom
20537
20538         return 0
20539 }
20540 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20541
20542 test_270c() {
20543         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20544                 skip "Need MDS version at least 2.10.55"
20545
20546         mkdir -p $DIR/$tdir
20547         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20548
20549         # check files inherit DoM EA
20550         touch $DIR/$tdir/first
20551         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20552                 error "bad pattern"
20553         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20554                 error "bad stripe count"
20555         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20556                 error "bad stripe size"
20557
20558         # check directory inherits DoM EA and uses it as default
20559         mkdir $DIR/$tdir/subdir
20560         touch $DIR/$tdir/subdir/second
20561         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20562                 error "bad pattern in sub-directory"
20563         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20564                 error "bad stripe count in sub-directory"
20565         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20566                 error "bad stripe size in sub-directory"
20567         return 0
20568 }
20569 run_test 270c "DoM: DoM EA inheritance tests"
20570
20571 test_270d() {
20572         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20573                 skip "Need MDS version at least 2.10.55"
20574
20575         mkdir -p $DIR/$tdir
20576         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20577
20578         # inherit default DoM striping
20579         mkdir $DIR/$tdir/subdir
20580         touch $DIR/$tdir/subdir/f1
20581
20582         # change default directory striping
20583         $LFS setstripe -c 1 $DIR/$tdir/subdir
20584         touch $DIR/$tdir/subdir/f2
20585         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20586                 error "wrong default striping in file 2"
20587         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20588                 error "bad pattern in file 2"
20589         return 0
20590 }
20591 run_test 270d "DoM: change striping from DoM to RAID0"
20592
20593 test_270e() {
20594         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20595                 skip "Need MDS version at least 2.10.55"
20596
20597         mkdir -p $DIR/$tdir/dom
20598         mkdir -p $DIR/$tdir/norm
20599         DOMFILES=20
20600         NORMFILES=10
20601         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20602         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20603
20604         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20605         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20606
20607         # find DoM files by layout
20608         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20609         [ $NUM -eq  $DOMFILES ] ||
20610                 error "lfs find -L: found $NUM, expected $DOMFILES"
20611         echo "Test 1: lfs find 20 DOM files by layout: OK"
20612
20613         # there should be 1 dir with default DOM striping
20614         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20615         [ $NUM -eq  1 ] ||
20616                 error "lfs find -L: found $NUM, expected 1 dir"
20617         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20618
20619         # find DoM files by stripe size
20620         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20621         [ $NUM -eq  $DOMFILES ] ||
20622                 error "lfs find -S: found $NUM, expected $DOMFILES"
20623         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20624
20625         # find files by stripe offset except DoM files
20626         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20627         [ $NUM -eq  $NORMFILES ] ||
20628                 error "lfs find -i: found $NUM, expected $NORMFILES"
20629         echo "Test 5: lfs find no DOM files by stripe index: OK"
20630         return 0
20631 }
20632 run_test 270e "DoM: lfs find with DoM files test"
20633
20634 test_270f() {
20635         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20636                 skip "Need MDS version at least 2.10.55"
20637
20638         local mdtname=${FSNAME}-MDT0000-mdtlov
20639         local dom=$DIR/$tdir/dom_file
20640         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20641                                                 lod.$mdtname.dom_stripesize)
20642         local dom_limit=131072
20643
20644         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20645         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20646                                                 lod.$mdtname.dom_stripesize)
20647         [ ${dom_limit} -eq ${dom_current} ] ||
20648                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20649
20650         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20651         $LFS setstripe -d $DIR/$tdir
20652         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20653                 error "Can't set directory default striping"
20654
20655         # exceed maximum stripe size
20656         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20657                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20658         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20659                 error "Able to create DoM component size more than LOD limit"
20660
20661         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20662         dom_current=$(do_facet mds1 $LCTL get_param -n \
20663                                                 lod.$mdtname.dom_stripesize)
20664         [ 0 -eq ${dom_current} ] ||
20665                 error "Can't set zero DoM stripe limit"
20666         rm $dom
20667
20668         # attempt to create DoM file on server with disabled DoM should
20669         # remove DoM entry from layout and be succeed
20670         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20671                 error "Can't create DoM file (DoM is disabled)"
20672         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20673                 error "File has DoM component while DoM is disabled"
20674         rm $dom
20675
20676         # attempt to create DoM file with only DoM stripe should return error
20677         $LFS setstripe -E $dom_limit -L mdt $dom &&
20678                 error "Able to create DoM-only file while DoM is disabled"
20679
20680         # too low values to be aligned with smallest stripe size 64K
20681         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20682         dom_current=$(do_facet mds1 $LCTL get_param -n \
20683                                                 lod.$mdtname.dom_stripesize)
20684         [ 30000 -eq ${dom_current} ] &&
20685                 error "Can set too small DoM stripe limit"
20686
20687         # 64K is a minimal stripe size in Lustre, expect limit of that size
20688         [ 65536 -eq ${dom_current} ] ||
20689                 error "Limit is not set to 64K but ${dom_current}"
20690
20691         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20692         dom_current=$(do_facet mds1 $LCTL get_param -n \
20693                                                 lod.$mdtname.dom_stripesize)
20694         echo $dom_current
20695         [ 2147483648 -eq ${dom_current} ] &&
20696                 error "Can set too large DoM stripe limit"
20697
20698         do_facet mds1 $LCTL set_param -n \
20699                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20700         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20701                 error "Can't create DoM component size after limit change"
20702         do_facet mds1 $LCTL set_param -n \
20703                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20704         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20705                 error "Can't create DoM file after limit decrease"
20706         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20707                 error "Can create big DoM component after limit decrease"
20708         touch ${dom}_def ||
20709                 error "Can't create file with old default layout"
20710
20711         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20712         return 0
20713 }
20714 run_test 270f "DoM: maximum DoM stripe size checks"
20715
20716 test_270g() {
20717         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20718                 skip "Need MDS version at least 2.13.52"
20719         local dom=$DIR/$tdir/$tfile
20720
20721         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20722         local lodname=${FSNAME}-MDT0000-mdtlov
20723
20724         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20725         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20726         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20727         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20728
20729         local dom_limit=1024
20730         local dom_threshold="50%"
20731
20732         $LFS setstripe -d $DIR/$tdir
20733         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20734                 error "Can't set directory default striping"
20735
20736         do_facet mds1 $LCTL set_param -n \
20737                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20738         # set 0 threshold and create DOM file to change tunable stripesize
20739         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20740         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20741                 error "Failed to create $dom file"
20742         # now tunable dom_cur_stripesize should reach maximum
20743         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20744                                         lod.${lodname}.dom_stripesize_cur_kb)
20745         [[ $dom_current == $dom_limit ]] ||
20746                 error "Current DOM stripesize is not maximum"
20747         rm $dom
20748
20749         # set threshold for further tests
20750         do_facet mds1 $LCTL set_param -n \
20751                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20752         echo "DOM threshold is $dom_threshold free space"
20753         local dom_def
20754         local dom_set
20755         # Spoof bfree to exceed threshold
20756         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20757         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20758         for spfree in 40 20 0 15 30 55; do
20759                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20760                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20761                         error "Failed to create $dom file"
20762                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20763                                         lod.${lodname}.dom_stripesize_cur_kb)
20764                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20765                 [[ $dom_def != $dom_current ]] ||
20766                         error "Default stripe size was not changed"
20767                 if [[ $spfree > 0 ]] ; then
20768                         dom_set=$($LFS getstripe -S $dom)
20769                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20770                                 error "DOM component size is still old"
20771                 else
20772                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20773                                 error "DoM component is set with no free space"
20774                 fi
20775                 rm $dom
20776                 dom_current=$dom_def
20777         done
20778 }
20779 run_test 270g "DoM: default DoM stripe size depends on free space"
20780
20781 test_270h() {
20782         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20783                 skip "Need MDS version at least 2.13.53"
20784
20785         local mdtname=${FSNAME}-MDT0000-mdtlov
20786         local dom=$DIR/$tdir/$tfile
20787         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20788
20789         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20790         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20791
20792         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20793         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20794                 error "can't create OST file"
20795         # mirrored file with DOM entry in the second mirror
20796         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20797                 error "can't create mirror with DoM component"
20798
20799         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20800
20801         # DOM component in the middle and has other enries in the same mirror,
20802         # should succeed but lost DoM component
20803         $LFS setstripe --copy=${dom}_1 $dom ||
20804                 error "Can't create file from OST|DOM mirror layout"
20805         # check new file has no DoM layout after all
20806         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20807                 error "File has DoM component while DoM is disabled"
20808 }
20809 run_test 270h "DoM: DoM stripe removal when disabled on server"
20810
20811 test_271a() {
20812         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20813                 skip "Need MDS version at least 2.10.55"
20814
20815         local dom=$DIR/$tdir/dom
20816
20817         mkdir -p $DIR/$tdir
20818
20819         $LFS setstripe -E 1024K -L mdt $dom
20820
20821         lctl set_param -n mdc.*.stats=clear
20822         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20823         cat $dom > /dev/null
20824         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20825         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20826         ls $dom
20827         rm -f $dom
20828 }
20829 run_test 271a "DoM: data is cached for read after write"
20830
20831 test_271b() {
20832         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20833                 skip "Need MDS version at least 2.10.55"
20834
20835         local dom=$DIR/$tdir/dom
20836
20837         mkdir -p $DIR/$tdir
20838
20839         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20840
20841         lctl set_param -n mdc.*.stats=clear
20842         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20843         cancel_lru_locks mdc
20844         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20845         # second stat to check size is cached on client
20846         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20847         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20848         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20849         rm -f $dom
20850 }
20851 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20852
20853 test_271ba() {
20854         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20855                 skip "Need MDS version at least 2.10.55"
20856
20857         local dom=$DIR/$tdir/dom
20858
20859         mkdir -p $DIR/$tdir
20860
20861         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20862
20863         lctl set_param -n mdc.*.stats=clear
20864         lctl set_param -n osc.*.stats=clear
20865         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20866         cancel_lru_locks mdc
20867         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20868         # second stat to check size is cached on client
20869         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20870         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20871         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20872         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20873         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20874         rm -f $dom
20875 }
20876 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20877
20878
20879 get_mdc_stats() {
20880         local mdtidx=$1
20881         local param=$2
20882         local mdt=MDT$(printf %04x $mdtidx)
20883
20884         if [ -z $param ]; then
20885                 lctl get_param -n mdc.*$mdt*.stats
20886         else
20887                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20888         fi
20889 }
20890
20891 test_271c() {
20892         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20893                 skip "Need MDS version at least 2.10.55"
20894
20895         local dom=$DIR/$tdir/dom
20896
20897         mkdir -p $DIR/$tdir
20898
20899         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20900
20901         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20902         local facet=mds$((mdtidx + 1))
20903
20904         cancel_lru_locks mdc
20905         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20906         createmany -o $dom 1000
20907         lctl set_param -n mdc.*.stats=clear
20908         smalliomany -w $dom 1000 200
20909         get_mdc_stats $mdtidx
20910         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20911         # Each file has 1 open, 1 IO enqueues, total 2000
20912         # but now we have also +1 getxattr for security.capability, total 3000
20913         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20914         unlinkmany $dom 1000
20915
20916         cancel_lru_locks mdc
20917         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20918         createmany -o $dom 1000
20919         lctl set_param -n mdc.*.stats=clear
20920         smalliomany -w $dom 1000 200
20921         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20922         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20923         # for OPEN and IO lock.
20924         [ $((enq - enq_2)) -ge 1000 ] ||
20925                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20926         unlinkmany $dom 1000
20927         return 0
20928 }
20929 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20930
20931 cleanup_271def_tests() {
20932         trap 0
20933         rm -f $1
20934 }
20935
20936 test_271d() {
20937         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20938                 skip "Need MDS version at least 2.10.57"
20939
20940         local dom=$DIR/$tdir/dom
20941         local tmp=$TMP/$tfile
20942         trap "cleanup_271def_tests $tmp" EXIT
20943
20944         mkdir -p $DIR/$tdir
20945
20946         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20947
20948         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20949
20950         cancel_lru_locks mdc
20951         dd if=/dev/urandom of=$tmp bs=1000 count=1
20952         dd if=$tmp of=$dom bs=1000 count=1
20953         cancel_lru_locks mdc
20954
20955         cat /etc/hosts >> $tmp
20956         lctl set_param -n mdc.*.stats=clear
20957
20958         # append data to the same file it should update local page
20959         echo "Append to the same page"
20960         cat /etc/hosts >> $dom
20961         local num=$(get_mdc_stats $mdtidx ost_read)
20962         local ra=$(get_mdc_stats $mdtidx req_active)
20963         local rw=$(get_mdc_stats $mdtidx req_waittime)
20964
20965         [ -z $num ] || error "$num READ RPC occured"
20966         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20967         echo "... DONE"
20968
20969         # compare content
20970         cmp $tmp $dom || error "file miscompare"
20971
20972         cancel_lru_locks mdc
20973         lctl set_param -n mdc.*.stats=clear
20974
20975         echo "Open and read file"
20976         cat $dom > /dev/null
20977         local num=$(get_mdc_stats $mdtidx ost_read)
20978         local ra=$(get_mdc_stats $mdtidx req_active)
20979         local rw=$(get_mdc_stats $mdtidx req_waittime)
20980
20981         [ -z $num ] || error "$num READ RPC occured"
20982         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20983         echo "... DONE"
20984
20985         # compare content
20986         cmp $tmp $dom || error "file miscompare"
20987
20988         return 0
20989 }
20990 run_test 271d "DoM: read on open (1K file in reply buffer)"
20991
20992 test_271f() {
20993         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20994                 skip "Need MDS version at least 2.10.57"
20995
20996         local dom=$DIR/$tdir/dom
20997         local tmp=$TMP/$tfile
20998         trap "cleanup_271def_tests $tmp" EXIT
20999
21000         mkdir -p $DIR/$tdir
21001
21002         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21003
21004         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21005
21006         cancel_lru_locks mdc
21007         dd if=/dev/urandom of=$tmp bs=265000 count=1
21008         dd if=$tmp of=$dom bs=265000 count=1
21009         cancel_lru_locks mdc
21010         cat /etc/hosts >> $tmp
21011         lctl set_param -n mdc.*.stats=clear
21012
21013         echo "Append to the same page"
21014         cat /etc/hosts >> $dom
21015         local num=$(get_mdc_stats $mdtidx ost_read)
21016         local ra=$(get_mdc_stats $mdtidx req_active)
21017         local rw=$(get_mdc_stats $mdtidx req_waittime)
21018
21019         [ -z $num ] || error "$num READ RPC occured"
21020         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21021         echo "... DONE"
21022
21023         # compare content
21024         cmp $tmp $dom || error "file miscompare"
21025
21026         cancel_lru_locks mdc
21027         lctl set_param -n mdc.*.stats=clear
21028
21029         echo "Open and read file"
21030         cat $dom > /dev/null
21031         local num=$(get_mdc_stats $mdtidx ost_read)
21032         local ra=$(get_mdc_stats $mdtidx req_active)
21033         local rw=$(get_mdc_stats $mdtidx req_waittime)
21034
21035         [ -z $num ] && num=0
21036         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21037         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21038         echo "... DONE"
21039
21040         # compare content
21041         cmp $tmp $dom || error "file miscompare"
21042
21043         return 0
21044 }
21045 run_test 271f "DoM: read on open (200K file and read tail)"
21046
21047 test_271g() {
21048         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21049                 skip "Skipping due to old client or server version"
21050
21051         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21052         # to get layout
21053         $CHECKSTAT -t file $DIR1/$tfile
21054
21055         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21056         MULTIOP_PID=$!
21057         sleep 1
21058         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21059         $LCTL set_param fail_loc=0x80000314
21060         rm $DIR1/$tfile || error "Unlink fails"
21061         RC=$?
21062         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21063         [ $RC -eq 0 ] || error "Failed write to stale object"
21064 }
21065 run_test 271g "Discard DoM data vs client flush race"
21066
21067 test_272a() {
21068         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21069                 skip "Need MDS version at least 2.11.50"
21070
21071         local dom=$DIR/$tdir/dom
21072         mkdir -p $DIR/$tdir
21073
21074         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21075         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21076                 error "failed to write data into $dom"
21077         local old_md5=$(md5sum $dom)
21078
21079         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21080                 error "failed to migrate to the same DoM component"
21081
21082         local new_md5=$(md5sum $dom)
21083
21084         [ "$old_md5" == "$new_md5" ] ||
21085                 error "md5sum differ: $old_md5, $new_md5"
21086
21087         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21088                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21089 }
21090 run_test 272a "DoM migration: new layout with the same DOM component"
21091
21092 test_272b() {
21093         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21094                 skip "Need MDS version at least 2.11.50"
21095
21096         local dom=$DIR/$tdir/dom
21097         mkdir -p $DIR/$tdir
21098         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21099
21100         local mdtidx=$($LFS getstripe -m $dom)
21101         local mdtname=MDT$(printf %04x $mdtidx)
21102         local facet=mds$((mdtidx + 1))
21103
21104         local mdtfree1=$(do_facet $facet \
21105                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21106         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21107                 error "failed to write data into $dom"
21108         local old_md5=$(md5sum $dom)
21109         cancel_lru_locks mdc
21110         local mdtfree1=$(do_facet $facet \
21111                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21112
21113         $LFS migrate -c2 $dom ||
21114                 error "failed to migrate to the new composite layout"
21115         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21116                 error "MDT stripe was not removed"
21117
21118         cancel_lru_locks mdc
21119         local new_md5=$(md5sum $dom)
21120         [ "$old_md5" == "$new_md5" ] ||
21121                 error "$old_md5 != $new_md5"
21122
21123         # Skip free space checks with ZFS
21124         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21125                 local mdtfree2=$(do_facet $facet \
21126                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21127                 [ $mdtfree2 -gt $mdtfree1 ] ||
21128                         error "MDT space is not freed after migration"
21129         fi
21130         return 0
21131 }
21132 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21133
21134 test_272c() {
21135         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21136                 skip "Need MDS version at least 2.11.50"
21137
21138         local dom=$DIR/$tdir/$tfile
21139         mkdir -p $DIR/$tdir
21140         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21141
21142         local mdtidx=$($LFS getstripe -m $dom)
21143         local mdtname=MDT$(printf %04x $mdtidx)
21144         local facet=mds$((mdtidx + 1))
21145
21146         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21147                 error "failed to write data into $dom"
21148         local old_md5=$(md5sum $dom)
21149         cancel_lru_locks mdc
21150         local mdtfree1=$(do_facet $facet \
21151                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21152
21153         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21154                 error "failed to migrate to the new composite layout"
21155         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21156                 error "MDT stripe was not removed"
21157
21158         cancel_lru_locks mdc
21159         local new_md5=$(md5sum $dom)
21160         [ "$old_md5" == "$new_md5" ] ||
21161                 error "$old_md5 != $new_md5"
21162
21163         # Skip free space checks with ZFS
21164         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21165                 local mdtfree2=$(do_facet $facet \
21166                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21167                 [ $mdtfree2 -gt $mdtfree1 ] ||
21168                         error "MDS space is not freed after migration"
21169         fi
21170         return 0
21171 }
21172 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21173
21174 test_272d() {
21175         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21176                 skip "Need MDS version at least 2.12.55"
21177
21178         local dom=$DIR/$tdir/$tfile
21179         mkdir -p $DIR/$tdir
21180         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21181
21182         local mdtidx=$($LFS getstripe -m $dom)
21183         local mdtname=MDT$(printf %04x $mdtidx)
21184         local facet=mds$((mdtidx + 1))
21185
21186         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21187                 error "failed to write data into $dom"
21188         local old_md5=$(md5sum $dom)
21189         cancel_lru_locks mdc
21190         local mdtfree1=$(do_facet $facet \
21191                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21192
21193         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21194                 error "failed mirroring to the new composite layout"
21195         $LFS mirror resync $dom ||
21196                 error "failed mirror resync"
21197         $LFS mirror split --mirror-id 1 -d $dom ||
21198                 error "failed mirror split"
21199
21200         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21201                 error "MDT stripe was not removed"
21202
21203         cancel_lru_locks mdc
21204         local new_md5=$(md5sum $dom)
21205         [ "$old_md5" == "$new_md5" ] ||
21206                 error "$old_md5 != $new_md5"
21207
21208         # Skip free space checks with ZFS
21209         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21210                 local mdtfree2=$(do_facet $facet \
21211                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21212                 [ $mdtfree2 -gt $mdtfree1 ] ||
21213                         error "MDS space is not freed after DOM mirror deletion"
21214         fi
21215         return 0
21216 }
21217 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21218
21219 test_272e() {
21220         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21221                 skip "Need MDS version at least 2.12.55"
21222
21223         local dom=$DIR/$tdir/$tfile
21224         mkdir -p $DIR/$tdir
21225         $LFS setstripe -c 2 $dom
21226
21227         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21228                 error "failed to write data into $dom"
21229         local old_md5=$(md5sum $dom)
21230         cancel_lru_locks mdc
21231
21232         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21233                 error "failed mirroring to the DOM layout"
21234         $LFS mirror resync $dom ||
21235                 error "failed mirror resync"
21236         $LFS mirror split --mirror-id 1 -d $dom ||
21237                 error "failed mirror split"
21238
21239         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21240                 error "MDT stripe was not removed"
21241
21242         cancel_lru_locks mdc
21243         local new_md5=$(md5sum $dom)
21244         [ "$old_md5" == "$new_md5" ] ||
21245                 error "$old_md5 != $new_md5"
21246
21247         return 0
21248 }
21249 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21250
21251 test_272f() {
21252         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21253                 skip "Need MDS version at least 2.12.55"
21254
21255         local dom=$DIR/$tdir/$tfile
21256         mkdir -p $DIR/$tdir
21257         $LFS setstripe -c 2 $dom
21258
21259         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21260                 error "failed to write data into $dom"
21261         local old_md5=$(md5sum $dom)
21262         cancel_lru_locks mdc
21263
21264         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21265                 error "failed migrating to the DOM file"
21266
21267         cancel_lru_locks mdc
21268         local new_md5=$(md5sum $dom)
21269         [ "$old_md5" != "$new_md5" ] &&
21270                 error "$old_md5 != $new_md5"
21271
21272         return 0
21273 }
21274 run_test 272f "DoM migration: OST-striped file to DOM file"
21275
21276 test_273a() {
21277         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21278                 skip "Need MDS version at least 2.11.50"
21279
21280         # Layout swap cannot be done if either file has DOM component,
21281         # this will never be supported, migration should be used instead
21282
21283         local dom=$DIR/$tdir/$tfile
21284         mkdir -p $DIR/$tdir
21285
21286         $LFS setstripe -c2 ${dom}_plain
21287         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21288         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21289                 error "can swap layout with DoM component"
21290         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21291                 error "can swap layout with DoM component"
21292
21293         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21294         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21295                 error "can swap layout with DoM component"
21296         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21297                 error "can swap layout with DoM component"
21298         return 0
21299 }
21300 run_test 273a "DoM: layout swapping should fail with DOM"
21301
21302 test_275() {
21303         remote_ost_nodsh && skip "remote OST with nodsh"
21304         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21305                 skip "Need OST version >= 2.10.57"
21306
21307         local file=$DIR/$tfile
21308         local oss
21309
21310         oss=$(comma_list $(osts_nodes))
21311
21312         dd if=/dev/urandom of=$file bs=1M count=2 ||
21313                 error "failed to create a file"
21314         cancel_lru_locks osc
21315
21316         #lock 1
21317         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21318                 error "failed to read a file"
21319
21320 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21321         $LCTL set_param fail_loc=0x8000031f
21322
21323         cancel_lru_locks osc &
21324         sleep 1
21325
21326 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21327         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21328         #IO takes another lock, but matches the PENDING one
21329         #and places it to the IO RPC
21330         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21331                 error "failed to read a file with PENDING lock"
21332 }
21333 run_test 275 "Read on a canceled duplicate lock"
21334
21335 test_276() {
21336         remote_ost_nodsh && skip "remote OST with nodsh"
21337         local pid
21338
21339         do_facet ost1 "(while true; do \
21340                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21341                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21342         pid=$!
21343
21344         for LOOP in $(seq 20); do
21345                 stop ost1
21346                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21347         done
21348         kill -9 $pid
21349         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21350                 rm $TMP/sanity_276_pid"
21351 }
21352 run_test 276 "Race between mount and obd_statfs"
21353
21354 test_277() {
21355         $LCTL set_param ldlm.namespaces.*.lru_size=0
21356         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21357         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21358                         grep ^used_mb | awk '{print $2}')
21359         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21360         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21361                 oflag=direct conv=notrunc
21362         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21363                         grep ^used_mb | awk '{print $2}')
21364         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21365 }
21366 run_test 277 "Direct IO shall drop page cache"
21367
21368 test_278() {
21369         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21370         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21371         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21372                 skip "needs the same host for mdt1 mdt2" && return
21373
21374         local pid1
21375         local pid2
21376
21377 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21378         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21379         stop mds2 &
21380         pid2=$!
21381
21382         stop mds1
21383
21384         echo "Starting MDTs"
21385         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21386         wait $pid2
21387 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21388 #will return NULL
21389         do_facet mds2 $LCTL set_param fail_loc=0
21390
21391         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21392         wait_recovery_complete mds2
21393 }
21394 run_test 278 "Race starting MDS between MDTs stop/start"
21395
21396 test_280() {
21397         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21398                 skip "Need MGS version at least 2.13.52"
21399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21400         combined_mgs_mds || skip "needs combined MGS/MDT"
21401
21402         umount_client $MOUNT
21403 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21404         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21405
21406         mount_client $MOUNT &
21407         sleep 1
21408         stop mgs || error "stop mgs failed"
21409         #for a race mgs would crash
21410         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21411         mount_client $MOUNT || error "mount client failed"
21412 }
21413 run_test 280 "Race between MGS umount and client llog processing"
21414
21415 cleanup_test_300() {
21416         trap 0
21417         umask $SAVE_UMASK
21418 }
21419 test_striped_dir() {
21420         local mdt_index=$1
21421         local stripe_count
21422         local stripe_index
21423
21424         mkdir -p $DIR/$tdir
21425
21426         SAVE_UMASK=$(umask)
21427         trap cleanup_test_300 RETURN EXIT
21428
21429         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21430                                                 $DIR/$tdir/striped_dir ||
21431                 error "set striped dir error"
21432
21433         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21434         [ "$mode" = "755" ] || error "expect 755 got $mode"
21435
21436         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21437                 error "getdirstripe failed"
21438         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21439         if [ "$stripe_count" != "2" ]; then
21440                 error "1:stripe_count is $stripe_count, expect 2"
21441         fi
21442         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21443         if [ "$stripe_count" != "2" ]; then
21444                 error "2:stripe_count is $stripe_count, expect 2"
21445         fi
21446
21447         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21448         if [ "$stripe_index" != "$mdt_index" ]; then
21449                 error "stripe_index is $stripe_index, expect $mdt_index"
21450         fi
21451
21452         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21453                 error "nlink error after create striped dir"
21454
21455         mkdir $DIR/$tdir/striped_dir/a
21456         mkdir $DIR/$tdir/striped_dir/b
21457
21458         stat $DIR/$tdir/striped_dir/a ||
21459                 error "create dir under striped dir failed"
21460         stat $DIR/$tdir/striped_dir/b ||
21461                 error "create dir under striped dir failed"
21462
21463         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21464                 error "nlink error after mkdir"
21465
21466         rmdir $DIR/$tdir/striped_dir/a
21467         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21468                 error "nlink error after rmdir"
21469
21470         rmdir $DIR/$tdir/striped_dir/b
21471         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21472                 error "nlink error after rmdir"
21473
21474         chattr +i $DIR/$tdir/striped_dir
21475         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21476                 error "immutable flags not working under striped dir!"
21477         chattr -i $DIR/$tdir/striped_dir
21478
21479         rmdir $DIR/$tdir/striped_dir ||
21480                 error "rmdir striped dir error"
21481
21482         cleanup_test_300
21483
21484         true
21485 }
21486
21487 test_300a() {
21488         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21489                 skip "skipped for lustre < 2.7.0"
21490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21491         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21492
21493         test_striped_dir 0 || error "failed on striped dir on MDT0"
21494         test_striped_dir 1 || error "failed on striped dir on MDT0"
21495 }
21496 run_test 300a "basic striped dir sanity test"
21497
21498 test_300b() {
21499         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21500                 skip "skipped for lustre < 2.7.0"
21501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21502         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21503
21504         local i
21505         local mtime1
21506         local mtime2
21507         local mtime3
21508
21509         test_mkdir $DIR/$tdir || error "mkdir fail"
21510         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21511                 error "set striped dir error"
21512         for i in {0..9}; do
21513                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21514                 sleep 1
21515                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21516                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21517                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21518                 sleep 1
21519                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21520                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21521                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21522         done
21523         true
21524 }
21525 run_test 300b "check ctime/mtime for striped dir"
21526
21527 test_300c() {
21528         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21529                 skip "skipped for lustre < 2.7.0"
21530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21531         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21532
21533         local file_count
21534
21535         mkdir -p $DIR/$tdir
21536         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21537                 error "set striped dir error"
21538
21539         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21540                 error "chown striped dir failed"
21541
21542         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21543                 error "create 5k files failed"
21544
21545         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21546
21547         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21548
21549         rm -rf $DIR/$tdir
21550 }
21551 run_test 300c "chown && check ls under striped directory"
21552
21553 test_300d() {
21554         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21555                 skip "skipped for lustre < 2.7.0"
21556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21557         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21558
21559         local stripe_count
21560         local file
21561
21562         mkdir -p $DIR/$tdir
21563         $LFS setstripe -c 2 $DIR/$tdir
21564
21565         #local striped directory
21566         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21567                 error "set striped dir error"
21568         #look at the directories for debug purposes
21569         ls -l $DIR/$tdir
21570         $LFS getdirstripe $DIR/$tdir
21571         ls -l $DIR/$tdir/striped_dir
21572         $LFS getdirstripe $DIR/$tdir/striped_dir
21573         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21574                 error "create 10 files failed"
21575
21576         #remote striped directory
21577         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21578                 error "set striped dir error"
21579         #look at the directories for debug purposes
21580         ls -l $DIR/$tdir
21581         $LFS getdirstripe $DIR/$tdir
21582         ls -l $DIR/$tdir/remote_striped_dir
21583         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21584         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21585                 error "create 10 files failed"
21586
21587         for file in $(find $DIR/$tdir); do
21588                 stripe_count=$($LFS getstripe -c $file)
21589                 [ $stripe_count -eq 2 ] ||
21590                         error "wrong stripe $stripe_count for $file"
21591         done
21592
21593         rm -rf $DIR/$tdir
21594 }
21595 run_test 300d "check default stripe under striped directory"
21596
21597 test_300e() {
21598         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21599                 skip "Need MDS version at least 2.7.55"
21600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21601         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21602
21603         local stripe_count
21604         local file
21605
21606         mkdir -p $DIR/$tdir
21607
21608         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21609                 error "set striped dir error"
21610
21611         touch $DIR/$tdir/striped_dir/a
21612         touch $DIR/$tdir/striped_dir/b
21613         touch $DIR/$tdir/striped_dir/c
21614
21615         mkdir $DIR/$tdir/striped_dir/dir_a
21616         mkdir $DIR/$tdir/striped_dir/dir_b
21617         mkdir $DIR/$tdir/striped_dir/dir_c
21618
21619         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21620                 error "set striped adir under striped dir error"
21621
21622         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21623                 error "set striped bdir under striped dir error"
21624
21625         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21626                 error "set striped cdir under striped dir error"
21627
21628         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21629                 error "rename dir under striped dir fails"
21630
21631         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21632                 error "rename dir under different stripes fails"
21633
21634         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21635                 error "rename file under striped dir should succeed"
21636
21637         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21638                 error "rename dir under striped dir should succeed"
21639
21640         rm -rf $DIR/$tdir
21641 }
21642 run_test 300e "check rename under striped directory"
21643
21644 test_300f() {
21645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21646         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21647         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21648                 skip "Need MDS version at least 2.7.55"
21649
21650         local stripe_count
21651         local file
21652
21653         rm -rf $DIR/$tdir
21654         mkdir -p $DIR/$tdir
21655
21656         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21657                 error "set striped dir error"
21658
21659         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21660                 error "set striped dir error"
21661
21662         touch $DIR/$tdir/striped_dir/a
21663         mkdir $DIR/$tdir/striped_dir/dir_a
21664         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21665                 error "create striped dir under striped dir fails"
21666
21667         touch $DIR/$tdir/striped_dir1/b
21668         mkdir $DIR/$tdir/striped_dir1/dir_b
21669         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21670                 error "create striped dir under striped dir fails"
21671
21672         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21673                 error "rename dir under different striped dir should fail"
21674
21675         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21676                 error "rename striped dir under diff striped dir should fail"
21677
21678         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21679                 error "rename file under diff striped dirs fails"
21680
21681         rm -rf $DIR/$tdir
21682 }
21683 run_test 300f "check rename cross striped directory"
21684
21685 test_300_check_default_striped_dir()
21686 {
21687         local dirname=$1
21688         local default_count=$2
21689         local default_index=$3
21690         local stripe_count
21691         local stripe_index
21692         local dir_stripe_index
21693         local dir
21694
21695         echo "checking $dirname $default_count $default_index"
21696         $LFS setdirstripe -D -c $default_count -i $default_index \
21697                                 -t all_char $DIR/$tdir/$dirname ||
21698                 error "set default stripe on striped dir error"
21699         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21700         [ $stripe_count -eq $default_count ] ||
21701                 error "expect $default_count get $stripe_count for $dirname"
21702
21703         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21704         [ $stripe_index -eq $default_index ] ||
21705                 error "expect $default_index get $stripe_index for $dirname"
21706
21707         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21708                                                 error "create dirs failed"
21709
21710         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21711         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21712         for dir in $(find $DIR/$tdir/$dirname/*); do
21713                 stripe_count=$($LFS getdirstripe -c $dir)
21714                 [ $stripe_count -eq $default_count ] ||
21715                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21716                 error "stripe count $default_count != $stripe_count for $dir"
21717
21718                 stripe_index=$($LFS getdirstripe -i $dir)
21719                 [ $default_index -eq -1 ] ||
21720                         [ $stripe_index -eq $default_index ] ||
21721                         error "$stripe_index != $default_index for $dir"
21722
21723                 #check default stripe
21724                 stripe_count=$($LFS getdirstripe -D -c $dir)
21725                 [ $stripe_count -eq $default_count ] ||
21726                 error "default count $default_count != $stripe_count for $dir"
21727
21728                 stripe_index=$($LFS getdirstripe -D -i $dir)
21729                 [ $stripe_index -eq $default_index ] ||
21730                 error "default index $default_index != $stripe_index for $dir"
21731         done
21732         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21733 }
21734
21735 test_300g() {
21736         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21737         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21738                 skip "Need MDS version at least 2.7.55"
21739
21740         local dir
21741         local stripe_count
21742         local stripe_index
21743
21744         mkdir $DIR/$tdir
21745         mkdir $DIR/$tdir/normal_dir
21746
21747         #Checking when client cache stripe index
21748         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21749         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21750                 error "create striped_dir failed"
21751
21752         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21753                 error "create dir0 fails"
21754         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21755         [ $stripe_index -eq 0 ] ||
21756                 error "dir0 expect index 0 got $stripe_index"
21757
21758         mkdir $DIR/$tdir/striped_dir/dir1 ||
21759                 error "create dir1 fails"
21760         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21761         [ $stripe_index -eq 1 ] ||
21762                 error "dir1 expect index 1 got $stripe_index"
21763
21764         #check default stripe count/stripe index
21765         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21766         test_300_check_default_striped_dir normal_dir 1 0
21767         test_300_check_default_striped_dir normal_dir 2 1
21768         test_300_check_default_striped_dir normal_dir 2 -1
21769
21770         #delete default stripe information
21771         echo "delete default stripeEA"
21772         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21773                 error "set default stripe on striped dir error"
21774
21775         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21776         for dir in $(find $DIR/$tdir/normal_dir/*); do
21777                 stripe_count=$($LFS getdirstripe -c $dir)
21778                 [ $stripe_count -eq 0 ] ||
21779                         error "expect 1 get $stripe_count for $dir"
21780                 stripe_index=$($LFS getdirstripe -i $dir)
21781                 [ $stripe_index -eq 0 ] ||
21782                         error "expect 0 get $stripe_index for $dir"
21783         done
21784 }
21785 run_test 300g "check default striped directory for normal directory"
21786
21787 test_300h() {
21788         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21789         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21790                 skip "Need MDS version at least 2.7.55"
21791
21792         local dir
21793         local stripe_count
21794
21795         mkdir $DIR/$tdir
21796         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21797                 error "set striped dir error"
21798
21799         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21800         test_300_check_default_striped_dir striped_dir 1 0
21801         test_300_check_default_striped_dir striped_dir 2 1
21802         test_300_check_default_striped_dir striped_dir 2 -1
21803
21804         #delete default stripe information
21805         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21806                 error "set default stripe on striped dir error"
21807
21808         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21809         for dir in $(find $DIR/$tdir/striped_dir/*); do
21810                 stripe_count=$($LFS getdirstripe -c $dir)
21811                 [ $stripe_count -eq 0 ] ||
21812                         error "expect 1 get $stripe_count for $dir"
21813         done
21814 }
21815 run_test 300h "check default striped directory for striped directory"
21816
21817 test_300i() {
21818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21819         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21820         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21821                 skip "Need MDS version at least 2.7.55"
21822
21823         local stripe_count
21824         local file
21825
21826         mkdir $DIR/$tdir
21827
21828         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21829                 error "set striped dir error"
21830
21831         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21832                 error "create files under striped dir failed"
21833
21834         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21835                 error "set striped hashdir error"
21836
21837         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21838                 error "create dir0 under hash dir failed"
21839         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21840                 error "create dir1 under hash dir failed"
21841
21842         # unfortunately, we need to umount to clear dir layout cache for now
21843         # once we fully implement dir layout, we can drop this
21844         umount_client $MOUNT || error "umount failed"
21845         mount_client $MOUNT || error "mount failed"
21846
21847         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21848         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21849         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21850
21851         #set the stripe to be unknown hash type
21852         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21853         $LCTL set_param fail_loc=0x1901
21854         for ((i = 0; i < 10; i++)); do
21855                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21856                         error "stat f-$i failed"
21857                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21858         done
21859
21860         touch $DIR/$tdir/striped_dir/f0 &&
21861                 error "create under striped dir with unknown hash should fail"
21862
21863         $LCTL set_param fail_loc=0
21864
21865         umount_client $MOUNT || error "umount failed"
21866         mount_client $MOUNT || error "mount failed"
21867
21868         return 0
21869 }
21870 run_test 300i "client handle unknown hash type striped directory"
21871
21872 test_300j() {
21873         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21875         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21876                 skip "Need MDS version at least 2.7.55"
21877
21878         local stripe_count
21879         local file
21880
21881         mkdir $DIR/$tdir
21882
21883         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21884         $LCTL set_param fail_loc=0x1702
21885         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21886                 error "set striped dir error"
21887
21888         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21889                 error "create files under striped dir failed"
21890
21891         $LCTL set_param fail_loc=0
21892
21893         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21894
21895         return 0
21896 }
21897 run_test 300j "test large update record"
21898
21899 test_300k() {
21900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21902         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21903                 skip "Need MDS version at least 2.7.55"
21904
21905         # this test needs a huge transaction
21906         local kb
21907         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21908              osd*.$FSNAME-MDT0000.kbytestotal")
21909         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21910
21911         local stripe_count
21912         local file
21913
21914         mkdir $DIR/$tdir
21915
21916         #define OBD_FAIL_LARGE_STRIPE   0x1703
21917         $LCTL set_param fail_loc=0x1703
21918         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21919                 error "set striped dir error"
21920         $LCTL set_param fail_loc=0
21921
21922         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21923                 error "getstripeddir fails"
21924         rm -rf $DIR/$tdir/striped_dir ||
21925                 error "unlink striped dir fails"
21926
21927         return 0
21928 }
21929 run_test 300k "test large striped directory"
21930
21931 test_300l() {
21932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21933         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21934         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21935                 skip "Need MDS version at least 2.7.55"
21936
21937         local stripe_index
21938
21939         test_mkdir -p $DIR/$tdir/striped_dir
21940         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21941                         error "chown $RUNAS_ID failed"
21942         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21943                 error "set default striped dir failed"
21944
21945         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21946         $LCTL set_param fail_loc=0x80000158
21947         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21948
21949         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21950         [ $stripe_index -eq 1 ] ||
21951                 error "expect 1 get $stripe_index for $dir"
21952 }
21953 run_test 300l "non-root user to create dir under striped dir with stale layout"
21954
21955 test_300m() {
21956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21957         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21958         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21959                 skip "Need MDS version at least 2.7.55"
21960
21961         mkdir -p $DIR/$tdir/striped_dir
21962         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21963                 error "set default stripes dir error"
21964
21965         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21966
21967         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21968         [ $stripe_count -eq 0 ] ||
21969                         error "expect 0 get $stripe_count for a"
21970
21971         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21972                 error "set default stripes dir error"
21973
21974         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21975
21976         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21977         [ $stripe_count -eq 0 ] ||
21978                         error "expect 0 get $stripe_count for b"
21979
21980         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21981                 error "set default stripes dir error"
21982
21983         mkdir $DIR/$tdir/striped_dir/c &&
21984                 error "default stripe_index is invalid, mkdir c should fails"
21985
21986         rm -rf $DIR/$tdir || error "rmdir fails"
21987 }
21988 run_test 300m "setstriped directory on single MDT FS"
21989
21990 cleanup_300n() {
21991         local list=$(comma_list $(mdts_nodes))
21992
21993         trap 0
21994         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21995 }
21996
21997 test_300n() {
21998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21999         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22000         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22001                 skip "Need MDS version at least 2.7.55"
22002         remote_mds_nodsh && skip "remote MDS with nodsh"
22003
22004         local stripe_index
22005         local list=$(comma_list $(mdts_nodes))
22006
22007         trap cleanup_300n RETURN EXIT
22008         mkdir -p $DIR/$tdir
22009         chmod 777 $DIR/$tdir
22010         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22011                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22012                 error "create striped dir succeeds with gid=0"
22013
22014         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22015         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22016                 error "create striped dir fails with gid=-1"
22017
22018         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22019         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22020                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22021                 error "set default striped dir succeeds with gid=0"
22022
22023
22024         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22025         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22026                 error "set default striped dir fails with gid=-1"
22027
22028
22029         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22030         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22031                                         error "create test_dir fails"
22032         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22033                                         error "create test_dir1 fails"
22034         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22035                                         error "create test_dir2 fails"
22036         cleanup_300n
22037 }
22038 run_test 300n "non-root user to create dir under striped dir with default EA"
22039
22040 test_300o() {
22041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22043         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22044                 skip "Need MDS version at least 2.7.55"
22045
22046         local numfree1
22047         local numfree2
22048
22049         mkdir -p $DIR/$tdir
22050
22051         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22052         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22053         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22054                 skip "not enough free inodes $numfree1 $numfree2"
22055         fi
22056
22057         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22058         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22059         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22060                 skip "not enough free space $numfree1 $numfree2"
22061         fi
22062
22063         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22064                 error "setdirstripe fails"
22065
22066         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22067                 error "create dirs fails"
22068
22069         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22070         ls $DIR/$tdir/striped_dir > /dev/null ||
22071                 error "ls striped dir fails"
22072         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22073                 error "unlink big striped dir fails"
22074 }
22075 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22076
22077 test_300p() {
22078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22079         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22080         remote_mds_nodsh && skip "remote MDS with nodsh"
22081
22082         mkdir -p $DIR/$tdir
22083
22084         #define OBD_FAIL_OUT_ENOSPC     0x1704
22085         do_facet mds2 lctl set_param fail_loc=0x80001704
22086         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22087                  && error "create striped directory should fail"
22088
22089         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22090
22091         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22092         true
22093 }
22094 run_test 300p "create striped directory without space"
22095
22096 test_300q() {
22097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22098         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22099
22100         local fd=$(free_fd)
22101         local cmd="exec $fd<$tdir"
22102         cd $DIR
22103         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22104         eval $cmd
22105         cmd="exec $fd<&-"
22106         trap "eval $cmd" EXIT
22107         cd $tdir || error "cd $tdir fails"
22108         rmdir  ../$tdir || error "rmdir $tdir fails"
22109         mkdir local_dir && error "create dir succeeds"
22110         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22111         eval $cmd
22112         return 0
22113 }
22114 run_test 300q "create remote directory under orphan directory"
22115
22116 test_300r() {
22117         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22118                 skip "Need MDS version at least 2.7.55" && return
22119         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22120
22121         mkdir $DIR/$tdir
22122
22123         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22124                 error "set striped dir error"
22125
22126         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22127                 error "getstripeddir fails"
22128
22129         local stripe_count
22130         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22131                       awk '/lmv_stripe_count:/ { print $2 }')
22132
22133         [ $MDSCOUNT -ne $stripe_count ] &&
22134                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22135
22136         rm -rf $DIR/$tdir/striped_dir ||
22137                 error "unlink striped dir fails"
22138 }
22139 run_test 300r "test -1 striped directory"
22140
22141 test_300s_helper() {
22142         local count=$1
22143
22144         local stripe_dir=$DIR/$tdir/striped_dir.$count
22145
22146         $LFS mkdir -c $count $stripe_dir ||
22147                 error "lfs mkdir -c error"
22148
22149         $LFS getdirstripe $stripe_dir ||
22150                 error "lfs getdirstripe fails"
22151
22152         local stripe_count
22153         stripe_count=$($LFS getdirstripe $stripe_dir |
22154                       awk '/lmv_stripe_count:/ { print $2 }')
22155
22156         [ $count -ne $stripe_count ] &&
22157                 error_noexit "bad stripe count $stripe_count expected $count"
22158
22159         local dupe_stripes
22160         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22161                 awk '/0x/ {count[$1] += 1}; END {
22162                         for (idx in count) {
22163                                 if (count[idx]>1) {
22164                                         print "index " idx " count " count[idx]
22165                                 }
22166                         }
22167                 }')
22168
22169         if [[ -n "$dupe_stripes" ]] ; then
22170                 lfs getdirstripe $stripe_dir
22171                 error_noexit "Dupe MDT above: $dupe_stripes "
22172         fi
22173
22174         rm -rf $stripe_dir ||
22175                 error_noexit "unlink $stripe_dir fails"
22176 }
22177
22178 test_300s() {
22179         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22180                 skip "Need MDS version at least 2.7.55" && return
22181         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22182
22183         mkdir $DIR/$tdir
22184         for count in $(seq 2 $MDSCOUNT); do
22185                 test_300s_helper $count
22186         done
22187 }
22188 run_test 300s "test lfs mkdir -c without -i"
22189
22190
22191 prepare_remote_file() {
22192         mkdir $DIR/$tdir/src_dir ||
22193                 error "create remote source failed"
22194
22195         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22196                  error "cp to remote source failed"
22197         touch $DIR/$tdir/src_dir/a
22198
22199         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22200                 error "create remote target dir failed"
22201
22202         touch $DIR/$tdir/tgt_dir/b
22203
22204         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22205                 error "rename dir cross MDT failed!"
22206
22207         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22208                 error "src_child still exists after rename"
22209
22210         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22211                 error "missing file(a) after rename"
22212
22213         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22214                 error "diff after rename"
22215 }
22216
22217 test_310a() {
22218         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22220
22221         local remote_file=$DIR/$tdir/tgt_dir/b
22222
22223         mkdir -p $DIR/$tdir
22224
22225         prepare_remote_file || error "prepare remote file failed"
22226
22227         #open-unlink file
22228         $OPENUNLINK $remote_file $remote_file ||
22229                 error "openunlink $remote_file failed"
22230         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22231 }
22232 run_test 310a "open unlink remote file"
22233
22234 test_310b() {
22235         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22237
22238         local remote_file=$DIR/$tdir/tgt_dir/b
22239
22240         mkdir -p $DIR/$tdir
22241
22242         prepare_remote_file || error "prepare remote file failed"
22243
22244         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22245         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22246         $CHECKSTAT -t file $remote_file || error "check file failed"
22247 }
22248 run_test 310b "unlink remote file with multiple links while open"
22249
22250 test_310c() {
22251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22252         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22253
22254         local remote_file=$DIR/$tdir/tgt_dir/b
22255
22256         mkdir -p $DIR/$tdir
22257
22258         prepare_remote_file || error "prepare remote file failed"
22259
22260         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22261         multiop_bg_pause $remote_file O_uc ||
22262                         error "mulitop failed for remote file"
22263         MULTIPID=$!
22264         $MULTIOP $DIR/$tfile Ouc
22265         kill -USR1 $MULTIPID
22266         wait $MULTIPID
22267 }
22268 run_test 310c "open-unlink remote file with multiple links"
22269
22270 #LU-4825
22271 test_311() {
22272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22273         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22274         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22275                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22276         remote_mds_nodsh && skip "remote MDS with nodsh"
22277
22278         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
22279         local mdts=$(comma_list $(mdts_nodes))
22280
22281         mkdir -p $DIR/$tdir
22282         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22283         createmany -o $DIR/$tdir/$tfile. 1000
22284
22285         # statfs data is not real time, let's just calculate it
22286         old_iused=$((old_iused + 1000))
22287
22288         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22289                         osp.*OST0000*MDT0000.create_count")
22290         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22291                                 osp.*OST0000*MDT0000.max_create_count")
22292         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22293
22294         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22295         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22296         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22297
22298         unlinkmany $DIR/$tdir/$tfile. 1000
22299
22300         do_nodes $mdts "$LCTL set_param -n \
22301                         osp.*OST0000*.max_create_count=$max_count"
22302         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22303                 do_nodes $mdts "$LCTL set_param -n \
22304                                 osp.*OST0000*.create_count=$count"
22305         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22306                         grep "=0" && error "create_count is zero"
22307
22308         local new_iused
22309         for i in $(seq 120); do
22310                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
22311                 # system may be too busy to destroy all objs in time, use
22312                 # a somewhat small value to not fail autotest
22313                 [ $((old_iused - new_iused)) -gt 400 ] && break
22314                 sleep 1
22315         done
22316
22317         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22318         [ $((old_iused - new_iused)) -gt 400 ] ||
22319                 error "objs not destroyed after unlink"
22320 }
22321 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22322
22323 zfs_oid_to_objid()
22324 {
22325         local ost=$1
22326         local objid=$2
22327
22328         local vdevdir=$(dirname $(facet_vdevice $ost))
22329         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22330         local zfs_zapid=$(do_facet $ost $cmd |
22331                           grep -w "/O/0/d$((objid%32))" -C 5 |
22332                           awk '/Object/{getline; print $1}')
22333         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22334                           awk "/$objid = /"'{printf $3}')
22335
22336         echo $zfs_objid
22337 }
22338
22339 zfs_object_blksz() {
22340         local ost=$1
22341         local objid=$2
22342
22343         local vdevdir=$(dirname $(facet_vdevice $ost))
22344         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22345         local blksz=$(do_facet $ost $cmd $objid |
22346                       awk '/dblk/{getline; printf $4}')
22347
22348         case "${blksz: -1}" in
22349                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22350                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22351                 *) ;;
22352         esac
22353
22354         echo $blksz
22355 }
22356
22357 test_312() { # LU-4856
22358         remote_ost_nodsh && skip "remote OST with nodsh"
22359         [ "$ost1_FSTYPE" = "zfs" ] ||
22360                 skip_env "the test only applies to zfs"
22361
22362         local max_blksz=$(do_facet ost1 \
22363                           $ZFS get -p recordsize $(facet_device ost1) |
22364                           awk '!/VALUE/{print $3}')
22365
22366         # to make life a little bit easier
22367         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22368         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22369
22370         local tf=$DIR/$tdir/$tfile
22371         touch $tf
22372         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22373
22374         # Get ZFS object id
22375         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22376         # block size change by sequential overwrite
22377         local bs
22378
22379         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22380                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22381
22382                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22383                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22384         done
22385         rm -f $tf
22386
22387         # block size change by sequential append write
22388         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22389         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22390         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22391         local count
22392
22393         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22394                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22395                         oflag=sync conv=notrunc
22396
22397                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22398                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22399                         error "blksz error, actual $blksz, " \
22400                                 "expected: 2 * $count * $PAGE_SIZE"
22401         done
22402         rm -f $tf
22403
22404         # random write
22405         touch $tf
22406         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22407         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22408
22409         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22410         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22411         [ $blksz -eq $PAGE_SIZE ] ||
22412                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22413
22414         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22415         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22416         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22417
22418         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22419         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22420         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22421 }
22422 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22423
22424 test_313() {
22425         remote_ost_nodsh && skip "remote OST with nodsh"
22426
22427         local file=$DIR/$tfile
22428
22429         rm -f $file
22430         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22431
22432         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22433         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22434         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22435                 error "write should failed"
22436         do_facet ost1 "$LCTL set_param fail_loc=0"
22437         rm -f $file
22438 }
22439 run_test 313 "io should fail after last_rcvd update fail"
22440
22441 test_314() {
22442         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22443
22444         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22445         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22446         rm -f $DIR/$tfile
22447         wait_delete_completed
22448         do_facet ost1 "$LCTL set_param fail_loc=0"
22449 }
22450 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22451
22452 test_315() { # LU-618
22453         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22454
22455         local file=$DIR/$tfile
22456         rm -f $file
22457
22458         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22459                 error "multiop file write failed"
22460         $MULTIOP $file oO_RDONLY:r4063232_c &
22461         PID=$!
22462
22463         sleep 2
22464
22465         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22466         kill -USR1 $PID
22467
22468         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22469         rm -f $file
22470 }
22471 run_test 315 "read should be accounted"
22472
22473 test_316() {
22474         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22475         large_xattr_enabled || skip_env "ea_inode feature disabled"
22476
22477         rm -rf $DIR/$tdir/d
22478         mkdir -p $DIR/$tdir/d
22479         chown nobody $DIR/$tdir/d
22480         touch $DIR/$tdir/d/file
22481
22482         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22483 }
22484 run_test 316 "lfs mv"
22485
22486 test_317() {
22487         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22488                 skip "Need MDS version at least 2.11.53"
22489         if [ "$ost1_FSTYPE" == "zfs" ]; then
22490                 skip "LU-10370: no implementation for ZFS"
22491         fi
22492
22493         local trunc_sz
22494         local grant_blk_size
22495
22496         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22497                         awk '/grant_block_size:/ { print $2; exit; }')
22498         #
22499         # Create File of size 5M. Truncate it to below size's and verify
22500         # blocks count.
22501         #
22502         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22503                 error "Create file $DIR/$tfile failed"
22504         stack_trap "rm -f $DIR/$tfile" EXIT
22505
22506         for trunc_sz in 2097152 4097 4000 509 0; do
22507                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22508                         error "truncate $tfile to $trunc_sz failed"
22509                 local sz=$(stat --format=%s $DIR/$tfile)
22510                 local blk=$(stat --format=%b $DIR/$tfile)
22511                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22512                                      grant_blk_size) * 8))
22513
22514                 if [[ $blk -ne $trunc_blk ]]; then
22515                         $(which stat) $DIR/$tfile
22516                         error "Expected Block $trunc_blk got $blk for $tfile"
22517                 fi
22518
22519                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22520                         error "Expected Size $trunc_sz got $sz for $tfile"
22521         done
22522
22523         #
22524         # sparse file test
22525         # Create file with a hole and write actual two blocks. Block count
22526         # must be 16.
22527         #
22528         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22529                 conv=fsync || error "Create file : $DIR/$tfile"
22530
22531         # Calculate the final truncate size.
22532         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22533
22534         #
22535         # truncate to size $trunc_sz bytes. Strip the last block
22536         # The block count must drop to 8
22537         #
22538         $TRUNCATE $DIR/$tfile $trunc_sz ||
22539                 error "truncate $tfile to $trunc_sz failed"
22540
22541         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22542         sz=$(stat --format=%s $DIR/$tfile)
22543         blk=$(stat --format=%b $DIR/$tfile)
22544
22545         if [[ $blk -ne $trunc_bsz ]]; then
22546                 $(which stat) $DIR/$tfile
22547                 error "Expected Block $trunc_bsz got $blk for $tfile"
22548         fi
22549
22550         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22551                 error "Expected Size $trunc_sz got $sz for $tfile"
22552 }
22553 run_test 317 "Verify blocks get correctly update after truncate"
22554
22555 test_318() {
22556         local old_max_active=$($LCTL get_param -n \
22557                             llite.*.max_read_ahead_async_active 2>/dev/null)
22558
22559         $LCTL set_param llite.*.max_read_ahead_async_active=256
22560         local max_active=$($LCTL get_param -n \
22561                            llite.*.max_read_ahead_async_active 2>/dev/null)
22562         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22563
22564         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22565                 error "set max_read_ahead_async_active should succeed"
22566
22567         $LCTL set_param llite.*.max_read_ahead_async_active=512
22568         max_active=$($LCTL get_param -n \
22569                      llite.*.max_read_ahead_async_active 2>/dev/null)
22570         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22571
22572         # restore @max_active
22573         [ $old_max_active -ne 0 ] && $LCTL set_param \
22574                 llite.*.max_read_ahead_async_active=$old_max_active
22575
22576         local old_threshold=$($LCTL get_param -n \
22577                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22578         local max_per_file_mb=$($LCTL get_param -n \
22579                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22580
22581         local invalid=$(($max_per_file_mb + 1))
22582         $LCTL set_param \
22583                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22584                         && error "set $invalid should fail"
22585
22586         local valid=$(($invalid - 1))
22587         $LCTL set_param \
22588                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22589                         error "set $valid should succeed"
22590         local threshold=$($LCTL get_param -n \
22591                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22592         [ $threshold -eq $valid ] || error \
22593                 "expect threshold $valid got $threshold"
22594         $LCTL set_param \
22595                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22596 }
22597 run_test 318 "Verify async readahead tunables"
22598
22599 test_319() {
22600         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22601
22602         local before=$(date +%s)
22603         local evict
22604         local mdir=$DIR/$tdir
22605         local file=$mdir/xxx
22606
22607         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22608         touch $file
22609
22610 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22611         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22612         $LFS mv -m1 $file &
22613
22614         sleep 1
22615         dd if=$file of=/dev/null
22616         wait
22617         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22618           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22619
22620         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22621 }
22622 run_test 319 "lost lease lock on migrate error"
22623
22624 test_398a() { # LU-4198
22625         local ost1_imp=$(get_osc_import_name client ost1)
22626         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22627                          cut -d'.' -f2)
22628
22629         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22630         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22631
22632         # request a new lock on client
22633         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22634
22635         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22636         local lock_count=$($LCTL get_param -n \
22637                            ldlm.namespaces.$imp_name.lru_size)
22638         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22639
22640         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22641
22642         # no lock cached, should use lockless IO and not enqueue new lock
22643         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22644         lock_count=$($LCTL get_param -n \
22645                      ldlm.namespaces.$imp_name.lru_size)
22646         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22647 }
22648 run_test 398a "direct IO should cancel lock otherwise lockless"
22649
22650 test_398b() { # LU-4198
22651         which fio || skip_env "no fio installed"
22652         $LFS setstripe -c -1 $DIR/$tfile
22653
22654         local size=12
22655         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22656
22657         local njobs=4
22658         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22659         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22660                 --numjobs=$njobs --fallocate=none \
22661                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22662                 --filename=$DIR/$tfile &
22663         bg_pid=$!
22664
22665         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22666         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22667                 --numjobs=$njobs --fallocate=none \
22668                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22669                 --filename=$DIR/$tfile || true
22670         wait $bg_pid
22671
22672         rm -rf $DIR/$tfile
22673 }
22674 run_test 398b "DIO and buffer IO race"
22675
22676 test_398c() { # LU-4198
22677         local ost1_imp=$(get_osc_import_name client ost1)
22678         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22679                          cut -d'.' -f2)
22680
22681         which fio || skip_env "no fio installed"
22682
22683         saved_debug=$($LCTL get_param -n debug)
22684         $LCTL set_param debug=0
22685
22686         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22687         ((size /= 1024)) # by megabytes
22688         ((size /= 2)) # write half of the OST at most
22689         [ $size -gt 40 ] && size=40 #reduce test time anyway
22690
22691         $LFS setstripe -c 1 $DIR/$tfile
22692
22693         # it seems like ldiskfs reserves more space than necessary if the
22694         # writing blocks are not mapped, so it extends the file firstly
22695         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22696         cancel_lru_locks osc
22697
22698         # clear and verify rpc_stats later
22699         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22700
22701         local njobs=4
22702         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22703         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22704                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22705                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22706                 --filename=$DIR/$tfile
22707         [ $? -eq 0 ] || error "fio write error"
22708
22709         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
22710                 error "Locks were requested while doing AIO"
22711
22712         # get the percentage of 1-page I/O
22713         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22714                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22715                 awk '{print $7}')
22716         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22717
22718         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22719         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22720                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22721                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22722                 --filename=$DIR/$tfile
22723         [ $? -eq 0 ] || error "fio mixed read write error"
22724
22725         echo "AIO with large block size ${size}M"
22726         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22727                 --numjobs=1 --fallocate=none --ioengine=libaio \
22728                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22729                 --filename=$DIR/$tfile
22730         [ $? -eq 0 ] || error "fio large block size failed"
22731
22732         rm -rf $DIR/$tfile
22733         $LCTL set_param debug="$saved_debug"
22734 }
22735 run_test 398c "run fio to test AIO"
22736
22737 test_398d() { #  LU-13846
22738         test -f aiocp || skip_env "no aiocp installed"
22739         local aio_file=$DIR/aio_file
22740
22741         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22742
22743         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22744         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22745
22746         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22747
22748         # make sure we don't crash and fail properly
22749         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22750                 error "aio not aligned with PAGE SIZE should fail"
22751
22752         rm -rf $DIR/$tfile $aio_file
22753 }
22754 run_test 398d "run aiocp to verify block size > stripe size"
22755
22756 test_398e() {
22757         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
22758         touch $DIR/$tfile.new
22759         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
22760 }
22761 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
22762
22763 test_fake_rw() {
22764         local read_write=$1
22765         if [ "$read_write" = "write" ]; then
22766                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22767         elif [ "$read_write" = "read" ]; then
22768                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22769         else
22770                 error "argument error"
22771         fi
22772
22773         # turn off debug for performance testing
22774         local saved_debug=$($LCTL get_param -n debug)
22775         $LCTL set_param debug=0
22776
22777         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22778
22779         # get ost1 size - $FSNAME-OST0000
22780         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22781         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22782         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22783
22784         if [ "$read_write" = "read" ]; then
22785                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22786         fi
22787
22788         local start_time=$(date +%s.%N)
22789         $dd_cmd bs=1M count=$blocks oflag=sync ||
22790                 error "real dd $read_write error"
22791         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22792
22793         if [ "$read_write" = "write" ]; then
22794                 rm -f $DIR/$tfile
22795         fi
22796
22797         # define OBD_FAIL_OST_FAKE_RW           0x238
22798         do_facet ost1 $LCTL set_param fail_loc=0x238
22799
22800         local start_time=$(date +%s.%N)
22801         $dd_cmd bs=1M count=$blocks oflag=sync ||
22802                 error "fake dd $read_write error"
22803         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22804
22805         if [ "$read_write" = "write" ]; then
22806                 # verify file size
22807                 cancel_lru_locks osc
22808                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22809                         error "$tfile size not $blocks MB"
22810         fi
22811         do_facet ost1 $LCTL set_param fail_loc=0
22812
22813         echo "fake $read_write $duration_fake vs. normal $read_write" \
22814                 "$duration in seconds"
22815         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22816                 error_not_in_vm "fake write is slower"
22817
22818         $LCTL set_param -n debug="$saved_debug"
22819         rm -f $DIR/$tfile
22820 }
22821 test_399a() { # LU-7655 for OST fake write
22822         remote_ost_nodsh && skip "remote OST with nodsh"
22823
22824         test_fake_rw write
22825 }
22826 run_test 399a "fake write should not be slower than normal write"
22827
22828 test_399b() { # LU-8726 for OST fake read
22829         remote_ost_nodsh && skip "remote OST with nodsh"
22830         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22831                 skip_env "ldiskfs only test"
22832         fi
22833
22834         test_fake_rw read
22835 }
22836 run_test 399b "fake read should not be slower than normal read"
22837
22838 test_400a() { # LU-1606, was conf-sanity test_74
22839         if ! which $CC > /dev/null 2>&1; then
22840                 skip_env "$CC is not installed"
22841         fi
22842
22843         local extra_flags=''
22844         local out=$TMP/$tfile
22845         local prefix=/usr/include/lustre
22846         local prog
22847
22848         # Oleg removes c files in his test rig so test if any c files exist
22849         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22850                 skip_env "Needed c test files are missing"
22851
22852         if ! [[ -d $prefix ]]; then
22853                 # Assume we're running in tree and fixup the include path.
22854                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22855                 extra_flags+=" -L$LUSTRE/utils/.lib"
22856         fi
22857
22858         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22859                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22860                         error "client api broken"
22861         done
22862         rm -f $out
22863 }
22864 run_test 400a "Lustre client api program can compile and link"
22865
22866 test_400b() { # LU-1606, LU-5011
22867         local header
22868         local out=$TMP/$tfile
22869         local prefix=/usr/include/linux/lustre
22870
22871         # We use a hard coded prefix so that this test will not fail
22872         # when run in tree. There are headers in lustre/include/lustre/
22873         # that are not packaged (like lustre_idl.h) and have more
22874         # complicated include dependencies (like config.h and lnet/types.h).
22875         # Since this test about correct packaging we just skip them when
22876         # they don't exist (see below) rather than try to fixup cppflags.
22877
22878         if ! which $CC > /dev/null 2>&1; then
22879                 skip_env "$CC is not installed"
22880         fi
22881
22882         for header in $prefix/*.h; do
22883                 if ! [[ -f "$header" ]]; then
22884                         continue
22885                 fi
22886
22887                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22888                         continue # lustre_ioctl.h is internal header
22889                 fi
22890
22891                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22892                         error "cannot compile '$header'"
22893         done
22894         rm -f $out
22895 }
22896 run_test 400b "packaged headers can be compiled"
22897
22898 test_401a() { #LU-7437
22899         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22900         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22901
22902         #count the number of parameters by "list_param -R"
22903         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22904         #count the number of parameters by listing proc files
22905         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22906         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22907         echo "proc_dirs='$proc_dirs'"
22908         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22909         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22910                       sort -u | wc -l)
22911
22912         [ $params -eq $procs ] ||
22913                 error "found $params parameters vs. $procs proc files"
22914
22915         # test the list_param -D option only returns directories
22916         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22917         #count the number of parameters by listing proc directories
22918         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22919                 sort -u | wc -l)
22920
22921         [ $params -eq $procs ] ||
22922                 error "found $params parameters vs. $procs proc files"
22923 }
22924 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22925
22926 test_401b() {
22927         # jobid_var may not allow arbitrary values, so use jobid_name
22928         # if available
22929         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22930                 local testname=jobid_name tmp='testing%p'
22931         else
22932                 local testname=jobid_var tmp=testing
22933         fi
22934
22935         local save=$($LCTL get_param -n $testname)
22936
22937         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22938                 error "no error returned when setting bad parameters"
22939
22940         local jobid_new=$($LCTL get_param -n foe $testname baz)
22941         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22942
22943         $LCTL set_param -n fog=bam $testname=$save bat=fog
22944         local jobid_old=$($LCTL get_param -n foe $testname bag)
22945         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22946 }
22947 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22948
22949 test_401c() {
22950         # jobid_var may not allow arbitrary values, so use jobid_name
22951         # if available
22952         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22953                 local testname=jobid_name
22954         else
22955                 local testname=jobid_var
22956         fi
22957
22958         local jobid_var_old=$($LCTL get_param -n $testname)
22959         local jobid_var_new
22960
22961         $LCTL set_param $testname= &&
22962                 error "no error returned for 'set_param a='"
22963
22964         jobid_var_new=$($LCTL get_param -n $testname)
22965         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22966                 error "$testname was changed by setting without value"
22967
22968         $LCTL set_param $testname &&
22969                 error "no error returned for 'set_param a'"
22970
22971         jobid_var_new=$($LCTL get_param -n $testname)
22972         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22973                 error "$testname was changed by setting without value"
22974 }
22975 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22976
22977 test_401d() {
22978         # jobid_var may not allow arbitrary values, so use jobid_name
22979         # if available
22980         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22981                 local testname=jobid_name new_value='foo=bar%p'
22982         else
22983                 local testname=jobid_var new_valuie=foo=bar
22984         fi
22985
22986         local jobid_var_old=$($LCTL get_param -n $testname)
22987         local jobid_var_new
22988
22989         $LCTL set_param $testname=$new_value ||
22990                 error "'set_param a=b' did not accept a value containing '='"
22991
22992         jobid_var_new=$($LCTL get_param -n $testname)
22993         [[ "$jobid_var_new" == "$new_value" ]] ||
22994                 error "'set_param a=b' failed on a value containing '='"
22995
22996         # Reset the $testname to test the other format
22997         $LCTL set_param $testname=$jobid_var_old
22998         jobid_var_new=$($LCTL get_param -n $testname)
22999         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23000                 error "failed to reset $testname"
23001
23002         $LCTL set_param $testname $new_value ||
23003                 error "'set_param a b' did not accept a value containing '='"
23004
23005         jobid_var_new=$($LCTL get_param -n $testname)
23006         [[ "$jobid_var_new" == "$new_value" ]] ||
23007                 error "'set_param a b' failed on a value containing '='"
23008
23009         $LCTL set_param $testname $jobid_var_old
23010         jobid_var_new=$($LCTL get_param -n $testname)
23011         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23012                 error "failed to reset $testname"
23013 }
23014 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23015
23016 test_402() {
23017         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23018         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23019                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23020         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23021                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23022                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23023         remote_mds_nodsh && skip "remote MDS with nodsh"
23024
23025         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23026 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23027         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23028         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23029                 echo "Touch failed - OK"
23030 }
23031 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23032
23033 test_403() {
23034         local file1=$DIR/$tfile.1
23035         local file2=$DIR/$tfile.2
23036         local tfile=$TMP/$tfile
23037
23038         rm -f $file1 $file2 $tfile
23039
23040         touch $file1
23041         ln $file1 $file2
23042
23043         # 30 sec OBD_TIMEOUT in ll_getattr()
23044         # right before populating st_nlink
23045         $LCTL set_param fail_loc=0x80001409
23046         stat -c %h $file1 > $tfile &
23047
23048         # create an alias, drop all locks and reclaim the dentry
23049         < $file2
23050         cancel_lru_locks mdc
23051         cancel_lru_locks osc
23052         sysctl -w vm.drop_caches=2
23053
23054         wait
23055
23056         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23057
23058         rm -f $tfile $file1 $file2
23059 }
23060 run_test 403 "i_nlink should not drop to zero due to aliasing"
23061
23062 test_404() { # LU-6601
23063         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23064                 skip "Need server version newer than 2.8.52"
23065         remote_mds_nodsh && skip "remote MDS with nodsh"
23066
23067         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23068                 awk '/osp .*-osc-MDT/ { print $4}')
23069
23070         local osp
23071         for osp in $mosps; do
23072                 echo "Deactivate: " $osp
23073                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23074                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23075                         awk -vp=$osp '$4 == p { print $2 }')
23076                 [ $stat = IN ] || {
23077                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23078                         error "deactivate error"
23079                 }
23080                 echo "Activate: " $osp
23081                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23082                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23083                         awk -vp=$osp '$4 == p { print $2 }')
23084                 [ $stat = UP ] || {
23085                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23086                         error "activate error"
23087                 }
23088         done
23089 }
23090 run_test 404 "validate manual {de}activated works properly for OSPs"
23091
23092 test_405() {
23093         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23094         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23095                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23096                         skip "Layout swap lock is not supported"
23097
23098         check_swap_layouts_support
23099         check_swap_layout_no_dom $DIR
23100
23101         test_mkdir $DIR/$tdir
23102         swap_lock_test -d $DIR/$tdir ||
23103                 error "One layout swap locked test failed"
23104 }
23105 run_test 405 "Various layout swap lock tests"
23106
23107 test_406() {
23108         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23109         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23110         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23112         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23113                 skip "Need MDS version at least 2.8.50"
23114
23115         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23116         local test_pool=$TESTNAME
23117
23118         pool_add $test_pool || error "pool_add failed"
23119         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23120                 error "pool_add_targets failed"
23121
23122         save_layout_restore_at_exit $MOUNT
23123
23124         # parent set default stripe count only, child will stripe from both
23125         # parent and fs default
23126         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23127                 error "setstripe $MOUNT failed"
23128         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23129         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23130         for i in $(seq 10); do
23131                 local f=$DIR/$tdir/$tfile.$i
23132                 touch $f || error "touch failed"
23133                 local count=$($LFS getstripe -c $f)
23134                 [ $count -eq $OSTCOUNT ] ||
23135                         error "$f stripe count $count != $OSTCOUNT"
23136                 local offset=$($LFS getstripe -i $f)
23137                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23138                 local size=$($LFS getstripe -S $f)
23139                 [ $size -eq $((def_stripe_size * 2)) ] ||
23140                         error "$f stripe size $size != $((def_stripe_size * 2))"
23141                 local pool=$($LFS getstripe -p $f)
23142                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23143         done
23144
23145         # change fs default striping, delete parent default striping, now child
23146         # will stripe from new fs default striping only
23147         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23148                 error "change $MOUNT default stripe failed"
23149         $LFS setstripe -c 0 $DIR/$tdir ||
23150                 error "delete $tdir default stripe failed"
23151         for i in $(seq 11 20); do
23152                 local f=$DIR/$tdir/$tfile.$i
23153                 touch $f || error "touch $f failed"
23154                 local count=$($LFS getstripe -c $f)
23155                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23156                 local offset=$($LFS getstripe -i $f)
23157                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23158                 local size=$($LFS getstripe -S $f)
23159                 [ $size -eq $def_stripe_size ] ||
23160                         error "$f stripe size $size != $def_stripe_size"
23161                 local pool=$($LFS getstripe -p $f)
23162                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23163         done
23164
23165         unlinkmany $DIR/$tdir/$tfile. 1 20
23166
23167         local f=$DIR/$tdir/$tfile
23168         pool_remove_all_targets $test_pool $f
23169         pool_remove $test_pool $f
23170 }
23171 run_test 406 "DNE support fs default striping"
23172
23173 test_407() {
23174         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23175         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23176                 skip "Need MDS version at least 2.8.55"
23177         remote_mds_nodsh && skip "remote MDS with nodsh"
23178
23179         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23180                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23181         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23182                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23183         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23184
23185         #define OBD_FAIL_DT_TXN_STOP    0x2019
23186         for idx in $(seq $MDSCOUNT); do
23187                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23188         done
23189         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23190         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23191                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23192         true
23193 }
23194 run_test 407 "transaction fail should cause operation fail"
23195
23196 test_408() {
23197         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23198
23199         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23200         lctl set_param fail_loc=0x8000040a
23201         # let ll_prepare_partial_page() fail
23202         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23203
23204         rm -f $DIR/$tfile
23205
23206         # create at least 100 unused inodes so that
23207         # shrink_icache_memory(0) should not return 0
23208         touch $DIR/$tfile-{0..100}
23209         rm -f $DIR/$tfile-{0..100}
23210         sync
23211
23212         echo 2 > /proc/sys/vm/drop_caches
23213 }
23214 run_test 408 "drop_caches should not hang due to page leaks"
23215
23216 test_409()
23217 {
23218         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23219
23220         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23221         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23222         touch $DIR/$tdir/guard || error "(2) Fail to create"
23223
23224         local PREFIX=$(str_repeat 'A' 128)
23225         echo "Create 1K hard links start at $(date)"
23226         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23227                 error "(3) Fail to hard link"
23228
23229         echo "Links count should be right although linkEA overflow"
23230         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23231         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23232         [ $linkcount -eq 1001 ] ||
23233                 error "(5) Unexpected hard links count: $linkcount"
23234
23235         echo "List all links start at $(date)"
23236         ls -l $DIR/$tdir/foo > /dev/null ||
23237                 error "(6) Fail to list $DIR/$tdir/foo"
23238
23239         echo "Unlink hard links start at $(date)"
23240         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23241                 error "(7) Fail to unlink"
23242         echo "Unlink hard links finished at $(date)"
23243 }
23244 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23245
23246 test_410()
23247 {
23248         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23249                 skip "Need client version at least 2.9.59"
23250         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23251                 skip "Need MODULES build"
23252
23253         # Create a file, and stat it from the kernel
23254         local testfile=$DIR/$tfile
23255         touch $testfile
23256
23257         local run_id=$RANDOM
23258         local my_ino=$(stat --format "%i" $testfile)
23259
23260         # Try to insert the module. This will always fail as the
23261         # module is designed to not be inserted.
23262         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23263             &> /dev/null
23264
23265         # Anything but success is a test failure
23266         dmesg | grep -q \
23267             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23268             error "no inode match"
23269 }
23270 run_test 410 "Test inode number returned from kernel thread"
23271
23272 cleanup_test411_cgroup() {
23273         trap 0
23274         rmdir "$1"
23275 }
23276
23277 test_411() {
23278         local cg_basedir=/sys/fs/cgroup/memory
23279         # LU-9966
23280         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23281                 skip "no setup for cgroup"
23282
23283         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23284                 error "test file creation failed"
23285         cancel_lru_locks osc
23286
23287         # Create a very small memory cgroup to force a slab allocation error
23288         local cgdir=$cg_basedir/osc_slab_alloc
23289         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23290         trap "cleanup_test411_cgroup $cgdir" EXIT
23291         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23292         echo 1M > $cgdir/memory.limit_in_bytes
23293
23294         # Should not LBUG, just be killed by oom-killer
23295         # dd will return 0 even allocation failure in some environment.
23296         # So don't check return value
23297         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23298         cleanup_test411_cgroup $cgdir
23299
23300         return 0
23301 }
23302 run_test 411 "Slab allocation error with cgroup does not LBUG"
23303
23304 test_412() {
23305         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23306         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23307                 skip "Need server version at least 2.10.55"
23308         fi
23309
23310         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23311                 error "mkdir failed"
23312         $LFS getdirstripe $DIR/$tdir
23313         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23314         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23315                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23316         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23317         [ $stripe_count -eq 2 ] ||
23318                 error "expect 2 get $stripe_count"
23319 }
23320 run_test 412 "mkdir on specific MDTs"
23321
23322 test_qos_mkdir() {
23323         local mkdir_cmd=$1
23324         local stripe_count=$2
23325         local mdts=$(comma_list $(mdts_nodes))
23326
23327         local testdir
23328         local lmv_qos_prio_free
23329         local lmv_qos_threshold_rr
23330         local lmv_qos_maxage
23331         local lod_qos_prio_free
23332         local lod_qos_threshold_rr
23333         local lod_qos_maxage
23334         local count
23335         local i
23336
23337         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23338         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23339         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23340                 head -n1)
23341         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23342         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23343         stack_trap "$LCTL set_param \
23344                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23345         stack_trap "$LCTL set_param \
23346                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23347         stack_trap "$LCTL set_param \
23348                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23349
23350         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23351                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23352         lod_qos_prio_free=${lod_qos_prio_free%%%}
23353         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23354                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23355         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23356         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23357                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23358         stack_trap "do_nodes $mdts $LCTL set_param \
23359                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23360         stack_trap "do_nodes $mdts $LCTL set_param \
23361                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23362                 EXIT
23363         stack_trap "do_nodes $mdts $LCTL set_param \
23364                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23365
23366         echo
23367         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23368
23369         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23370         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23371
23372         testdir=$DIR/$tdir-s$stripe_count/rr
23373
23374         for i in $(seq $((100 * MDSCOUNT))); do
23375                 eval $mkdir_cmd $testdir/subdir$i ||
23376                         error "$mkdir_cmd subdir$i failed"
23377         done
23378
23379         for i in $(seq $MDSCOUNT); do
23380                 count=$($LFS getdirstripe -i $testdir/* |
23381                                 grep ^$((i - 1))$ | wc -l)
23382                 echo "$count directories created on MDT$((i - 1))"
23383                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23384
23385                 if [ $stripe_count -gt 1 ]; then
23386                         count=$($LFS getdirstripe $testdir/* |
23387                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23388                         echo "$count stripes created on MDT$((i - 1))"
23389                         # deviation should < 5% of average
23390                         [ $count -lt $((95 * stripe_count)) ] ||
23391                         [ $count -gt $((105 * stripe_count)) ] &&
23392                                 error "stripes are not evenly distributed"
23393                 fi
23394         done
23395
23396         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23397         do_nodes $mdts $LCTL set_param \
23398                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23399
23400         echo
23401         echo "Check for uneven MDTs: "
23402
23403         local ffree
23404         local bavail
23405         local max
23406         local min
23407         local max_index
23408         local min_index
23409         local tmp
23410
23411         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23412         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23413         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23414
23415         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23416         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23417         max_index=0
23418         min_index=0
23419         for ((i = 1; i < ${#ffree[@]}; i++)); do
23420                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23421                 if [ $tmp -gt $max ]; then
23422                         max=$tmp
23423                         max_index=$i
23424                 fi
23425                 if [ $tmp -lt $min ]; then
23426                         min=$tmp
23427                         min_index=$i
23428                 fi
23429         done
23430
23431         [ ${ffree[min_index]} -eq 0 ] &&
23432                 skip "no free files in MDT$min_index"
23433         [ ${ffree[min_index]} -gt 100000000 ] &&
23434                 skip "too much free files in MDT$min_index"
23435
23436         # Check if we need to generate uneven MDTs
23437         local threshold=50
23438         local diff=$(((max - min) * 100 / min))
23439         local value="$(generate_string 1024)"
23440
23441         while [ $diff -lt $threshold ]; do
23442                 # generate uneven MDTs, create till $threshold% diff
23443                 echo -n "weight diff=$diff% must be > $threshold% ..."
23444                 count=$((${ffree[min_index]} / 10))
23445                 # 50 sec per 10000 files in vm
23446                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23447                         skip "$count files to create"
23448                 echo "Fill MDT$min_index with $count files"
23449                 [ -d $DIR/$tdir-MDT$min_index ] ||
23450                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23451                         error "mkdir $tdir-MDT$min_index failed"
23452                 for i in $(seq $count); do
23453                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23454                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23455                                 error "create f$j_$i failed"
23456                         setfattr -n user.413b -v $value \
23457                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23458                                 error "setfattr f$j_$i failed"
23459                 done
23460
23461                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23462                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23463                 max=$(((${ffree[max_index]} >> 8) * \
23464                         (${bavail[max_index]} * bsize >> 16)))
23465                 min=$(((${ffree[min_index]} >> 8) * \
23466                         (${bavail[min_index]} * bsize >> 16)))
23467                 diff=$(((max - min) * 100 / min))
23468         done
23469
23470         echo "MDT filesfree available: ${ffree[@]}"
23471         echo "MDT blocks available: ${bavail[@]}"
23472         echo "weight diff=$diff%"
23473
23474         echo
23475         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23476
23477         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23478         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23479         # decrease statfs age, so that it can be updated in time
23480         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23481         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23482
23483         sleep 1
23484
23485         testdir=$DIR/$tdir-s$stripe_count/qos
23486
23487         for i in $(seq $((100 * MDSCOUNT))); do
23488                 eval $mkdir_cmd $testdir/subdir$i ||
23489                         error "$mkdir_cmd subdir$i failed"
23490         done
23491
23492         for i in $(seq $MDSCOUNT); do
23493                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23494                         wc -l)
23495                 echo "$count directories created on MDT$((i - 1))"
23496
23497                 if [ $stripe_count -gt 1 ]; then
23498                         count=$($LFS getdirstripe $testdir/* |
23499                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23500                         echo "$count stripes created on MDT$((i - 1))"
23501                 fi
23502         done
23503
23504         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23505         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23506
23507         # D-value should > 10% of averge
23508         [ $((max - min)) -lt 10 ] &&
23509                 error "subdirs shouldn't be evenly distributed"
23510
23511         # ditto
23512         if [ $stripe_count -gt 1 ]; then
23513                 max=$($LFS getdirstripe $testdir/* |
23514                         grep -P "^\s+$max_index\t" | wc -l)
23515                 min=$($LFS getdirstripe $testdir/* |
23516                         grep -P "^\s+$min_index\t" | wc -l)
23517                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23518                         error "stripes shouldn't be evenly distributed"|| true
23519         fi
23520 }
23521
23522 test_413a() {
23523         [ $MDSCOUNT -lt 2 ] &&
23524                 skip "We need at least 2 MDTs for this test"
23525
23526         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23527                 skip "Need server version at least 2.12.52"
23528
23529         local stripe_count
23530
23531         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23532                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23533                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23534                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23535                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23536         done
23537 }
23538 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23539
23540 test_413b() {
23541         [ $MDSCOUNT -lt 2 ] &&
23542                 skip "We need at least 2 MDTs for this test"
23543
23544         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23545                 skip "Need server version at least 2.12.52"
23546
23547         local stripe_count
23548
23549         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23550                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23551                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23552                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23553                 $LFS setdirstripe -D -c $stripe_count \
23554                         $DIR/$tdir-s$stripe_count/rr ||
23555                         error "setdirstripe failed"
23556                 $LFS setdirstripe -D -c $stripe_count \
23557                         $DIR/$tdir-s$stripe_count/qos ||
23558                         error "setdirstripe failed"
23559                 test_qos_mkdir "mkdir" $stripe_count
23560         done
23561 }
23562 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23563
23564 test_414() {
23565 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23566         $LCTL set_param fail_loc=0x80000521
23567         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23568         rm -f $DIR/$tfile
23569 }
23570 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23571
23572 test_415() {
23573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23574         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23575                 skip "Need server version at least 2.11.52"
23576
23577         # LU-11102
23578         local total
23579         local setattr_pid
23580         local start_time
23581         local end_time
23582         local duration
23583
23584         total=500
23585         # this test may be slow on ZFS
23586         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23587
23588         # though this test is designed for striped directory, let's test normal
23589         # directory too since lock is always saved as CoS lock.
23590         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23591         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23592
23593         (
23594                 while true; do
23595                         touch $DIR/$tdir
23596                 done
23597         ) &
23598         setattr_pid=$!
23599
23600         start_time=$(date +%s)
23601         for i in $(seq $total); do
23602                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23603                         > /dev/null
23604         done
23605         end_time=$(date +%s)
23606         duration=$((end_time - start_time))
23607
23608         kill -9 $setattr_pid
23609
23610         echo "rename $total files took $duration sec"
23611         [ $duration -lt 100 ] || error "rename took $duration sec"
23612 }
23613 run_test 415 "lock revoke is not missing"
23614
23615 test_416() {
23616         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23617                 skip "Need server version at least 2.11.55"
23618
23619         # define OBD_FAIL_OSD_TXN_START    0x19a
23620         do_facet mds1 lctl set_param fail_loc=0x19a
23621
23622         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23623
23624         true
23625 }
23626 run_test 416 "transaction start failure won't cause system hung"
23627
23628 cleanup_417() {
23629         trap 0
23630         do_nodes $(comma_list $(mdts_nodes)) \
23631                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23632         do_nodes $(comma_list $(mdts_nodes)) \
23633                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23634         do_nodes $(comma_list $(mdts_nodes)) \
23635                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23636 }
23637
23638 test_417() {
23639         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23640         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23641                 skip "Need MDS version at least 2.11.56"
23642
23643         trap cleanup_417 RETURN EXIT
23644
23645         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23646         do_nodes $(comma_list $(mdts_nodes)) \
23647                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23648         $LFS migrate -m 0 $DIR/$tdir.1 &&
23649                 error "migrate dir $tdir.1 should fail"
23650
23651         do_nodes $(comma_list $(mdts_nodes)) \
23652                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23653         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23654                 error "create remote dir $tdir.2 should fail"
23655
23656         do_nodes $(comma_list $(mdts_nodes)) \
23657                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23658         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23659                 error "create striped dir $tdir.3 should fail"
23660         true
23661 }
23662 run_test 417 "disable remote dir, striped dir and dir migration"
23663
23664 # Checks that the outputs of df [-i] and lfs df [-i] match
23665 #
23666 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23667 check_lfs_df() {
23668         local dir=$2
23669         local inodes
23670         local df_out
23671         local lfs_df_out
23672         local count
23673         local passed=false
23674
23675         # blocks or inodes
23676         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23677
23678         for count in {1..100}; do
23679                 cancel_lru_locks
23680                 sync; sleep 0.2
23681
23682                 # read the lines of interest
23683                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23684                         error "df $inodes $dir | tail -n +2 failed"
23685                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23686                         error "lfs df $inodes $dir | grep summary: failed"
23687
23688                 # skip first substrings of each output as they are different
23689                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23690                 # compare the two outputs
23691                 passed=true
23692                 for i in {1..5}; do
23693                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23694                 done
23695                 $passed && break
23696         done
23697
23698         if ! $passed; then
23699                 df -P $inodes $dir
23700                 echo
23701                 lfs df $inodes $dir
23702                 error "df and lfs df $1 output mismatch: "      \
23703                       "df ${inodes}: ${df_out[*]}, "            \
23704                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23705         fi
23706 }
23707
23708 test_418() {
23709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23710
23711         local dir=$DIR/$tdir
23712         local numfiles=$((RANDOM % 4096 + 2))
23713         local numblocks=$((RANDOM % 256 + 1))
23714
23715         wait_delete_completed
23716         test_mkdir $dir
23717
23718         # check block output
23719         check_lfs_df blocks $dir
23720         # check inode output
23721         check_lfs_df inodes $dir
23722
23723         # create a single file and retest
23724         echo "Creating a single file and testing"
23725         createmany -o $dir/$tfile- 1 &>/dev/null ||
23726                 error "creating 1 file in $dir failed"
23727         check_lfs_df blocks $dir
23728         check_lfs_df inodes $dir
23729
23730         # create a random number of files
23731         echo "Creating $((numfiles - 1)) files and testing"
23732         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23733                 error "creating $((numfiles - 1)) files in $dir failed"
23734
23735         # write a random number of blocks to the first test file
23736         echo "Writing $numblocks 4K blocks and testing"
23737         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23738                 count=$numblocks &>/dev/null ||
23739                 error "dd to $dir/${tfile}-0 failed"
23740
23741         # retest
23742         check_lfs_df blocks $dir
23743         check_lfs_df inodes $dir
23744
23745         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23746                 error "unlinking $numfiles files in $dir failed"
23747 }
23748 run_test 418 "df and lfs df outputs match"
23749
23750 test_419()
23751 {
23752         local dir=$DIR/$tdir
23753
23754         mkdir -p $dir
23755         touch $dir/file
23756
23757         cancel_lru_locks mdc
23758
23759         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23760         $LCTL set_param fail_loc=0x1410
23761         cat $dir/file
23762         $LCTL set_param fail_loc=0
23763         rm -rf $dir
23764 }
23765 run_test 419 "Verify open file by name doesn't crash kernel"
23766
23767 test_420()
23768 {
23769         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23770                 skip "Need MDS version at least 2.12.53"
23771
23772         local SAVE_UMASK=$(umask)
23773         local dir=$DIR/$tdir
23774         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23775
23776         mkdir -p $dir
23777         umask 0000
23778         mkdir -m03777 $dir/testdir
23779         ls -dn $dir/testdir
23780         # Need to remove trailing '.' when SELinux is enabled
23781         local dirperms=$(ls -dn $dir/testdir |
23782                          awk '{ sub(/\.$/, "", $1); print $1}')
23783         [ $dirperms == "drwxrwsrwt" ] ||
23784                 error "incorrect perms on $dir/testdir"
23785
23786         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23787                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23788         ls -n $dir/testdir/testfile
23789         local fileperms=$(ls -n $dir/testdir/testfile |
23790                           awk '{ sub(/\.$/, "", $1); print $1}')
23791         [ $fileperms == "-rwxr-xr-x" ] ||
23792                 error "incorrect perms on $dir/testdir/testfile"
23793
23794         umask $SAVE_UMASK
23795 }
23796 run_test 420 "clear SGID bit on non-directories for non-members"
23797
23798 test_421a() {
23799         local cnt
23800         local fid1
23801         local fid2
23802
23803         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23804                 skip "Need MDS version at least 2.12.54"
23805
23806         test_mkdir $DIR/$tdir
23807         createmany -o $DIR/$tdir/f 3
23808         cnt=$(ls -1 $DIR/$tdir | wc -l)
23809         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23810
23811         fid1=$(lfs path2fid $DIR/$tdir/f1)
23812         fid2=$(lfs path2fid $DIR/$tdir/f2)
23813         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23814
23815         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23816         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23817
23818         cnt=$(ls -1 $DIR/$tdir | wc -l)
23819         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23820
23821         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23822         createmany -o $DIR/$tdir/f 3
23823         cnt=$(ls -1 $DIR/$tdir | wc -l)
23824         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23825
23826         fid1=$(lfs path2fid $DIR/$tdir/f1)
23827         fid2=$(lfs path2fid $DIR/$tdir/f2)
23828         echo "remove using fsname $FSNAME"
23829         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23830
23831         cnt=$(ls -1 $DIR/$tdir | wc -l)
23832         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23833 }
23834 run_test 421a "simple rm by fid"
23835
23836 test_421b() {
23837         local cnt
23838         local FID1
23839         local FID2
23840
23841         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23842                 skip "Need MDS version at least 2.12.54"
23843
23844         test_mkdir $DIR/$tdir
23845         createmany -o $DIR/$tdir/f 3
23846         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23847         MULTIPID=$!
23848
23849         FID1=$(lfs path2fid $DIR/$tdir/f1)
23850         FID2=$(lfs path2fid $DIR/$tdir/f2)
23851         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23852
23853         kill -USR1 $MULTIPID
23854         wait
23855
23856         cnt=$(ls $DIR/$tdir | wc -l)
23857         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23858 }
23859 run_test 421b "rm by fid on open file"
23860
23861 test_421c() {
23862         local cnt
23863         local FIDS
23864
23865         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23866                 skip "Need MDS version at least 2.12.54"
23867
23868         test_mkdir $DIR/$tdir
23869         createmany -o $DIR/$tdir/f 3
23870         touch $DIR/$tdir/$tfile
23871         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23872         cnt=$(ls -1 $DIR/$tdir | wc -l)
23873         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23874
23875         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23876         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23877
23878         cnt=$(ls $DIR/$tdir | wc -l)
23879         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23880 }
23881 run_test 421c "rm by fid against hardlinked files"
23882
23883 test_421d() {
23884         local cnt
23885         local FIDS
23886
23887         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23888                 skip "Need MDS version at least 2.12.54"
23889
23890         test_mkdir $DIR/$tdir
23891         createmany -o $DIR/$tdir/f 4097
23892         cnt=$(ls -1 $DIR/$tdir | wc -l)
23893         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23894
23895         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23896         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23897
23898         cnt=$(ls $DIR/$tdir | wc -l)
23899         rm -rf $DIR/$tdir
23900         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23901 }
23902 run_test 421d "rmfid en masse"
23903
23904 test_421e() {
23905         local cnt
23906         local FID
23907
23908         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23909         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23910                 skip "Need MDS version at least 2.12.54"
23911
23912         mkdir -p $DIR/$tdir
23913         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23914         createmany -o $DIR/$tdir/striped_dir/f 512
23915         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23916         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23917
23918         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23919                 sed "s/[/][^:]*://g")
23920         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23921
23922         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23923         rm -rf $DIR/$tdir
23924         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23925 }
23926 run_test 421e "rmfid in DNE"
23927
23928 test_421f() {
23929         local cnt
23930         local FID
23931
23932         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23933                 skip "Need MDS version at least 2.12.54"
23934
23935         test_mkdir $DIR/$tdir
23936         touch $DIR/$tdir/f
23937         cnt=$(ls -1 $DIR/$tdir | wc -l)
23938         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23939
23940         FID=$(lfs path2fid $DIR/$tdir/f)
23941         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23942         # rmfid should fail
23943         cnt=$(ls -1 $DIR/$tdir | wc -l)
23944         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23945
23946         chmod a+rw $DIR/$tdir
23947         ls -la $DIR/$tdir
23948         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23949         # rmfid should fail
23950         cnt=$(ls -1 $DIR/$tdir | wc -l)
23951         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23952
23953         rm -f $DIR/$tdir/f
23954         $RUNAS touch $DIR/$tdir/f
23955         FID=$(lfs path2fid $DIR/$tdir/f)
23956         echo "rmfid as root"
23957         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23958         cnt=$(ls -1 $DIR/$tdir | wc -l)
23959         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23960
23961         rm -f $DIR/$tdir/f
23962         $RUNAS touch $DIR/$tdir/f
23963         cnt=$(ls -1 $DIR/$tdir | wc -l)
23964         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23965         FID=$(lfs path2fid $DIR/$tdir/f)
23966         # rmfid w/o user_fid2path mount option should fail
23967         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23968         cnt=$(ls -1 $DIR/$tdir | wc -l)
23969         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23970
23971         umount_client $MOUNT || error "failed to umount client"
23972         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23973                 error "failed to mount client'"
23974
23975         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23976         # rmfid should succeed
23977         cnt=$(ls -1 $DIR/$tdir | wc -l)
23978         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23979
23980         # rmfid shouldn't allow to remove files due to dir's permission
23981         chmod a+rwx $DIR/$tdir
23982         touch $DIR/$tdir/f
23983         ls -la $DIR/$tdir
23984         FID=$(lfs path2fid $DIR/$tdir/f)
23985         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23986
23987         umount_client $MOUNT || error "failed to umount client"
23988         mount_client $MOUNT "$MOUNT_OPTS" ||
23989                 error "failed to mount client'"
23990
23991 }
23992 run_test 421f "rmfid checks permissions"
23993
23994 test_421g() {
23995         local cnt
23996         local FIDS
23997
23998         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23999         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24000                 skip "Need MDS version at least 2.12.54"
24001
24002         mkdir -p $DIR/$tdir
24003         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24004         createmany -o $DIR/$tdir/striped_dir/f 512
24005         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24006         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24007
24008         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24009                 sed "s/[/][^:]*://g")
24010
24011         rm -f $DIR/$tdir/striped_dir/f1*
24012         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24013         removed=$((512 - cnt))
24014
24015         # few files have been just removed, so we expect
24016         # rmfid to fail on their fids
24017         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24018         [ $removed != $errors ] && error "$errors != $removed"
24019
24020         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24021         rm -rf $DIR/$tdir
24022         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24023 }
24024 run_test 421g "rmfid to return errors properly"
24025
24026 test_422() {
24027         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24028         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24029         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24030         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24031         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24032
24033         local amc=$(at_max_get client)
24034         local amo=$(at_max_get mds1)
24035         local timeout=`lctl get_param -n timeout`
24036
24037         at_max_set 0 client
24038         at_max_set 0 mds1
24039
24040 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24041         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24042                         fail_val=$(((2*timeout + 10)*1000))
24043         touch $DIR/$tdir/d3/file &
24044         sleep 2
24045 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24046         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24047                         fail_val=$((2*timeout + 5))
24048         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24049         local pid=$!
24050         sleep 1
24051         kill -9 $pid
24052         sleep $((2 * timeout))
24053         echo kill $pid
24054         kill -9 $pid
24055         lctl mark touch
24056         touch $DIR/$tdir/d2/file3
24057         touch $DIR/$tdir/d2/file4
24058         touch $DIR/$tdir/d2/file5
24059
24060         wait
24061         at_max_set $amc client
24062         at_max_set $amo mds1
24063
24064         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24065         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24066                 error "Watchdog is always throttled"
24067 }
24068 run_test 422 "kill a process with RPC in progress"
24069
24070 stat_test() {
24071     df -h $MOUNT &
24072     df -h $MOUNT &
24073     df -h $MOUNT &
24074     df -h $MOUNT &
24075     df -h $MOUNT &
24076     df -h $MOUNT &
24077 }
24078
24079 test_423() {
24080     local _stats
24081     # ensure statfs cache is expired
24082     sleep 2;
24083
24084     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24085     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24086
24087     return 0
24088 }
24089 run_test 423 "statfs should return a right data"
24090
24091 test_424() {
24092 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24093         $LCTL set_param fail_loc=0x80000522
24094         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24095         rm -f $DIR/$tfile
24096 }
24097 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24098
24099 test_425() {
24100         test_mkdir -c -1 $DIR/$tdir
24101         $LFS setstripe -c -1 $DIR/$tdir
24102
24103         lru_resize_disable "" 100
24104         stack_trap "lru_resize_enable" EXIT
24105
24106         sleep 5
24107
24108         for i in $(seq $((MDSCOUNT * 125))); do
24109                 local t=$DIR/$tdir/$tfile_$i
24110
24111                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24112                         error_noexit "Create file $t"
24113         done
24114         stack_trap "rm -rf $DIR/$tdir" EXIT
24115
24116         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24117                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24118                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24119
24120                 [ $lock_count -le $lru_size ] ||
24121                         error "osc lock count $lock_count > lru size $lru_size"
24122         done
24123
24124         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24125                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24126                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24127
24128                 [ $lock_count -le $lru_size ] ||
24129                         error "mdc lock count $lock_count > lru size $lru_size"
24130         done
24131 }
24132 run_test 425 "lock count should not exceed lru size"
24133
24134 test_426() {
24135         splice-test -r $DIR/$tfile
24136         splice-test -rd $DIR/$tfile
24137         splice-test $DIR/$tfile
24138         splice-test -d $DIR/$tfile
24139 }
24140 run_test 426 "splice test on Lustre"
24141
24142 test_427() {
24143         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24144         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24145                 skip "Need MDS version at least 2.12.4"
24146         local log
24147
24148         mkdir $DIR/$tdir
24149         mkdir $DIR/$tdir/1
24150         mkdir $DIR/$tdir/2
24151         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24152         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24153
24154         $LFS getdirstripe $DIR/$tdir/1/dir
24155
24156         #first setfattr for creating updatelog
24157         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24158
24159 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24160         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24161         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24162         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24163
24164         sleep 2
24165         fail mds2
24166         wait_recovery_complete mds2 $((2*TIMEOUT))
24167
24168         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24169         echo $log | grep "get update log failed" &&
24170                 error "update log corruption is detected" || true
24171 }
24172 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24173
24174 lseek_test_430() {
24175         local offset
24176         local file=$1
24177
24178         # data at [200K, 400K)
24179         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24180                 error "256K->512K dd fails"
24181         # data at [2M, 3M)
24182         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24183                 error "2M->3M dd fails"
24184         # data at [4M, 5M)
24185         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24186                 error "4M->5M dd fails"
24187         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24188         # start at first component hole #1
24189         printf "Seeking hole from 1000 ... "
24190         offset=$(lseek_test -l 1000 $file)
24191         echo $offset
24192         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24193         printf "Seeking data from 1000 ... "
24194         offset=$(lseek_test -d 1000 $file)
24195         echo $offset
24196         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24197
24198         # start at first component data block
24199         printf "Seeking hole from 300000 ... "
24200         offset=$(lseek_test -l 300000 $file)
24201         echo $offset
24202         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24203         printf "Seeking data from 300000 ... "
24204         offset=$(lseek_test -d 300000 $file)
24205         echo $offset
24206         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24207
24208         # start at the first component but beyond end of object size
24209         printf "Seeking hole from 1000000 ... "
24210         offset=$(lseek_test -l 1000000 $file)
24211         echo $offset
24212         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24213         printf "Seeking data from 1000000 ... "
24214         offset=$(lseek_test -d 1000000 $file)
24215         echo $offset
24216         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24217
24218         # start at second component stripe 2 (empty file)
24219         printf "Seeking hole from 1500000 ... "
24220         offset=$(lseek_test -l 1500000 $file)
24221         echo $offset
24222         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
24223         printf "Seeking data from 1500000 ... "
24224         offset=$(lseek_test -d 1500000 $file)
24225         echo $offset
24226         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24227
24228         # start at second component stripe 1 (all data)
24229         printf "Seeking hole from 3000000 ... "
24230         offset=$(lseek_test -l 3000000 $file)
24231         echo $offset
24232         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
24233         printf "Seeking data from 3000000 ... "
24234         offset=$(lseek_test -d 3000000 $file)
24235         echo $offset
24236         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
24237
24238         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
24239                 error "2nd dd fails"
24240         echo "Add data block at 640K...1280K"
24241
24242         # start at before new data block, in hole
24243         printf "Seeking hole from 600000 ... "
24244         offset=$(lseek_test -l 600000 $file)
24245         echo $offset
24246         [[ $offset == 600000 ]] || error "offset $offset != 600000"
24247         printf "Seeking data from 600000 ... "
24248         offset=$(lseek_test -d 600000 $file)
24249         echo $offset
24250         [[ $offset == 655360 ]] || error "offset $offset != 655360"
24251
24252         # start at the first component new data block
24253         printf "Seeking hole from 1000000 ... "
24254         offset=$(lseek_test -l 1000000 $file)
24255         echo $offset
24256         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24257         printf "Seeking data from 1000000 ... "
24258         offset=$(lseek_test -d 1000000 $file)
24259         echo $offset
24260         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24261
24262         # start at second component stripe 2, new data
24263         printf "Seeking hole from 1200000 ... "
24264         offset=$(lseek_test -l 1200000 $file)
24265         echo $offset
24266         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24267         printf "Seeking data from 1200000 ... "
24268         offset=$(lseek_test -d 1200000 $file)
24269         echo $offset
24270         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
24271
24272         # start beyond file end
24273         printf "Using offset > filesize ... "
24274         lseek_test -l 4000000 $file && error "lseek should fail"
24275         printf "Using offset > filesize ... "
24276         lseek_test -d 4000000 $file && error "lseek should fail"
24277
24278         printf "Done\n\n"
24279 }
24280
24281 test_430a() {
24282         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
24283                 skip "MDT does not support SEEK_HOLE"
24284
24285         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24286                 skip "OST does not support SEEK_HOLE"
24287
24288         local file=$DIR/$tdir/$tfile
24289
24290         mkdir -p $DIR/$tdir
24291
24292         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
24293         # OST stripe #1 will have continuous data at [1M, 3M)
24294         # OST stripe #2 is empty
24295         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
24296         lseek_test_430 $file
24297         rm $file
24298         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
24299         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
24300         lseek_test_430 $file
24301         rm $file
24302         $LFS setstripe -c2 -S 512K $file
24303         echo "Two stripes, stripe size 512K"
24304         lseek_test_430 $file
24305         rm $file
24306         # FLR with stale mirror
24307         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
24308                        -N -c2 -S 1M $file
24309         echo "Mirrored file:"
24310         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
24311         echo "Plain 2 stripes 1M"
24312         lseek_test_430 $file
24313         rm $file
24314 }
24315 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
24316
24317 test_430b() {
24318         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24319                 skip "OST does not support SEEK_HOLE"
24320
24321         local offset
24322         local file=$DIR/$tdir/$tfile
24323
24324         mkdir -p $DIR/$tdir
24325         # Empty layout lseek should fail
24326         $MCREATE $file
24327         # seek from 0
24328         printf "Seeking hole from 0 ... "
24329         lseek_test -l 0 $file && error "lseek should fail"
24330         printf "Seeking data from 0 ... "
24331         lseek_test -d 0 $file && error "lseek should fail"
24332         rm $file
24333
24334         # 1M-hole file
24335         $LFS setstripe -E 1M -c2 -E eof $file
24336         $TRUNCATE $file 1048576
24337         printf "Seeking hole from 1000000 ... "
24338         offset=$(lseek_test -l 1000000 $file)
24339         echo $offset
24340         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24341         printf "Seeking data from 1000000 ... "
24342         lseek_test -d 1000000 $file && error "lseek should fail"
24343         rm $file
24344
24345         # full component followed by non-inited one
24346         $LFS setstripe -E 1M -c2 -E eof $file
24347         dd if=/dev/urandom of=$file bs=1M count=1
24348         printf "Seeking hole from 1000000 ... "
24349         offset=$(lseek_test -l 1000000 $file)
24350         echo $offset
24351         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24352         printf "Seeking hole from 1048576 ... "
24353         lseek_test -l 1048576 $file && error "lseek should fail"
24354         # init second component and truncate back
24355         echo "123" >> $file
24356         $TRUNCATE $file 1048576
24357         printf "Seeking hole from 1000000 ... "
24358         offset=$(lseek_test -l 1000000 $file)
24359         echo $offset
24360         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24361         printf "Seeking hole from 1048576 ... "
24362         lseek_test -l 1048576 $file && error "lseek should fail"
24363         # boundary checks for big values
24364         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
24365         offset=$(lseek_test -d 0 $file.10g)
24366         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
24367         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
24368         offset=$(lseek_test -d 0 $file.100g)
24369         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
24370         return 0
24371 }
24372 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
24373
24374 test_430c() {
24375         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24376                 skip "OST does not support SEEK_HOLE"
24377
24378         local file=$DIR/$tdir/$tfile
24379         local start
24380
24381         mkdir -p $DIR/$tdir
24382         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
24383
24384         # cp version 8.33+ prefers lseek over fiemap
24385         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
24386                 start=$SECONDS
24387                 time cp $file /dev/null
24388                 (( SECONDS - start < 5 )) ||
24389                         error "cp: too long runtime $((SECONDS - start))"
24390
24391         fi
24392         # tar version 1.29+ supports SEEK_HOLE/DATA
24393         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
24394                 start=$SECONDS
24395                 time tar cS $file - | cat > /dev/null
24396                 (( SECONDS - start < 5 )) ||
24397                         error "tar: too long runtime $((SECONDS - start))"
24398         fi
24399 }
24400 run_test 430c "lseek: external tools check"
24401
24402 test_431() { # LU-14187
24403         local file=$DIR/$tdir/$tfile
24404
24405         mkdir -p $DIR/$tdir
24406         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
24407         dd if=/dev/urandom of=$file bs=4k count=1
24408         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
24409         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
24410         #define OBD_FAIL_OST_RESTART_IO 0x251
24411         do_facet ost1 "$LCTL set_param fail_loc=0x251"
24412         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
24413         cp $file $file.0
24414         cancel_lru_locks
24415         sync_all_data
24416         echo 3 > /proc/sys/vm/drop_caches
24417         diff  $file $file.0 || error "data diff"
24418 }
24419 run_test 431 "Restart transaction for IO"
24420
24421 prep_801() {
24422         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24423         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24424                 skip "Need server version at least 2.9.55"
24425
24426         start_full_debug_logging
24427 }
24428
24429 post_801() {
24430         stop_full_debug_logging
24431 }
24432
24433 barrier_stat() {
24434         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24435                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24436                            awk '/The barrier for/ { print $7 }')
24437                 echo $st
24438         else
24439                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24440                 echo \'$st\'
24441         fi
24442 }
24443
24444 barrier_expired() {
24445         local expired
24446
24447         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24448                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24449                           awk '/will be expired/ { print $7 }')
24450         else
24451                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24452         fi
24453
24454         echo $expired
24455 }
24456
24457 test_801a() {
24458         prep_801
24459
24460         echo "Start barrier_freeze at: $(date)"
24461         #define OBD_FAIL_BARRIER_DELAY          0x2202
24462         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24463         # Do not reduce barrier time - See LU-11873
24464         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24465
24466         sleep 2
24467         local b_status=$(barrier_stat)
24468         echo "Got barrier status at: $(date)"
24469         [ "$b_status" = "'freezing_p1'" ] ||
24470                 error "(1) unexpected barrier status $b_status"
24471
24472         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24473         wait
24474         b_status=$(barrier_stat)
24475         [ "$b_status" = "'frozen'" ] ||
24476                 error "(2) unexpected barrier status $b_status"
24477
24478         local expired=$(barrier_expired)
24479         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24480         sleep $((expired + 3))
24481
24482         b_status=$(barrier_stat)
24483         [ "$b_status" = "'expired'" ] ||
24484                 error "(3) unexpected barrier status $b_status"
24485
24486         # Do not reduce barrier time - See LU-11873
24487         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24488                 error "(4) fail to freeze barrier"
24489
24490         b_status=$(barrier_stat)
24491         [ "$b_status" = "'frozen'" ] ||
24492                 error "(5) unexpected barrier status $b_status"
24493
24494         echo "Start barrier_thaw at: $(date)"
24495         #define OBD_FAIL_BARRIER_DELAY          0x2202
24496         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24497         do_facet mgs $LCTL barrier_thaw $FSNAME &
24498
24499         sleep 2
24500         b_status=$(barrier_stat)
24501         echo "Got barrier status at: $(date)"
24502         [ "$b_status" = "'thawing'" ] ||
24503                 error "(6) unexpected barrier status $b_status"
24504
24505         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24506         wait
24507         b_status=$(barrier_stat)
24508         [ "$b_status" = "'thawed'" ] ||
24509                 error "(7) unexpected barrier status $b_status"
24510
24511         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24512         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24513         do_facet mgs $LCTL barrier_freeze $FSNAME
24514
24515         b_status=$(barrier_stat)
24516         [ "$b_status" = "'failed'" ] ||
24517                 error "(8) unexpected barrier status $b_status"
24518
24519         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24520         do_facet mgs $LCTL barrier_thaw $FSNAME
24521
24522         post_801
24523 }
24524 run_test 801a "write barrier user interfaces and stat machine"
24525
24526 test_801b() {
24527         prep_801
24528
24529         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24530         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24531         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24532         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24533         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24534
24535         cancel_lru_locks mdc
24536
24537         # 180 seconds should be long enough
24538         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24539
24540         local b_status=$(barrier_stat)
24541         [ "$b_status" = "'frozen'" ] ||
24542                 error "(6) unexpected barrier status $b_status"
24543
24544         mkdir $DIR/$tdir/d0/d10 &
24545         mkdir_pid=$!
24546
24547         touch $DIR/$tdir/d1/f13 &
24548         touch_pid=$!
24549
24550         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24551         ln_pid=$!
24552
24553         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24554         mv_pid=$!
24555
24556         rm -f $DIR/$tdir/d4/f12 &
24557         rm_pid=$!
24558
24559         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24560
24561         # To guarantee taht the 'stat' is not blocked
24562         b_status=$(barrier_stat)
24563         [ "$b_status" = "'frozen'" ] ||
24564                 error "(8) unexpected barrier status $b_status"
24565
24566         # let above commands to run at background
24567         sleep 5
24568
24569         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24570         ps -p $touch_pid || error "(10) touch should be blocked"
24571         ps -p $ln_pid || error "(11) link should be blocked"
24572         ps -p $mv_pid || error "(12) rename should be blocked"
24573         ps -p $rm_pid || error "(13) unlink should be blocked"
24574
24575         b_status=$(barrier_stat)
24576         [ "$b_status" = "'frozen'" ] ||
24577                 error "(14) unexpected barrier status $b_status"
24578
24579         do_facet mgs $LCTL barrier_thaw $FSNAME
24580         b_status=$(barrier_stat)
24581         [ "$b_status" = "'thawed'" ] ||
24582                 error "(15) unexpected barrier status $b_status"
24583
24584         wait $mkdir_pid || error "(16) mkdir should succeed"
24585         wait $touch_pid || error "(17) touch should succeed"
24586         wait $ln_pid || error "(18) link should succeed"
24587         wait $mv_pid || error "(19) rename should succeed"
24588         wait $rm_pid || error "(20) unlink should succeed"
24589
24590         post_801
24591 }
24592 run_test 801b "modification will be blocked by write barrier"
24593
24594 test_801c() {
24595         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24596
24597         prep_801
24598
24599         stop mds2 || error "(1) Fail to stop mds2"
24600
24601         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24602
24603         local b_status=$(barrier_stat)
24604         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24605                 do_facet mgs $LCTL barrier_thaw $FSNAME
24606                 error "(2) unexpected barrier status $b_status"
24607         }
24608
24609         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24610                 error "(3) Fail to rescan barrier bitmap"
24611
24612         # Do not reduce barrier time - See LU-11873
24613         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24614
24615         b_status=$(barrier_stat)
24616         [ "$b_status" = "'frozen'" ] ||
24617                 error "(4) unexpected barrier status $b_status"
24618
24619         do_facet mgs $LCTL barrier_thaw $FSNAME
24620         b_status=$(barrier_stat)
24621         [ "$b_status" = "'thawed'" ] ||
24622                 error "(5) unexpected barrier status $b_status"
24623
24624         local devname=$(mdsdevname 2)
24625
24626         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24627
24628         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24629                 error "(7) Fail to rescan barrier bitmap"
24630
24631         post_801
24632 }
24633 run_test 801c "rescan barrier bitmap"
24634
24635 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24636 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24637 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24638 saved_MOUNT_OPTS=$MOUNT_OPTS
24639
24640 cleanup_802a() {
24641         trap 0
24642
24643         stopall
24644         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24645         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24646         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24647         MOUNT_OPTS=$saved_MOUNT_OPTS
24648         setupall
24649 }
24650
24651 test_802a() {
24652         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24653         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24654         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24655                 skip "Need server version at least 2.9.55"
24656
24657         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24658
24659         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24660
24661         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24662                 error "(2) Fail to copy"
24663
24664         trap cleanup_802a EXIT
24665
24666         # sync by force before remount as readonly
24667         sync; sync_all_data; sleep 3; sync_all_data
24668
24669         stopall
24670
24671         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24672         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24673         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24674
24675         echo "Mount the server as read only"
24676         setupall server_only || error "(3) Fail to start servers"
24677
24678         echo "Mount client without ro should fail"
24679         mount_client $MOUNT &&
24680                 error "(4) Mount client without 'ro' should fail"
24681
24682         echo "Mount client with ro should succeed"
24683         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24684         mount_client $MOUNT ||
24685                 error "(5) Mount client with 'ro' should succeed"
24686
24687         echo "Modify should be refused"
24688         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24689
24690         echo "Read should be allowed"
24691         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24692                 error "(7) Read should succeed under ro mode"
24693
24694         cleanup_802a
24695 }
24696 run_test 802a "simulate readonly device"
24697
24698 test_802b() {
24699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24700         remote_mds_nodsh && skip "remote MDS with nodsh"
24701
24702         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24703                 skip "readonly option not available"
24704
24705         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24706
24707         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24708                 error "(2) Fail to copy"
24709
24710         # write back all cached data before setting MDT to readonly
24711         cancel_lru_locks
24712         sync_all_data
24713
24714         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24715         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24716
24717         echo "Modify should be refused"
24718         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24719
24720         echo "Read should be allowed"
24721         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24722                 error "(7) Read should succeed under ro mode"
24723
24724         # disable readonly
24725         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24726 }
24727 run_test 802b "be able to set MDTs to readonly"
24728
24729 test_803a() {
24730         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24731         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24732                 skip "MDS needs to be newer than 2.10.54"
24733
24734         mkdir -p $DIR/$tdir
24735         # Create some objects on all MDTs to trigger related logs objects
24736         for idx in $(seq $MDSCOUNT); do
24737                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24738                         $DIR/$tdir/dir${idx} ||
24739                         error "Fail to create $DIR/$tdir/dir${idx}"
24740         done
24741
24742         sync; sleep 3
24743         wait_delete_completed # ensure old test cleanups are finished
24744         echo "before create:"
24745         $LFS df -i $MOUNT
24746         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24747
24748         for i in {1..10}; do
24749                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24750                         error "Fail to create $DIR/$tdir/foo$i"
24751         done
24752
24753         sync; sleep 3
24754         echo "after create:"
24755         $LFS df -i $MOUNT
24756         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24757
24758         # allow for an llog to be cleaned up during the test
24759         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24760                 error "before ($before_used) + 10 > after ($after_used)"
24761
24762         for i in {1..10}; do
24763                 rm -rf $DIR/$tdir/foo$i ||
24764                         error "Fail to remove $DIR/$tdir/foo$i"
24765         done
24766
24767         sleep 3 # avoid MDT return cached statfs
24768         wait_delete_completed
24769         echo "after unlink:"
24770         $LFS df -i $MOUNT
24771         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24772
24773         # allow for an llog to be created during the test
24774         [ $after_used -le $((before_used + 1)) ] ||
24775                 error "after ($after_used) > before ($before_used) + 1"
24776 }
24777 run_test 803a "verify agent object for remote object"
24778
24779 test_803b() {
24780         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24781         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24782                 skip "MDS needs to be newer than 2.13.56"
24783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24784
24785         for i in $(seq 0 $((MDSCOUNT - 1))); do
24786                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24787         done
24788
24789         local before=0
24790         local after=0
24791
24792         local tmp
24793
24794         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24795         for i in $(seq 0 $((MDSCOUNT - 1))); do
24796                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24797                         awk '/getattr/ { print $2 }')
24798                 before=$((before + tmp))
24799         done
24800         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24801         for i in $(seq 0 $((MDSCOUNT - 1))); do
24802                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24803                         awk '/getattr/ { print $2 }')
24804                 after=$((after + tmp))
24805         done
24806
24807         [ $before -eq $after ] || error "getattr count $before != $after"
24808 }
24809 run_test 803b "remote object can getattr from cache"
24810
24811 test_804() {
24812         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24813         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24814                 skip "MDS needs to be newer than 2.10.54"
24815         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24816
24817         mkdir -p $DIR/$tdir
24818         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24819                 error "Fail to create $DIR/$tdir/dir0"
24820
24821         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24822         local dev=$(mdsdevname 2)
24823
24824         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24825                 grep ${fid} || error "NOT found agent entry for dir0"
24826
24827         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24828                 error "Fail to create $DIR/$tdir/dir1"
24829
24830         touch $DIR/$tdir/dir1/foo0 ||
24831                 error "Fail to create $DIR/$tdir/dir1/foo0"
24832         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24833         local rc=0
24834
24835         for idx in $(seq $MDSCOUNT); do
24836                 dev=$(mdsdevname $idx)
24837                 do_facet mds${idx} \
24838                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24839                         grep ${fid} && rc=$idx
24840         done
24841
24842         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24843                 error "Fail to rename foo0 to foo1"
24844         if [ $rc -eq 0 ]; then
24845                 for idx in $(seq $MDSCOUNT); do
24846                         dev=$(mdsdevname $idx)
24847                         do_facet mds${idx} \
24848                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24849                         grep ${fid} && rc=$idx
24850                 done
24851         fi
24852
24853         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24854                 error "Fail to rename foo1 to foo2"
24855         if [ $rc -eq 0 ]; then
24856                 for idx in $(seq $MDSCOUNT); do
24857                         dev=$(mdsdevname $idx)
24858                         do_facet mds${idx} \
24859                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24860                         grep ${fid} && rc=$idx
24861                 done
24862         fi
24863
24864         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24865
24866         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24867                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24868         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24869                 error "Fail to rename foo2 to foo0"
24870         unlink $DIR/$tdir/dir1/foo0 ||
24871                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24872         rm -rf $DIR/$tdir/dir0 ||
24873                 error "Fail to rm $DIR/$tdir/dir0"
24874
24875         for idx in $(seq $MDSCOUNT); do
24876                 dev=$(mdsdevname $idx)
24877                 rc=0
24878
24879                 stop mds${idx}
24880                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24881                         rc=$?
24882                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24883                         error "mount mds$idx failed"
24884                 df $MOUNT > /dev/null 2>&1
24885
24886                 # e2fsck should not return error
24887                 [ $rc -eq 0 ] ||
24888                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24889         done
24890 }
24891 run_test 804 "verify agent entry for remote entry"
24892
24893 cleanup_805() {
24894         do_facet $SINGLEMDS zfs set quota=$old $fsset
24895         unlinkmany $DIR/$tdir/f- 1000000
24896         trap 0
24897 }
24898
24899 test_805() {
24900         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24901         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24902         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24903                 skip "netfree not implemented before 0.7"
24904         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24905                 skip "Need MDS version at least 2.10.57"
24906
24907         local fsset
24908         local freekb
24909         local usedkb
24910         local old
24911         local quota
24912         local pref="osd-zfs.$FSNAME-MDT0000."
24913
24914         # limit available space on MDS dataset to meet nospace issue
24915         # quickly. then ZFS 0.7.2 can use reserved space if asked
24916         # properly (using netfree flag in osd_declare_destroy()
24917         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24918         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24919                 gawk '{print $3}')
24920         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24921         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24922         let "usedkb=usedkb-freekb"
24923         let "freekb=freekb/2"
24924         if let "freekb > 5000"; then
24925                 let "freekb=5000"
24926         fi
24927         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24928         trap cleanup_805 EXIT
24929         mkdir $DIR/$tdir
24930         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24931                 error "Can't set PFL layout"
24932         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24933         rm -rf $DIR/$tdir || error "not able to remove"
24934         do_facet $SINGLEMDS zfs set quota=$old $fsset
24935         trap 0
24936 }
24937 run_test 805 "ZFS can remove from full fs"
24938
24939 # Size-on-MDS test
24940 check_lsom_data()
24941 {
24942         local file=$1
24943         local size=$($LFS getsom -s $file)
24944         local expect=$(stat -c %s $file)
24945
24946         [[ $size == $expect ]] ||
24947                 error "$file expected size: $expect, got: $size"
24948
24949         local blocks=$($LFS getsom -b $file)
24950         expect=$(stat -c %b $file)
24951         [[ $blocks == $expect ]] ||
24952                 error "$file expected blocks: $expect, got: $blocks"
24953 }
24954
24955 check_lsom_size()
24956 {
24957         local size=$($LFS getsom -s $1)
24958         local expect=$2
24959
24960         [[ $size == $expect ]] ||
24961                 error "$file expected size: $expect, got: $size"
24962 }
24963
24964 test_806() {
24965         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24966                 skip "Need MDS version at least 2.11.52"
24967
24968         local bs=1048576
24969
24970         touch $DIR/$tfile || error "touch $tfile failed"
24971
24972         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24973         save_lustre_params client "llite.*.xattr_cache" > $save
24974         lctl set_param llite.*.xattr_cache=0
24975         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24976
24977         # single-threaded write
24978         echo "Test SOM for single-threaded write"
24979         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24980                 error "write $tfile failed"
24981         check_lsom_size $DIR/$tfile $bs
24982
24983         local num=32
24984         local size=$(($num * $bs))
24985         local offset=0
24986         local i
24987
24988         echo "Test SOM for single client multi-threaded($num) write"
24989         $TRUNCATE $DIR/$tfile 0
24990         for ((i = 0; i < $num; i++)); do
24991                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24992                 local pids[$i]=$!
24993                 offset=$((offset + $bs))
24994         done
24995         for (( i=0; i < $num; i++ )); do
24996                 wait ${pids[$i]}
24997         done
24998         check_lsom_size $DIR/$tfile $size
24999
25000         $TRUNCATE $DIR/$tfile 0
25001         for ((i = 0; i < $num; i++)); do
25002                 offset=$((offset - $bs))
25003                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25004                 local pids[$i]=$!
25005         done
25006         for (( i=0; i < $num; i++ )); do
25007                 wait ${pids[$i]}
25008         done
25009         check_lsom_size $DIR/$tfile $size
25010
25011         # multi-client writes
25012         num=$(get_node_count ${CLIENTS//,/ })
25013         size=$(($num * $bs))
25014         offset=0
25015         i=0
25016
25017         echo "Test SOM for multi-client ($num) writes"
25018         $TRUNCATE $DIR/$tfile 0
25019         for client in ${CLIENTS//,/ }; do
25020                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25021                 local pids[$i]=$!
25022                 i=$((i + 1))
25023                 offset=$((offset + $bs))
25024         done
25025         for (( i=0; i < $num; i++ )); do
25026                 wait ${pids[$i]}
25027         done
25028         check_lsom_size $DIR/$tfile $offset
25029
25030         i=0
25031         $TRUNCATE $DIR/$tfile 0
25032         for client in ${CLIENTS//,/ }; do
25033                 offset=$((offset - $bs))
25034                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25035                 local pids[$i]=$!
25036                 i=$((i + 1))
25037         done
25038         for (( i=0; i < $num; i++ )); do
25039                 wait ${pids[$i]}
25040         done
25041         check_lsom_size $DIR/$tfile $size
25042
25043         # verify truncate
25044         echo "Test SOM for truncate"
25045         $TRUNCATE $DIR/$tfile 1048576
25046         check_lsom_size $DIR/$tfile 1048576
25047         $TRUNCATE $DIR/$tfile 1234
25048         check_lsom_size $DIR/$tfile 1234
25049
25050         # verify SOM blocks count
25051         echo "Verify SOM block count"
25052         $TRUNCATE $DIR/$tfile 0
25053         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25054                 error "failed to write file $tfile"
25055         check_lsom_data $DIR/$tfile
25056 }
25057 run_test 806 "Verify Lazy Size on MDS"
25058
25059 test_807() {
25060         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25061         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25062                 skip "Need MDS version at least 2.11.52"
25063
25064         # Registration step
25065         changelog_register || error "changelog_register failed"
25066         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25067         changelog_users $SINGLEMDS | grep -q $cl_user ||
25068                 error "User $cl_user not found in changelog_users"
25069
25070         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25071         save_lustre_params client "llite.*.xattr_cache" > $save
25072         lctl set_param llite.*.xattr_cache=0
25073         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25074
25075         rm -rf $DIR/$tdir || error "rm $tdir failed"
25076         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25077         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25078         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25079         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25080                 error "truncate $tdir/trunc failed"
25081
25082         local bs=1048576
25083         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25084                 error "write $tfile failed"
25085
25086         # multi-client wirtes
25087         local num=$(get_node_count ${CLIENTS//,/ })
25088         local offset=0
25089         local i=0
25090
25091         echo "Test SOM for multi-client ($num) writes"
25092         touch $DIR/$tfile || error "touch $tfile failed"
25093         $TRUNCATE $DIR/$tfile 0
25094         for client in ${CLIENTS//,/ }; do
25095                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25096                 local pids[$i]=$!
25097                 i=$((i + 1))
25098                 offset=$((offset + $bs))
25099         done
25100         for (( i=0; i < $num; i++ )); do
25101                 wait ${pids[$i]}
25102         done
25103
25104         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25105         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25106         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25107         check_lsom_data $DIR/$tdir/trunc
25108         check_lsom_data $DIR/$tdir/single_dd
25109         check_lsom_data $DIR/$tfile
25110
25111         rm -rf $DIR/$tdir
25112         # Deregistration step
25113         changelog_deregister || error "changelog_deregister failed"
25114 }
25115 run_test 807 "verify LSOM syncing tool"
25116
25117 check_som_nologged()
25118 {
25119         local lines=$($LFS changelog $FSNAME-MDT0000 |
25120                 grep 'x=trusted.som' | wc -l)
25121         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25122 }
25123
25124 test_808() {
25125         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25126                 skip "Need MDS version at least 2.11.55"
25127
25128         # Registration step
25129         changelog_register || error "changelog_register failed"
25130
25131         touch $DIR/$tfile || error "touch $tfile failed"
25132         check_som_nologged
25133
25134         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25135                 error "write $tfile failed"
25136         check_som_nologged
25137
25138         $TRUNCATE $DIR/$tfile 1234
25139         check_som_nologged
25140
25141         $TRUNCATE $DIR/$tfile 1048576
25142         check_som_nologged
25143
25144         # Deregistration step
25145         changelog_deregister || error "changelog_deregister failed"
25146 }
25147 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25148
25149 check_som_nodata()
25150 {
25151         $LFS getsom $1
25152         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25153 }
25154
25155 test_809() {
25156         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25157                 skip "Need MDS version at least 2.11.56"
25158
25159         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25160                 error "failed to create DoM-only file $DIR/$tfile"
25161         touch $DIR/$tfile || error "touch $tfile failed"
25162         check_som_nodata $DIR/$tfile
25163
25164         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25165                 error "write $tfile failed"
25166         check_som_nodata $DIR/$tfile
25167
25168         $TRUNCATE $DIR/$tfile 1234
25169         check_som_nodata $DIR/$tfile
25170
25171         $TRUNCATE $DIR/$tfile 4097
25172         check_som_nodata $DIR/$file
25173 }
25174 run_test 809 "Verify no SOM xattr store for DoM-only files"
25175
25176 test_810() {
25177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25178         $GSS && skip_env "could not run with gss"
25179         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25180                 skip "OST < 2.12.58 doesn't align checksum"
25181
25182         set_checksums 1
25183         stack_trap "set_checksums $ORIG_CSUM" EXIT
25184         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25185
25186         local csum
25187         local before
25188         local after
25189         for csum in $CKSUM_TYPES; do
25190                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25191                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25192                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25193                         eval set -- $i
25194                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25195                         before=$(md5sum $DIR/$tfile)
25196                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25197                         after=$(md5sum $DIR/$tfile)
25198                         [ "$before" == "$after" ] ||
25199                                 error "$csum: $before != $after bs=$1 seek=$2"
25200                 done
25201         done
25202 }
25203 run_test 810 "partial page writes on ZFS (LU-11663)"
25204
25205 test_812a() {
25206         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25207                 skip "OST < 2.12.51 doesn't support this fail_loc"
25208
25209         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25210         # ensure ost1 is connected
25211         stat $DIR/$tfile >/dev/null || error "can't stat"
25212         wait_osc_import_state client ost1 FULL
25213         # no locks, no reqs to let the connection idle
25214         cancel_lru_locks osc
25215
25216         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25217 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25218         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25219         wait_osc_import_state client ost1 CONNECTING
25220         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25221
25222         stat $DIR/$tfile >/dev/null || error "can't stat file"
25223 }
25224 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
25225
25226 test_812b() { # LU-12378
25227         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25228                 skip "OST < 2.12.51 doesn't support this fail_loc"
25229
25230         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
25231         # ensure ost1 is connected
25232         stat $DIR/$tfile >/dev/null || error "can't stat"
25233         wait_osc_import_state client ost1 FULL
25234         # no locks, no reqs to let the connection idle
25235         cancel_lru_locks osc
25236
25237         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25238 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25239         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25240         wait_osc_import_state client ost1 CONNECTING
25241         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25242
25243         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
25244         wait_osc_import_state client ost1 IDLE
25245 }
25246 run_test 812b "do not drop no resend request for idle connect"
25247
25248 test_813() {
25249         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
25250         [ -z "$file_heat_sav" ] && skip "no file heat support"
25251
25252         local readsample
25253         local writesample
25254         local readbyte
25255         local writebyte
25256         local readsample1
25257         local writesample1
25258         local readbyte1
25259         local writebyte1
25260
25261         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
25262         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
25263
25264         $LCTL set_param -n llite.*.file_heat=1
25265         echo "Turn on file heat"
25266         echo "Period second: $period_second, Decay percentage: $decay_pct"
25267
25268         echo "QQQQ" > $DIR/$tfile
25269         echo "QQQQ" > $DIR/$tfile
25270         echo "QQQQ" > $DIR/$tfile
25271         cat $DIR/$tfile > /dev/null
25272         cat $DIR/$tfile > /dev/null
25273         cat $DIR/$tfile > /dev/null
25274         cat $DIR/$tfile > /dev/null
25275
25276         local out=$($LFS heat_get $DIR/$tfile)
25277
25278         $LFS heat_get $DIR/$tfile
25279         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25280         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25281         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25282         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25283
25284         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
25285         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
25286         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
25287         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
25288
25289         sleep $((period_second + 3))
25290         echo "Sleep $((period_second + 3)) seconds..."
25291         # The recursion formula to calculate the heat of the file f is as
25292         # follow:
25293         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
25294         # Where Hi is the heat value in the period between time points i*I and
25295         # (i+1)*I; Ci is the access count in the period; the symbol P refers
25296         # to the weight of Ci.
25297         out=$($LFS heat_get $DIR/$tfile)
25298         $LFS heat_get $DIR/$tfile
25299         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25300         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25301         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25302         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25303
25304         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
25305                 error "read sample ($readsample) is wrong"
25306         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
25307                 error "write sample ($writesample) is wrong"
25308         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
25309                 error "read bytes ($readbyte) is wrong"
25310         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
25311                 error "write bytes ($writebyte) is wrong"
25312
25313         echo "QQQQ" > $DIR/$tfile
25314         echo "QQQQ" > $DIR/$tfile
25315         echo "QQQQ" > $DIR/$tfile
25316         cat $DIR/$tfile > /dev/null
25317         cat $DIR/$tfile > /dev/null
25318         cat $DIR/$tfile > /dev/null
25319         cat $DIR/$tfile > /dev/null
25320
25321         sleep $((period_second + 3))
25322         echo "Sleep $((period_second + 3)) seconds..."
25323
25324         out=$($LFS heat_get $DIR/$tfile)
25325         $LFS heat_get $DIR/$tfile
25326         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25327         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25328         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25329         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25330
25331         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
25332                 4 * $decay_pct) / 100") -eq 1 ] ||
25333                 error "read sample ($readsample1) is wrong"
25334         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
25335                 3 * $decay_pct) / 100") -eq 1 ] ||
25336                 error "write sample ($writesample1) is wrong"
25337         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
25338                 20 * $decay_pct) / 100") -eq 1 ] ||
25339                 error "read bytes ($readbyte1) is wrong"
25340         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
25341                 15 * $decay_pct) / 100") -eq 1 ] ||
25342                 error "write bytes ($writebyte1) is wrong"
25343
25344         echo "Turn off file heat for the file $DIR/$tfile"
25345         $LFS heat_set -o $DIR/$tfile
25346
25347         echo "QQQQ" > $DIR/$tfile
25348         echo "QQQQ" > $DIR/$tfile
25349         echo "QQQQ" > $DIR/$tfile
25350         cat $DIR/$tfile > /dev/null
25351         cat $DIR/$tfile > /dev/null
25352         cat $DIR/$tfile > /dev/null
25353         cat $DIR/$tfile > /dev/null
25354
25355         out=$($LFS heat_get $DIR/$tfile)
25356         $LFS heat_get $DIR/$tfile
25357         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25358         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25359         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25360         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25361
25362         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25363         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25364         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25365         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25366
25367         echo "Trun on file heat for the file $DIR/$tfile"
25368         $LFS heat_set -O $DIR/$tfile
25369
25370         echo "QQQQ" > $DIR/$tfile
25371         echo "QQQQ" > $DIR/$tfile
25372         echo "QQQQ" > $DIR/$tfile
25373         cat $DIR/$tfile > /dev/null
25374         cat $DIR/$tfile > /dev/null
25375         cat $DIR/$tfile > /dev/null
25376         cat $DIR/$tfile > /dev/null
25377
25378         out=$($LFS heat_get $DIR/$tfile)
25379         $LFS heat_get $DIR/$tfile
25380         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25381         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25382         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25383         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25384
25385         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
25386         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
25387         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
25388         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
25389
25390         $LFS heat_set -c $DIR/$tfile
25391         $LCTL set_param -n llite.*.file_heat=0
25392         echo "Turn off file heat support for the Lustre filesystem"
25393
25394         echo "QQQQ" > $DIR/$tfile
25395         echo "QQQQ" > $DIR/$tfile
25396         echo "QQQQ" > $DIR/$tfile
25397         cat $DIR/$tfile > /dev/null
25398         cat $DIR/$tfile > /dev/null
25399         cat $DIR/$tfile > /dev/null
25400         cat $DIR/$tfile > /dev/null
25401
25402         out=$($LFS heat_get $DIR/$tfile)
25403         $LFS heat_get $DIR/$tfile
25404         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25405         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25406         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25407         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25408
25409         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25410         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25411         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25412         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25413
25414         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
25415         rm -f $DIR/$tfile
25416 }
25417 run_test 813 "File heat verfication"
25418
25419 test_814()
25420 {
25421         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25422         echo -n y >> $DIR/$tfile
25423         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25424         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25425 }
25426 run_test 814 "sparse cp works as expected (LU-12361)"
25427
25428 test_815()
25429 {
25430         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25431         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25432 }
25433 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25434
25435 test_816() {
25436         local ost1_imp=$(get_osc_import_name client ost1)
25437         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25438                          cut -d'.' -f2)
25439
25440         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25441         # ensure ost1 is connected
25442
25443         stat $DIR/$tfile >/dev/null || error "can't stat"
25444         wait_osc_import_state client ost1 FULL
25445         # no locks, no reqs to let the connection idle
25446         cancel_lru_locks osc
25447         lru_resize_disable osc
25448         local before
25449         local now
25450         before=$($LCTL get_param -n \
25451                  ldlm.namespaces.$imp_name.lru_size)
25452
25453         wait_osc_import_state client ost1 IDLE
25454         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25455         now=$($LCTL get_param -n \
25456               ldlm.namespaces.$imp_name.lru_size)
25457         [ $before == $now ] || error "lru_size changed $before != $now"
25458 }
25459 run_test 816 "do not reset lru_resize on idle reconnect"
25460
25461 cleanup_817() {
25462         umount $tmpdir
25463         exportfs -u localhost:$DIR/nfsexp
25464         rm -rf $DIR/nfsexp
25465 }
25466
25467 test_817() {
25468         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25469
25470         mkdir -p $DIR/nfsexp
25471         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25472                 error "failed to export nfs"
25473
25474         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25475         stack_trap cleanup_817 EXIT
25476
25477         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25478                 error "failed to mount nfs to $tmpdir"
25479
25480         cp /bin/true $tmpdir
25481         $DIR/nfsexp/true || error "failed to execute 'true' command"
25482 }
25483 run_test 817 "nfsd won't cache write lock for exec file"
25484
25485 test_818() {
25486         mkdir $DIR/$tdir
25487         $LFS setstripe -c1 -i0 $DIR/$tfile
25488         $LFS setstripe -c1 -i1 $DIR/$tfile
25489         stop $SINGLEMDS
25490         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25491         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25492         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25493                 error "start $SINGLEMDS failed"
25494         rm -rf $DIR/$tdir
25495 }
25496 run_test 818 "unlink with failed llog"
25497
25498 test_819a() {
25499         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25500         cancel_lru_locks osc
25501         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25502         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25503         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25504         rm -f $TDIR/$tfile
25505 }
25506 run_test 819a "too big niobuf in read"
25507
25508 test_819b() {
25509         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25510         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25511         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25512         cancel_lru_locks osc
25513         sleep 1
25514         rm -f $TDIR/$tfile
25515 }
25516 run_test 819b "too big niobuf in write"
25517
25518
25519 function test_820_start_ost() {
25520         sleep 5
25521
25522         for num in $(seq $OSTCOUNT); do
25523                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25524         done
25525 }
25526
25527 test_820() {
25528         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25529
25530         mkdir $DIR/$tdir
25531         umount_client $MOUNT || error "umount failed"
25532         for num in $(seq $OSTCOUNT); do
25533                 stop ost$num
25534         done
25535
25536         # mount client with no active OSTs
25537         # so that the client can't initialize max LOV EA size
25538         # from OSC notifications
25539         mount_client $MOUNT || error "mount failed"
25540         # delay OST starting to keep this 0 max EA size for a while
25541         test_820_start_ost &
25542
25543         # create a directory on MDS2
25544         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25545                 error "Failed to create directory"
25546         # open intent should update default EA size
25547         # see mdc_update_max_ea_from_body()
25548         # notice this is the very first RPC to MDS2
25549         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25550         ret=$?
25551         echo $out
25552         # With SSK, this situation can lead to -EPERM being returned.
25553         # In that case, simply retry.
25554         if [ $ret -ne 0 ] && $SHARED_KEY; then
25555                 if echo "$out" | grep -q "not permitted"; then
25556                         cp /etc/services $DIR/$tdir/mds2
25557                         ret=$?
25558                 fi
25559         fi
25560         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25561 }
25562 run_test 820 "update max EA from open intent"
25563
25564 test_822() {
25565         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
25566
25567         save_lustre_params mds1 \
25568                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
25569         do_facet $SINGLEMDS "$LCTL set_param -n \
25570                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
25571         do_facet $SINGLEMDS "$LCTL set_param -n \
25572                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
25573
25574         # wait for statfs update to clear OS_STATFS_NOPRECREATE
25575         local maxage=$(do_facet mds1 $LCTL get_param -n \
25576                        osp.$FSNAME-OST0000*MDT0000.maxage)
25577         sleep $((maxage + 1))
25578
25579         #define OBD_FAIL_NET_ERROR_RPC          0x532
25580         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
25581
25582         stack_trap "restore_lustre_params < $p; rm $p"
25583
25584         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
25585                       osp.$FSNAME-OST0000*MDT0000.create_count")
25586         for i in $(seq 1 $count); do
25587                 touch $DIR/$tfile.${i} || error "touch failed"
25588         done
25589 }
25590 run_test 822 "test precreate failure"
25591
25592 #
25593 # tests that do cleanup/setup should be run at the end
25594 #
25595
25596 test_900() {
25597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25598         local ls
25599
25600         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25601         $LCTL set_param fail_loc=0x903
25602
25603         cancel_lru_locks MGC
25604
25605         FAIL_ON_ERROR=true cleanup
25606         FAIL_ON_ERROR=true setup
25607 }
25608 run_test 900 "umount should not race with any mgc requeue thread"
25609
25610 # LUS-6253/LU-11185
25611 test_901() {
25612         local oldc
25613         local newc
25614         local olds
25615         local news
25616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25617
25618         # some get_param have a bug to handle dot in param name
25619         cancel_lru_locks MGC
25620         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25621         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25622         umount_client $MOUNT || error "umount failed"
25623         mount_client $MOUNT || error "mount failed"
25624         cancel_lru_locks MGC
25625         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25626         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25627
25628         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25629         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25630
25631         return 0
25632 }
25633 run_test 901 "don't leak a mgc lock on client umount"
25634
25635 # LU-13377
25636 test_902() {
25637         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25638                 skip "client does not have LU-13377 fix"
25639         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25640         $LCTL set_param fail_loc=0x1415
25641         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25642         cancel_lru_locks osc
25643         rm -f $DIR/$tfile
25644 }
25645 run_test 902 "test short write doesn't hang lustre"
25646
25647 complete $SECONDS
25648 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25649 check_and_cleanup_lustre
25650 if [ "$I_MOUNTED" != "yes" ]; then
25651         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25652 fi
25653 exit_status