Whamcloud - gitweb
737e16d8a13f471b6525719b09da3fcbfd268a5c
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5          12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 # Get the SLES distro version
96 #
97 # Returns a version string that should only be used in comparing
98 # strings returned by version_code()
99 sles_version_code()
100 {
101         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
102
103         # All SuSE Linux versions have one decimal. version_code expects two
104         local sles_version=$version.0
105         version_code $sles_version
106 }
107
108 # Check if we are running on Ubuntu or SLES so we can make decisions on
109 # what tests to run
110 if [ -r /etc/SuSE-release ]; then
111         sles_version=$(sles_version_code)
112         [ $sles_version -lt $(version_code 11.4.0) ] &&
113                 # bug number for skipped test: LU-4341
114                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
115         [ $sles_version -lt $(version_code 12.0.0) ] &&
116                 # bug number for skipped test: LU-3703
117                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
118 elif [ -r /etc/os-release ]; then
119         if grep -qi ubuntu /etc/os-release; then
120                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
121                                                 -e 's/^VERSION=//p' \
122                                                 /etc/os-release |
123                                                 awk '{ print $1 }'))
124
125                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
126                         # bug number for skipped test:
127                         #                LU-10334 LU-10366
128                         ALWAYS_EXCEPT+=" 103a     410"
129                 fi
130         fi
131 fi
132
133 build_test_filter
134 FAIL_ON_ERROR=false
135
136 cleanup() {
137         echo -n "cln.."
138         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
139         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
140 }
141 setup() {
142         echo -n "mnt.."
143         load_modules
144         setupall || exit 10
145         echo "done"
146 }
147
148 check_swap_layouts_support()
149 {
150         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
151                 skip "Does not support layout lock."
152 }
153
154 check_swap_layout_no_dom()
155 {
156         local FOLDER=$1
157         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
158         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
159 }
160
161 check_and_setup_lustre
162 DIR=${DIR:-$MOUNT}
163 assert_DIR
164
165 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
166
167 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
168 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
169 rm -rf $DIR/[Rdfs][0-9]*
170
171 # $RUNAS_ID may get set incorrectly somewhere else
172 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
173         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
174
175 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
176
177 if [ "${ONLY}" = "MOUNT" ] ; then
178         echo "Lustre is up, please go on"
179         exit
180 fi
181
182 echo "preparing for tests involving mounts"
183 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
184 touch $EXT2_DEV
185 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
186 echo # add a newline after mke2fs.
187
188 umask 077
189
190 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
191 lctl set_param debug=-1 2> /dev/null || true
192 test_0a() {
193         touch $DIR/$tfile
194         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
195         rm $DIR/$tfile
196         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
197 }
198 run_test 0a "touch; rm ====================="
199
200 test_0b() {
201         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
202         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
203 }
204 run_test 0b "chmod 0755 $DIR ============================="
205
206 test_0c() {
207         $LCTL get_param mdc.*.import | grep "state: FULL" ||
208                 error "import not FULL"
209         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
210                 error "bad target"
211 }
212 run_test 0c "check import proc"
213
214 test_0d() { # LU-3397
215         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
216                 skip "proc exports not supported before 2.10.57"
217
218         local mgs_exp="mgs.MGS.exports"
219         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
220         local exp_client_nid
221         local exp_client_version
222         local exp_val
223         local imp_val
224         local temp_imp=$DIR/$tfile.import
225         local temp_exp=$DIR/$tfile.export
226
227         # save mgc import file to $temp_imp
228         $LCTL get_param mgc.*.import | tee $temp_imp
229         # Check if client uuid is found in MGS export
230         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
231                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
232                         $client_uuid ] &&
233                         break;
234         done
235         # save mgs export file to $temp_exp
236         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
237
238         # Compare the value of field "connect_flags"
239         imp_val=$(grep "connect_flags" $temp_imp)
240         exp_val=$(grep "connect_flags" $temp_exp)
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export flags '$exp_val' != import flags '$imp_val'"
243
244         # Compare client versions.  Only compare top-3 fields for compatibility
245         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
246         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
247         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
248         [ "$exp_val" == "$imp_val" ] ||
249                 error "exp version '$exp_client_version'($exp_val) != " \
250                         "'$(lustre_build_version client)'($imp_val)"
251 }
252 run_test 0d "check export proc ============================="
253
254 test_1() {
255         test_mkdir $DIR/$tdir
256         test_mkdir $DIR/$tdir/d2
257         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
258         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
259         rmdir $DIR/$tdir/d2
260         rmdir $DIR/$tdir
261         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
262 }
263 run_test 1 "mkdir; remkdir; rmdir"
264
265 test_2() {
266         test_mkdir $DIR/$tdir
267         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
268         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
269         rm -r $DIR/$tdir
270         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
271 }
272 run_test 2 "mkdir; touch; rmdir; check file"
273
274 test_3() {
275         test_mkdir $DIR/$tdir
276         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
277         touch $DIR/$tdir/$tfile
278         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
279         rm -r $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
281 }
282 run_test 3 "mkdir; touch; rmdir; check dir"
283
284 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
285 test_4() {
286         test_mkdir -i 1 $DIR/$tdir
287
288         touch $DIR/$tdir/$tfile ||
289                 error "Create file under remote directory failed"
290
291         rmdir $DIR/$tdir &&
292                 error "Expect error removing in-use dir $DIR/$tdir"
293
294         test -d $DIR/$tdir || error "Remote directory disappeared"
295
296         rm -rf $DIR/$tdir || error "remove remote dir error"
297 }
298 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
299
300 test_5() {
301         test_mkdir $DIR/$tdir
302         test_mkdir $DIR/$tdir/d2
303         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
304         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
305         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
306 }
307 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
308
309 test_6a() {
310         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
311         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
312         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
313                 error "$tfile does not have perm 0666 or UID $UID"
314         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
315         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
316                 error "$tfile should be 0666 and owned by UID $UID"
317 }
318 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
319
320 test_6c() {
321         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
322
323         touch $DIR/$tfile
324         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
325         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $RUNAS_ID"
327         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
328         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
329                 error "$tfile should be owned by UID $RUNAS_ID"
330 }
331 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
332
333 test_6e() {
334         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
335
336         touch $DIR/$tfile
337         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
338         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
339                 error "$tfile should be owned by GID $UID"
340         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
341         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
342                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
343 }
344 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
345
346 test_6g() {
347         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
348
349         test_mkdir $DIR/$tdir
350         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
351         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
352         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
353         test_mkdir $DIR/$tdir/d/subdir
354         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
355                 error "$tdir/d/subdir should be GID $RUNAS_GID"
356         if [[ $MDSCOUNT -gt 1 ]]; then
357                 # check remote dir sgid inherite
358                 $LFS mkdir -i 0 $DIR/$tdir.local ||
359                         error "mkdir $tdir.local failed"
360                 chmod g+s $DIR/$tdir.local ||
361                         error "chmod $tdir.local failed"
362                 chgrp $RUNAS_GID $DIR/$tdir.local ||
363                         error "chgrp $tdir.local failed"
364                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
365                         error "mkdir $tdir.remote failed"
366                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
367                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
368                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
369                         error "$tdir.remote should be mode 02755"
370         fi
371 }
372 run_test 6g "verify new dir in sgid dir inherits group"
373
374 test_6h() { # bug 7331
375         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
376
377         touch $DIR/$tfile || error "touch failed"
378         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
379         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
380                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
381         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
382                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
383 }
384 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
385
386 test_7a() {
387         test_mkdir $DIR/$tdir
388         $MCREATE $DIR/$tdir/$tfile
389         chmod 0666 $DIR/$tdir/$tfile
390         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
391                 error "$tdir/$tfile should be mode 0666"
392 }
393 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
394
395 test_7b() {
396         if [ ! -d $DIR/$tdir ]; then
397                 test_mkdir $DIR/$tdir
398         fi
399         $MCREATE $DIR/$tdir/$tfile
400         echo -n foo > $DIR/$tdir/$tfile
401         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
402         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
403 }
404 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
405
406 test_8() {
407         test_mkdir $DIR/$tdir
408         touch $DIR/$tdir/$tfile
409         chmod 0666 $DIR/$tdir/$tfile
410         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
411                 error "$tfile mode not 0666"
412 }
413 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
414
415 test_9() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         test_mkdir $DIR/$tdir/d2/d3
419         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
420 }
421 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
422
423 test_10() {
424         test_mkdir $DIR/$tdir
425         test_mkdir $DIR/$tdir/d2
426         touch $DIR/$tdir/d2/$tfile
427         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
428                 error "$tdir/d2/$tfile not a file"
429 }
430 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
431
432 test_11() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         chmod 0666 $DIR/$tdir/d2
436         chmod 0705 $DIR/$tdir/d2
437         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
438                 error "$tdir/d2 mode not 0705"
439 }
440 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
441
442 test_12() {
443         test_mkdir $DIR/$tdir
444         touch $DIR/$tdir/$tfile
445         chmod 0666 $DIR/$tdir/$tfile
446         chmod 0654 $DIR/$tdir/$tfile
447         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
448                 error "$tdir/d2 mode not 0654"
449 }
450 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
451
452 test_13() {
453         test_mkdir $DIR/$tdir
454         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
455         >  $DIR/$tdir/$tfile
456         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
457                 error "$tdir/$tfile size not 0 after truncate"
458 }
459 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
460
461 test_14() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         rm $DIR/$tdir/$tfile
465         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
466 }
467 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
468
469 test_15() {
470         test_mkdir $DIR/$tdir
471         touch $DIR/$tdir/$tfile
472         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
473         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
474                 error "$tdir/${tfile_2} not a file after rename"
475         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
476 }
477 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
478
479 test_16() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         rm -rf $DIR/$tdir/$tfile
483         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
484 }
485 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
486
487 test_17a() {
488         test_mkdir $DIR/$tdir
489         touch $DIR/$tdir/$tfile
490         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
491         ls -l $DIR/$tdir
492         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
493                 error "$tdir/l-exist not a symlink"
494         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
495                 error "$tdir/l-exist not referencing a file"
496         rm -f $DIR/$tdir/l-exist
497         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
498 }
499 run_test 17a "symlinks: create, remove (real)"
500
501 test_17b() {
502         test_mkdir $DIR/$tdir
503         ln -s no-such-file $DIR/$tdir/l-dangle
504         ls -l $DIR/$tdir
505         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
506                 error "$tdir/l-dangle not referencing no-such-file"
507         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
508                 error "$tdir/l-dangle not referencing non-existent file"
509         rm -f $DIR/$tdir/l-dangle
510         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
511 }
512 run_test 17b "symlinks: create, remove (dangling)"
513
514 test_17c() { # bug 3440 - don't save failed open RPC for replay
515         test_mkdir $DIR/$tdir
516         ln -s foo $DIR/$tdir/$tfile
517         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
518 }
519 run_test 17c "symlinks: open dangling (should return error)"
520
521 test_17d() {
522         test_mkdir $DIR/$tdir
523         ln -s foo $DIR/$tdir/$tfile
524         touch $DIR/$tdir/$tfile || error "creating to new symlink"
525 }
526 run_test 17d "symlinks: create dangling"
527
528 test_17e() {
529         test_mkdir $DIR/$tdir
530         local foo=$DIR/$tdir/$tfile
531         ln -s $foo $foo || error "create symlink failed"
532         ls -l $foo || error "ls -l failed"
533         ls $foo && error "ls not failed" || true
534 }
535 run_test 17e "symlinks: create recursive symlink (should return error)"
536
537 test_17f() {
538         test_mkdir $DIR/$tdir
539         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
540         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
541         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
542         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
543         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
544         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
545         ls -l  $DIR/$tdir
546 }
547 run_test 17f "symlinks: long and very long symlink name"
548
549 # str_repeat(S, N) generate a string that is string S repeated N times
550 str_repeat() {
551         local s=$1
552         local n=$2
553         local ret=''
554         while [ $((n -= 1)) -ge 0 ]; do
555                 ret=$ret$s
556         done
557         echo $ret
558 }
559
560 # Long symlinks and LU-2241
561 test_17g() {
562         test_mkdir $DIR/$tdir
563         local TESTS="59 60 61 4094 4095"
564
565         # Fix for inode size boundary in 2.1.4
566         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
567                 TESTS="4094 4095"
568
569         # Patch not applied to 2.2 or 2.3 branches
570         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
571         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
572                 TESTS="4094 4095"
573
574         for i in $TESTS; do
575                 local SYMNAME=$(str_repeat 'x' $i)
576                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
577                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
578         done
579 }
580 run_test 17g "symlinks: really long symlink name and inode boundaries"
581
582 test_17h() { #bug 17378
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local mdt_idx
587
588         test_mkdir $DIR/$tdir
589         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
590         $LFS setstripe -c -1 $DIR/$tdir
591         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
592         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
593         touch $DIR/$tdir/$tfile || true
594 }
595 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
596
597 test_17i() { #bug 20018
598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
599         remote_mds_nodsh && skip "remote MDS with nodsh"
600
601         local foo=$DIR/$tdir/$tfile
602         local mdt_idx
603
604         test_mkdir -c1 $DIR/$tdir
605         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
606         ln -s $foo $foo || error "create symlink failed"
607 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
608         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
609         ls -l $foo && error "error not detected"
610         return 0
611 }
612 run_test 17i "don't panic on short symlink (should return error)"
613
614 test_17k() { #bug 22301
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         [[ -z "$(which rsync 2>/dev/null)" ]] &&
617                 skip "no rsync command"
618         rsync --help | grep -q xattr ||
619                 skip_env "$(rsync --version | head -n1) does not support xattrs"
620         test_mkdir $DIR/$tdir
621         test_mkdir $DIR/$tdir.new
622         touch $DIR/$tdir/$tfile
623         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
624         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
625                 error "rsync failed with xattrs enabled"
626 }
627 run_test 17k "symlinks: rsync with xattrs enabled"
628
629 test_17l() { # LU-279
630         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
631                 skip "no getfattr command"
632
633         test_mkdir $DIR/$tdir
634         touch $DIR/$tdir/$tfile
635         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
636         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
637                 # -h to not follow symlinks. -m '' to list all the xattrs.
638                 # grep to remove first line: '# file: $path'.
639                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
640                 do
641                         lgetxattr_size_check $path $xattr ||
642                                 error "lgetxattr_size_check $path $xattr failed"
643                 done
644         done
645 }
646 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
647
648 # LU-1540
649 test_17m() {
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
652         remote_mds_nodsh && skip "remote MDS with nodsh"
653         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
654         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
655                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
656
657         local short_sym="0123456789"
658         local wdir=$DIR/$tdir
659         local i
660
661         test_mkdir $wdir
662         long_sym=$short_sym
663         # create a long symlink file
664         for ((i = 0; i < 4; ++i)); do
665                 long_sym=${long_sym}${long_sym}
666         done
667
668         echo "create 512 short and long symlink files under $wdir"
669         for ((i = 0; i < 256; ++i)); do
670                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
671                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
672         done
673
674         echo "erase them"
675         rm -f $wdir/*
676         sync
677         wait_delete_completed
678
679         echo "recreate the 512 symlink files with a shorter string"
680         for ((i = 0; i < 512; ++i)); do
681                 # rewrite the symlink file with a shorter string
682                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
683                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
684         done
685
686         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
687         local devname=$(mdsdevname $mds_index)
688
689         echo "stop and checking mds${mds_index}:"
690         # e2fsck should not return error
691         stop mds${mds_index}
692         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
693         rc=$?
694
695         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
696                 error "start mds${mds_index} failed"
697         df $MOUNT > /dev/null 2>&1
698         [ $rc -eq 0 ] ||
699                 error "e2fsck detected error for short/long symlink: rc=$rc"
700         rm -f $wdir/*
701 }
702 run_test 17m "run e2fsck against MDT which contains short/long symlink"
703
704 check_fs_consistency_17n() {
705         local mdt_index
706         local rc=0
707
708         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
709         # so it only check MDT1/MDT2 instead of all of MDTs.
710         for mdt_index in 1 2; do
711                 local devname=$(mdsdevname $mdt_index)
712                 # e2fsck should not return error
713                 stop mds${mdt_index}
714                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
715                         rc=$((rc + $?))
716
717                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
718                         error "mount mds$mdt_index failed"
719                 df $MOUNT > /dev/null 2>&1
720         done
721         return $rc
722 }
723
724 test_17n() {
725         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
727         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
728         remote_mds_nodsh && skip "remote MDS with nodsh"
729         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
730         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
731                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
732
733         local i
734
735         test_mkdir $DIR/$tdir
736         for ((i=0; i<10; i++)); do
737                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
738                         error "create remote dir error $i"
739                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
740                         error "create files under remote dir failed $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after create files under remote dir"
745
746         for ((i = 0; i < 10; i++)); do
747                 rm -rf $DIR/$tdir/remote_dir_${i} ||
748                         error "destroy remote dir error $i"
749         done
750
751         check_fs_consistency_17n ||
752                 error "e2fsck report error after unlink files under remote dir"
753
754         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
755                 skip "lustre < 2.4.50 does not support migrate mv"
756
757         for ((i = 0; i < 10; i++)); do
758                 mkdir -p $DIR/$tdir/remote_dir_${i}
759                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
760                         error "create files under remote dir failed $i"
761                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
762                         error "migrate remote dir error $i"
763         done
764         check_fs_consistency_17n || error "e2fsck report error after migration"
765
766         for ((i = 0; i < 10; i++)); do
767                 rm -rf $DIR/$tdir/remote_dir_${i} ||
768                         error "destroy remote dir error $i"
769         done
770
771         check_fs_consistency_17n || error "e2fsck report error after unlink"
772 }
773 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
774
775 test_17o() {
776         remote_mds_nodsh && skip "remote MDS with nodsh"
777         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
778                 skip "Need MDS version at least 2.3.64"
779
780         local wdir=$DIR/${tdir}o
781         local mdt_index
782         local rc=0
783
784         test_mkdir $wdir
785         touch $wdir/$tfile
786         mdt_index=$($LFS getstripe -m $wdir/$tfile)
787         mdt_index=$((mdt_index + 1))
788
789         cancel_lru_locks mdc
790         #fail mds will wait the failover finish then set
791         #following fail_loc to avoid interfer the recovery process.
792         fail mds${mdt_index}
793
794         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
795         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
796         ls -l $wdir/$tfile && rc=1
797         do_facet mds${mdt_index} lctl set_param fail_loc=0
798         [[ $rc -eq 0 ]] || error "stat file should fail"
799 }
800 run_test 17o "stat file with incompat LMA feature"
801
802 test_18() {
803         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
804         ls $DIR || error "Failed to ls $DIR: $?"
805 }
806 run_test 18 "touch .../f ; ls ... =============================="
807
808 test_19a() {
809         touch $DIR/$tfile
810         ls -l $DIR
811         rm $DIR/$tfile
812         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
813 }
814 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
815
816 test_19b() {
817         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
818 }
819 run_test 19b "ls -l .../f19 (should return error) =============="
820
821 test_19c() {
822         [ $RUNAS_ID -eq $UID ] &&
823                 skip_env "RUNAS_ID = UID = $UID -- skipping"
824
825         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
826 }
827 run_test 19c "$RUNAS touch .../f19 (should return error) =="
828
829 test_19d() {
830         cat $DIR/f19 && error || true
831 }
832 run_test 19d "cat .../f19 (should return error) =============="
833
834 test_20() {
835         touch $DIR/$tfile
836         rm $DIR/$tfile
837         touch $DIR/$tfile
838         rm $DIR/$tfile
839         touch $DIR/$tfile
840         rm $DIR/$tfile
841         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
842 }
843 run_test 20 "touch .../f ; ls -l ..."
844
845 test_21() {
846         test_mkdir $DIR/$tdir
847         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
848         ln -s dangle $DIR/$tdir/link
849         echo foo >> $DIR/$tdir/link
850         cat $DIR/$tdir/dangle
851         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
852         $CHECKSTAT -f -t file $DIR/$tdir/link ||
853                 error "$tdir/link not linked to a file"
854 }
855 run_test 21 "write to dangling link"
856
857 test_22() {
858         local wdir=$DIR/$tdir
859         test_mkdir $wdir
860         chown $RUNAS_ID:$RUNAS_GID $wdir
861         (cd $wdir || error "cd $wdir failed";
862                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
863                 $RUNAS tar xf -)
864         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
865         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
866         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
867                 error "checkstat -u failed"
868 }
869 run_test 22 "unpack tar archive as non-root user"
870
871 # was test_23
872 test_23a() {
873         test_mkdir $DIR/$tdir
874         local file=$DIR/$tdir/$tfile
875
876         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
877         openfile -f O_CREAT:O_EXCL $file &&
878                 error "$file recreate succeeded" || true
879 }
880 run_test 23a "O_CREAT|O_EXCL in subdir"
881
882 test_23b() { # bug 18988
883         test_mkdir $DIR/$tdir
884         local file=$DIR/$tdir/$tfile
885
886         rm -f $file
887         echo foo > $file || error "write filed"
888         echo bar >> $file || error "append filed"
889         $CHECKSTAT -s 8 $file || error "wrong size"
890         rm $file
891 }
892 run_test 23b "O_APPEND check"
893
894 # LU-9409, size with O_APPEND and tiny writes
895 test_23c() {
896         local file=$DIR/$tfile
897
898         # single dd
899         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
900         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
901         rm -f $file
902
903         # racing tiny writes
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
905         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
906         wait
907         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
908         rm -f $file
909
910         #racing tiny & normal writes
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
912         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
913         wait
914         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
915         rm -f $file
916
917         #racing tiny & normal writes 2, ugly numbers
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
920         wait
921         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
922         rm -f $file
923 }
924 run_test 23c "O_APPEND size checks for tiny writes"
925
926 # LU-11069 file offset is correct after appending writes
927 test_23d() {
928         local file=$DIR/$tfile
929         local offset
930
931         echo CentaurHauls > $file
932         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
933         if ((offset != 26)); then
934                 error "wrong offset, expected 26, got '$offset'"
935         fi
936 }
937 run_test 23d "file offset is correct after appending writes"
938
939 # rename sanity
940 test_24a() {
941         echo '-- same directory rename'
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.1
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
946 }
947 run_test 24a "rename file to non-existent target"
948
949 test_24b() {
950         test_mkdir $DIR/$tdir
951         touch $DIR/$tdir/$tfile.{1,2}
952         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
953         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
954         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
955 }
956 run_test 24b "rename file to existing target"
957
958 test_24c() {
959         test_mkdir $DIR/$tdir
960         test_mkdir $DIR/$tdir/d$testnum.1
961         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
962         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
963         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
964 }
965 run_test 24c "rename directory to non-existent target"
966
967 test_24d() {
968         test_mkdir -c1 $DIR/$tdir
969         test_mkdir -c1 $DIR/$tdir/d$testnum.1
970         test_mkdir -c1 $DIR/$tdir/d$testnum.2
971         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
972         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
973         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
974 }
975 run_test 24d "rename directory to existing target"
976
977 test_24e() {
978         echo '-- cross directory renames --'
979         test_mkdir $DIR/R5a
980         test_mkdir $DIR/R5b
981         touch $DIR/R5a/f
982         mv $DIR/R5a/f $DIR/R5b/g
983         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
984         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
985 }
986 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
987
988 test_24f() {
989         test_mkdir $DIR/R6a
990         test_mkdir $DIR/R6b
991         touch $DIR/R6a/f $DIR/R6b/g
992         mv $DIR/R6a/f $DIR/R6b/g
993         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
994         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
995 }
996 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
997
998 test_24g() {
999         test_mkdir $DIR/R7a
1000         test_mkdir $DIR/R7b
1001         test_mkdir $DIR/R7a/d
1002         mv $DIR/R7a/d $DIR/R7b/e
1003         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1004         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1005 }
1006 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1007
1008 test_24h() {
1009         test_mkdir -c1 $DIR/R8a
1010         test_mkdir -c1 $DIR/R8b
1011         test_mkdir -c1 $DIR/R8a/d
1012         test_mkdir -c1 $DIR/R8b/e
1013         mrename $DIR/R8a/d $DIR/R8b/e
1014         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1015         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1016 }
1017 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1018
1019 test_24i() {
1020         echo "-- rename error cases"
1021         test_mkdir $DIR/R9
1022         test_mkdir $DIR/R9/a
1023         touch $DIR/R9/f
1024         mrename $DIR/R9/f $DIR/R9/a
1025         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1026         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1027         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1028 }
1029 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1030
1031 test_24j() {
1032         test_mkdir $DIR/R10
1033         mrename $DIR/R10/f $DIR/R10/g
1034         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1035         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1036         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1037 }
1038 run_test 24j "source does not exist ============================"
1039
1040 test_24k() {
1041         test_mkdir $DIR/R11a
1042         test_mkdir $DIR/R11a/d
1043         touch $DIR/R11a/f
1044         mv $DIR/R11a/f $DIR/R11a/d
1045         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1046         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1047 }
1048 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1049
1050 # bug 2429 - rename foo foo foo creates invalid file
1051 test_24l() {
1052         f="$DIR/f24l"
1053         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1054 }
1055 run_test 24l "Renaming a file to itself ========================"
1056
1057 test_24m() {
1058         f="$DIR/f24m"
1059         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1060         # on ext3 this does not remove either the source or target files
1061         # though the "expected" operation would be to remove the source
1062         $CHECKSTAT -t file ${f} || error "${f} missing"
1063         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1064 }
1065 run_test 24m "Renaming a file to a hard link to itself ========="
1066
1067 test_24n() {
1068     f="$DIR/f24n"
1069     # this stats the old file after it was renamed, so it should fail
1070     touch ${f}
1071     $CHECKSTAT ${f} || error "${f} missing"
1072     mv ${f} ${f}.rename
1073     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1074     $CHECKSTAT -a ${f} || error "${f} exists"
1075 }
1076 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1077
1078 test_24o() {
1079         test_mkdir $DIR/$tdir
1080         rename_many -s random -v -n 10 $DIR/$tdir
1081 }
1082 run_test 24o "rename of files during htree split"
1083
1084 test_24p() {
1085         test_mkdir $DIR/R12a
1086         test_mkdir $DIR/R12b
1087         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1088         mrename $DIR/R12a $DIR/R12b
1089         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1090         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1091         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1092         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1093 }
1094 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1095
1096 cleanup_multiop_pause() {
1097         trap 0
1098         kill -USR1 $MULTIPID
1099 }
1100
1101 test_24q() {
1102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1103
1104         test_mkdir $DIR/R13a
1105         test_mkdir $DIR/R13b
1106         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1107         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1108         MULTIPID=$!
1109
1110         trap cleanup_multiop_pause EXIT
1111         mrename $DIR/R13a $DIR/R13b
1112         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1113         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1114         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1115         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1116         cleanup_multiop_pause
1117         wait $MULTIPID || error "multiop close failed"
1118 }
1119 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1120
1121 test_24r() { #bug 3789
1122         test_mkdir $DIR/R14a
1123         test_mkdir $DIR/R14a/b
1124         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1125         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1126         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1127 }
1128 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1129
1130 test_24s() {
1131         test_mkdir $DIR/R15a
1132         test_mkdir $DIR/R15a/b
1133         test_mkdir $DIR/R15a/b/c
1134         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1135         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1136         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1137 }
1138 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1139 test_24t() {
1140         test_mkdir $DIR/R16a
1141         test_mkdir $DIR/R16a/b
1142         test_mkdir $DIR/R16a/b/c
1143         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1145         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1146 }
1147 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1148
1149 test_24u() { # bug12192
1150         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1151         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1152 }
1153 run_test 24u "create stripe file"
1154
1155 simple_cleanup_common() {
1156         local rc=0
1157         trap 0
1158         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1159
1160         local start=$SECONDS
1161         rm -rf $DIR/$tdir
1162         rc=$?
1163         wait_delete_completed
1164         echo "cleanup time $((SECONDS - start))"
1165         return $rc
1166 }
1167
1168 max_pages_per_rpc() {
1169         local mdtname="$(printf "MDT%04x" ${1:-0})"
1170         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1171 }
1172
1173 test_24v() {
1174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1175
1176         local nrfiles=${COUNT:-100000}
1177         local fname="$DIR/$tdir/$tfile"
1178
1179         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1180         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1181
1182         test_mkdir "$(dirname $fname)"
1183         # assume MDT0000 has the fewest inodes
1184         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1185         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1186         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1187
1188         trap simple_cleanup_common EXIT
1189
1190         createmany -m "$fname" $nrfiles
1191
1192         cancel_lru_locks mdc
1193         lctl set_param mdc.*.stats clear
1194
1195         # was previously test_24D: LU-6101
1196         # readdir() returns correct number of entries after cursor reload
1197         local num_ls=$(ls $DIR/$tdir | wc -l)
1198         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1199         local num_all=$(ls -a $DIR/$tdir | wc -l)
1200         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1201                 [ $num_all -ne $((nrfiles + 2)) ]; then
1202                         error "Expected $nrfiles files, got $num_ls " \
1203                                 "($num_uniq unique $num_all .&..)"
1204         fi
1205         # LU-5 large readdir
1206         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1207         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1208         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1209         # take into account of overhead in lu_dirpage header and end mark in
1210         # each page, plus one in rpc_num calculation.
1211         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1212         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1213         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1214         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1215         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1216         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1217         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1218         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1219                 error "large readdir doesn't take effect: " \
1220                       "$mds_readpage should be about $rpc_max"
1221
1222         simple_cleanup_common
1223 }
1224 run_test 24v "list large directory (test hash collision, b=17560)"
1225
1226 test_24w() { # bug21506
1227         SZ1=234852
1228         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1229         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1230         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1231         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1232         [[ "$SZ1" -eq "$SZ2" ]] ||
1233                 error "Error reading at the end of the file $tfile"
1234 }
1235 run_test 24w "Reading a file larger than 4Gb"
1236
1237 test_24x() {
1238         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1240         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1241                 skip "Need MDS version at least 2.7.56"
1242
1243         local MDTIDX=1
1244         local remote_dir=$DIR/$tdir/remote_dir
1245
1246         test_mkdir $DIR/$tdir
1247         $LFS mkdir -i $MDTIDX $remote_dir ||
1248                 error "create remote directory failed"
1249
1250         test_mkdir $DIR/$tdir/src_dir
1251         touch $DIR/$tdir/src_file
1252         test_mkdir $remote_dir/tgt_dir
1253         touch $remote_dir/tgt_file
1254
1255         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1256                 error "rename dir cross MDT failed!"
1257
1258         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1259                 error "rename file cross MDT failed!"
1260
1261         touch $DIR/$tdir/ln_file
1262         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1263                 error "ln file cross MDT failed"
1264
1265         rm -rf $DIR/$tdir || error "Can not delete directories"
1266 }
1267 run_test 24x "cross MDT rename/link"
1268
1269 test_24y() {
1270         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1272
1273         local remote_dir=$DIR/$tdir/remote_dir
1274         local mdtidx=1
1275
1276         test_mkdir $DIR/$tdir
1277         $LFS mkdir -i $mdtidx $remote_dir ||
1278                 error "create remote directory failed"
1279
1280         test_mkdir $remote_dir/src_dir
1281         touch $remote_dir/src_file
1282         test_mkdir $remote_dir/tgt_dir
1283         touch $remote_dir/tgt_file
1284
1285         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1286                 error "rename subdir in the same remote dir failed!"
1287
1288         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1289                 error "rename files in the same remote dir failed!"
1290
1291         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1292                 error "link files in the same remote dir failed!"
1293
1294         rm -rf $DIR/$tdir || error "Can not delete directories"
1295 }
1296 run_test 24y "rename/link on the same dir should succeed"
1297
1298 test_24z() {
1299         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1300         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1301                 skip "Need MDS version at least 2.12.51"
1302
1303         local index
1304
1305         for index in 0 1; do
1306                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1307                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1308         done
1309
1310         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1313         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1314
1315         local mdts=$(comma_list $(mdts_nodes))
1316
1317         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1318         stack_trap "do_nodes $mdts $LCTL \
1319                 set_param mdt.*.enable_remote_rename=1" EXIT
1320
1321         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1322
1323         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1324         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1325 }
1326 run_test 24z "cross-MDT rename is done as cp"
1327
1328 test_24A() { # LU-3182
1329         local NFILES=5000
1330
1331         rm -rf $DIR/$tdir
1332         test_mkdir $DIR/$tdir
1333         trap simple_cleanup_common EXIT
1334         createmany -m $DIR/$tdir/$tfile $NFILES
1335         local t=$(ls $DIR/$tdir | wc -l)
1336         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1337         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1338         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1339            [ $v -ne $((NFILES + 2)) ] ; then
1340                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1341         fi
1342
1343         simple_cleanup_common || error "Can not delete directories"
1344 }
1345 run_test 24A "readdir() returns correct number of entries."
1346
1347 test_24B() { # LU-4805
1348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1349
1350         local count
1351
1352         test_mkdir $DIR/$tdir
1353         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1354                 error "create striped dir failed"
1355
1356         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1357         [ $count -eq 2 ] || error "Expected 2, got $count"
1358
1359         touch $DIR/$tdir/striped_dir/a
1360
1361         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1362         [ $count -eq 3 ] || error "Expected 3, got $count"
1363
1364         touch $DIR/$tdir/striped_dir/.f
1365
1366         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1367         [ $count -eq 4 ] || error "Expected 4, got $count"
1368
1369         rm -rf $DIR/$tdir || error "Can not delete directories"
1370 }
1371 run_test 24B "readdir for striped dir return correct number of entries"
1372
1373 test_24C() {
1374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1375
1376         mkdir $DIR/$tdir
1377         mkdir $DIR/$tdir/d0
1378         mkdir $DIR/$tdir/d1
1379
1380         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1381                 error "create striped dir failed"
1382
1383         cd $DIR/$tdir/d0/striped_dir
1384
1385         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1386         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1387         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d0_ino" = "$parent_ino" ] ||
1390                 error ".. wrong, expect $d0_ino, get $parent_ino"
1391
1392         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1393                 error "mv striped dir failed"
1394
1395         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1396
1397         [ "$d1_ino" = "$parent_ino" ] ||
1398                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1399 }
1400 run_test 24C "check .. in striped dir"
1401
1402 test_24E() {
1403         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1405
1406         mkdir -p $DIR/$tdir
1407         mkdir $DIR/$tdir/src_dir
1408         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1409                 error "create remote source failed"
1410
1411         touch $DIR/$tdir/src_dir/src_child/a
1412
1413         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1414                 error "create remote target dir failed"
1415
1416         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1417                 error "create remote target child failed"
1418
1419         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1420                 error "rename dir cross MDT failed!"
1421
1422         find $DIR/$tdir
1423
1424         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1425                 error "src_child still exists after rename"
1426
1427         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1428                 error "missing file(a) after rename"
1429
1430         rm -rf $DIR/$tdir || error "Can not delete directories"
1431 }
1432 run_test 24E "cross MDT rename/link"
1433
1434 test_24F () {
1435         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1436
1437         local repeats=1000
1438         [ "$SLOW" = "no" ] && repeats=100
1439
1440         mkdir -p $DIR/$tdir
1441
1442         echo "$repeats repeats"
1443         for ((i = 0; i < repeats; i++)); do
1444                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1445                 touch $DIR/$tdir/test/a || error "touch fails"
1446                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1447                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1448         done
1449
1450         true
1451 }
1452 run_test 24F "hash order vs readdir (LU-11330)"
1453
1454 test_24G () {
1455         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1456
1457         local ino1
1458         local ino2
1459
1460         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1461         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1462         touch $DIR/$tdir-0/f1 || error "touch f1"
1463         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1464         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1465         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1466         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1467         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1468 }
1469 run_test 24G "migrate symlink in rename"
1470
1471 test_25a() {
1472         echo '== symlink sanity ============================================='
1473
1474         test_mkdir $DIR/d25
1475         ln -s d25 $DIR/s25
1476         touch $DIR/s25/foo ||
1477                 error "File creation in symlinked directory failed"
1478 }
1479 run_test 25a "create file in symlinked directory ==============="
1480
1481 test_25b() {
1482         [ ! -d $DIR/d25 ] && test_25a
1483         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1484 }
1485 run_test 25b "lookup file in symlinked directory ==============="
1486
1487 test_26a() {
1488         test_mkdir $DIR/d26
1489         test_mkdir $DIR/d26/d26-2
1490         ln -s d26/d26-2 $DIR/s26
1491         touch $DIR/s26/foo || error "File creation failed"
1492 }
1493 run_test 26a "multiple component symlink ======================="
1494
1495 test_26b() {
1496         test_mkdir -p $DIR/$tdir/d26-2
1497         ln -s $tdir/d26-2/foo $DIR/s26-2
1498         touch $DIR/s26-2 || error "File creation failed"
1499 }
1500 run_test 26b "multiple component symlink at end of lookup ======"
1501
1502 test_26c() {
1503         test_mkdir $DIR/d26.2
1504         touch $DIR/d26.2/foo
1505         ln -s d26.2 $DIR/s26.2-1
1506         ln -s s26.2-1 $DIR/s26.2-2
1507         ln -s s26.2-2 $DIR/s26.2-3
1508         chmod 0666 $DIR/s26.2-3/foo
1509 }
1510 run_test 26c "chain of symlinks"
1511
1512 # recursive symlinks (bug 439)
1513 test_26d() {
1514         ln -s d26-3/foo $DIR/d26-3
1515 }
1516 run_test 26d "create multiple component recursive symlink"
1517
1518 test_26e() {
1519         [ ! -h $DIR/d26-3 ] && test_26d
1520         rm $DIR/d26-3
1521 }
1522 run_test 26e "unlink multiple component recursive symlink"
1523
1524 # recursive symlinks (bug 7022)
1525 test_26f() {
1526         test_mkdir $DIR/$tdir
1527         test_mkdir $DIR/$tdir/$tfile
1528         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1529         test_mkdir -p lndir/bar1
1530         test_mkdir $DIR/$tdir/$tfile/$tfile
1531         cd $tfile                || error "cd $tfile failed"
1532         ln -s .. dotdot          || error "ln dotdot failed"
1533         ln -s dotdot/lndir lndir || error "ln lndir failed"
1534         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1535         output=`ls $tfile/$tfile/lndir/bar1`
1536         [ "$output" = bar1 ] && error "unexpected output"
1537         rm -r $tfile             || error "rm $tfile failed"
1538         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1539 }
1540 run_test 26f "rm -r of a directory which has recursive symlink"
1541
1542 test_27a() {
1543         test_mkdir $DIR/$tdir
1544         $LFS getstripe $DIR/$tdir
1545         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1546         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1547         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1548 }
1549 run_test 27a "one stripe file"
1550
1551 test_27b() {
1552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1553
1554         test_mkdir $DIR/$tdir
1555         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1556         $LFS getstripe -c $DIR/$tdir/$tfile
1557         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1558                 error "two-stripe file doesn't have two stripes"
1559
1560         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1561 }
1562 run_test 27b "create and write to two stripe file"
1563
1564 # 27c family tests specific striping, setstripe -o
1565 test_27ca() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         test_mkdir -p $DIR/$tdir
1568         local osts="1"
1569
1570         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1571         $LFS getstripe -i $DIR/$tdir/$tfile
1572         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1573                 error "stripe not on specified OST"
1574
1575         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1576 }
1577 run_test 27ca "one stripe on specified OST"
1578
1579 test_27cb() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1581         test_mkdir -p $DIR/$tdir
1582         local osts="1,0"
1583         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1584         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1585         echo "$getstripe"
1586
1587         # Strip getstripe output to a space separated list of OSTs
1588         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1589                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1590         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1591                 error "stripes not on specified OSTs"
1592
1593         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1594 }
1595 run_test 27cb "two stripes on specified OSTs"
1596
1597 test_27cc() {
1598         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1599         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1600                 skip "server does not support overstriping"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts="0,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cc "two stripes on the same OST"
1617
1618 test_27cd() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="0,1,1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cd "four stripes on two OSTs"
1637
1638 test_27ce() {
1639         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1640                 skip_env "too many osts, skipping"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         # We do one more stripe than we have OSTs
1644         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1645                 skip_env "ea_inode feature disabled"
1646
1647         test_mkdir -p $DIR/$tdir
1648         local osts=""
1649         for i in $(seq 0 $OSTCOUNT);
1650         do
1651                 osts=$osts"0"
1652                 if [ $i -ne $OSTCOUNT ]; then
1653                         osts=$osts","
1654                 fi
1655         done
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27ce "more stripes than OSTs with -o"
1669
1670 test_27cf() {
1671         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1672         local pid=0
1673
1674         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1675         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1676         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1677         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1678                 error "failed to set $osp_proc=0"
1679
1680         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1681         pid=$!
1682         sleep 1
1683         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1684         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1685                 error "failed to set $osp_proc=1"
1686         wait $pid
1687         [[ $pid -ne 0 ]] ||
1688                 error "should return error due to $osp_proc=0"
1689 }
1690 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1691
1692 test_27d() {
1693         test_mkdir $DIR/$tdir
1694         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1695                 error "setstripe failed"
1696         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1698 }
1699 run_test 27d "create file with default settings"
1700
1701 test_27e() {
1702         # LU-5839 adds check for existed layout before setting it
1703         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1704                 skip "Need MDS version at least 2.7.56"
1705
1706         test_mkdir $DIR/$tdir
1707         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1708         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1709         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1710 }
1711 run_test 27e "setstripe existing file (should return error)"
1712
1713 test_27f() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1716                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1718                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1719         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1720         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1721 }
1722 run_test 27f "setstripe with bad stripe size (should return error)"
1723
1724 test_27g() {
1725         test_mkdir $DIR/$tdir
1726         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1727         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1728                 error "$DIR/$tdir/$tfile has object"
1729 }
1730 run_test 27g "$LFS getstripe with no objects"
1731
1732 test_27ga() {
1733         test_mkdir $DIR/$tdir
1734         touch $DIR/$tdir/$tfile || error "touch failed"
1735         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1736         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1737         local rc=$?
1738         (( rc == 2 )) || error "getstripe did not return ENOENT"
1739 }
1740 run_test 27ga "$LFS getstripe with missing file (should return error)"
1741
1742 test_27i() {
1743         test_mkdir $DIR/$tdir
1744         touch $DIR/$tdir/$tfile || error "touch failed"
1745         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1746                 error "missing objects"
1747 }
1748 run_test 27i "$LFS getstripe with some objects"
1749
1750 test_27j() {
1751         test_mkdir $DIR/$tdir
1752         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1753                 error "setstripe failed" || true
1754 }
1755 run_test 27j "setstripe with bad stripe offset (should return error)"
1756
1757 test_27k() { # bug 2844
1758         test_mkdir $DIR/$tdir
1759         local file=$DIR/$tdir/$tfile
1760         local ll_max_blksize=$((4 * 1024 * 1024))
1761         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1762         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1763         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1764         dd if=/dev/zero of=$file bs=4k count=1
1765         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1766         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1767 }
1768 run_test 27k "limit i_blksize for broken user apps"
1769
1770 test_27l() {
1771         mcreate $DIR/$tfile || error "creating file"
1772         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1773                 error "setstripe should have failed" || true
1774 }
1775 run_test 27l "check setstripe permissions (should return error)"
1776
1777 test_27m() {
1778         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1779
1780         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1781                 skip_env "multiple clients -- skipping"
1782
1783         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1784                    head -n1)
1785         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1786                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1787         fi
1788         trap simple_cleanup_common EXIT
1789         test_mkdir $DIR/$tdir
1790         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1791         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1792                 error "dd should fill OST0"
1793         i=2
1794         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1795                 i=$((i + 1))
1796                 [ $i -gt 256 ] && break
1797         done
1798         i=$((i + 1))
1799         touch $DIR/$tdir/$tfile.$i
1800         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1801             awk '{print $1}'| grep -w "0") ] &&
1802                 error "OST0 was full but new created file still use it"
1803         i=$((i + 1))
1804         touch $DIR/$tdir/$tfile.$i
1805         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1806             awk '{print $1}'| grep -w "0") ] &&
1807                 error "OST0 was full but new created file still use it"
1808         simple_cleanup_common
1809 }
1810 run_test 27m "create file while OST0 was full"
1811
1812 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1813 # if the OST isn't full anymore.
1814 reset_enospc() {
1815         local ostidx=${1:-""}
1816         local delay
1817         local ready
1818         local get_prealloc
1819
1820         local list=$(comma_list $(osts_nodes))
1821         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1822
1823         do_nodes $list lctl set_param fail_loc=0
1824         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1825         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1826                 awk '{print $1 * 2;exit;}')
1827         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1828                         grep -v \"^0$\""
1829         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1830 }
1831
1832 __exhaust_precreations() {
1833         local OSTIDX=$1
1834         local FAILLOC=$2
1835         local FAILIDX=${3:-$OSTIDX}
1836         local ofacet=ost$((OSTIDX + 1))
1837
1838         test_mkdir -p -c1 $DIR/$tdir
1839         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1840         local mfacet=mds$((mdtidx + 1))
1841         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1842
1843         local OST=$(ostname_from_index $OSTIDX)
1844
1845         # on the mdt's osc
1846         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1847         local last_id=$(do_facet $mfacet lctl get_param -n \
1848                         osp.$mdtosc_proc1.prealloc_last_id)
1849         local next_id=$(do_facet $mfacet lctl get_param -n \
1850                         osp.$mdtosc_proc1.prealloc_next_id)
1851
1852         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1853         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1854
1855         test_mkdir -p $DIR/$tdir/${OST}
1856         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1857 #define OBD_FAIL_OST_ENOSPC              0x215
1858         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1859         echo "Creating to objid $last_id on ost $OST..."
1860         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1861         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1862         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1863 }
1864
1865 exhaust_precreations() {
1866         __exhaust_precreations $1 $2 $3
1867         sleep_maxage
1868 }
1869
1870 exhaust_all_precreations() {
1871         local i
1872         for (( i=0; i < OSTCOUNT; i++ )) ; do
1873                 __exhaust_precreations $i $1 -1
1874         done
1875         sleep_maxage
1876 }
1877
1878 test_27n() {
1879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1881         remote_mds_nodsh && skip "remote MDS with nodsh"
1882         remote_ost_nodsh && skip "remote OST with nodsh"
1883
1884         reset_enospc
1885         rm -f $DIR/$tdir/$tfile
1886         exhaust_precreations 0 0x80000215
1887         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1888         touch $DIR/$tdir/$tfile || error "touch failed"
1889         $LFS getstripe $DIR/$tdir/$tfile
1890         reset_enospc
1891 }
1892 run_test 27n "create file with some full OSTs"
1893
1894 test_27o() {
1895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899
1900         reset_enospc
1901         rm -f $DIR/$tdir/$tfile
1902         exhaust_all_precreations 0x215
1903
1904         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1905
1906         reset_enospc
1907         rm -rf $DIR/$tdir/*
1908 }
1909 run_test 27o "create file with all full OSTs (should error)"
1910
1911 function create_and_checktime() {
1912         local fname=$1
1913         local loops=$2
1914         local i
1915
1916         for ((i=0; i < $loops; i++)); do
1917                 local start=$SECONDS
1918                 multiop $fname-$i Oc
1919                 ((SECONDS-start < TIMEOUT)) ||
1920                         error "creation took " $((SECONDS-$start)) && return 1
1921         done
1922 }
1923
1924 test_27oo() {
1925         local mdts=$(comma_list $(mdts_nodes))
1926
1927         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1928                 skip "Need MDS version at least 2.13.57"
1929
1930         local f0=$DIR/${tfile}-0
1931         local f1=$DIR/${tfile}-1
1932
1933         wait_delete_completed
1934
1935         # refill precreated objects
1936         $LFS setstripe -i0 -c1 $f0
1937
1938         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1939         # force QoS allocation policy
1940         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1941         stack_trap "do_nodes $mdts $LCTL set_param \
1942                 lov.*.qos_threshold_rr=$saved" EXIT
1943         sleep_maxage
1944
1945         # one OST is unavailable, but still have few objects preallocated
1946         stop ost1
1947         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1948                 rm -rf $f1 $DIR/$tdir*" EXIT
1949
1950         for ((i=0; i < 7; i++)); do
1951                 mkdir $DIR/$tdir$i || error "can't create dir"
1952                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1953                         error "can't set striping"
1954         done
1955         for ((i=0; i < 7; i++)); do
1956                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1957         done
1958         wait
1959 }
1960 run_test 27oo "don't let few threads to reserve too many objects"
1961
1962 test_27p() {
1963         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1965         remote_mds_nodsh && skip "remote MDS with nodsh"
1966         remote_ost_nodsh && skip "remote OST with nodsh"
1967
1968         reset_enospc
1969         rm -f $DIR/$tdir/$tfile
1970         test_mkdir $DIR/$tdir
1971
1972         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1973         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1974         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1975
1976         exhaust_precreations 0 0x80000215
1977         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1978         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1979         $LFS getstripe $DIR/$tdir/$tfile
1980
1981         reset_enospc
1982 }
1983 run_test 27p "append to a truncated file with some full OSTs"
1984
1985 test_27q() {
1986         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1988         remote_mds_nodsh && skip "remote MDS with nodsh"
1989         remote_ost_nodsh && skip "remote OST with nodsh"
1990
1991         reset_enospc
1992         rm -f $DIR/$tdir/$tfile
1993
1994         test_mkdir $DIR/$tdir
1995         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1996         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1997                 error "truncate $DIR/$tdir/$tfile failed"
1998         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1999
2000         exhaust_all_precreations 0x215
2001
2002         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2003         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2004
2005         reset_enospc
2006 }
2007 run_test 27q "append to truncated file with all OSTs full (should error)"
2008
2009 test_27r() {
2010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2012         remote_mds_nodsh && skip "remote MDS with nodsh"
2013         remote_ost_nodsh && skip "remote OST with nodsh"
2014
2015         reset_enospc
2016         rm -f $DIR/$tdir/$tfile
2017         exhaust_precreations 0 0x80000215
2018
2019         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2020
2021         reset_enospc
2022 }
2023 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2024
2025 test_27s() { # bug 10725
2026         test_mkdir $DIR/$tdir
2027         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2028         local stripe_count=0
2029         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2030         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2031                 error "stripe width >= 2^32 succeeded" || true
2032
2033 }
2034 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2035
2036 test_27t() { # bug 10864
2037         WDIR=$(pwd)
2038         WLFS=$(which lfs)
2039         cd $DIR
2040         touch $tfile
2041         $WLFS getstripe $tfile
2042         cd $WDIR
2043 }
2044 run_test 27t "check that utils parse path correctly"
2045
2046 test_27u() { # bug 4900
2047         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2048         remote_mds_nodsh && skip "remote MDS with nodsh"
2049
2050         local index
2051         local list=$(comma_list $(mdts_nodes))
2052
2053 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2054         do_nodes $list $LCTL set_param fail_loc=0x139
2055         test_mkdir -p $DIR/$tdir
2056         trap simple_cleanup_common EXIT
2057         createmany -o $DIR/$tdir/t- 1000
2058         do_nodes $list $LCTL set_param fail_loc=0
2059
2060         TLOG=$TMP/$tfile.getstripe
2061         $LFS getstripe $DIR/$tdir > $TLOG
2062         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2063         unlinkmany $DIR/$tdir/t- 1000
2064         trap 0
2065         [[ $OBJS -gt 0 ]] &&
2066                 error "$OBJS objects created on OST-0. See $TLOG" ||
2067                 rm -f $TLOG
2068 }
2069 run_test 27u "skip object creation on OSC w/o objects"
2070
2071 test_27v() { # bug 4900
2072         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2074         remote_mds_nodsh && skip "remote MDS with nodsh"
2075         remote_ost_nodsh && skip "remote OST with nodsh"
2076
2077         exhaust_all_precreations 0x215
2078         reset_enospc
2079
2080         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2081
2082         touch $DIR/$tdir/$tfile
2083         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2084         # all except ost1
2085         for (( i=1; i < OSTCOUNT; i++ )); do
2086                 do_facet ost$i lctl set_param fail_loc=0x705
2087         done
2088         local START=`date +%s`
2089         createmany -o $DIR/$tdir/$tfile 32
2090
2091         local FINISH=`date +%s`
2092         local TIMEOUT=`lctl get_param -n timeout`
2093         local PROCESS=$((FINISH - START))
2094         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2095                error "$FINISH - $START >= $TIMEOUT / 2"
2096         sleep $((TIMEOUT / 2 - PROCESS))
2097         reset_enospc
2098 }
2099 run_test 27v "skip object creation on slow OST"
2100
2101 test_27w() { # bug 10997
2102         test_mkdir $DIR/$tdir
2103         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2104         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2105                 error "stripe size $size != 65536" || true
2106         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2107                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2108 }
2109 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2110
2111 test_27wa() {
2112         [[ $OSTCOUNT -lt 2 ]] &&
2113                 skip_env "skipping multiple stripe count/offset test"
2114
2115         test_mkdir $DIR/$tdir
2116         for i in $(seq 1 $OSTCOUNT); do
2117                 offset=$((i - 1))
2118                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2119                         error "setstripe -c $i -i $offset failed"
2120                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2121                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2122                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2123                 [ $index -ne $offset ] &&
2124                         error "stripe offset $index != $offset" || true
2125         done
2126 }
2127 run_test 27wa "check $LFS setstripe -c -i options"
2128
2129 test_27x() {
2130         remote_ost_nodsh && skip "remote OST with nodsh"
2131         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2133
2134         OFFSET=$(($OSTCOUNT - 1))
2135         OSTIDX=0
2136         local OST=$(ostname_from_index $OSTIDX)
2137
2138         test_mkdir $DIR/$tdir
2139         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2140         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2141         sleep_maxage
2142         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2143         for i in $(seq 0 $OFFSET); do
2144                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2145                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2146                 error "OST0 was degraded but new created file still use it"
2147         done
2148         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2149 }
2150 run_test 27x "create files while OST0 is degraded"
2151
2152 test_27y() {
2153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2154         remote_mds_nodsh && skip "remote MDS with nodsh"
2155         remote_ost_nodsh && skip "remote OST with nodsh"
2156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2157
2158         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2159         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2160                 osp.$mdtosc.prealloc_last_id)
2161         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2162                 osp.$mdtosc.prealloc_next_id)
2163         local fcount=$((last_id - next_id))
2164         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2165         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2166
2167         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2168                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2169         local OST_DEACTIVE_IDX=-1
2170         local OSC
2171         local OSTIDX
2172         local OST
2173
2174         for OSC in $MDS_OSCS; do
2175                 OST=$(osc_to_ost $OSC)
2176                 OSTIDX=$(index_from_ostuuid $OST)
2177                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2178                         OST_DEACTIVE_IDX=$OSTIDX
2179                 fi
2180                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2181                         echo $OSC "is Deactivated:"
2182                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2183                 fi
2184         done
2185
2186         OSTIDX=$(index_from_ostuuid $OST)
2187         test_mkdir $DIR/$tdir
2188         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2189
2190         for OSC in $MDS_OSCS; do
2191                 OST=$(osc_to_ost $OSC)
2192                 OSTIDX=$(index_from_ostuuid $OST)
2193                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2194                         echo $OST "is degraded:"
2195                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2196                                                 obdfilter.$OST.degraded=1
2197                 fi
2198         done
2199
2200         sleep_maxage
2201         createmany -o $DIR/$tdir/$tfile $fcount
2202
2203         for OSC in $MDS_OSCS; do
2204                 OST=$(osc_to_ost $OSC)
2205                 OSTIDX=$(index_from_ostuuid $OST)
2206                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2207                         echo $OST "is recovered from degraded:"
2208                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2209                                                 obdfilter.$OST.degraded=0
2210                 else
2211                         do_facet $SINGLEMDS lctl --device %$OSC activate
2212                 fi
2213         done
2214
2215         # all osp devices get activated, hence -1 stripe count restored
2216         local stripe_count=0
2217
2218         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2219         # devices get activated.
2220         sleep_maxage
2221         $LFS setstripe -c -1 $DIR/$tfile
2222         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2223         rm -f $DIR/$tfile
2224         [ $stripe_count -ne $OSTCOUNT ] &&
2225                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2226         return 0
2227 }
2228 run_test 27y "create files while OST0 is degraded and the rest inactive"
2229
2230 check_seq_oid()
2231 {
2232         log "check file $1"
2233
2234         lmm_count=$($LFS getstripe -c $1)
2235         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2236         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2237
2238         local old_ifs="$IFS"
2239         IFS=$'[:]'
2240         fid=($($LFS path2fid $1))
2241         IFS="$old_ifs"
2242
2243         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2244         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2245
2246         # compare lmm_seq and lu_fid->f_seq
2247         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2248         # compare lmm_object_id and lu_fid->oid
2249         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2250
2251         # check the trusted.fid attribute of the OST objects of the file
2252         local have_obdidx=false
2253         local stripe_nr=0
2254         $LFS getstripe $1 | while read obdidx oid hex seq; do
2255                 # skip lines up to and including "obdidx"
2256                 [ -z "$obdidx" ] && break
2257                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2258                 $have_obdidx || continue
2259
2260                 local ost=$((obdidx + 1))
2261                 local dev=$(ostdevname $ost)
2262                 local oid_hex
2263
2264                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2265
2266                 seq=$(echo $seq | sed -e "s/^0x//g")
2267                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2268                         oid_hex=$(echo $oid)
2269                 else
2270                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2271                 fi
2272                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2273
2274                 local ff=""
2275                 #
2276                 # Don't unmount/remount the OSTs if we don't need to do that.
2277                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2278                 # update too, until that use mount/ll_decode_filter_fid/mount.
2279                 # Re-enable when debugfs will understand new filter_fid.
2280                 #
2281                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2282                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2283                                 $dev 2>/dev/null" | grep "parent=")
2284                 fi
2285                 if [ -z "$ff" ]; then
2286                         stop ost$ost
2287                         mount_fstype ost$ost
2288                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2289                                 $(facet_mntpt ost$ost)/$obj_file)
2290                         unmount_fstype ost$ost
2291                         start ost$ost $dev $OST_MOUNT_OPTS
2292                         clients_up
2293                 fi
2294
2295                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2296
2297                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2298
2299                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2300                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2301                 #
2302                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2303                 #       stripe_size=1048576 component_id=1 component_start=0 \
2304                 #       component_end=33554432
2305                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2306                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2307                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2308                 local ff_pstripe
2309                 if grep -q 'stripe=' <<<$ff; then
2310                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2311                 else
2312                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2313                         # into f_ver in this case.  See comment on ff_parent.
2314                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2315                 fi
2316
2317                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2318                 [ $ff_pseq = $lmm_seq ] ||
2319                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2320                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2321                 [ $ff_poid = $lmm_oid ] ||
2322                         error "FF parent OID $ff_poid != $lmm_oid"
2323                 (($ff_pstripe == $stripe_nr)) ||
2324                         error "FF stripe $ff_pstripe != $stripe_nr"
2325
2326                 stripe_nr=$((stripe_nr + 1))
2327                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2328                         continue
2329                 if grep -q 'stripe_count=' <<<$ff; then
2330                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2331                                             -e 's/ .*//' <<<$ff)
2332                         [ $lmm_count = $ff_scnt ] ||
2333                                 error "FF stripe count $lmm_count != $ff_scnt"
2334                 fi
2335         done
2336 }
2337
2338 test_27z() {
2339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2340         remote_ost_nodsh && skip "remote OST with nodsh"
2341
2342         test_mkdir $DIR/$tdir
2343         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2344                 { error "setstripe -c -1 failed"; return 1; }
2345         # We need to send a write to every object to get parent FID info set.
2346         # This _should_ also work for setattr, but does not currently.
2347         # touch $DIR/$tdir/$tfile-1 ||
2348         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2349                 { error "dd $tfile-1 failed"; return 2; }
2350         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2351                 { error "setstripe -c -1 failed"; return 3; }
2352         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2353                 { error "dd $tfile-2 failed"; return 4; }
2354
2355         # make sure write RPCs have been sent to OSTs
2356         sync; sleep 5; sync
2357
2358         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2359         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2360 }
2361 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2362
2363 test_27A() { # b=19102
2364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2365
2366         save_layout_restore_at_exit $MOUNT
2367         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2368         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2369                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2370         local default_size=$($LFS getstripe -S $MOUNT)
2371         local default_offset=$($LFS getstripe -i $MOUNT)
2372         local dsize=$(do_facet $SINGLEMDS \
2373                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2374         [ $default_size -eq $dsize ] ||
2375                 error "stripe size $default_size != $dsize"
2376         [ $default_offset -eq -1 ] ||
2377                 error "stripe offset $default_offset != -1"
2378 }
2379 run_test 27A "check filesystem-wide default LOV EA values"
2380
2381 test_27B() { # LU-2523
2382         test_mkdir $DIR/$tdir
2383         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2384         touch $DIR/$tdir/f0
2385         # open f1 with O_LOV_DELAY_CREATE
2386         # rename f0 onto f1
2387         # call setstripe ioctl on open file descriptor for f1
2388         # close
2389         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2390                 $DIR/$tdir/f0
2391
2392         rm -f $DIR/$tdir/f1
2393         # open f1 with O_LOV_DELAY_CREATE
2394         # unlink f1
2395         # call setstripe ioctl on open file descriptor for f1
2396         # close
2397         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2398
2399         # Allow multiop to fail in imitation of NFS's busted semantics.
2400         true
2401 }
2402 run_test 27B "call setstripe on open unlinked file/rename victim"
2403
2404 # 27C family tests full striping and overstriping
2405 test_27Ca() { #LU-2871
2406         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2407
2408         declare -a ost_idx
2409         local index
2410         local found
2411         local i
2412         local j
2413
2414         test_mkdir $DIR/$tdir
2415         cd $DIR/$tdir
2416         for i in $(seq 0 $((OSTCOUNT - 1))); do
2417                 # set stripe across all OSTs starting from OST$i
2418                 $LFS setstripe -i $i -c -1 $tfile$i
2419                 # get striping information
2420                 ost_idx=($($LFS getstripe $tfile$i |
2421                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2422                 echo ${ost_idx[@]}
2423
2424                 # check the layout
2425                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2426                         error "${#ost_idx[@]} != $OSTCOUNT"
2427
2428                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2429                         found=0
2430                         for j in $(echo ${ost_idx[@]}); do
2431                                 if [ $index -eq $j ]; then
2432                                         found=1
2433                                         break
2434                                 fi
2435                         done
2436                         [ $found = 1 ] ||
2437                                 error "Can not find $index in ${ost_idx[@]}"
2438                 done
2439         done
2440 }
2441 run_test 27Ca "check full striping across all OSTs"
2442
2443 test_27Cb() {
2444         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2445                 skip "server does not support overstriping"
2446         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2447                 skip_env "too many osts, skipping"
2448
2449         test_mkdir -p $DIR/$tdir
2450         local setcount=$(($OSTCOUNT * 2))
2451         [ $setcount -lt 160 ] || large_xattr_enabled ||
2452                 skip_env "ea_inode feature disabled"
2453
2454         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2455                 error "setstripe failed"
2456
2457         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2458         [ $count -eq $setcount ] ||
2459                 error "stripe count $count, should be $setcount"
2460
2461         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2462                 error "overstriped should be set in pattern"
2463
2464         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2465                 error "dd failed"
2466 }
2467 run_test 27Cb "more stripes than OSTs with -C"
2468
2469 test_27Cc() {
2470         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2471                 skip "server does not support overstriping"
2472         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2473
2474         test_mkdir -p $DIR/$tdir
2475         local setcount=$(($OSTCOUNT - 1))
2476
2477         [ $setcount -lt 160 ] || large_xattr_enabled ||
2478                 skip_env "ea_inode feature disabled"
2479
2480         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2481                 error "setstripe failed"
2482
2483         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2484         [ $count -eq $setcount ] ||
2485                 error "stripe count $count, should be $setcount"
2486
2487         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2488                 error "overstriped should not be set in pattern"
2489
2490         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2491                 error "dd failed"
2492 }
2493 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2494
2495 test_27Cd() {
2496         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2497                 skip "server does not support overstriping"
2498         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2499         large_xattr_enabled || skip_env "ea_inode feature disabled"
2500
2501         test_mkdir -p $DIR/$tdir
2502         local setcount=$LOV_MAX_STRIPE_COUNT
2503
2504         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2505                 error "setstripe failed"
2506
2507         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2508         [ $count -eq $setcount ] ||
2509                 error "stripe count $count, should be $setcount"
2510
2511         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2512                 error "overstriped should be set in pattern"
2513
2514         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2515                 error "dd failed"
2516
2517         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2518 }
2519 run_test 27Cd "test maximum stripe count"
2520
2521 test_27Ce() {
2522         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2523                 skip "server does not support overstriping"
2524         test_mkdir -p $DIR/$tdir
2525
2526         pool_add $TESTNAME || error "Pool creation failed"
2527         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2528
2529         local setcount=8
2530
2531         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2532                 error "setstripe failed"
2533
2534         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2535         [ $count -eq $setcount ] ||
2536                 error "stripe count $count, should be $setcount"
2537
2538         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2539                 error "overstriped should be set in pattern"
2540
2541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2542                 error "dd failed"
2543
2544         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2545 }
2546 run_test 27Ce "test pool with overstriping"
2547
2548 test_27Cf() {
2549         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2550                 skip "server does not support overstriping"
2551         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2552                 skip_env "too many osts, skipping"
2553
2554         test_mkdir -p $DIR/$tdir
2555
2556         local setcount=$(($OSTCOUNT * 2))
2557         [ $setcount -lt 160 ] || large_xattr_enabled ||
2558                 skip_env "ea_inode feature disabled"
2559
2560         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2561                 error "setstripe failed"
2562
2563         echo 1 > $DIR/$tdir/$tfile
2564
2565         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2566         [ $count -eq $setcount ] ||
2567                 error "stripe count $count, should be $setcount"
2568
2569         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2570                 error "overstriped should be set in pattern"
2571
2572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2573                 error "dd failed"
2574
2575         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2576 }
2577 run_test 27Cf "test default inheritance with overstriping"
2578
2579 test_27D() {
2580         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2581         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2582         remote_mds_nodsh && skip "remote MDS with nodsh"
2583
2584         local POOL=${POOL:-testpool}
2585         local first_ost=0
2586         local last_ost=$(($OSTCOUNT - 1))
2587         local ost_step=1
2588         local ost_list=$(seq $first_ost $ost_step $last_ost)
2589         local ost_range="$first_ost $last_ost $ost_step"
2590
2591         test_mkdir $DIR/$tdir
2592         pool_add $POOL || error "pool_add failed"
2593         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2594
2595         local skip27D
2596         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2597                 skip27D+="-s 29"
2598         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2599                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2600                         skip27D+=" -s 30,31"
2601         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2602           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2603                 skip27D+=" -s 32,33"
2604         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2605                 skip27D+=" -s 34"
2606         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2607                 error "llapi_layout_test failed"
2608
2609         destroy_test_pools || error "destroy test pools failed"
2610 }
2611 run_test 27D "validate llapi_layout API"
2612
2613 # Verify that default_easize is increased from its initial value after
2614 # accessing a widely striped file.
2615 test_27E() {
2616         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2617         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2618                 skip "client does not have LU-3338 fix"
2619
2620         # 72 bytes is the minimum space required to store striping
2621         # information for a file striped across one OST:
2622         # (sizeof(struct lov_user_md_v3) +
2623         #  sizeof(struct lov_user_ost_data_v1))
2624         local min_easize=72
2625         $LCTL set_param -n llite.*.default_easize $min_easize ||
2626                 error "lctl set_param failed"
2627         local easize=$($LCTL get_param -n llite.*.default_easize)
2628
2629         [ $easize -eq $min_easize ] ||
2630                 error "failed to set default_easize"
2631
2632         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2633                 error "setstripe failed"
2634         # In order to ensure stat() call actually talks to MDS we need to
2635         # do something drastic to this file to shake off all lock, e.g.
2636         # rename it (kills lookup lock forcing cache cleaning)
2637         mv $DIR/$tfile $DIR/${tfile}-1
2638         ls -l $DIR/${tfile}-1
2639         rm $DIR/${tfile}-1
2640
2641         easize=$($LCTL get_param -n llite.*.default_easize)
2642
2643         [ $easize -gt $min_easize ] ||
2644                 error "default_easize not updated"
2645 }
2646 run_test 27E "check that default extended attribute size properly increases"
2647
2648 test_27F() { # LU-5346/LU-7975
2649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2650         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2651         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2652                 skip "Need MDS version at least 2.8.51"
2653         remote_ost_nodsh && skip "remote OST with nodsh"
2654
2655         test_mkdir $DIR/$tdir
2656         rm -f $DIR/$tdir/f0
2657         $LFS setstripe -c 2 $DIR/$tdir
2658
2659         # stop all OSTs to reproduce situation for LU-7975 ticket
2660         for num in $(seq $OSTCOUNT); do
2661                 stop ost$num
2662         done
2663
2664         # open/create f0 with O_LOV_DELAY_CREATE
2665         # truncate f0 to a non-0 size
2666         # close
2667         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2668
2669         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2670         # open/write it again to force delayed layout creation
2671         cat /etc/hosts > $DIR/$tdir/f0 &
2672         catpid=$!
2673
2674         # restart OSTs
2675         for num in $(seq $OSTCOUNT); do
2676                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2677                         error "ost$num failed to start"
2678         done
2679
2680         wait $catpid || error "cat failed"
2681
2682         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2683         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2684                 error "wrong stripecount"
2685
2686 }
2687 run_test 27F "Client resend delayed layout creation with non-zero size"
2688
2689 test_27G() { #LU-10629
2690         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2691                 skip "Need MDS version at least 2.11.51"
2692         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2693         remote_mds_nodsh && skip "remote MDS with nodsh"
2694         local POOL=${POOL:-testpool}
2695         local ostrange="0 0 1"
2696
2697         test_mkdir $DIR/$tdir
2698         touch $DIR/$tdir/$tfile.nopool
2699         pool_add $POOL || error "pool_add failed"
2700         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2701         $LFS setstripe -p $POOL $DIR/$tdir
2702
2703         local pool=$($LFS getstripe -p $DIR/$tdir)
2704
2705         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2706         touch $DIR/$tdir/$tfile.default
2707         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2708         $LFS find $DIR/$tdir -type f --pool $POOL
2709         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2710         [[ "$found" == "2" ]] ||
2711                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2712
2713         $LFS setstripe -d $DIR/$tdir
2714
2715         pool=$($LFS getstripe -p -d $DIR/$tdir)
2716
2717         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2718 }
2719 run_test 27G "Clear OST pool from stripe"
2720
2721 test_27H() {
2722         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2723                 skip "Need MDS version newer than 2.11.54"
2724         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2725         test_mkdir $DIR/$tdir
2726         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2727         touch $DIR/$tdir/$tfile
2728         $LFS getstripe -c $DIR/$tdir/$tfile
2729         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2730                 error "two-stripe file doesn't have two stripes"
2731
2732         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2733         $LFS getstripe -y $DIR/$tdir/$tfile
2734         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2735              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2736                 error "expected l_ost_idx: [02]$ not matched"
2737
2738         # make sure ost list has been cleared
2739         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2740         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2741                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2742         touch $DIR/$tdir/f3
2743         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2744 }
2745 run_test 27H "Set specific OSTs stripe"
2746
2747 test_27I() {
2748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2750         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2751                 skip "Need MDS version newer than 2.12.52"
2752         local pool=$TESTNAME
2753         local ostrange="1 1 1"
2754
2755         save_layout_restore_at_exit $MOUNT
2756         $LFS setstripe -c 2 -i 0 $MOUNT
2757         pool_add $pool || error "pool_add failed"
2758         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2759         test_mkdir $DIR/$tdir
2760         $LFS setstripe -p $pool $DIR/$tdir
2761         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2762         $LFS getstripe $DIR/$tdir/$tfile
2763 }
2764 run_test 27I "check that root dir striping does not break parent dir one"
2765
2766 test_27J() {
2767         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2768                 skip "Need MDS version newer than 2.12.51"
2769
2770         test_mkdir $DIR/$tdir
2771         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2772         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2773
2774         # create foreign file (raw way)
2775         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2776                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2777
2778         ! $LFS setstripe --foreign --flags foo \
2779                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2780                         error "creating $tfile with '--flags foo' should fail"
2781
2782         ! $LFS setstripe --foreign --flags 0xffffffff \
2783                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2784                         error "creating $tfile w/ 0xffffffff flags should fail"
2785
2786         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2787                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2788
2789         # verify foreign file (raw way)
2790         parse_foreign_file -f $DIR/$tdir/$tfile |
2791                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2792                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2793         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2794                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2795         parse_foreign_file -f $DIR/$tdir/$tfile |
2796                 grep "lov_foreign_size: 73" ||
2797                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2798         parse_foreign_file -f $DIR/$tdir/$tfile |
2799                 grep "lov_foreign_type: 1" ||
2800                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2801         parse_foreign_file -f $DIR/$tdir/$tfile |
2802                 grep "lov_foreign_flags: 0x0000DA08" ||
2803                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2804         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2805                 grep "lov_foreign_value: 0x" |
2806                 sed -e 's/lov_foreign_value: 0x//')
2807         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2808         [[ $lov = ${lov2// /} ]] ||
2809                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2810
2811         # create foreign file (lfs + API)
2812         $LFS setstripe --foreign=none --flags 0xda08 \
2813                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2814                 error "$DIR/$tdir/${tfile}2: create failed"
2815
2816         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2817                 grep "lfm_magic:.*0x0BD70BD0" ||
2818                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2819         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2820         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2821                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2822         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2823                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2824         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2825                 grep "lfm_flags:.*0x0000DA08" ||
2826                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2827         $LFS getstripe $DIR/$tdir/${tfile}2 |
2828                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2829                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2830
2831         # modify striping should fail
2832         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2833                 error "$DIR/$tdir/$tfile: setstripe should fail"
2834         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2835                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2836
2837         # R/W should fail
2838         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2839         cat $DIR/$tdir/${tfile}2 &&
2840                 error "$DIR/$tdir/${tfile}2: read should fail"
2841         cat /etc/passwd > $DIR/$tdir/$tfile &&
2842                 error "$DIR/$tdir/$tfile: write should fail"
2843         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2844                 error "$DIR/$tdir/${tfile}2: write should fail"
2845
2846         # chmod should work
2847         chmod 222 $DIR/$tdir/$tfile ||
2848                 error "$DIR/$tdir/$tfile: chmod failed"
2849         chmod 222 $DIR/$tdir/${tfile}2 ||
2850                 error "$DIR/$tdir/${tfile}2: chmod failed"
2851
2852         # chown should work
2853         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2854                 error "$DIR/$tdir/$tfile: chown failed"
2855         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2856                 error "$DIR/$tdir/${tfile}2: chown failed"
2857
2858         # rename should work
2859         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2860                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2861         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2862                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2863
2864         #remove foreign file
2865         rm $DIR/$tdir/${tfile}.new ||
2866                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2867         rm $DIR/$tdir/${tfile}2.new ||
2868                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2869 }
2870 run_test 27J "basic ops on file with foreign LOV"
2871
2872 test_27K() {
2873         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2874                 skip "Need MDS version newer than 2.12.49"
2875
2876         test_mkdir $DIR/$tdir
2877         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2878         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2879
2880         # create foreign dir (raw way)
2881         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2882                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2883
2884         ! $LFS setdirstripe --foreign --flags foo \
2885                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2886                         error "creating $tdir with '--flags foo' should fail"
2887
2888         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2889                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2890                         error "creating $tdir w/ 0xffffffff flags should fail"
2891
2892         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2893                 error "create_foreign_dir FAILED"
2894
2895         # verify foreign dir (raw way)
2896         parse_foreign_dir -d $DIR/$tdir/$tdir |
2897                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2898                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2899         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2900                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2901         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2902                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2903         parse_foreign_dir -d $DIR/$tdir/$tdir |
2904                 grep "lmv_foreign_flags: 55813$" ||
2905                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2906         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2907                 grep "lmv_foreign_value: 0x" |
2908                 sed 's/lmv_foreign_value: 0x//')
2909         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2910                 sed 's/ //g')
2911         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2912
2913         # create foreign dir (lfs + API)
2914         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2915                 $DIR/$tdir/${tdir}2 ||
2916                 error "$DIR/$tdir/${tdir}2: create failed"
2917
2918         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2919                 grep "lfm_magic:.*0x0CD50CD0" ||
2920                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2921         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2922         # - sizeof(lfm_type) - sizeof(lfm_flags)
2923         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2924                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2925         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2926                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2927         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2928                 grep "lfm_flags:.*0x0000DA05" ||
2929                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2930         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2931                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2932                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2933
2934         # file create in dir should fail
2935         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2936         touch $DIR/$tdir/${tdir}2/$tfile &&
2937                 "$DIR/${tdir}2: file create should fail"
2938
2939         # chmod should work
2940         chmod 777 $DIR/$tdir/$tdir ||
2941                 error "$DIR/$tdir: chmod failed"
2942         chmod 777 $DIR/$tdir/${tdir}2 ||
2943                 error "$DIR/${tdir}2: chmod failed"
2944
2945         # chown should work
2946         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2947                 error "$DIR/$tdir: chown failed"
2948         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2949                 error "$DIR/${tdir}2: chown failed"
2950
2951         # rename should work
2952         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2953                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2954         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2955                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2956
2957         #remove foreign dir
2958         rmdir $DIR/$tdir/${tdir}.new ||
2959                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2960         rmdir $DIR/$tdir/${tdir}2.new ||
2961                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2962 }
2963 run_test 27K "basic ops on dir with foreign LMV"
2964
2965 test_27L() {
2966         remote_mds_nodsh && skip "remote MDS with nodsh"
2967
2968         local POOL=${POOL:-$TESTNAME}
2969
2970         pool_add $POOL || error "pool_add failed"
2971
2972         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2973                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2974                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2975 }
2976 run_test 27L "lfs pool_list gives correct pool name"
2977
2978 test_27M() {
2979         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2980                 skip "Need MDS version >= than 2.12.57"
2981         remote_mds_nodsh && skip "remote MDS with nodsh"
2982         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2983
2984         test_mkdir $DIR/$tdir
2985
2986         # Set default striping on directory
2987         $LFS setstripe -C 4 $DIR/$tdir
2988
2989         echo 1 > $DIR/$tdir/${tfile}.1
2990         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2991         local setcount=4
2992         [ $count -eq $setcount ] ||
2993                 error "(1) stripe count $count, should be $setcount"
2994
2995         # Capture existing append_stripe_count setting for restore
2996         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2997         local mdts=$(comma_list $(mdts_nodes))
2998         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2999
3000         local appendcount=$orig_count
3001         echo 1 >> $DIR/$tdir/${tfile}.2_append
3002         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3003         [ $count -eq $appendcount ] ||
3004                 error "(2)stripe count $count, should be $appendcount for append"
3005
3006         # Disable O_APPEND striping, verify it works
3007         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3008
3009         # Should now get the default striping, which is 4
3010         setcount=4
3011         echo 1 >> $DIR/$tdir/${tfile}.3_append
3012         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3013         [ $count -eq $setcount ] ||
3014                 error "(3) stripe count $count, should be $setcount"
3015
3016         # Try changing the stripe count for append files
3017         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3018
3019         # Append striping is now 2 (directory default is still 4)
3020         appendcount=2
3021         echo 1 >> $DIR/$tdir/${tfile}.4_append
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3023         [ $count -eq $appendcount ] ||
3024                 error "(4) stripe count $count, should be $appendcount for append"
3025
3026         # Test append stripe count of -1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3028         appendcount=$OSTCOUNT
3029         echo 1 >> $DIR/$tdir/${tfile}.5
3030         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3031         [ $count -eq $appendcount ] ||
3032                 error "(5) stripe count $count, should be $appendcount for append"
3033
3034         # Set append striping back to default of 1
3035         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3036
3037         # Try a new default striping, PFL + DOM
3038         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3039
3040         # Create normal DOM file, DOM returns stripe count == 0
3041         setcount=0
3042         touch $DIR/$tdir/${tfile}.6
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3044         [ $count -eq $setcount ] ||
3045                 error "(6) stripe count $count, should be $setcount"
3046
3047         # Show
3048         appendcount=1
3049         echo 1 >> $DIR/$tdir/${tfile}.7_append
3050         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3051         [ $count -eq $appendcount ] ||
3052                 error "(7) stripe count $count, should be $appendcount for append"
3053
3054         # Clean up DOM layout
3055         $LFS setstripe -d $DIR/$tdir
3056
3057         # Now test that append striping works when layout is from root
3058         $LFS setstripe -c 2 $MOUNT
3059         # Make a special directory for this
3060         mkdir $DIR/${tdir}/${tdir}.2
3061         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3062
3063         # Verify for normal file
3064         setcount=2
3065         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3066         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3067         [ $count -eq $setcount ] ||
3068                 error "(8) stripe count $count, should be $setcount"
3069
3070         appendcount=1
3071         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3072         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3073         [ $count -eq $appendcount ] ||
3074                 error "(9) stripe count $count, should be $appendcount for append"
3075
3076         # Now test O_APPEND striping with pools
3077         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3078         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3079
3080         # Create the pool
3081         pool_add $TESTNAME || error "pool creation failed"
3082         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3083
3084         echo 1 >> $DIR/$tdir/${tfile}.10_append
3085
3086         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3087         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3088
3089         # Check that count is still correct
3090         appendcount=1
3091         echo 1 >> $DIR/$tdir/${tfile}.11_append
3092         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3093         [ $count -eq $appendcount ] ||
3094                 error "(11) stripe count $count, should be $appendcount for append"
3095
3096         # Disable O_APPEND stripe count, verify pool works separately
3097         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3098
3099         echo 1 >> $DIR/$tdir/${tfile}.12_append
3100
3101         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3102         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3103
3104         # Remove pool setting, verify it's not applied
3105         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.13_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3110         [ "$pool" = "" ] || error "(13) pool found: $pool"
3111 }
3112 run_test 27M "test O_APPEND striping"
3113
3114 test_27N() {
3115         combined_mgs_mds && skip "needs separate MGS/MDT"
3116
3117         pool_add $TESTNAME || error "pool_add failed"
3118         do_facet mgs "$LCTL pool_list $FSNAME" |
3119                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3120                 error "lctl pool_list on MGS failed"
3121 }
3122 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3123
3124 clean_foreign_symlink() {
3125         trap 0
3126         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3127         for i in $DIR/$tdir/* ; do
3128                 $LFS unlink_foreign $i || true
3129         done
3130 }
3131
3132 test_27O() {
3133         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3134                 skip "Need MDS version newer than 2.12.51"
3135
3136         test_mkdir $DIR/$tdir
3137         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3138         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3139
3140         trap clean_foreign_symlink EXIT
3141
3142         # enable foreign_symlink behaviour
3143         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3144
3145         # foreign symlink LOV format is a partial path by default
3146
3147         # create foreign file (lfs + API)
3148         $LFS setstripe --foreign=symlink --flags 0xda05 \
3149                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3150                 error "$DIR/$tdir/${tfile}: create failed"
3151
3152         $LFS getstripe -v $DIR/$tdir/${tfile} |
3153                 grep "lfm_magic:.*0x0BD70BD0" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3155         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3156                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3157         $LFS getstripe -v $DIR/$tdir/${tfile} |
3158                 grep "lfm_flags:.*0x0000DA05" ||
3159                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3160         $LFS getstripe $DIR/$tdir/${tfile} |
3161                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3163
3164         # modify striping should fail
3165         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3166                 error "$DIR/$tdir/$tfile: setstripe should fail"
3167
3168         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3169         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3170         cat /etc/passwd > $DIR/$tdir/$tfile &&
3171                 error "$DIR/$tdir/$tfile: write should fail"
3172
3173         # rename should succeed
3174         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3175                 error "$DIR/$tdir/$tfile: rename has failed"
3176
3177         #remove foreign_symlink file should fail
3178         rm $DIR/$tdir/${tfile}.new &&
3179                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3180
3181         #test fake symlink
3182         mkdir /tmp/${uuid1} ||
3183                 error "/tmp/${uuid1}: mkdir has failed"
3184         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3185                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3186         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3187         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3188                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3189         #read should succeed now
3190         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3191                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3192         #write should succeed now
3193         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3195         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3197         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3198                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3199
3200         #check that getstripe still works
3201         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3203
3204         # chmod should still succeed
3205         chmod 644 $DIR/$tdir/${tfile}.new ||
3206                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3207
3208         # chown should still succeed
3209         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3211
3212         # rename should still succeed
3213         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3214                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3215
3216         #remove foreign_symlink file should still fail
3217         rm $DIR/$tdir/${tfile} &&
3218                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3219
3220         #use special ioctl() to unlink foreign_symlink file
3221         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3222                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3223
3224 }
3225 run_test 27O "basic ops on foreign file of symlink type"
3226
3227 test_27P() {
3228         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3229                 skip "Need MDS version newer than 2.12.49"
3230
3231         test_mkdir $DIR/$tdir
3232         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3233         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3234
3235         trap clean_foreign_symlink EXIT
3236
3237         # enable foreign_symlink behaviour
3238         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3239
3240         # foreign symlink LMV format is a partial path by default
3241
3242         # create foreign dir (lfs + API)
3243         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3244                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3245                 error "$DIR/$tdir/${tdir}: create failed"
3246
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3248                 grep "lfm_magic:.*0x0CD50CD0" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3250         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3251                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3252         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3253                 grep "lfm_flags:.*0x0000DA05" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3255         $LFS getdirstripe $DIR/$tdir/${tdir} |
3256                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3258
3259         # file create in dir should fail
3260         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3261         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3262
3263         # rename should succeed
3264         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3265                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3266
3267         #remove foreign_symlink dir should fail
3268         rmdir $DIR/$tdir/${tdir}.new &&
3269                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3270
3271         #test fake symlink
3272         mkdir -p /tmp/${uuid1}/${uuid2} ||
3273                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3274         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3275                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3276         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3277         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3278                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3279         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3280                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3281
3282         #check that getstripe fails now that foreign_symlink enabled
3283         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3284                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3285
3286         # file create in dir should work now
3287         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3288                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3289         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3290                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3291         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3292                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3293
3294         # chmod should still succeed
3295         chmod 755 $DIR/$tdir/${tdir}.new ||
3296                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3297
3298         # chown should still succeed
3299         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3300                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3301
3302         # rename should still succeed
3303         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3305
3306         #remove foreign_symlink dir should still fail
3307         rmdir $DIR/$tdir/${tdir} &&
3308                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3309
3310         #use special ioctl() to unlink foreign_symlink file
3311         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3312                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3313
3314         #created file should still exist
3315         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3316                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3317         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3318                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3319 }
3320 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3321
3322 # createtest also checks that device nodes are created and
3323 # then visible correctly (#2091)
3324 test_28() { # bug 2091
3325         test_mkdir $DIR/d28
3326         $CREATETEST $DIR/d28/ct || error "createtest failed"
3327 }
3328 run_test 28 "create/mknod/mkdir with bad file types ============"
3329
3330 test_29() {
3331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3332
3333         sync; sleep 1; sync # flush out any dirty pages from previous tests
3334         cancel_lru_locks
3335         test_mkdir $DIR/d29
3336         touch $DIR/d29/foo
3337         log 'first d29'
3338         ls -l $DIR/d29
3339
3340         declare -i LOCKCOUNTORIG=0
3341         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3342                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3343         done
3344         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3345
3346         declare -i LOCKUNUSEDCOUNTORIG=0
3347         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3348                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3349         done
3350
3351         log 'second d29'
3352         ls -l $DIR/d29
3353         log 'done'
3354
3355         declare -i LOCKCOUNTCURRENT=0
3356         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3357                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3358         done
3359
3360         declare -i LOCKUNUSEDCOUNTCURRENT=0
3361         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3362                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3363         done
3364
3365         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3366                 $LCTL set_param -n ldlm.dump_namespaces ""
3367                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3368                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3369                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3370                 return 2
3371         fi
3372         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3373                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3374                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3375                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3376                 return 3
3377         fi
3378 }
3379 run_test 29 "IT_GETATTR regression  ============================"
3380
3381 test_30a() { # was test_30
3382         cp $(which ls) $DIR || cp /bin/ls $DIR
3383         $DIR/ls / || error "Can't execute binary from lustre"
3384         rm $DIR/ls
3385 }
3386 run_test 30a "execute binary from Lustre (execve) =============="
3387
3388 test_30b() {
3389         cp `which ls` $DIR || cp /bin/ls $DIR
3390         chmod go+rx $DIR/ls
3391         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3392         rm $DIR/ls
3393 }
3394 run_test 30b "execute binary from Lustre as non-root ==========="
3395
3396 test_30c() { # b=22376
3397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3398
3399         cp $(which ls) $DIR || cp /bin/ls $DIR
3400         chmod a-rw $DIR/ls
3401         cancel_lru_locks mdc
3402         cancel_lru_locks osc
3403         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3404         rm -f $DIR/ls
3405 }
3406 run_test 30c "execute binary from Lustre without read perms ===="
3407
3408 test_30d() {
3409         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3410
3411         for i in {1..10}; do
3412                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3413                 local PID=$!
3414                 sleep 1
3415                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3416                 wait $PID || error "executing dd from Lustre failed"
3417                 rm -f $DIR/$tfile
3418         done
3419
3420         rm -f $DIR/dd
3421 }
3422 run_test 30d "execute binary from Lustre while clear locks"
3423
3424 test_31a() {
3425         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3426         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3427 }
3428 run_test 31a "open-unlink file =================================="
3429
3430 test_31b() {
3431         touch $DIR/f31 || error "touch $DIR/f31 failed"
3432         ln $DIR/f31 $DIR/f31b || error "ln failed"
3433         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3434         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3435 }
3436 run_test 31b "unlink file with multiple links while open ======="
3437
3438 test_31c() {
3439         touch $DIR/f31 || error "touch $DIR/f31 failed"
3440         ln $DIR/f31 $DIR/f31c || error "ln failed"
3441         multiop_bg_pause $DIR/f31 O_uc ||
3442                 error "multiop_bg_pause for $DIR/f31 failed"
3443         MULTIPID=$!
3444         $MULTIOP $DIR/f31c Ouc
3445         kill -USR1 $MULTIPID
3446         wait $MULTIPID
3447 }
3448 run_test 31c "open-unlink file with multiple links ============="
3449
3450 test_31d() {
3451         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3452         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3453 }
3454 run_test 31d "remove of open directory ========================="
3455
3456 test_31e() { # bug 2904
3457         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3458 }
3459 run_test 31e "remove of open non-empty directory ==============="
3460
3461 test_31f() { # bug 4554
3462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3463
3464         set -vx
3465         test_mkdir $DIR/d31f
3466         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3467         cp /etc/hosts $DIR/d31f
3468         ls -l $DIR/d31f
3469         $LFS getstripe $DIR/d31f/hosts
3470         multiop_bg_pause $DIR/d31f D_c || return 1
3471         MULTIPID=$!
3472
3473         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3474         test_mkdir $DIR/d31f
3475         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3476         cp /etc/hosts $DIR/d31f
3477         ls -l $DIR/d31f
3478         $LFS getstripe $DIR/d31f/hosts
3479         multiop_bg_pause $DIR/d31f D_c || return 1
3480         MULTIPID2=$!
3481
3482         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3483         wait $MULTIPID || error "first opendir $MULTIPID failed"
3484
3485         sleep 6
3486
3487         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3488         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3489         set +vx
3490 }
3491 run_test 31f "remove of open directory with open-unlink file ==="
3492
3493 test_31g() {
3494         echo "-- cross directory link --"
3495         test_mkdir -c1 $DIR/${tdir}ga
3496         test_mkdir -c1 $DIR/${tdir}gb
3497         touch $DIR/${tdir}ga/f
3498         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3499         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3500         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3501         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3502         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3503 }
3504 run_test 31g "cross directory link==============="
3505
3506 test_31h() {
3507         echo "-- cross directory link --"
3508         test_mkdir -c1 $DIR/${tdir}
3509         test_mkdir -c1 $DIR/${tdir}/dir
3510         touch $DIR/${tdir}/f
3511         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3512         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3513         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3514         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3515         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3516 }
3517 run_test 31h "cross directory link under child==============="
3518
3519 test_31i() {
3520         echo "-- cross directory link --"
3521         test_mkdir -c1 $DIR/$tdir
3522         test_mkdir -c1 $DIR/$tdir/dir
3523         touch $DIR/$tdir/dir/f
3524         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3525         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3526         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3527         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3528         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3529 }
3530 run_test 31i "cross directory link under parent==============="
3531
3532 test_31j() {
3533         test_mkdir -c1 -p $DIR/$tdir
3534         test_mkdir -c1 -p $DIR/$tdir/dir1
3535         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3536         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3537         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3538         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3539         return 0
3540 }
3541 run_test 31j "link for directory==============="
3542
3543 test_31k() {
3544         test_mkdir -c1 -p $DIR/$tdir
3545         touch $DIR/$tdir/s
3546         touch $DIR/$tdir/exist
3547         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3548         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3549         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3550         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3551         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3552         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3553         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3554         return 0
3555 }
3556 run_test 31k "link to file: the same, non-existing, dir==============="
3557
3558 test_31m() {
3559         mkdir $DIR/d31m
3560         touch $DIR/d31m/s
3561         mkdir $DIR/d31m2
3562         touch $DIR/d31m2/exist
3563         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3564         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3565         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3566         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3567         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3568         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3569         return 0
3570 }
3571 run_test 31m "link to file: the same, non-existing, dir==============="
3572
3573 test_31n() {
3574         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3575         nlink=$(stat --format=%h $DIR/$tfile)
3576         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3577         local fd=$(free_fd)
3578         local cmd="exec $fd<$DIR/$tfile"
3579         eval $cmd
3580         cmd="exec $fd<&-"
3581         trap "eval $cmd" EXIT
3582         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3583         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3584         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3585         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3586         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3587         eval $cmd
3588 }
3589 run_test 31n "check link count of unlinked file"
3590
3591 link_one() {
3592         local tempfile=$(mktemp $1_XXXXXX)
3593         mlink $tempfile $1 2> /dev/null &&
3594                 echo "$BASHPID: link $tempfile to $1 succeeded"
3595         munlink $tempfile
3596 }
3597
3598 test_31o() { # LU-2901
3599         test_mkdir $DIR/$tdir
3600         for LOOP in $(seq 100); do
3601                 rm -f $DIR/$tdir/$tfile*
3602                 for THREAD in $(seq 8); do
3603                         link_one $DIR/$tdir/$tfile.$LOOP &
3604                 done
3605                 wait
3606                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3607                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3608                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3609                         break || true
3610         done
3611 }
3612 run_test 31o "duplicate hard links with same filename"
3613
3614 test_31p() {
3615         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3616
3617         test_mkdir $DIR/$tdir
3618         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3619         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3620
3621         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3622                 error "open unlink test1 failed"
3623         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3624                 error "open unlink test2 failed"
3625
3626         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3627                 error "test1 still exists"
3628         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3629                 error "test2 still exists"
3630 }
3631 run_test 31p "remove of open striped directory"
3632
3633 test_31q() {
3634         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3635
3636         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3637         index=$($LFS getdirstripe -i $DIR/$tdir)
3638         [ $index -eq 3 ] || error "first stripe index $index != 3"
3639         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3640         [ $index -eq 1 ] || error "second stripe index $index != 1"
3641
3642         # when "-c <stripe_count>" is set, the number of MDTs specified after
3643         # "-i" should equal to the stripe count
3644         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3645 }
3646 run_test 31q "create striped directory on specific MDTs"
3647
3648 cleanup_test32_mount() {
3649         local rc=0
3650         trap 0
3651         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3652         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3653         losetup -d $loopdev || true
3654         rm -rf $DIR/$tdir
3655         return $rc
3656 }
3657
3658 test_32a() {
3659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3660
3661         echo "== more mountpoints and symlinks ================="
3662         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3663         trap cleanup_test32_mount EXIT
3664         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3665         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3666                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3667         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3668                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3669         cleanup_test32_mount
3670 }
3671 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3672
3673 test_32b() {
3674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3675
3676         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3677         trap cleanup_test32_mount EXIT
3678         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3679         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3680                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3681         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3682                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3683         cleanup_test32_mount
3684 }
3685 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3686
3687 test_32c() {
3688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3689
3690         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3691         trap cleanup_test32_mount EXIT
3692         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3693         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3694                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3695         test_mkdir -p $DIR/$tdir/d2/test_dir
3696         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3697                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3698         cleanup_test32_mount
3699 }
3700 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3701
3702 test_32d() {
3703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3704
3705         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3706         trap cleanup_test32_mount EXIT
3707         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3708         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3709                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3710         test_mkdir -p $DIR/$tdir/d2/test_dir
3711         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3712                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3713         cleanup_test32_mount
3714 }
3715 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3716
3717 test_32e() {
3718         rm -fr $DIR/$tdir
3719         test_mkdir -p $DIR/$tdir/tmp
3720         local tmp_dir=$DIR/$tdir/tmp
3721         ln -s $DIR/$tdir $tmp_dir/symlink11
3722         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3723         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3724         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3725 }
3726 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3727
3728 test_32f() {
3729         rm -fr $DIR/$tdir
3730         test_mkdir -p $DIR/$tdir/tmp
3731         local tmp_dir=$DIR/$tdir/tmp
3732         ln -s $DIR/$tdir $tmp_dir/symlink11
3733         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3734         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3735         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3736 }
3737 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3738
3739 test_32g() {
3740         local tmp_dir=$DIR/$tdir/tmp
3741         test_mkdir -p $tmp_dir
3742         test_mkdir $DIR/${tdir}2
3743         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3744         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3745         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3746         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3747         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3748         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3749 }
3750 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3751
3752 test_32h() {
3753         rm -fr $DIR/$tdir $DIR/${tdir}2
3754         tmp_dir=$DIR/$tdir/tmp
3755         test_mkdir -p $tmp_dir
3756         test_mkdir $DIR/${tdir}2
3757         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3758         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3759         ls $tmp_dir/symlink12 || error "listing symlink12"
3760         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3761 }
3762 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3763
3764 test_32i() {
3765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3766
3767         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3768         trap cleanup_test32_mount EXIT
3769         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3770         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3771                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3772         touch $DIR/$tdir/test_file
3773         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3774                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3775         cleanup_test32_mount
3776 }
3777 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3778
3779 test_32j() {
3780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3781
3782         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3783         trap cleanup_test32_mount EXIT
3784         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3785         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3786                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3787         touch $DIR/$tdir/test_file
3788         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3789                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3790         cleanup_test32_mount
3791 }
3792 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3793
3794 test_32k() {
3795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3796
3797         rm -fr $DIR/$tdir
3798         trap cleanup_test32_mount EXIT
3799         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3800         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3801                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3802         test_mkdir -p $DIR/$tdir/d2
3803         touch $DIR/$tdir/d2/test_file || error "touch failed"
3804         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3805                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3806         cleanup_test32_mount
3807 }
3808 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3809
3810 test_32l() {
3811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3812
3813         rm -fr $DIR/$tdir
3814         trap cleanup_test32_mount EXIT
3815         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3816         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3817                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3818         test_mkdir -p $DIR/$tdir/d2
3819         touch $DIR/$tdir/d2/test_file || error "touch failed"
3820         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3821                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3822         cleanup_test32_mount
3823 }
3824 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3825
3826 test_32m() {
3827         rm -fr $DIR/d32m
3828         test_mkdir -p $DIR/d32m/tmp
3829         TMP_DIR=$DIR/d32m/tmp
3830         ln -s $DIR $TMP_DIR/symlink11
3831         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3832         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3833                 error "symlink11 not a link"
3834         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3835                 error "symlink01 not a link"
3836 }
3837 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3838
3839 test_32n() {
3840         rm -fr $DIR/d32n
3841         test_mkdir -p $DIR/d32n/tmp
3842         TMP_DIR=$DIR/d32n/tmp
3843         ln -s $DIR $TMP_DIR/symlink11
3844         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3845         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3846         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3847 }
3848 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3849
3850 test_32o() {
3851         touch $DIR/$tfile
3852         test_mkdir -p $DIR/d32o/tmp
3853         TMP_DIR=$DIR/d32o/tmp
3854         ln -s $DIR/$tfile $TMP_DIR/symlink12
3855         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3856         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3857                 error "symlink12 not a link"
3858         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3859         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3860                 error "$DIR/d32o/tmp/symlink12 not file type"
3861         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3862                 error "$DIR/d32o/symlink02 not file type"
3863 }
3864 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3865
3866 test_32p() {
3867         log 32p_1
3868         rm -fr $DIR/d32p
3869         log 32p_2
3870         rm -f $DIR/$tfile
3871         log 32p_3
3872         touch $DIR/$tfile
3873         log 32p_4
3874         test_mkdir -p $DIR/d32p/tmp
3875         log 32p_5
3876         TMP_DIR=$DIR/d32p/tmp
3877         log 32p_6
3878         ln -s $DIR/$tfile $TMP_DIR/symlink12
3879         log 32p_7
3880         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3881         log 32p_8
3882         cat $DIR/d32p/tmp/symlink12 ||
3883                 error "Can't open $DIR/d32p/tmp/symlink12"
3884         log 32p_9
3885         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3886         log 32p_10
3887 }
3888 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3889
3890 test_32q() {
3891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3892
3893         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3894         trap cleanup_test32_mount EXIT
3895         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3896         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3897         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3898                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3899         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3900         cleanup_test32_mount
3901 }
3902 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3903
3904 test_32r() {
3905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3906
3907         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3908         trap cleanup_test32_mount EXIT
3909         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3910         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3911         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3912                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3913         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3914         cleanup_test32_mount
3915 }
3916 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3917
3918 test_33aa() {
3919         rm -f $DIR/$tfile
3920         touch $DIR/$tfile
3921         chmod 444 $DIR/$tfile
3922         chown $RUNAS_ID $DIR/$tfile
3923         log 33_1
3924         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3925         log 33_2
3926 }
3927 run_test 33aa "write file with mode 444 (should return error)"
3928
3929 test_33a() {
3930         rm -fr $DIR/$tdir
3931         test_mkdir $DIR/$tdir
3932         chown $RUNAS_ID $DIR/$tdir
3933         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3934                 error "$RUNAS create $tdir/$tfile failed"
3935         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3936                 error "open RDWR" || true
3937 }
3938 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3939
3940 test_33b() {
3941         rm -fr $DIR/$tdir
3942         test_mkdir $DIR/$tdir
3943         chown $RUNAS_ID $DIR/$tdir
3944         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3945 }
3946 run_test 33b "test open file with malformed flags (No panic)"
3947
3948 test_33c() {
3949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3950         remote_ost_nodsh && skip "remote OST with nodsh"
3951
3952         local ostnum
3953         local ostname
3954         local write_bytes
3955         local all_zeros
3956
3957         all_zeros=true
3958         test_mkdir $DIR/$tdir
3959         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3960
3961         sync
3962         for ostnum in $(seq $OSTCOUNT); do
3963                 # test-framework's OST numbering is one-based, while Lustre's
3964                 # is zero-based
3965                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3966                 # check if at least some write_bytes stats are counted
3967                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3968                               obdfilter.$ostname.stats |
3969                               awk '/^write_bytes/ {print $7}' )
3970                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
3971                 if (( ${write_bytes:-0} > 0 )); then
3972                         all_zeros=false
3973                         break
3974                 fi
3975         done
3976
3977         $all_zeros || return 0
3978
3979         # Write four bytes
3980         echo foo > $DIR/$tdir/bar
3981         # Really write them
3982         sync
3983
3984         # Total up write_bytes after writing.  We'd better find non-zeros.
3985         for ostnum in $(seq $OSTCOUNT); do
3986                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3987                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3988                               obdfilter/$ostname/stats |
3989                               awk '/^write_bytes/ {print $7}' )
3990                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
3991                 if (( ${write_bytes:-0} > 0 )); then
3992                         all_zeros=false
3993                         break
3994                 fi
3995         done
3996
3997         if $all_zeros; then
3998                 for ostnum in $(seq $OSTCOUNT); do
3999                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4000                         echo "Check write_bytes is in obdfilter.*.stats:"
4001                         do_facet ost$ostnum lctl get_param -n \
4002                                 obdfilter.$ostname.stats
4003                 done
4004                 error "OST not keeping write_bytes stats (b=22312)"
4005         fi
4006 }
4007 run_test 33c "test write_bytes stats"
4008
4009 test_33d() {
4010         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4012
4013         local MDTIDX=1
4014         local remote_dir=$DIR/$tdir/remote_dir
4015
4016         test_mkdir $DIR/$tdir
4017         $LFS mkdir -i $MDTIDX $remote_dir ||
4018                 error "create remote directory failed"
4019
4020         touch $remote_dir/$tfile
4021         chmod 444 $remote_dir/$tfile
4022         chown $RUNAS_ID $remote_dir/$tfile
4023
4024         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4025
4026         chown $RUNAS_ID $remote_dir
4027         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4028                                         error "create" || true
4029         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4030                                     error "open RDWR" || true
4031         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4032 }
4033 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4034
4035 test_33e() {
4036         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4037
4038         mkdir $DIR/$tdir
4039
4040         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4041         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4042         mkdir $DIR/$tdir/local_dir
4043
4044         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4045         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4046         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4047
4048         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4049                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4050
4051         rmdir $DIR/$tdir/* || error "rmdir failed"
4052
4053         umask 777
4054         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4055         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4056         mkdir $DIR/$tdir/local_dir
4057
4058         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4059         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4060         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4061
4062         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4063                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4064
4065         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4066
4067         umask 000
4068         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4069         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4070         mkdir $DIR/$tdir/local_dir
4071
4072         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4073         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4074         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4075
4076         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4077                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4078 }
4079 run_test 33e "mkdir and striped directory should have same mode"
4080
4081 cleanup_33f() {
4082         trap 0
4083         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4084 }
4085
4086 test_33f() {
4087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4088         remote_mds_nodsh && skip "remote MDS with nodsh"
4089
4090         mkdir $DIR/$tdir
4091         chmod go+rwx $DIR/$tdir
4092         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4093         trap cleanup_33f EXIT
4094
4095         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4096                 error "cannot create striped directory"
4097
4098         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4099                 error "cannot create files in striped directory"
4100
4101         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4102                 error "cannot remove files in striped directory"
4103
4104         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4105                 error "cannot remove striped directory"
4106
4107         cleanup_33f
4108 }
4109 run_test 33f "nonroot user can create, access, and remove a striped directory"
4110
4111 test_33g() {
4112         mkdir -p $DIR/$tdir/dir2
4113
4114         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4115         echo $err
4116         [[ $err =~ "exists" ]] || error "Not exists error"
4117 }
4118 run_test 33g "nonroot user create already existing root created file"
4119
4120 test_33h() {
4121         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4122         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4123                 skip "Need MDS version at least 2.13.50"
4124
4125         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4126                 error "mkdir $tdir failed"
4127         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4128
4129         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4130         local index2
4131
4132         for fname in $DIR/$tdir/$tfile.bak \
4133                      $DIR/$tdir/$tfile.SAV \
4134                      $DIR/$tdir/$tfile.orig \
4135                      $DIR/$tdir/$tfile~; do
4136                 touch $fname  || error "touch $fname failed"
4137                 index2=$($LFS getstripe -m $fname)
4138                 [ $index -eq $index2 ] ||
4139                         error "$fname MDT index mismatch $index != $index2"
4140         done
4141
4142         local failed=0
4143         for i in {1..250}; do
4144                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4145                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4146                         touch $fname  || error "touch $fname failed"
4147                         index2=$($LFS getstripe -m $fname)
4148                         if [[ $index != $index2 ]]; then
4149                                 failed=$((failed + 1))
4150                                 echo "$fname MDT index mismatch $index != $index2"
4151                         fi
4152                 done
4153         done
4154         echo "$failed MDT index mismatches"
4155         (( failed < 20 )) || error "MDT index mismatch $failed times"
4156
4157 }
4158 run_test 33h "temp file is located on the same MDT as target"
4159
4160 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4161 test_34a() {
4162         rm -f $DIR/f34
4163         $MCREATE $DIR/f34 || error "mcreate failed"
4164         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4165                 error "getstripe failed"
4166         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4167         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4168                 error "getstripe failed"
4169         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4170                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4171 }
4172 run_test 34a "truncate file that has not been opened ==========="
4173
4174 test_34b() {
4175         [ ! -f $DIR/f34 ] && test_34a
4176         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4177                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4178         $OPENFILE -f O_RDONLY $DIR/f34
4179         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4180                 error "getstripe failed"
4181         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4182                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4183 }
4184 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4185
4186 test_34c() {
4187         [ ! -f $DIR/f34 ] && test_34a
4188         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4189                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4190         $OPENFILE -f O_RDWR $DIR/f34
4191         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4192                 error "$LFS getstripe failed"
4193         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4194                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4195 }
4196 run_test 34c "O_RDWR opening file-with-size works =============="
4197
4198 test_34d() {
4199         [ ! -f $DIR/f34 ] && test_34a
4200         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4201                 error "dd failed"
4202         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4203                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4204         rm $DIR/f34
4205 }
4206 run_test 34d "write to sparse file ============================="
4207
4208 test_34e() {
4209         rm -f $DIR/f34e
4210         $MCREATE $DIR/f34e || error "mcreate failed"
4211         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4212         $CHECKSTAT -s 1000 $DIR/f34e ||
4213                 error "Size of $DIR/f34e not equal to 1000 bytes"
4214         $OPENFILE -f O_RDWR $DIR/f34e
4215         $CHECKSTAT -s 1000 $DIR/f34e ||
4216                 error "Size of $DIR/f34e not equal to 1000 bytes"
4217 }
4218 run_test 34e "create objects, some with size and some without =="
4219
4220 test_34f() { # bug 6242, 6243
4221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4222
4223         SIZE34F=48000
4224         rm -f $DIR/f34f
4225         $MCREATE $DIR/f34f || error "mcreate failed"
4226         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4227         dd if=$DIR/f34f of=$TMP/f34f
4228         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4229         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4230         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4231         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4232         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4233 }
4234 run_test 34f "read from a file with no objects until EOF ======="
4235
4236 test_34g() {
4237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4238
4239         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4240                 error "dd failed"
4241         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4242         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4243                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4244         cancel_lru_locks osc
4245         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4246                 error "wrong size after lock cancel"
4247
4248         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4249         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4250                 error "expanding truncate failed"
4251         cancel_lru_locks osc
4252         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4253                 error "wrong expanded size after lock cancel"
4254 }
4255 run_test 34g "truncate long file ==============================="
4256
4257 test_34h() {
4258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4259
4260         local gid=10
4261         local sz=1000
4262
4263         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4264         sync # Flush the cache so that multiop below does not block on cache
4265              # flush when getting the group lock
4266         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4267         MULTIPID=$!
4268
4269         # Since just timed wait is not good enough, let's do a sync write
4270         # that way we are sure enough time for a roundtrip + processing
4271         # passed + 2 seconds of extra margin.
4272         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4273         rm $DIR/${tfile}-1
4274         sleep 2
4275
4276         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4277                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4278                 kill -9 $MULTIPID
4279         fi
4280         wait $MULTIPID
4281         local nsz=`stat -c %s $DIR/$tfile`
4282         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4283 }
4284 run_test 34h "ftruncate file under grouplock should not block"
4285
4286 test_35a() {
4287         cp /bin/sh $DIR/f35a
4288         chmod 444 $DIR/f35a
4289         chown $RUNAS_ID $DIR/f35a
4290         $RUNAS $DIR/f35a && error || true
4291         rm $DIR/f35a
4292 }
4293 run_test 35a "exec file with mode 444 (should return and not leak)"
4294
4295 test_36a() {
4296         rm -f $DIR/f36
4297         utime $DIR/f36 || error "utime failed for MDS"
4298 }
4299 run_test 36a "MDS utime check (mknod, utime)"
4300
4301 test_36b() {
4302         echo "" > $DIR/f36
4303         utime $DIR/f36 || error "utime failed for OST"
4304 }
4305 run_test 36b "OST utime check (open, utime)"
4306
4307 test_36c() {
4308         rm -f $DIR/d36/f36
4309         test_mkdir $DIR/d36
4310         chown $RUNAS_ID $DIR/d36
4311         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4312 }
4313 run_test 36c "non-root MDS utime check (mknod, utime)"
4314
4315 test_36d() {
4316         [ ! -d $DIR/d36 ] && test_36c
4317         echo "" > $DIR/d36/f36
4318         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4319 }
4320 run_test 36d "non-root OST utime check (open, utime)"
4321
4322 test_36e() {
4323         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4324
4325         test_mkdir $DIR/$tdir
4326         touch $DIR/$tdir/$tfile
4327         $RUNAS utime $DIR/$tdir/$tfile &&
4328                 error "utime worked, expected failure" || true
4329 }
4330 run_test 36e "utime on non-owned file (should return error)"
4331
4332 subr_36fh() {
4333         local fl="$1"
4334         local LANG_SAVE=$LANG
4335         local LC_LANG_SAVE=$LC_LANG
4336         export LANG=C LC_LANG=C # for date language
4337
4338         DATESTR="Dec 20  2000"
4339         test_mkdir $DIR/$tdir
4340         lctl set_param fail_loc=$fl
4341         date; date +%s
4342         cp /etc/hosts $DIR/$tdir/$tfile
4343         sync & # write RPC generated with "current" inode timestamp, but delayed
4344         sleep 1
4345         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4346         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4347         cancel_lru_locks $OSC
4348         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4349         date; date +%s
4350         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4351                 echo "BEFORE: $LS_BEFORE" && \
4352                 echo "AFTER : $LS_AFTER" && \
4353                 echo "WANT  : $DATESTR" && \
4354                 error "$DIR/$tdir/$tfile timestamps changed" || true
4355
4356         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4357 }
4358
4359 test_36f() {
4360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4361
4362         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4363         subr_36fh "0x80000214"
4364 }
4365 run_test 36f "utime on file racing with OST BRW write =========="
4366
4367 test_36g() {
4368         remote_ost_nodsh && skip "remote OST with nodsh"
4369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4370         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4371                 skip "Need MDS version at least 2.12.51"
4372
4373         local fmd_max_age
4374         local fmd
4375         local facet="ost1"
4376         local tgt="obdfilter"
4377
4378         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4379
4380         test_mkdir $DIR/$tdir
4381         fmd_max_age=$(do_facet $facet \
4382                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4383                 head -n 1")
4384
4385         echo "FMD max age: ${fmd_max_age}s"
4386         touch $DIR/$tdir/$tfile
4387         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4388                 gawk '{cnt=cnt+$1}  END{print cnt}')
4389         echo "FMD before: $fmd"
4390         [[ $fmd == 0 ]] &&
4391                 error "FMD wasn't create by touch"
4392         sleep $((fmd_max_age + 12))
4393         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4394                 gawk '{cnt=cnt+$1}  END{print cnt}')
4395         echo "FMD after: $fmd"
4396         [[ $fmd == 0 ]] ||
4397                 error "FMD wasn't expired by ping"
4398 }
4399 run_test 36g "FMD cache expiry ====================="
4400
4401 test_36h() {
4402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4403
4404         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4405         subr_36fh "0x80000227"
4406 }
4407 run_test 36h "utime on file racing with OST BRW write =========="
4408
4409 test_36i() {
4410         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4411
4412         test_mkdir $DIR/$tdir
4413         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4414
4415         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4416         local new_mtime=$((mtime + 200))
4417
4418         #change Modify time of striped dir
4419         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4420                         error "change mtime failed"
4421
4422         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4423
4424         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4425 }
4426 run_test 36i "change mtime on striped directory"
4427
4428 # test_37 - duplicate with tests 32q 32r
4429
4430 test_38() {
4431         local file=$DIR/$tfile
4432         touch $file
4433         openfile -f O_DIRECTORY $file
4434         local RC=$?
4435         local ENOTDIR=20
4436         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4437         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4438 }
4439 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4440
4441 test_39a() { # was test_39
4442         touch $DIR/$tfile
4443         touch $DIR/${tfile}2
4444 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4445 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4446 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4447         sleep 2
4448         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4449         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4450                 echo "mtime"
4451                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4452                 echo "atime"
4453                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4454                 echo "ctime"
4455                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4456                 error "O_TRUNC didn't change timestamps"
4457         fi
4458 }
4459 run_test 39a "mtime changed on create"
4460
4461 test_39b() {
4462         test_mkdir -c1 $DIR/$tdir
4463         cp -p /etc/passwd $DIR/$tdir/fopen
4464         cp -p /etc/passwd $DIR/$tdir/flink
4465         cp -p /etc/passwd $DIR/$tdir/funlink
4466         cp -p /etc/passwd $DIR/$tdir/frename
4467         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4468
4469         sleep 1
4470         echo "aaaaaa" >> $DIR/$tdir/fopen
4471         echo "aaaaaa" >> $DIR/$tdir/flink
4472         echo "aaaaaa" >> $DIR/$tdir/funlink
4473         echo "aaaaaa" >> $DIR/$tdir/frename
4474
4475         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4476         local link_new=`stat -c %Y $DIR/$tdir/flink`
4477         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4478         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4479
4480         cat $DIR/$tdir/fopen > /dev/null
4481         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4482         rm -f $DIR/$tdir/funlink2
4483         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4484
4485         for (( i=0; i < 2; i++ )) ; do
4486                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4487                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4488                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4489                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4490
4491                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4492                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4493                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4494                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4495
4496                 cancel_lru_locks $OSC
4497                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4498         done
4499 }
4500 run_test 39b "mtime change on open, link, unlink, rename  ======"
4501
4502 # this should be set to past
4503 TEST_39_MTIME=`date -d "1 year ago" +%s`
4504
4505 # bug 11063
4506 test_39c() {
4507         touch $DIR1/$tfile
4508         sleep 2
4509         local mtime0=`stat -c %Y $DIR1/$tfile`
4510
4511         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4512         local mtime1=`stat -c %Y $DIR1/$tfile`
4513         [ "$mtime1" = $TEST_39_MTIME ] || \
4514                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4515
4516         local d1=`date +%s`
4517         echo hello >> $DIR1/$tfile
4518         local d2=`date +%s`
4519         local mtime2=`stat -c %Y $DIR1/$tfile`
4520         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4521                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4522
4523         mv $DIR1/$tfile $DIR1/$tfile-1
4524
4525         for (( i=0; i < 2; i++ )) ; do
4526                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4527                 [ "$mtime2" = "$mtime3" ] || \
4528                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4529
4530                 cancel_lru_locks $OSC
4531                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4532         done
4533 }
4534 run_test 39c "mtime change on rename ==========================="
4535
4536 # bug 21114
4537 test_39d() {
4538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4539
4540         touch $DIR1/$tfile
4541         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4542
4543         for (( i=0; i < 2; i++ )) ; do
4544                 local mtime=`stat -c %Y $DIR1/$tfile`
4545                 [ $mtime = $TEST_39_MTIME ] || \
4546                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4547
4548                 cancel_lru_locks $OSC
4549                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4550         done
4551 }
4552 run_test 39d "create, utime, stat =============================="
4553
4554 # bug 21114
4555 test_39e() {
4556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4557
4558         touch $DIR1/$tfile
4559         local mtime1=`stat -c %Y $DIR1/$tfile`
4560
4561         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4562
4563         for (( i=0; i < 2; i++ )) ; do
4564                 local mtime2=`stat -c %Y $DIR1/$tfile`
4565                 [ $mtime2 = $TEST_39_MTIME ] || \
4566                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4567
4568                 cancel_lru_locks $OSC
4569                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4570         done
4571 }
4572 run_test 39e "create, stat, utime, stat ========================"
4573
4574 # bug 21114
4575 test_39f() {
4576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4577
4578         touch $DIR1/$tfile
4579         mtime1=`stat -c %Y $DIR1/$tfile`
4580
4581         sleep 2
4582         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4583
4584         for (( i=0; i < 2; i++ )) ; do
4585                 local mtime2=`stat -c %Y $DIR1/$tfile`
4586                 [ $mtime2 = $TEST_39_MTIME ] || \
4587                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4588
4589                 cancel_lru_locks $OSC
4590                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4591         done
4592 }
4593 run_test 39f "create, stat, sleep, utime, stat ================="
4594
4595 # bug 11063
4596 test_39g() {
4597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4598
4599         echo hello >> $DIR1/$tfile
4600         local mtime1=`stat -c %Y $DIR1/$tfile`
4601
4602         sleep 2
4603         chmod o+r $DIR1/$tfile
4604
4605         for (( i=0; i < 2; i++ )) ; do
4606                 local mtime2=`stat -c %Y $DIR1/$tfile`
4607                 [ "$mtime1" = "$mtime2" ] || \
4608                         error "lost mtime: $mtime2, should be $mtime1"
4609
4610                 cancel_lru_locks $OSC
4611                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4612         done
4613 }
4614 run_test 39g "write, chmod, stat ==============================="
4615
4616 # bug 11063
4617 test_39h() {
4618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4619
4620         touch $DIR1/$tfile
4621         sleep 1
4622
4623         local d1=`date`
4624         echo hello >> $DIR1/$tfile
4625         local mtime1=`stat -c %Y $DIR1/$tfile`
4626
4627         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4628         local d2=`date`
4629         if [ "$d1" != "$d2" ]; then
4630                 echo "write and touch not within one second"
4631         else
4632                 for (( i=0; i < 2; i++ )) ; do
4633                         local mtime2=`stat -c %Y $DIR1/$tfile`
4634                         [ "$mtime2" = $TEST_39_MTIME ] || \
4635                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4636
4637                         cancel_lru_locks $OSC
4638                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4639                 done
4640         fi
4641 }
4642 run_test 39h "write, utime within one second, stat ============="
4643
4644 test_39i() {
4645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4646
4647         touch $DIR1/$tfile
4648         sleep 1
4649
4650         echo hello >> $DIR1/$tfile
4651         local mtime1=`stat -c %Y $DIR1/$tfile`
4652
4653         mv $DIR1/$tfile $DIR1/$tfile-1
4654
4655         for (( i=0; i < 2; i++ )) ; do
4656                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4657
4658                 [ "$mtime1" = "$mtime2" ] || \
4659                         error "lost mtime: $mtime2, should be $mtime1"
4660
4661                 cancel_lru_locks $OSC
4662                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4663         done
4664 }
4665 run_test 39i "write, rename, stat =============================="
4666
4667 test_39j() {
4668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4669
4670         start_full_debug_logging
4671         touch $DIR1/$tfile
4672         sleep 1
4673
4674         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4675         lctl set_param fail_loc=0x80000412
4676         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4677                 error "multiop failed"
4678         local multipid=$!
4679         local mtime1=`stat -c %Y $DIR1/$tfile`
4680
4681         mv $DIR1/$tfile $DIR1/$tfile-1
4682
4683         kill -USR1 $multipid
4684         wait $multipid || error "multiop close failed"
4685
4686         for (( i=0; i < 2; i++ )) ; do
4687                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4688                 [ "$mtime1" = "$mtime2" ] ||
4689                         error "mtime is lost on close: $mtime2, " \
4690                               "should be $mtime1"
4691
4692                 cancel_lru_locks
4693                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4694         done
4695         lctl set_param fail_loc=0
4696         stop_full_debug_logging
4697 }
4698 run_test 39j "write, rename, close, stat ======================="
4699
4700 test_39k() {
4701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4702
4703         touch $DIR1/$tfile
4704         sleep 1
4705
4706         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4707         local multipid=$!
4708         local mtime1=`stat -c %Y $DIR1/$tfile`
4709
4710         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4711
4712         kill -USR1 $multipid
4713         wait $multipid || error "multiop close failed"
4714
4715         for (( i=0; i < 2; i++ )) ; do
4716                 local mtime2=`stat -c %Y $DIR1/$tfile`
4717
4718                 [ "$mtime2" = $TEST_39_MTIME ] || \
4719                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4720
4721                 cancel_lru_locks
4722                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4723         done
4724 }
4725 run_test 39k "write, utime, close, stat ========================"
4726
4727 # this should be set to future
4728 TEST_39_ATIME=`date -d "1 year" +%s`
4729
4730 test_39l() {
4731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4732         remote_mds_nodsh && skip "remote MDS with nodsh"
4733
4734         local atime_diff=$(do_facet $SINGLEMDS \
4735                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4736         rm -rf $DIR/$tdir
4737         mkdir -p $DIR/$tdir
4738
4739         # test setting directory atime to future
4740         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4741         local atime=$(stat -c %X $DIR/$tdir)
4742         [ "$atime" = $TEST_39_ATIME ] ||
4743                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4744
4745         # test setting directory atime from future to now
4746         local now=$(date +%s)
4747         touch -a -d @$now $DIR/$tdir
4748
4749         atime=$(stat -c %X $DIR/$tdir)
4750         [ "$atime" -eq "$now"  ] ||
4751                 error "atime is not updated from future: $atime, $now"
4752
4753         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4754         sleep 3
4755
4756         # test setting directory atime when now > dir atime + atime_diff
4757         local d1=$(date +%s)
4758         ls $DIR/$tdir
4759         local d2=$(date +%s)
4760         cancel_lru_locks mdc
4761         atime=$(stat -c %X $DIR/$tdir)
4762         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4763                 error "atime is not updated  : $atime, should be $d2"
4764
4765         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4766         sleep 3
4767
4768         # test not setting directory atime when now < dir atime + atime_diff
4769         ls $DIR/$tdir
4770         cancel_lru_locks mdc
4771         atime=$(stat -c %X $DIR/$tdir)
4772         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4773                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4774
4775         do_facet $SINGLEMDS \
4776                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4777 }
4778 run_test 39l "directory atime update ==========================="
4779
4780 test_39m() {
4781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4782
4783         touch $DIR1/$tfile
4784         sleep 2
4785         local far_past_mtime=$(date -d "May 29 1953" +%s)
4786         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4787
4788         touch -m -d @$far_past_mtime $DIR1/$tfile
4789         touch -a -d @$far_past_atime $DIR1/$tfile
4790
4791         for (( i=0; i < 2; i++ )) ; do
4792                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4793                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4794                         error "atime or mtime set incorrectly"
4795
4796                 cancel_lru_locks $OSC
4797                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4798         done
4799 }
4800 run_test 39m "test atime and mtime before 1970"
4801
4802 test_39n() { # LU-3832
4803         remote_mds_nodsh && skip "remote MDS with nodsh"
4804
4805         local atime_diff=$(do_facet $SINGLEMDS \
4806                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4807         local atime0
4808         local atime1
4809         local atime2
4810
4811         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4812
4813         rm -rf $DIR/$tfile
4814         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4815         atime0=$(stat -c %X $DIR/$tfile)
4816
4817         sleep 5
4818         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4819         atime1=$(stat -c %X $DIR/$tfile)
4820
4821         sleep 5
4822         cancel_lru_locks mdc
4823         cancel_lru_locks osc
4824         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4825         atime2=$(stat -c %X $DIR/$tfile)
4826
4827         do_facet $SINGLEMDS \
4828                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4829
4830         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4831         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4832 }
4833 run_test 39n "check that O_NOATIME is honored"
4834
4835 test_39o() {
4836         TESTDIR=$DIR/$tdir/$tfile
4837         [ -e $TESTDIR ] && rm -rf $TESTDIR
4838         mkdir -p $TESTDIR
4839         cd $TESTDIR
4840         links1=2
4841         ls
4842         mkdir a b
4843         ls
4844         links2=$(stat -c %h .)
4845         [ $(($links1 + 2)) != $links2 ] &&
4846                 error "wrong links count $(($links1 + 2)) != $links2"
4847         rmdir b
4848         links3=$(stat -c %h .)
4849         [ $(($links1 + 1)) != $links3 ] &&
4850                 error "wrong links count $links1 != $links3"
4851         return 0
4852 }
4853 run_test 39o "directory cached attributes updated after create"
4854
4855 test_39p() {
4856         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4857
4858         local MDTIDX=1
4859         TESTDIR=$DIR/$tdir/$tdir
4860         [ -e $TESTDIR ] && rm -rf $TESTDIR
4861         test_mkdir -p $TESTDIR
4862         cd $TESTDIR
4863         links1=2
4864         ls
4865         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4866         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4867         ls
4868         links2=$(stat -c %h .)
4869         [ $(($links1 + 2)) != $links2 ] &&
4870                 error "wrong links count $(($links1 + 2)) != $links2"
4871         rmdir remote_dir2
4872         links3=$(stat -c %h .)
4873         [ $(($links1 + 1)) != $links3 ] &&
4874                 error "wrong links count $links1 != $links3"
4875         return 0
4876 }
4877 run_test 39p "remote directory cached attributes updated after create ========"
4878
4879 test_39r() {
4880         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4881                 skip "no atime update on old OST"
4882         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4883                 skip_env "ldiskfs only test"
4884         fi
4885
4886         local saved_adiff
4887         saved_adiff=$(do_facet ost1 \
4888                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4889         stack_trap "do_facet ost1 \
4890                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4891
4892         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4893
4894         $LFS setstripe -i 0 $DIR/$tfile
4895         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4896                 error "can't write initial file"
4897         cancel_lru_locks osc
4898
4899         # exceed atime_diff and access file
4900         sleep 6
4901         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4902                 error "can't udpate atime"
4903
4904         local atime_cli=$(stat -c %X $DIR/$tfile)
4905         echo "client atime: $atime_cli"
4906         # allow atime update to be written to device
4907         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4908         sleep 5
4909
4910         local ostdev=$(ostdevname 1)
4911         local fid=($(lfs getstripe -y $DIR/$tfile |
4912                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4913         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4914         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4915
4916         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4917         local atime_ost=$(do_facet ost1 "$cmd" |&
4918                           awk -F'[: ]' '/atime:/ { print $4 }')
4919         (( atime_cli == atime_ost )) ||
4920                 error "atime on client $atime_cli != ost $atime_ost"
4921 }
4922 run_test 39r "lazy atime update on OST"
4923
4924 test_39q() { # LU-8041
4925         local testdir=$DIR/$tdir
4926         mkdir -p $testdir
4927         multiop_bg_pause $testdir D_c || error "multiop failed"
4928         local multipid=$!
4929         cancel_lru_locks mdc
4930         kill -USR1 $multipid
4931         local atime=$(stat -c %X $testdir)
4932         [ "$atime" -ne 0 ] || error "atime is zero"
4933 }
4934 run_test 39q "close won't zero out atime"
4935
4936 test_40() {
4937         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4938         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4939                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4940         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4941                 error "$tfile is not 4096 bytes in size"
4942 }
4943 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4944
4945 test_41() {
4946         # bug 1553
4947         small_write $DIR/f41 18
4948 }
4949 run_test 41 "test small file write + fstat ====================="
4950
4951 count_ost_writes() {
4952         lctl get_param -n ${OSC}.*.stats |
4953                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4954                         END { printf("%0.0f", writes) }'
4955 }
4956
4957 # decent default
4958 WRITEBACK_SAVE=500
4959 DIRTY_RATIO_SAVE=40
4960 MAX_DIRTY_RATIO=50
4961 BG_DIRTY_RATIO_SAVE=10
4962 MAX_BG_DIRTY_RATIO=25
4963
4964 start_writeback() {
4965         trap 0
4966         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4967         # dirty_ratio, dirty_background_ratio
4968         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4969                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4970                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4971                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4972         else
4973                 # if file not here, we are a 2.4 kernel
4974                 kill -CONT `pidof kupdated`
4975         fi
4976 }
4977
4978 stop_writeback() {
4979         # setup the trap first, so someone cannot exit the test at the
4980         # exact wrong time and mess up a machine
4981         trap start_writeback EXIT
4982         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4983         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4984                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4985                 sysctl -w vm.dirty_writeback_centisecs=0
4986                 sysctl -w vm.dirty_writeback_centisecs=0
4987                 # save and increase /proc/sys/vm/dirty_ratio
4988                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4989                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4990                 # save and increase /proc/sys/vm/dirty_background_ratio
4991                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4992                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4993         else
4994                 # if file not here, we are a 2.4 kernel
4995                 kill -STOP `pidof kupdated`
4996         fi
4997 }
4998
4999 # ensure that all stripes have some grant before we test client-side cache
5000 setup_test42() {
5001         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5002                 dd if=/dev/zero of=$i bs=4k count=1
5003                 rm $i
5004         done
5005 }
5006
5007 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5008 # file truncation, and file removal.
5009 test_42a() {
5010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5011
5012         setup_test42
5013         cancel_lru_locks $OSC
5014         stop_writeback
5015         sync; sleep 1; sync # just to be safe
5016         BEFOREWRITES=`count_ost_writes`
5017         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5018         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5019         AFTERWRITES=`count_ost_writes`
5020         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5021                 error "$BEFOREWRITES < $AFTERWRITES"
5022         start_writeback
5023 }
5024 run_test 42a "ensure that we don't flush on close"
5025
5026 test_42b() {
5027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5028
5029         setup_test42
5030         cancel_lru_locks $OSC
5031         stop_writeback
5032         sync
5033         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5034         BEFOREWRITES=$(count_ost_writes)
5035         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5036         AFTERWRITES=$(count_ost_writes)
5037         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5038                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5039         fi
5040         BEFOREWRITES=$(count_ost_writes)
5041         sync || error "sync: $?"
5042         AFTERWRITES=$(count_ost_writes)
5043         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5044                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5045         fi
5046         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5047         start_writeback
5048         return 0
5049 }
5050 run_test 42b "test destroy of file with cached dirty data ======"
5051
5052 # if these tests just want to test the effect of truncation,
5053 # they have to be very careful.  consider:
5054 # - the first open gets a {0,EOF}PR lock
5055 # - the first write conflicts and gets a {0, count-1}PW
5056 # - the rest of the writes are under {count,EOF}PW
5057 # - the open for truncate tries to match a {0,EOF}PR
5058 #   for the filesize and cancels the PWs.
5059 # any number of fixes (don't get {0,EOF} on open, match
5060 # composite locks, do smarter file size management) fix
5061 # this, but for now we want these tests to verify that
5062 # the cancellation with truncate intent works, so we
5063 # start the file with a full-file pw lock to match against
5064 # until the truncate.
5065 trunc_test() {
5066         test=$1
5067         file=$DIR/$test
5068         offset=$2
5069         cancel_lru_locks $OSC
5070         stop_writeback
5071         # prime the file with 0,EOF PW to match
5072         touch $file
5073         $TRUNCATE $file 0
5074         sync; sync
5075         # now the real test..
5076         dd if=/dev/zero of=$file bs=1024 count=100
5077         BEFOREWRITES=`count_ost_writes`
5078         $TRUNCATE $file $offset
5079         cancel_lru_locks $OSC
5080         AFTERWRITES=`count_ost_writes`
5081         start_writeback
5082 }
5083
5084 test_42c() {
5085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5086
5087         trunc_test 42c 1024
5088         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5089                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5090         rm $file
5091 }
5092 run_test 42c "test partial truncate of file with cached dirty data"
5093
5094 test_42d() {
5095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5096
5097         trunc_test 42d 0
5098         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5099                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5100         rm $file
5101 }
5102 run_test 42d "test complete truncate of file with cached dirty data"
5103
5104 test_42e() { # bug22074
5105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5106
5107         local TDIR=$DIR/${tdir}e
5108         local pages=16 # hardcoded 16 pages, don't change it.
5109         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5110         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5111         local max_dirty_mb
5112         local warmup_files
5113
5114         test_mkdir $DIR/${tdir}e
5115         $LFS setstripe -c 1 $TDIR
5116         createmany -o $TDIR/f $files
5117
5118         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5119
5120         # we assume that with $OSTCOUNT files, at least one of them will
5121         # be allocated on OST0.
5122         warmup_files=$((OSTCOUNT * max_dirty_mb))
5123         createmany -o $TDIR/w $warmup_files
5124
5125         # write a large amount of data into one file and sync, to get good
5126         # avail_grant number from OST.
5127         for ((i=0; i<$warmup_files; i++)); do
5128                 idx=$($LFS getstripe -i $TDIR/w$i)
5129                 [ $idx -ne 0 ] && continue
5130                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5131                 break
5132         done
5133         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5134         sync
5135         $LCTL get_param $proc_osc0/cur_dirty_bytes
5136         $LCTL get_param $proc_osc0/cur_grant_bytes
5137
5138         # create as much dirty pages as we can while not to trigger the actual
5139         # RPCs directly. but depends on the env, VFS may trigger flush during this
5140         # period, hopefully we are good.
5141         for ((i=0; i<$warmup_files; i++)); do
5142                 idx=$($LFS getstripe -i $TDIR/w$i)
5143                 [ $idx -ne 0 ] && continue
5144                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5145         done
5146         $LCTL get_param $proc_osc0/cur_dirty_bytes
5147         $LCTL get_param $proc_osc0/cur_grant_bytes
5148
5149         # perform the real test
5150         $LCTL set_param $proc_osc0/rpc_stats 0
5151         for ((;i<$files; i++)); do
5152                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5153                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5154         done
5155         sync
5156         $LCTL get_param $proc_osc0/rpc_stats
5157
5158         local percent=0
5159         local have_ppr=false
5160         $LCTL get_param $proc_osc0/rpc_stats |
5161                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5162                         # skip lines until we are at the RPC histogram data
5163                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5164                         $have_ppr || continue
5165
5166                         # we only want the percent stat for < 16 pages
5167                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5168
5169                         percent=$((percent + WPCT))
5170                         if [[ $percent -gt 15 ]]; then
5171                                 error "less than 16-pages write RPCs" \
5172                                       "$percent% > 15%"
5173                                 break
5174                         fi
5175                 done
5176         rm -rf $TDIR
5177 }
5178 run_test 42e "verify sub-RPC writes are not done synchronously"
5179
5180 test_43A() { # was test_43
5181         test_mkdir $DIR/$tdir
5182         cp -p /bin/ls $DIR/$tdir/$tfile
5183         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5184         pid=$!
5185         # give multiop a chance to open
5186         sleep 1
5187
5188         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5189         kill -USR1 $pid
5190         # Wait for multiop to exit
5191         wait $pid
5192 }
5193 run_test 43A "execution of file opened for write should return -ETXTBSY"
5194
5195 test_43a() {
5196         test_mkdir $DIR/$tdir
5197         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5198         $DIR/$tdir/sleep 60 &
5199         SLEEP_PID=$!
5200         # Make sure exec of $tdir/sleep wins race with truncate
5201         sleep 1
5202         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5203         kill $SLEEP_PID
5204 }
5205 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5206
5207 test_43b() {
5208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5209
5210         test_mkdir $DIR/$tdir
5211         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5212         $DIR/$tdir/sleep 60 &
5213         SLEEP_PID=$!
5214         # Make sure exec of $tdir/sleep wins race with truncate
5215         sleep 1
5216         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5217         kill $SLEEP_PID
5218 }
5219 run_test 43b "truncate of file being executed should return -ETXTBSY"
5220
5221 test_43c() {
5222         local testdir="$DIR/$tdir"
5223         test_mkdir $testdir
5224         cp $SHELL $testdir/
5225         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5226                 ( cd $testdir && md5sum -c )
5227 }
5228 run_test 43c "md5sum of copy into lustre"
5229
5230 test_44A() { # was test_44
5231         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5232
5233         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5234         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5235 }
5236 run_test 44A "zero length read from a sparse stripe"
5237
5238 test_44a() {
5239         local nstripe=$($LFS getstripe -c -d $DIR)
5240         [ -z "$nstripe" ] && skip "can't get stripe info"
5241         [[ $nstripe -gt $OSTCOUNT ]] &&
5242                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5243
5244         local stride=$($LFS getstripe -S -d $DIR)
5245         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5246                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5247         fi
5248
5249         OFFSETS="0 $((stride/2)) $((stride-1))"
5250         for offset in $OFFSETS; do
5251                 for i in $(seq 0 $((nstripe-1))); do
5252                         local GLOBALOFFSETS=""
5253                         # size in Bytes
5254                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5255                         local myfn=$DIR/d44a-$size
5256                         echo "--------writing $myfn at $size"
5257                         ll_sparseness_write $myfn $size ||
5258                                 error "ll_sparseness_write"
5259                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5260                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5261                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5262
5263                         for j in $(seq 0 $((nstripe-1))); do
5264                                 # size in Bytes
5265                                 size=$((((j + $nstripe )*$stride + $offset)))
5266                                 ll_sparseness_write $myfn $size ||
5267                                         error "ll_sparseness_write"
5268                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5269                         done
5270                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5271                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5272                         rm -f $myfn
5273                 done
5274         done
5275 }
5276 run_test 44a "test sparse pwrite ==============================="
5277
5278 dirty_osc_total() {
5279         tot=0
5280         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5281                 tot=$(($tot + $d))
5282         done
5283         echo $tot
5284 }
5285 do_dirty_record() {
5286         before=`dirty_osc_total`
5287         echo executing "\"$*\""
5288         eval $*
5289         after=`dirty_osc_total`
5290         echo before $before, after $after
5291 }
5292 test_45() {
5293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5294
5295         f="$DIR/f45"
5296         # Obtain grants from OST if it supports it
5297         echo blah > ${f}_grant
5298         stop_writeback
5299         sync
5300         do_dirty_record "echo blah > $f"
5301         [[ $before -eq $after ]] && error "write wasn't cached"
5302         do_dirty_record "> $f"
5303         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5304         do_dirty_record "echo blah > $f"
5305         [[ $before -eq $after ]] && error "write wasn't cached"
5306         do_dirty_record "sync"
5307         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5308         do_dirty_record "echo blah > $f"
5309         [[ $before -eq $after ]] && error "write wasn't cached"
5310         do_dirty_record "cancel_lru_locks osc"
5311         [[ $before -gt $after ]] ||
5312                 error "lock cancellation didn't lower dirty count"
5313         start_writeback
5314 }
5315 run_test 45 "osc io page accounting ============================"
5316
5317 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5318 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5319 # objects offset and an assert hit when an rpc was built with 1023's mapped
5320 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5321 test_46() {
5322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5323
5324         f="$DIR/f46"
5325         stop_writeback
5326         sync
5327         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5328         sync
5329         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5330         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5331         sync
5332         start_writeback
5333 }
5334 run_test 46 "dirtying a previously written page ================"
5335
5336 # test_47 is removed "Device nodes check" is moved to test_28
5337
5338 test_48a() { # bug 2399
5339         [ "$mds1_FSTYPE" = "zfs" ] &&
5340         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5341                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5342
5343         test_mkdir $DIR/$tdir
5344         cd $DIR/$tdir
5345         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5346         test_mkdir $DIR/$tdir
5347         touch foo || error "'touch foo' failed after recreating cwd"
5348         test_mkdir bar
5349         touch .foo || error "'touch .foo' failed after recreating cwd"
5350         test_mkdir .bar
5351         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5352         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5353         cd . || error "'cd .' failed after recreating cwd"
5354         mkdir . && error "'mkdir .' worked after recreating cwd"
5355         rmdir . && error "'rmdir .' worked after recreating cwd"
5356         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5357         cd .. || error "'cd ..' failed after recreating cwd"
5358 }
5359 run_test 48a "Access renamed working dir (should return errors)="
5360
5361 test_48b() { # bug 2399
5362         rm -rf $DIR/$tdir
5363         test_mkdir $DIR/$tdir
5364         cd $DIR/$tdir
5365         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5366         touch foo && error "'touch foo' worked after removing cwd"
5367         mkdir foo && error "'mkdir foo' worked after removing cwd"
5368         touch .foo && error "'touch .foo' worked after removing cwd"
5369         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5370         ls . > /dev/null && error "'ls .' worked after removing cwd"
5371         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5372         mkdir . && error "'mkdir .' worked after removing cwd"
5373         rmdir . && error "'rmdir .' worked after removing cwd"
5374         ln -s . foo && error "'ln -s .' worked after removing cwd"
5375         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5376 }
5377 run_test 48b "Access removed working dir (should return errors)="
5378
5379 test_48c() { # bug 2350
5380         #lctl set_param debug=-1
5381         #set -vx
5382         rm -rf $DIR/$tdir
5383         test_mkdir -p $DIR/$tdir/dir
5384         cd $DIR/$tdir/dir
5385         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5386         $TRACE touch foo && error "touch foo worked after removing cwd"
5387         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5388         touch .foo && error "touch .foo worked after removing cwd"
5389         mkdir .foo && error "mkdir .foo worked after removing cwd"
5390         $TRACE ls . && error "'ls .' worked after removing cwd"
5391         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5392         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5393         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5394         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5395         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5396 }
5397 run_test 48c "Access removed working subdir (should return errors)"
5398
5399 test_48d() { # bug 2350
5400         #lctl set_param debug=-1
5401         #set -vx
5402         rm -rf $DIR/$tdir
5403         test_mkdir -p $DIR/$tdir/dir
5404         cd $DIR/$tdir/dir
5405         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5406         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5407         $TRACE touch foo && error "'touch foo' worked after removing parent"
5408         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5409         touch .foo && error "'touch .foo' worked after removing parent"
5410         mkdir .foo && error "mkdir .foo worked after removing parent"
5411         $TRACE ls . && error "'ls .' worked after removing parent"
5412         $TRACE ls .. && error "'ls ..' worked after removing parent"
5413         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5414         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5415         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5416         true
5417 }
5418 run_test 48d "Access removed parent subdir (should return errors)"
5419
5420 test_48e() { # bug 4134
5421         #lctl set_param debug=-1
5422         #set -vx
5423         rm -rf $DIR/$tdir
5424         test_mkdir -p $DIR/$tdir/dir
5425         cd $DIR/$tdir/dir
5426         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5427         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5428         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5429         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5430         # On a buggy kernel addition of "touch foo" after cd .. will
5431         # produce kernel oops in lookup_hash_it
5432         touch ../foo && error "'cd ..' worked after recreate parent"
5433         cd $DIR
5434         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5435 }
5436 run_test 48e "Access to recreated parent subdir (should return errors)"
5437
5438 test_48f() {
5439         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5440                 skip "need MDS >= 2.13.55"
5441         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5442         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5443                 skip "needs different host for mdt1 mdt2"
5444         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5445
5446         $LFS mkdir -i0 $DIR/$tdir
5447         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5448
5449         for d in sub1 sub2 sub3; do
5450                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5451                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5452                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5453         done
5454
5455         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5456 }
5457 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5458
5459 test_49() { # LU-1030
5460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5461         remote_ost_nodsh && skip "remote OST with nodsh"
5462
5463         # get ost1 size - $FSNAME-OST0000
5464         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5465                 awk '{ print $4 }')
5466         # write 800M at maximum
5467         [[ $ost1_size -lt 2 ]] && ost1_size=2
5468         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5469
5470         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5471         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5472         local dd_pid=$!
5473
5474         # change max_pages_per_rpc while writing the file
5475         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5476         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5477         # loop until dd process exits
5478         while ps ax -opid | grep -wq $dd_pid; do
5479                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5480                 sleep $((RANDOM % 5 + 1))
5481         done
5482         # restore original max_pages_per_rpc
5483         $LCTL set_param $osc1_mppc=$orig_mppc
5484         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5485 }
5486 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5487
5488 test_50() {
5489         # bug 1485
5490         test_mkdir $DIR/$tdir
5491         cd $DIR/$tdir
5492         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5493 }
5494 run_test 50 "special situations: /proc symlinks  ==============="
5495
5496 test_51a() {    # was test_51
5497         # bug 1516 - create an empty entry right after ".." then split dir
5498         test_mkdir -c1 $DIR/$tdir
5499         touch $DIR/$tdir/foo
5500         $MCREATE $DIR/$tdir/bar
5501         rm $DIR/$tdir/foo
5502         createmany -m $DIR/$tdir/longfile 201
5503         FNUM=202
5504         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5505                 $MCREATE $DIR/$tdir/longfile$FNUM
5506                 FNUM=$(($FNUM + 1))
5507                 echo -n "+"
5508         done
5509         echo
5510         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5511 }
5512 run_test 51a "special situations: split htree with empty entry =="
5513
5514 cleanup_print_lfs_df () {
5515         trap 0
5516         $LFS df
5517         $LFS df -i
5518 }
5519
5520 test_51b() {
5521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5522
5523         local dir=$DIR/$tdir
5524         local nrdirs=$((65536 + 100))
5525
5526         # cleanup the directory
5527         rm -fr $dir
5528
5529         test_mkdir -c1 $dir
5530
5531         $LFS df
5532         $LFS df -i
5533         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5534         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5535         [[ $numfree -lt $nrdirs ]] &&
5536                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5537
5538         # need to check free space for the directories as well
5539         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5540         numfree=$(( blkfree / $(fs_inode_ksize) ))
5541         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5542
5543         trap cleanup_print_lfs_df EXIT
5544
5545         # create files
5546         createmany -d $dir/d $nrdirs || {
5547                 unlinkmany $dir/d $nrdirs
5548                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5549         }
5550
5551         # really created :
5552         nrdirs=$(ls -U $dir | wc -l)
5553
5554         # unlink all but 100 subdirectories, then check it still works
5555         local left=100
5556         local delete=$((nrdirs - left))
5557
5558         $LFS df
5559         $LFS df -i
5560
5561         # for ldiskfs the nlink count should be 1, but this is OSD specific
5562         # and so this is listed for informational purposes only
5563         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5564         unlinkmany -d $dir/d $delete ||
5565                 error "unlink of first $delete subdirs failed"
5566
5567         echo "nlink between: $(stat -c %h $dir)"
5568         local found=$(ls -U $dir | wc -l)
5569         [ $found -ne $left ] &&
5570                 error "can't find subdirs: found only $found, expected $left"
5571
5572         unlinkmany -d $dir/d $delete $left ||
5573                 error "unlink of second $left subdirs failed"
5574         # regardless of whether the backing filesystem tracks nlink accurately
5575         # or not, the nlink count shouldn't be more than "." and ".." here
5576         local after=$(stat -c %h $dir)
5577         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5578                 echo "nlink after: $after"
5579
5580         cleanup_print_lfs_df
5581 }
5582 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5583
5584 test_51d() {
5585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5586         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5587
5588         test_mkdir $DIR/$tdir
5589         createmany -o $DIR/$tdir/t- 1000
5590         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5591         for N in $(seq 0 $((OSTCOUNT - 1))); do
5592                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5593                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5594                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5595                         '($1 == '$N') { objs += 1 } \
5596                         END { printf("%0.0f", objs) }')
5597                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5598         done
5599         unlinkmany $DIR/$tdir/t- 1000
5600
5601         NLAST=0
5602         for N in $(seq 1 $((OSTCOUNT - 1))); do
5603                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5604                         error "OST $N has less objects vs OST $NLAST" \
5605                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5606                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5607                         error "OST $N has less objects vs OST $NLAST" \
5608                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5609
5610                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5611                         error "OST $N has less #0 objects vs OST $NLAST" \
5612                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5613                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5614                         error "OST $N has less #0 objects vs OST $NLAST" \
5615                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5616                 NLAST=$N
5617         done
5618         rm -f $TMP/$tfile
5619 }
5620 run_test 51d "check object distribution"
5621
5622 test_51e() {
5623         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5624                 skip_env "ldiskfs only test"
5625         fi
5626
5627         test_mkdir -c1 $DIR/$tdir
5628         test_mkdir -c1 $DIR/$tdir/d0
5629
5630         touch $DIR/$tdir/d0/foo
5631         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5632                 error "file exceed 65000 nlink limit!"
5633         unlinkmany $DIR/$tdir/d0/f- 65001
5634         return 0
5635 }
5636 run_test 51e "check file nlink limit"
5637
5638 test_51f() {
5639         test_mkdir $DIR/$tdir
5640
5641         local max=100000
5642         local ulimit_old=$(ulimit -n)
5643         local spare=20 # number of spare fd's for scripts/libraries, etc.
5644         local mdt=$($LFS getstripe -m $DIR/$tdir)
5645         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5646
5647         echo "MDT$mdt numfree=$numfree, max=$max"
5648         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5649         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5650                 while ! ulimit -n $((numfree + spare)); do
5651                         numfree=$((numfree * 3 / 4))
5652                 done
5653                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5654         else
5655                 echo "left ulimit at $ulimit_old"
5656         fi
5657
5658         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5659                 unlinkmany $DIR/$tdir/f $numfree
5660                 error "create+open $numfree files in $DIR/$tdir failed"
5661         }
5662         ulimit -n $ulimit_old
5663
5664         # if createmany exits at 120s there will be fewer than $numfree files
5665         unlinkmany $DIR/$tdir/f $numfree || true
5666 }
5667 run_test 51f "check many open files limit"
5668
5669 test_52a() {
5670         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5671         test_mkdir $DIR/$tdir
5672         touch $DIR/$tdir/foo
5673         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5674         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5675         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5676         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5677         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5678                                         error "link worked"
5679         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5680         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5681         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5682                                                      error "lsattr"
5683         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5684         cp -r $DIR/$tdir $TMP/
5685         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5686 }
5687 run_test 52a "append-only flag test (should return errors)"
5688
5689 test_52b() {
5690         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5691         test_mkdir $DIR/$tdir
5692         touch $DIR/$tdir/foo
5693         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5694         cat test > $DIR/$tdir/foo && error "cat test worked"
5695         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5696         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5697         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5698                                         error "link worked"
5699         echo foo >> $DIR/$tdir/foo && error "echo worked"
5700         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5701         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5702         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5703         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5704                                                         error "lsattr"
5705         chattr -i $DIR/$tdir/foo || error "chattr failed"
5706
5707         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5708 }
5709 run_test 52b "immutable flag test (should return errors) ======="
5710
5711 test_53() {
5712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5713         remote_mds_nodsh && skip "remote MDS with nodsh"
5714         remote_ost_nodsh && skip "remote OST with nodsh"
5715
5716         local param
5717         local param_seq
5718         local ostname
5719         local mds_last
5720         local mds_last_seq
5721         local ost_last
5722         local ost_last_seq
5723         local ost_last_id
5724         local ostnum
5725         local node
5726         local found=false
5727         local support_last_seq=true
5728
5729         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5730                 support_last_seq=false
5731
5732         # only test MDT0000
5733         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5734         local value
5735         for value in $(do_facet $SINGLEMDS \
5736                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5737                 param=$(echo ${value[0]} | cut -d "=" -f1)
5738                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5739
5740                 if $support_last_seq; then
5741                         param_seq=$(echo $param |
5742                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5743                         mds_last_seq=$(do_facet $SINGLEMDS \
5744                                        $LCTL get_param -n $param_seq)
5745                 fi
5746                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5747
5748                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5749                 node=$(facet_active_host ost$((ostnum+1)))
5750                 param="obdfilter.$ostname.last_id"
5751                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5752                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5753                         ost_last_id=$ost_last
5754
5755                         if $support_last_seq; then
5756                                 ost_last_id=$(echo $ost_last |
5757                                               awk -F':' '{print $2}' |
5758                                               sed -e "s/^0x//g")
5759                                 ost_last_seq=$(echo $ost_last |
5760                                                awk -F':' '{print $1}')
5761                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5762                         fi
5763
5764                         if [[ $ost_last_id != $mds_last ]]; then
5765                                 error "$ost_last_id != $mds_last"
5766                         else
5767                                 found=true
5768                                 break
5769                         fi
5770                 done
5771         done
5772         $found || error "can not match last_seq/last_id for $mdtosc"
5773         return 0
5774 }
5775 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5776
5777 test_54a() {
5778         perl -MSocket -e ';' || skip "no Socket perl module installed"
5779
5780         $SOCKETSERVER $DIR/socket ||
5781                 error "$SOCKETSERVER $DIR/socket failed: $?"
5782         $SOCKETCLIENT $DIR/socket ||
5783                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5784         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5785 }
5786 run_test 54a "unix domain socket test =========================="
5787
5788 test_54b() {
5789         f="$DIR/f54b"
5790         mknod $f c 1 3
5791         chmod 0666 $f
5792         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5793 }
5794 run_test 54b "char device works in lustre ======================"
5795
5796 find_loop_dev() {
5797         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5798         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5799         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5800
5801         for i in $(seq 3 7); do
5802                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5803                 LOOPDEV=$LOOPBASE$i
5804                 LOOPNUM=$i
5805                 break
5806         done
5807 }
5808
5809 cleanup_54c() {
5810         local rc=0
5811         loopdev="$DIR/loop54c"
5812
5813         trap 0
5814         $UMOUNT $DIR/$tdir || rc=$?
5815         losetup -d $loopdev || true
5816         losetup -d $LOOPDEV || true
5817         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5818         return $rc
5819 }
5820
5821 test_54c() {
5822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5823
5824         loopdev="$DIR/loop54c"
5825
5826         find_loop_dev
5827         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5828         trap cleanup_54c EXIT
5829         mknod $loopdev b 7 $LOOPNUM
5830         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5831         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5832         losetup $loopdev $DIR/$tfile ||
5833                 error "can't set up $loopdev for $DIR/$tfile"
5834         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5835         test_mkdir $DIR/$tdir
5836         mount -t ext2 $loopdev $DIR/$tdir ||
5837                 error "error mounting $loopdev on $DIR/$tdir"
5838         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5839                 error "dd write"
5840         df $DIR/$tdir
5841         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5842                 error "dd read"
5843         cleanup_54c
5844 }
5845 run_test 54c "block device works in lustre ====================="
5846
5847 test_54d() {
5848         f="$DIR/f54d"
5849         string="aaaaaa"
5850         mknod $f p
5851         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5852 }
5853 run_test 54d "fifo device works in lustre ======================"
5854
5855 test_54e() {
5856         f="$DIR/f54e"
5857         string="aaaaaa"
5858         cp -aL /dev/console $f
5859         echo $string > $f || error "echo $string to $f failed"
5860 }
5861 run_test 54e "console/tty device works in lustre ======================"
5862
5863 test_56a() {
5864         local numfiles=3
5865         local dir=$DIR/$tdir
5866
5867         rm -rf $dir
5868         test_mkdir -p $dir/dir
5869         for i in $(seq $numfiles); do
5870                 touch $dir/file$i
5871                 touch $dir/dir/file$i
5872         done
5873
5874         local numcomp=$($LFS getstripe --component-count $dir)
5875
5876         [[ $numcomp == 0 ]] && numcomp=1
5877
5878         # test lfs getstripe with --recursive
5879         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5880
5881         [[ $filenum -eq $((numfiles * 2)) ]] ||
5882                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5883         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5884         [[ $filenum -eq $numfiles ]] ||
5885                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5886         echo "$LFS getstripe showed obdidx or l_ost_idx"
5887
5888         # test lfs getstripe with file instead of dir
5889         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5890         [[ $filenum -eq 1 ]] ||
5891                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5892         echo "$LFS getstripe file1 passed"
5893
5894         #test lfs getstripe with --verbose
5895         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5896         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5897                 error "$LFS getstripe --verbose $dir: "\
5898                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5899         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5900                 error "$LFS getstripe $dir: showed lmm_magic"
5901
5902         #test lfs getstripe with -v prints lmm_fid
5903         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5904         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5905                 error "$LFS getstripe -v $dir: "\
5906                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5907         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5908                 error "$LFS getstripe $dir: showed lmm_fid by default"
5909         echo "$LFS getstripe --verbose passed"
5910
5911         #check for FID information
5912         local fid1=$($LFS getstripe --fid $dir/file1)
5913         local fid2=$($LFS getstripe --verbose $dir/file1 |
5914                      awk '/lmm_fid: / { print $2; exit; }')
5915         local fid3=$($LFS path2fid $dir/file1)
5916
5917         [ "$fid1" != "$fid2" ] &&
5918                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5919         [ "$fid1" != "$fid3" ] &&
5920                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5921         echo "$LFS getstripe --fid passed"
5922
5923         #test lfs getstripe with --obd
5924         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5925                 error "$LFS getstripe --obd wrong_uuid: should return error"
5926
5927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5928
5929         local ostidx=1
5930         local obduuid=$(ostuuid_from_index $ostidx)
5931         local found=$($LFS getstripe -r --obd $obduuid $dir |
5932                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5933
5934         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5935         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5936                 ((filenum--))
5937         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5938                 ((filenum--))
5939
5940         [[ $found -eq $filenum ]] ||
5941                 error "$LFS getstripe --obd: found $found expect $filenum"
5942         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5943                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5944                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5945                 error "$LFS getstripe --obd: should not show file on other obd"
5946         echo "$LFS getstripe --obd passed"
5947 }
5948 run_test 56a "check $LFS getstripe"
5949
5950 test_56b() {
5951         local dir=$DIR/$tdir
5952         local numdirs=3
5953
5954         test_mkdir $dir
5955         for i in $(seq $numdirs); do
5956                 test_mkdir $dir/dir$i
5957         done
5958
5959         # test lfs getdirstripe default mode is non-recursion, which is
5960         # different from lfs getstripe
5961         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5962
5963         [[ $dircnt -eq 1 ]] ||
5964                 error "$LFS getdirstripe: found $dircnt, not 1"
5965         dircnt=$($LFS getdirstripe --recursive $dir |
5966                 grep -c lmv_stripe_count)
5967         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5968                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5969 }
5970 run_test 56b "check $LFS getdirstripe"
5971
5972 test_56c() {
5973         remote_ost_nodsh && skip "remote OST with nodsh"
5974
5975         local ost_idx=0
5976         local ost_name=$(ostname_from_index $ost_idx)
5977         local old_status=$(ost_dev_status $ost_idx)
5978         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5979
5980         [[ -z "$old_status" ]] ||
5981                 skip_env "OST $ost_name is in $old_status status"
5982
5983         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5984         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5985                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5986         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5987                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5988                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5989         fi
5990
5991         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5992                 error "$LFS df -v showing inactive devices"
5993         sleep_maxage
5994
5995         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5996
5997         [[ "$new_status" =~ "D" ]] ||
5998                 error "$ost_name status is '$new_status', missing 'D'"
5999         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6000                 [[ "$new_status" =~ "N" ]] ||
6001                         error "$ost_name status is '$new_status', missing 'N'"
6002         fi
6003         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6004                 [[ "$new_status" =~ "f" ]] ||
6005                         error "$ost_name status is '$new_status', missing 'f'"
6006         fi
6007
6008         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6009         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6010                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6011         [[ -z "$p" ]] && restore_lustre_params < $p || true
6012         sleep_maxage
6013
6014         new_status=$(ost_dev_status $ost_idx)
6015         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6016                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6017         # can't check 'f' as devices may actually be on flash
6018 }
6019 run_test 56c "check 'lfs df' showing device status"
6020
6021 test_56d() {
6022         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6023         local osts=$($LFS df -v $MOUNT | grep -c OST)
6024
6025         $LFS df $MOUNT
6026
6027         (( mdts == MDSCOUNT )) ||
6028                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6029         (( osts == OSTCOUNT )) ||
6030                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6031 }
6032 run_test 56d "'lfs df -v' prints only configured devices"
6033
6034 NUMFILES=3
6035 NUMDIRS=3
6036 setup_56() {
6037         local local_tdir="$1"
6038         local local_numfiles="$2"
6039         local local_numdirs="$3"
6040         local dir_params="$4"
6041         local dir_stripe_params="$5"
6042
6043         if [ ! -d "$local_tdir" ] ; then
6044                 test_mkdir -p $dir_stripe_params $local_tdir
6045                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6046                 for i in $(seq $local_numfiles) ; do
6047                         touch $local_tdir/file$i
6048                 done
6049                 for i in $(seq $local_numdirs) ; do
6050                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6051                         for j in $(seq $local_numfiles) ; do
6052                                 touch $local_tdir/dir$i/file$j
6053                         done
6054                 done
6055         fi
6056 }
6057
6058 setup_56_special() {
6059         local local_tdir=$1
6060         local local_numfiles=$2
6061         local local_numdirs=$3
6062
6063         setup_56 $local_tdir $local_numfiles $local_numdirs
6064
6065         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6066                 for i in $(seq $local_numfiles) ; do
6067                         mknod $local_tdir/loop${i}b b 7 $i
6068                         mknod $local_tdir/null${i}c c 1 3
6069                         ln -s $local_tdir/file1 $local_tdir/link${i}
6070                 done
6071                 for i in $(seq $local_numdirs) ; do
6072                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6073                         mknod $local_tdir/dir$i/null${i}c c 1 3
6074                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6075                 done
6076         fi
6077 }
6078
6079 test_56g() {
6080         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6081         local expected=$(($NUMDIRS + 2))
6082
6083         setup_56 $dir $NUMFILES $NUMDIRS
6084
6085         # test lfs find with -name
6086         for i in $(seq $NUMFILES) ; do
6087                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6088
6089                 [ $nums -eq $expected ] ||
6090                         error "lfs find -name '*$i' $dir wrong: "\
6091                               "found $nums, expected $expected"
6092         done
6093 }
6094 run_test 56g "check lfs find -name"
6095
6096 test_56h() {
6097         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6098         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6099
6100         setup_56 $dir $NUMFILES $NUMDIRS
6101
6102         # test lfs find with ! -name
6103         for i in $(seq $NUMFILES) ; do
6104                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6105
6106                 [ $nums -eq $expected ] ||
6107                         error "lfs find ! -name '*$i' $dir wrong: "\
6108                               "found $nums, expected $expected"
6109         done
6110 }
6111 run_test 56h "check lfs find ! -name"
6112
6113 test_56i() {
6114         local dir=$DIR/$tdir
6115
6116         test_mkdir $dir
6117
6118         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6119         local out=$($cmd)
6120
6121         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6122 }
6123 run_test 56i "check 'lfs find -ost UUID' skips directories"
6124
6125 test_56j() {
6126         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6127
6128         setup_56_special $dir $NUMFILES $NUMDIRS
6129
6130         local expected=$((NUMDIRS + 1))
6131         local cmd="$LFS find -type d $dir"
6132         local nums=$($cmd | wc -l)
6133
6134         [ $nums -eq $expected ] ||
6135                 error "'$cmd' wrong: found $nums, expected $expected"
6136 }
6137 run_test 56j "check lfs find -type d"
6138
6139 test_56k() {
6140         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6141
6142         setup_56_special $dir $NUMFILES $NUMDIRS
6143
6144         local expected=$(((NUMDIRS + 1) * NUMFILES))
6145         local cmd="$LFS find -type f $dir"
6146         local nums=$($cmd | wc -l)
6147
6148         [ $nums -eq $expected ] ||
6149                 error "'$cmd' wrong: found $nums, expected $expected"
6150 }
6151 run_test 56k "check lfs find -type f"
6152
6153 test_56l() {
6154         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6155
6156         setup_56_special $dir $NUMFILES $NUMDIRS
6157
6158         local expected=$((NUMDIRS + NUMFILES))
6159         local cmd="$LFS find -type b $dir"
6160         local nums=$($cmd | wc -l)
6161
6162         [ $nums -eq $expected ] ||
6163                 error "'$cmd' wrong: found $nums, expected $expected"
6164 }
6165 run_test 56l "check lfs find -type b"
6166
6167 test_56m() {
6168         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6169
6170         setup_56_special $dir $NUMFILES $NUMDIRS
6171
6172         local expected=$((NUMDIRS + NUMFILES))
6173         local cmd="$LFS find -type c $dir"
6174         local nums=$($cmd | wc -l)
6175         [ $nums -eq $expected ] ||
6176                 error "'$cmd' wrong: found $nums, expected $expected"
6177 }
6178 run_test 56m "check lfs find -type c"
6179
6180 test_56n() {
6181         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6182         setup_56_special $dir $NUMFILES $NUMDIRS
6183
6184         local expected=$((NUMDIRS + NUMFILES))
6185         local cmd="$LFS find -type l $dir"
6186         local nums=$($cmd | wc -l)
6187
6188         [ $nums -eq $expected ] ||
6189                 error "'$cmd' wrong: found $nums, expected $expected"
6190 }
6191 run_test 56n "check lfs find -type l"
6192
6193 test_56o() {
6194         local dir=$DIR/$tdir
6195
6196         setup_56 $dir $NUMFILES $NUMDIRS
6197         utime $dir/file1 > /dev/null || error "utime (1)"
6198         utime $dir/file2 > /dev/null || error "utime (2)"
6199         utime $dir/dir1 > /dev/null || error "utime (3)"
6200         utime $dir/dir2 > /dev/null || error "utime (4)"
6201         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6202         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6203
6204         local expected=4
6205         local nums=$($LFS find -mtime +0 $dir | wc -l)
6206
6207         [ $nums -eq $expected ] ||
6208                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6209
6210         expected=12
6211         cmd="$LFS find -mtime 0 $dir"
6212         nums=$($cmd | wc -l)
6213         [ $nums -eq $expected ] ||
6214                 error "'$cmd' wrong: found $nums, expected $expected"
6215 }
6216 run_test 56o "check lfs find -mtime for old files"
6217
6218 test_56ob() {
6219         local dir=$DIR/$tdir
6220         local expected=1
6221         local count=0
6222
6223         # just to make sure there is something that won't be found
6224         test_mkdir $dir
6225         touch $dir/$tfile.now
6226
6227         for age in year week day hour min; do
6228                 count=$((count + 1))
6229
6230                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6231                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6232                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6233
6234                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6235                 local nums=$($cmd | wc -l)
6236                 [ $nums -eq $expected ] ||
6237                         error "'$cmd' wrong: found $nums, expected $expected"
6238
6239                 cmd="$LFS find $dir -atime $count${age:0:1}"
6240                 nums=$($cmd | wc -l)
6241                 [ $nums -eq $expected ] ||
6242                         error "'$cmd' wrong: found $nums, expected $expected"
6243         done
6244
6245         sleep 2
6246         cmd="$LFS find $dir -ctime +1s -type f"
6247         nums=$($cmd | wc -l)
6248         (( $nums == $count * 2 + 1)) ||
6249                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6250 }
6251 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6252
6253 test_newerXY_base() {
6254         local x=$1
6255         local y=$2
6256         local dir=$DIR/$tdir
6257         local ref
6258         local negref
6259
6260         if [ $y == "t" ]; then
6261                 if [ $x == "b" ]; then
6262                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6263                 else
6264                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6265                 fi
6266         else
6267                 ref=$DIR/$tfile.newer.$x$y
6268                 touch $ref || error "touch $ref failed"
6269         fi
6270
6271         echo "before = $ref"
6272         sleep 2
6273         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6274         sleep 2
6275         if [ $y == "t" ]; then
6276                 if [ $x == "b" ]; then
6277                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6278                 else
6279                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6280                 fi
6281         else
6282                 negref=$DIR/$tfile.negnewer.$x$y
6283                 touch $negref || error "touch $negref failed"
6284         fi
6285
6286         echo "after = $negref"
6287         local cmd="$LFS find $dir -newer$x$y $ref"
6288         local nums=$(eval $cmd | wc -l)
6289         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6290
6291         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6292                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6293
6294         cmd="$LFS find $dir ! -newer$x$y $negref"
6295         nums=$(eval $cmd | wc -l)
6296         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6297                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6298
6299         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6300         nums=$(eval $cmd | wc -l)
6301         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6302                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6303
6304         rm -rf $DIR/*
6305 }
6306
6307 test_56oc() {
6308         test_newerXY_base "a" "a"
6309         test_newerXY_base "a" "m"
6310         test_newerXY_base "a" "c"
6311         test_newerXY_base "m" "a"
6312         test_newerXY_base "m" "m"
6313         test_newerXY_base "m" "c"
6314         test_newerXY_base "c" "a"
6315         test_newerXY_base "c" "m"
6316         test_newerXY_base "c" "c"
6317
6318         [[ -n "$sles_version" ]] &&
6319                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6320
6321         test_newerXY_base "a" "t"
6322         test_newerXY_base "m" "t"
6323         test_newerXY_base "c" "t"
6324
6325         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6326            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6327                 ! btime_supported && echo "btime unsupported" && return 0
6328
6329         test_newerXY_base "b" "b"
6330         test_newerXY_base "b" "t"
6331 }
6332 run_test 56oc "check lfs find -newerXY work"
6333
6334 btime_supported() {
6335         local dir=$DIR/$tdir
6336         local rc
6337
6338         mkdir -p $dir
6339         touch $dir/$tfile
6340         $LFS find $dir -btime -1d -type f
6341         rc=$?
6342         rm -rf $dir
6343         return $rc
6344 }
6345
6346 test_56od() {
6347         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6348                 ! btime_supported && skip "btime unsupported on MDS"
6349
6350         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6351                 ! btime_supported && skip "btime unsupported on clients"
6352
6353         local dir=$DIR/$tdir
6354         local ref=$DIR/$tfile.ref
6355         local negref=$DIR/$tfile.negref
6356
6357         mkdir $dir || error "mkdir $dir failed"
6358         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6359         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6360         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6361         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6362         touch $ref || error "touch $ref failed"
6363         # sleep 3 seconds at least
6364         sleep 3
6365
6366         local before=$(do_facet mds1 date +%s)
6367         local skew=$(($(date +%s) - before + 1))
6368
6369         if (( skew < 0 && skew > -5 )); then
6370                 sleep $((0 - skew + 1))
6371                 skew=0
6372         fi
6373
6374         # Set the dir stripe params to limit files all on MDT0,
6375         # otherwise we need to calc the max clock skew between
6376         # the client and MDTs.
6377         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6378         sleep 2
6379         touch $negref || error "touch $negref failed"
6380
6381         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6382         local nums=$($cmd | wc -l)
6383         local expected=$(((NUMFILES + 1) * NUMDIRS))
6384
6385         [ $nums -eq $expected ] ||
6386                 error "'$cmd' wrong: found $nums, expected $expected"
6387
6388         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6389         nums=$($cmd | wc -l)
6390         expected=$((NUMFILES + 1))
6391         [ $nums -eq $expected ] ||
6392                 error "'$cmd' wrong: found $nums, expected $expected"
6393
6394         [ $skew -lt 0 ] && return
6395
6396         local after=$(do_facet mds1 date +%s)
6397         local age=$((after - before + 1 + skew))
6398
6399         cmd="$LFS find $dir -btime -${age}s -type f"
6400         nums=$($cmd | wc -l)
6401         expected=$(((NUMFILES + 1) * NUMDIRS))
6402
6403         echo "Clock skew between client and server: $skew, age:$age"
6404         [ $nums -eq $expected ] ||
6405                 error "'$cmd' wrong: found $nums, expected $expected"
6406
6407         expected=$(($NUMDIRS + 1))
6408         cmd="$LFS find $dir -btime -${age}s -type d"
6409         nums=$($cmd | wc -l)
6410         [ $nums -eq $expected ] ||
6411                 error "'$cmd' wrong: found $nums, expected $expected"
6412         rm -f $ref $negref || error "Failed to remove $ref $negref"
6413 }
6414 run_test 56od "check lfs find -btime with units"
6415
6416 test_56p() {
6417         [ $RUNAS_ID -eq $UID ] &&
6418                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6419
6420         local dir=$DIR/$tdir
6421
6422         setup_56 $dir $NUMFILES $NUMDIRS
6423         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6424
6425         local expected=$NUMFILES
6426         local cmd="$LFS find -uid $RUNAS_ID $dir"
6427         local nums=$($cmd | wc -l)
6428
6429         [ $nums -eq $expected ] ||
6430                 error "'$cmd' wrong: found $nums, expected $expected"
6431
6432         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6433         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6434         nums=$($cmd | wc -l)
6435         [ $nums -eq $expected ] ||
6436                 error "'$cmd' wrong: found $nums, expected $expected"
6437 }
6438 run_test 56p "check lfs find -uid and ! -uid"
6439
6440 test_56q() {
6441         [ $RUNAS_ID -eq $UID ] &&
6442                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6443
6444         local dir=$DIR/$tdir
6445
6446         setup_56 $dir $NUMFILES $NUMDIRS
6447         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6448
6449         local expected=$NUMFILES
6450         local cmd="$LFS find -gid $RUNAS_GID $dir"
6451         local nums=$($cmd | wc -l)
6452
6453         [ $nums -eq $expected ] ||
6454                 error "'$cmd' wrong: found $nums, expected $expected"
6455
6456         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6457         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6458         nums=$($cmd | wc -l)
6459         [ $nums -eq $expected ] ||
6460                 error "'$cmd' wrong: found $nums, expected $expected"
6461 }
6462 run_test 56q "check lfs find -gid and ! -gid"
6463
6464 test_56r() {
6465         local dir=$DIR/$tdir
6466
6467         setup_56 $dir $NUMFILES $NUMDIRS
6468
6469         local expected=12
6470         local cmd="$LFS find -size 0 -type f -lazy $dir"
6471         local nums=$($cmd | wc -l)
6472
6473         [ $nums -eq $expected ] ||
6474                 error "'$cmd' wrong: found $nums, expected $expected"
6475         cmd="$LFS find -size 0 -type f $dir"
6476         nums=$($cmd | wc -l)
6477         [ $nums -eq $expected ] ||
6478                 error "'$cmd' wrong: found $nums, expected $expected"
6479
6480         expected=0
6481         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6482         nums=$($cmd | wc -l)
6483         [ $nums -eq $expected ] ||
6484                 error "'$cmd' wrong: found $nums, expected $expected"
6485         cmd="$LFS find ! -size 0 -type f $dir"
6486         nums=$($cmd | wc -l)
6487         [ $nums -eq $expected ] ||
6488                 error "'$cmd' wrong: found $nums, expected $expected"
6489
6490         echo "test" > $dir/$tfile
6491         echo "test2" > $dir/$tfile.2 && sync
6492         expected=1
6493         cmd="$LFS find -size 5 -type f -lazy $dir"
6494         nums=$($cmd | wc -l)
6495         [ $nums -eq $expected ] ||
6496                 error "'$cmd' wrong: found $nums, expected $expected"
6497         cmd="$LFS find -size 5 -type f $dir"
6498         nums=$($cmd | wc -l)
6499         [ $nums -eq $expected ] ||
6500                 error "'$cmd' wrong: found $nums, expected $expected"
6501
6502         expected=1
6503         cmd="$LFS find -size +5 -type f -lazy $dir"
6504         nums=$($cmd | wc -l)
6505         [ $nums -eq $expected ] ||
6506                 error "'$cmd' wrong: found $nums, expected $expected"
6507         cmd="$LFS find -size +5 -type f $dir"
6508         nums=$($cmd | wc -l)
6509         [ $nums -eq $expected ] ||
6510                 error "'$cmd' wrong: found $nums, expected $expected"
6511
6512         expected=2
6513         cmd="$LFS find -size +0 -type f -lazy $dir"
6514         nums=$($cmd | wc -l)
6515         [ $nums -eq $expected ] ||
6516                 error "'$cmd' wrong: found $nums, expected $expected"
6517         cmd="$LFS find -size +0 -type f $dir"
6518         nums=$($cmd | wc -l)
6519         [ $nums -eq $expected ] ||
6520                 error "'$cmd' wrong: found $nums, expected $expected"
6521
6522         expected=2
6523         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6524         nums=$($cmd | wc -l)
6525         [ $nums -eq $expected ] ||
6526                 error "'$cmd' wrong: found $nums, expected $expected"
6527         cmd="$LFS find ! -size -5 -type f $dir"
6528         nums=$($cmd | wc -l)
6529         [ $nums -eq $expected ] ||
6530                 error "'$cmd' wrong: found $nums, expected $expected"
6531
6532         expected=12
6533         cmd="$LFS find -size -5 -type f -lazy $dir"
6534         nums=$($cmd | wc -l)
6535         [ $nums -eq $expected ] ||
6536                 error "'$cmd' wrong: found $nums, expected $expected"
6537         cmd="$LFS find -size -5 -type f $dir"
6538         nums=$($cmd | wc -l)
6539         [ $nums -eq $expected ] ||
6540                 error "'$cmd' wrong: found $nums, expected $expected"
6541 }
6542 run_test 56r "check lfs find -size works"
6543
6544 test_56ra_sub() {
6545         local expected=$1
6546         local glimpses=$2
6547         local cmd="$3"
6548
6549         cancel_lru_locks $OSC
6550
6551         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6552         local nums=$($cmd | wc -l)
6553
6554         [ $nums -eq $expected ] ||
6555                 error "'$cmd' wrong: found $nums, expected $expected"
6556
6557         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6558
6559         if (( rpcs_before + glimpses != rpcs_after )); then
6560                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6561                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6562
6563                 if [[ $glimpses == 0 ]]; then
6564                         error "'$cmd' should not send glimpse RPCs to OST"
6565                 else
6566                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6567                 fi
6568         fi
6569 }
6570
6571 test_56ra() {
6572         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6573                 skip "MDS < 2.12.58 doesn't return LSOM data"
6574         local dir=$DIR/$tdir
6575         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6576
6577         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6578
6579         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6580         $LCTL set_param -n llite.*.statahead_agl=0
6581         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6582
6583         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6584         # open and close all files to ensure LSOM is updated
6585         cancel_lru_locks $OSC
6586         find $dir -type f | xargs cat > /dev/null
6587
6588         #   expect_found  glimpse_rpcs  command_to_run
6589         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6590         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6591         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6592         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6593
6594         echo "test" > $dir/$tfile
6595         echo "test2" > $dir/$tfile.2 && sync
6596         cancel_lru_locks $OSC
6597         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6598
6599         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6600         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6601         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6602         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6603
6604         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6605         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6606         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6607         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6608         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6609         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6610 }
6611 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6612
6613 test_56rb() {
6614         local dir=$DIR/$tdir
6615         local tmp=$TMP/$tfile.log
6616         local mdt_idx;
6617
6618         test_mkdir -p $dir || error "failed to mkdir $dir"
6619         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6620                 error "failed to setstripe $dir/$tfile"
6621         mdt_idx=$($LFS getdirstripe -i $dir)
6622         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6623
6624         stack_trap "rm -f $tmp" EXIT
6625         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6626         ! grep -q obd_uuid $tmp ||
6627                 error "failed to find --size +100K --ost 0 $dir"
6628         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6629         ! grep -q obd_uuid $tmp ||
6630                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6631 }
6632 run_test 56rb "check lfs find --size --ost/--mdt works"
6633
6634 test_56s() { # LU-611 #LU-9369
6635         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6636
6637         local dir=$DIR/$tdir
6638         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6639
6640         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6641         for i in $(seq $NUMDIRS); do
6642                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6643         done
6644
6645         local expected=$NUMDIRS
6646         local cmd="$LFS find -c $OSTCOUNT $dir"
6647         local nums=$($cmd | wc -l)
6648
6649         [ $nums -eq $expected ] || {
6650                 $LFS getstripe -R $dir
6651                 error "'$cmd' wrong: found $nums, expected $expected"
6652         }
6653
6654         expected=$((NUMDIRS + onestripe))
6655         cmd="$LFS find -stripe-count +0 -type f $dir"
6656         nums=$($cmd | wc -l)
6657         [ $nums -eq $expected ] || {
6658                 $LFS getstripe -R $dir
6659                 error "'$cmd' wrong: found $nums, expected $expected"
6660         }
6661
6662         expected=$onestripe
6663         cmd="$LFS find -stripe-count 1 -type f $dir"
6664         nums=$($cmd | wc -l)
6665         [ $nums -eq $expected ] || {
6666                 $LFS getstripe -R $dir
6667                 error "'$cmd' wrong: found $nums, expected $expected"
6668         }
6669
6670         cmd="$LFS find -stripe-count -2 -type f $dir"
6671         nums=$($cmd | wc -l)
6672         [ $nums -eq $expected ] || {
6673                 $LFS getstripe -R $dir
6674                 error "'$cmd' wrong: found $nums, expected $expected"
6675         }
6676
6677         expected=0
6678         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6679         nums=$($cmd | wc -l)
6680         [ $nums -eq $expected ] || {
6681                 $LFS getstripe -R $dir
6682                 error "'$cmd' wrong: found $nums, expected $expected"
6683         }
6684 }
6685 run_test 56s "check lfs find -stripe-count works"
6686
6687 test_56t() { # LU-611 #LU-9369
6688         local dir=$DIR/$tdir
6689
6690         setup_56 $dir 0 $NUMDIRS
6691         for i in $(seq $NUMDIRS); do
6692                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6693         done
6694
6695         local expected=$NUMDIRS
6696         local cmd="$LFS find -S 8M $dir"
6697         local nums=$($cmd | wc -l)
6698
6699         [ $nums -eq $expected ] || {
6700                 $LFS getstripe -R $dir
6701                 error "'$cmd' wrong: found $nums, expected $expected"
6702         }
6703         rm -rf $dir
6704
6705         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6706
6707         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6708
6709         expected=$(((NUMDIRS + 1) * NUMFILES))
6710         cmd="$LFS find -stripe-size 512k -type f $dir"
6711         nums=$($cmd | wc -l)
6712         [ $nums -eq $expected ] ||
6713                 error "'$cmd' wrong: found $nums, expected $expected"
6714
6715         cmd="$LFS find -stripe-size +320k -type f $dir"
6716         nums=$($cmd | wc -l)
6717         [ $nums -eq $expected ] ||
6718                 error "'$cmd' wrong: found $nums, expected $expected"
6719
6720         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6721         cmd="$LFS find -stripe-size +200k -type f $dir"
6722         nums=$($cmd | wc -l)
6723         [ $nums -eq $expected ] ||
6724                 error "'$cmd' wrong: found $nums, expected $expected"
6725
6726         cmd="$LFS find -stripe-size -640k -type f $dir"
6727         nums=$($cmd | wc -l)
6728         [ $nums -eq $expected ] ||
6729                 error "'$cmd' wrong: found $nums, expected $expected"
6730
6731         expected=4
6732         cmd="$LFS find -stripe-size 256k -type f $dir"
6733         nums=$($cmd | wc -l)
6734         [ $nums -eq $expected ] ||
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736
6737         cmd="$LFS find -stripe-size -320k -type f $dir"
6738         nums=$($cmd | wc -l)
6739         [ $nums -eq $expected ] ||
6740                 error "'$cmd' wrong: found $nums, expected $expected"
6741
6742         expected=0
6743         cmd="$LFS find -stripe-size 1024k -type f $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] ||
6746                 error "'$cmd' wrong: found $nums, expected $expected"
6747 }
6748 run_test 56t "check lfs find -stripe-size works"
6749
6750 test_56u() { # LU-611
6751         local dir=$DIR/$tdir
6752
6753         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6754
6755         if [[ $OSTCOUNT -gt 1 ]]; then
6756                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6757                 onestripe=4
6758         else
6759                 onestripe=0
6760         fi
6761
6762         local expected=$(((NUMDIRS + 1) * NUMFILES))
6763         local cmd="$LFS find -stripe-index 0 -type f $dir"
6764         local nums=$($cmd | wc -l)
6765
6766         [ $nums -eq $expected ] ||
6767                 error "'$cmd' wrong: found $nums, expected $expected"
6768
6769         expected=$onestripe
6770         cmd="$LFS find -stripe-index 1 -type f $dir"
6771         nums=$($cmd | wc -l)
6772         [ $nums -eq $expected ] ||
6773                 error "'$cmd' wrong: found $nums, expected $expected"
6774
6775         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6776         nums=$($cmd | wc -l)
6777         [ $nums -eq $expected ] ||
6778                 error "'$cmd' wrong: found $nums, expected $expected"
6779
6780         expected=0
6781         # This should produce an error and not return any files
6782         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6783         nums=$($cmd 2>/dev/null | wc -l)
6784         [ $nums -eq $expected ] ||
6785                 error "'$cmd' wrong: found $nums, expected $expected"
6786
6787         if [[ $OSTCOUNT -gt 1 ]]; then
6788                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6789                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6790                 nums=$($cmd | wc -l)
6791                 [ $nums -eq $expected ] ||
6792                         error "'$cmd' wrong: found $nums, expected $expected"
6793         fi
6794 }
6795 run_test 56u "check lfs find -stripe-index works"
6796
6797 test_56v() {
6798         local mdt_idx=0
6799         local dir=$DIR/$tdir
6800
6801         setup_56 $dir $NUMFILES $NUMDIRS
6802
6803         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6804         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6805
6806         for file in $($LFS find -m $UUID $dir); do
6807                 file_midx=$($LFS getstripe -m $file)
6808                 [ $file_midx -eq $mdt_idx ] ||
6809                         error "lfs find -m $UUID != getstripe -m $file_midx"
6810         done
6811 }
6812 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6813
6814 test_56w() {
6815         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6817
6818         local dir=$DIR/$tdir
6819
6820         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6821
6822         local stripe_size=$($LFS getstripe -S -d $dir) ||
6823                 error "$LFS getstripe -S -d $dir failed"
6824         stripe_size=${stripe_size%% *}
6825
6826         local file_size=$((stripe_size * OSTCOUNT))
6827         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6828         local required_space=$((file_num * file_size))
6829         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6830                            head -n1)
6831         [[ $free_space -le $((required_space / 1024)) ]] &&
6832                 skip_env "need $required_space, have $free_space kbytes"
6833
6834         local dd_bs=65536
6835         local dd_count=$((file_size / dd_bs))
6836
6837         # write data into the files
6838         local i
6839         local j
6840         local file
6841
6842         for i in $(seq $NUMFILES); do
6843                 file=$dir/file$i
6844                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6845                         error "write data into $file failed"
6846         done
6847         for i in $(seq $NUMDIRS); do
6848                 for j in $(seq $NUMFILES); do
6849                         file=$dir/dir$i/file$j
6850                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6851                                 error "write data into $file failed"
6852                 done
6853         done
6854
6855         # $LFS_MIGRATE will fail if hard link migration is unsupported
6856         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6857                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6858                         error "creating links to $dir/dir1/file1 failed"
6859         fi
6860
6861         local expected=-1
6862
6863         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6864
6865         # lfs_migrate file
6866         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6867
6868         echo "$cmd"
6869         eval $cmd || error "$cmd failed"
6870
6871         check_stripe_count $dir/file1 $expected
6872
6873         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6874         then
6875                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6876                 # OST 1 if it is on OST 0. This file is small enough to
6877                 # be on only one stripe.
6878                 file=$dir/migr_1_ost
6879                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6880                         error "write data into $file failed"
6881                 local obdidx=$($LFS getstripe -i $file)
6882                 local oldmd5=$(md5sum $file)
6883                 local newobdidx=0
6884
6885                 [[ $obdidx -eq 0 ]] && newobdidx=1
6886                 cmd="$LFS migrate -i $newobdidx $file"
6887                 echo $cmd
6888                 eval $cmd || error "$cmd failed"
6889
6890                 local realobdix=$($LFS getstripe -i $file)
6891                 local newmd5=$(md5sum $file)
6892
6893                 [[ $newobdidx -ne $realobdix ]] &&
6894                         error "new OST is different (was=$obdidx, "\
6895                               "wanted=$newobdidx, got=$realobdix)"
6896                 [[ "$oldmd5" != "$newmd5" ]] &&
6897                         error "md5sum differ: $oldmd5, $newmd5"
6898         fi
6899
6900         # lfs_migrate dir
6901         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6902         echo "$cmd"
6903         eval $cmd || error "$cmd failed"
6904
6905         for j in $(seq $NUMFILES); do
6906                 check_stripe_count $dir/dir1/file$j $expected
6907         done
6908
6909         # lfs_migrate works with lfs find
6910         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6911              $LFS_MIGRATE -y -c $expected"
6912         echo "$cmd"
6913         eval $cmd || error "$cmd failed"
6914
6915         for i in $(seq 2 $NUMFILES); do
6916                 check_stripe_count $dir/file$i $expected
6917         done
6918         for i in $(seq 2 $NUMDIRS); do
6919                 for j in $(seq $NUMFILES); do
6920                 check_stripe_count $dir/dir$i/file$j $expected
6921                 done
6922         done
6923 }
6924 run_test 56w "check lfs_migrate -c stripe_count works"
6925
6926 test_56wb() {
6927         local file1=$DIR/$tdir/file1
6928         local create_pool=false
6929         local initial_pool=$($LFS getstripe -p $DIR)
6930         local pool_list=()
6931         local pool=""
6932
6933         echo -n "Creating test dir..."
6934         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6935         echo "done."
6936
6937         echo -n "Creating test file..."
6938         touch $file1 || error "cannot create file"
6939         echo "done."
6940
6941         echo -n "Detecting existing pools..."
6942         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6943
6944         if [ ${#pool_list[@]} -gt 0 ]; then
6945                 echo "${pool_list[@]}"
6946                 for thispool in "${pool_list[@]}"; do
6947                         if [[ -z "$initial_pool" ||
6948                               "$initial_pool" != "$thispool" ]]; then
6949                                 pool="$thispool"
6950                                 echo "Using existing pool '$pool'"
6951                                 break
6952                         fi
6953                 done
6954         else
6955                 echo "none detected."
6956         fi
6957         if [ -z "$pool" ]; then
6958                 pool=${POOL:-testpool}
6959                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6960                 echo -n "Creating pool '$pool'..."
6961                 create_pool=true
6962                 pool_add $pool &> /dev/null ||
6963                         error "pool_add failed"
6964                 echo "done."
6965
6966                 echo -n "Adding target to pool..."
6967                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6968                         error "pool_add_targets failed"
6969                 echo "done."
6970         fi
6971
6972         echo -n "Setting pool using -p option..."
6973         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6974                 error "migrate failed rc = $?"
6975         echo "done."
6976
6977         echo -n "Verifying test file is in pool after migrating..."
6978         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6979                 error "file was not migrated to pool $pool"
6980         echo "done."
6981
6982         echo -n "Removing test file from pool '$pool'..."
6983         # "lfs migrate $file" won't remove the file from the pool
6984         # until some striping information is changed.
6985         $LFS migrate -c 1 $file1 &> /dev/null ||
6986                 error "cannot remove from pool"
6987         [ "$($LFS getstripe -p $file1)" ] &&
6988                 error "pool still set"
6989         echo "done."
6990
6991         echo -n "Setting pool using --pool option..."
6992         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6993                 error "migrate failed rc = $?"
6994         echo "done."
6995
6996         # Clean up
6997         rm -f $file1
6998         if $create_pool; then
6999                 destroy_test_pools 2> /dev/null ||
7000                         error "destroy test pools failed"
7001         fi
7002 }
7003 run_test 56wb "check lfs_migrate pool support"
7004
7005 test_56wc() {
7006         local file1="$DIR/$tdir/file1"
7007         local parent_ssize
7008         local parent_scount
7009         local cur_ssize
7010         local cur_scount
7011         local orig_ssize
7012
7013         echo -n "Creating test dir..."
7014         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7015         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7016                 error "cannot set stripe by '-S 1M -c 1'"
7017         echo "done"
7018
7019         echo -n "Setting initial stripe for test file..."
7020         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7021                 error "cannot set stripe"
7022         cur_ssize=$($LFS getstripe -S "$file1")
7023         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7024         echo "done."
7025
7026         # File currently set to -S 512K -c 1
7027
7028         # Ensure -c and -S options are rejected when -R is set
7029         echo -n "Verifying incompatible options are detected..."
7030         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7031                 error "incompatible -c and -R options not detected"
7032         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7033                 error "incompatible -S and -R options not detected"
7034         echo "done."
7035
7036         # Ensure unrecognized options are passed through to 'lfs migrate'
7037         echo -n "Verifying -S option is passed through to lfs migrate..."
7038         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7039                 error "migration failed"
7040         cur_ssize=$($LFS getstripe -S "$file1")
7041         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7042         echo "done."
7043
7044         # File currently set to -S 1M -c 1
7045
7046         # Ensure long options are supported
7047         echo -n "Verifying long options supported..."
7048         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7049                 error "long option without argument not supported"
7050         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7051                 error "long option with argument not supported"
7052         cur_ssize=$($LFS getstripe -S "$file1")
7053         [ $cur_ssize -eq 524288 ] ||
7054                 error "migrate --stripe-size $cur_ssize != 524288"
7055         echo "done."
7056
7057         # File currently set to -S 512K -c 1
7058
7059         if [ "$OSTCOUNT" -gt 1 ]; then
7060                 echo -n "Verifying explicit stripe count can be set..."
7061                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7062                         error "migrate failed"
7063                 cur_scount=$($LFS getstripe -c "$file1")
7064                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7065                 echo "done."
7066         fi
7067
7068         # File currently set to -S 512K -c 1 or -S 512K -c 2
7069
7070         # Ensure parent striping is used if -R is set, and no stripe
7071         # count or size is specified
7072         echo -n "Setting stripe for parent directory..."
7073         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7074                 error "cannot set stripe '-S 2M -c 1'"
7075         echo "done."
7076
7077         echo -n "Verifying restripe option uses parent stripe settings..."
7078         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7079         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7080         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7081                 error "migrate failed"
7082         cur_ssize=$($LFS getstripe -S "$file1")
7083         [ $cur_ssize -eq $parent_ssize ] ||
7084                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7085         cur_scount=$($LFS getstripe -c "$file1")
7086         [ $cur_scount -eq $parent_scount ] ||
7087                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7088         echo "done."
7089
7090         # File currently set to -S 1M -c 1
7091
7092         # Ensure striping is preserved if -R is not set, and no stripe
7093         # count or size is specified
7094         echo -n "Verifying striping size preserved when not specified..."
7095         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7096         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7097                 error "cannot set stripe on parent directory"
7098         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7099                 error "migrate failed"
7100         cur_ssize=$($LFS getstripe -S "$file1")
7101         [ $cur_ssize -eq $orig_ssize ] ||
7102                 error "migrate by default $cur_ssize != $orig_ssize"
7103         echo "done."
7104
7105         # Ensure file name properly detected when final option has no argument
7106         echo -n "Verifying file name properly detected..."
7107         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7108                 error "file name interpreted as option argument"
7109         echo "done."
7110
7111         # Clean up
7112         rm -f "$file1"
7113 }
7114 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7115
7116 test_56wd() {
7117         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7118
7119         local file1=$DIR/$tdir/file1
7120
7121         echo -n "Creating test dir..."
7122         test_mkdir $DIR/$tdir || error "cannot create dir"
7123         echo "done."
7124
7125         echo -n "Creating test file..."
7126         touch $file1
7127         echo "done."
7128
7129         # Ensure 'lfs migrate' will fail by using a non-existent option,
7130         # and make sure rsync is not called to recover
7131         echo -n "Make sure --no-rsync option works..."
7132         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7133                 grep -q 'refusing to fall back to rsync' ||
7134                 error "rsync was called with --no-rsync set"
7135         echo "done."
7136
7137         # Ensure rsync is called without trying 'lfs migrate' first
7138         echo -n "Make sure --rsync option works..."
7139         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7140                 grep -q 'falling back to rsync' &&
7141                 error "lfs migrate was called with --rsync set"
7142         echo "done."
7143
7144         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7145         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7146                 grep -q 'at the same time' ||
7147                 error "--rsync and --no-rsync accepted concurrently"
7148         echo "done."
7149
7150         # Clean up
7151         rm -f $file1
7152 }
7153 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7154
7155 test_56we() {
7156         local td=$DIR/$tdir
7157         local tf=$td/$tfile
7158
7159         test_mkdir $td || error "cannot create $td"
7160         touch $tf || error "cannot touch $tf"
7161
7162         echo -n "Make sure --non-direct|-D works..."
7163         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7164                 grep -q "lfs migrate --non-direct" ||
7165                 error "--non-direct option cannot work correctly"
7166         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7167                 grep -q "lfs migrate -D" ||
7168                 error "-D option cannot work correctly"
7169         echo "done."
7170 }
7171 run_test 56we "check lfs_migrate --non-direct|-D support"
7172
7173 test_56x() {
7174         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7175         check_swap_layouts_support
7176
7177         local dir=$DIR/$tdir
7178         local ref1=/etc/passwd
7179         local file1=$dir/file1
7180
7181         test_mkdir $dir || error "creating dir $dir"
7182         $LFS setstripe -c 2 $file1
7183         cp $ref1 $file1
7184         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7185         stripe=$($LFS getstripe -c $file1)
7186         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7187         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7188
7189         # clean up
7190         rm -f $file1
7191 }
7192 run_test 56x "lfs migration support"
7193
7194 test_56xa() {
7195         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7196         check_swap_layouts_support
7197
7198         local dir=$DIR/$tdir/$testnum
7199
7200         test_mkdir -p $dir
7201
7202         local ref1=/etc/passwd
7203         local file1=$dir/file1
7204
7205         $LFS setstripe -c 2 $file1
7206         cp $ref1 $file1
7207         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7208
7209         local stripe=$($LFS getstripe -c $file1)
7210
7211         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7212         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7213
7214         # clean up
7215         rm -f $file1
7216 }
7217 run_test 56xa "lfs migration --block support"
7218
7219 check_migrate_links() {
7220         local dir="$1"
7221         local file1="$dir/file1"
7222         local begin="$2"
7223         local count="$3"
7224         local runas="$4"
7225         local total_count=$(($begin + $count - 1))
7226         local symlink_count=10
7227         local uniq_count=10
7228
7229         if [ ! -f "$file1" ]; then
7230                 echo -n "creating initial file..."
7231                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7232                         error "cannot setstripe initial file"
7233                 echo "done"
7234
7235                 echo -n "creating symlinks..."
7236                 for s in $(seq 1 $symlink_count); do
7237                         ln -s "$file1" "$dir/slink$s" ||
7238                                 error "cannot create symlinks"
7239                 done
7240                 echo "done"
7241
7242                 echo -n "creating nonlinked files..."
7243                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7244                         error "cannot create nonlinked files"
7245                 echo "done"
7246         fi
7247
7248         # create hard links
7249         if [ ! -f "$dir/file$total_count" ]; then
7250                 echo -n "creating hard links $begin:$total_count..."
7251                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7252                         /dev/null || error "cannot create hard links"
7253                 echo "done"
7254         fi
7255
7256         echo -n "checking number of hard links listed in xattrs..."
7257         local fid=$($LFS getstripe -F "$file1")
7258         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7259
7260         echo "${#paths[*]}"
7261         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7262                         skip "hard link list has unexpected size, skipping test"
7263         fi
7264         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7265                         error "link names should exceed xattrs size"
7266         fi
7267
7268         echo -n "migrating files..."
7269         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7270         local rc=$?
7271         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7272         echo "done"
7273
7274         # make sure all links have been properly migrated
7275         echo -n "verifying files..."
7276         fid=$($LFS getstripe -F "$file1") ||
7277                 error "cannot get fid for file $file1"
7278         for i in $(seq 2 $total_count); do
7279                 local fid2=$($LFS getstripe -F $dir/file$i)
7280
7281                 [ "$fid2" == "$fid" ] ||
7282                         error "migrated hard link has mismatched FID"
7283         done
7284
7285         # make sure hard links were properly detected, and migration was
7286         # performed only once for the entire link set; nonlinked files should
7287         # also be migrated
7288         local actual=$(grep -c 'done' <<< "$migrate_out")
7289         local expected=$(($uniq_count + 1))
7290
7291         [ "$actual" -eq  "$expected" ] ||
7292                 error "hard links individually migrated ($actual != $expected)"
7293
7294         # make sure the correct number of hard links are present
7295         local hardlinks=$(stat -c '%h' "$file1")
7296
7297         [ $hardlinks -eq $total_count ] ||
7298                 error "num hard links $hardlinks != $total_count"
7299         echo "done"
7300
7301         return 0
7302 }
7303
7304 test_56xb() {
7305         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7306                 skip "Need MDS version at least 2.10.55"
7307
7308         local dir="$DIR/$tdir"
7309
7310         test_mkdir "$dir" || error "cannot create dir $dir"
7311
7312         echo "testing lfs migrate mode when all links fit within xattrs"
7313         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7314
7315         echo "testing rsync mode when all links fit within xattrs"
7316         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7317
7318         echo "testing lfs migrate mode when all links do not fit within xattrs"
7319         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7320
7321         echo "testing rsync mode when all links do not fit within xattrs"
7322         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7323
7324         chown -R $RUNAS_ID $dir
7325         echo "testing non-root lfs migrate mode when not all links are in xattr"
7326         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7327
7328         # clean up
7329         rm -rf $dir
7330 }
7331 run_test 56xb "lfs migration hard link support"
7332
7333 test_56xc() {
7334         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7335
7336         local dir="$DIR/$tdir"
7337
7338         test_mkdir "$dir" || error "cannot create dir $dir"
7339
7340         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7341         echo -n "Setting initial stripe for 20MB test file..."
7342         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7343                 error "cannot setstripe 20MB file"
7344         echo "done"
7345         echo -n "Sizing 20MB test file..."
7346         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7347         echo "done"
7348         echo -n "Verifying small file autostripe count is 1..."
7349         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7350                 error "cannot migrate 20MB file"
7351         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7352                 error "cannot get stripe for $dir/20mb"
7353         [ $stripe_count -eq 1 ] ||
7354                 error "unexpected stripe count $stripe_count for 20MB file"
7355         rm -f "$dir/20mb"
7356         echo "done"
7357
7358         # Test 2: File is small enough to fit within the available space on
7359         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7360         # have at least an additional 1KB for each desired stripe for test 3
7361         echo -n "Setting stripe for 1GB test file..."
7362         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7363         echo "done"
7364         echo -n "Sizing 1GB test file..."
7365         # File size is 1GB + 3KB
7366         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7367         echo "done"
7368
7369         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7370         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7371         if (( avail > 524288 * OSTCOUNT )); then
7372                 echo -n "Migrating 1GB file..."
7373                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7374                         error "cannot migrate 1GB file"
7375                 echo "done"
7376                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7377                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7378                         error "cannot getstripe for 1GB file"
7379                 [ $stripe_count -eq 2 ] ||
7380                         error "unexpected stripe count $stripe_count != 2"
7381                 echo "done"
7382         fi
7383
7384         # Test 3: File is too large to fit within the available space on
7385         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7386         if [ $OSTCOUNT -ge 3 ]; then
7387                 # The required available space is calculated as
7388                 # file size (1GB + 3KB) / OST count (3).
7389                 local kb_per_ost=349526
7390
7391                 echo -n "Migrating 1GB file with limit..."
7392                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7393                         error "cannot migrate 1GB file with limit"
7394                 echo "done"
7395
7396                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7397                 echo -n "Verifying 1GB autostripe count with limited space..."
7398                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7399                         error "unexpected stripe count $stripe_count (min 3)"
7400                 echo "done"
7401         fi
7402
7403         # clean up
7404         rm -rf $dir
7405 }
7406 run_test 56xc "lfs migration autostripe"
7407
7408 test_56xd() {
7409         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7410
7411         local dir=$DIR/$tdir
7412         local f_mgrt=$dir/$tfile.mgrt
7413         local f_yaml=$dir/$tfile.yaml
7414         local f_copy=$dir/$tfile.copy
7415         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7416         local layout_copy="-c 2 -S 2M -i 1"
7417         local yamlfile=$dir/yamlfile
7418         local layout_before;
7419         local layout_after;
7420
7421         test_mkdir "$dir" || error "cannot create dir $dir"
7422         $LFS setstripe $layout_yaml $f_yaml ||
7423                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7424         $LFS getstripe --yaml $f_yaml > $yamlfile
7425         $LFS setstripe $layout_copy $f_copy ||
7426                 error "cannot setstripe $f_copy with layout $layout_copy"
7427         touch $f_mgrt
7428         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7429
7430         # 1. test option --yaml
7431         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7432                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7433         layout_before=$(get_layout_param $f_yaml)
7434         layout_after=$(get_layout_param $f_mgrt)
7435         [ "$layout_after" == "$layout_before" ] ||
7436                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7437
7438         # 2. test option --copy
7439         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7440                 error "cannot migrate $f_mgrt with --copy $f_copy"
7441         layout_before=$(get_layout_param $f_copy)
7442         layout_after=$(get_layout_param $f_mgrt)
7443         [ "$layout_after" == "$layout_before" ] ||
7444                 error "lfs_migrate --copy: $layout_after != $layout_before"
7445 }
7446 run_test 56xd "check lfs_migrate --yaml and --copy support"
7447
7448 test_56xe() {
7449         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7450
7451         local dir=$DIR/$tdir
7452         local f_comp=$dir/$tfile
7453         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7454         local layout_before=""
7455         local layout_after=""
7456
7457         test_mkdir "$dir" || error "cannot create dir $dir"
7458         $LFS setstripe $layout $f_comp ||
7459                 error "cannot setstripe $f_comp with layout $layout"
7460         layout_before=$(get_layout_param $f_comp)
7461         dd if=/dev/zero of=$f_comp bs=1M count=4
7462
7463         # 1. migrate a comp layout file by lfs_migrate
7464         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7465         layout_after=$(get_layout_param $f_comp)
7466         [ "$layout_before" == "$layout_after" ] ||
7467                 error "lfs_migrate: $layout_before != $layout_after"
7468
7469         # 2. migrate a comp layout file by lfs migrate
7470         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7471         layout_after=$(get_layout_param $f_comp)
7472         [ "$layout_before" == "$layout_after" ] ||
7473                 error "lfs migrate: $layout_before != $layout_after"
7474 }
7475 run_test 56xe "migrate a composite layout file"
7476
7477 test_56xf() {
7478         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7479
7480         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7481                 skip "Need server version at least 2.13.53"
7482
7483         local dir=$DIR/$tdir
7484         local f_comp=$dir/$tfile
7485         local layout="-E 1M -c1 -E -1 -c2"
7486         local fid_before=""
7487         local fid_after=""
7488
7489         test_mkdir "$dir" || error "cannot create dir $dir"
7490         $LFS setstripe $layout $f_comp ||
7491                 error "cannot setstripe $f_comp with layout $layout"
7492         fid_before=$($LFS getstripe --fid $f_comp)
7493         dd if=/dev/zero of=$f_comp bs=1M count=4
7494
7495         # 1. migrate a comp layout file to a comp layout
7496         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7497         fid_after=$($LFS getstripe --fid $f_comp)
7498         [ "$fid_before" == "$fid_after" ] ||
7499                 error "comp-to-comp migrate: $fid_before != $fid_after"
7500
7501         # 2. migrate a comp layout file to a plain layout
7502         $LFS migrate -c2 $f_comp ||
7503                 error "cannot migrate $f_comp by lfs migrate"
7504         fid_after=$($LFS getstripe --fid $f_comp)
7505         [ "$fid_before" == "$fid_after" ] ||
7506                 error "comp-to-plain migrate: $fid_before != $fid_after"
7507
7508         # 3. migrate a plain layout file to a comp layout
7509         $LFS migrate $layout $f_comp ||
7510                 error "cannot migrate $f_comp by lfs migrate"
7511         fid_after=$($LFS getstripe --fid $f_comp)
7512         [ "$fid_before" == "$fid_after" ] ||
7513                 error "plain-to-comp migrate: $fid_before != $fid_after"
7514 }
7515 run_test 56xf "FID is not lost during migration of a composite layout file"
7516
7517 test_56y() {
7518         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7519                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7520
7521         local res=""
7522         local dir=$DIR/$tdir
7523         local f1=$dir/file1
7524         local f2=$dir/file2
7525
7526         test_mkdir -p $dir || error "creating dir $dir"
7527         touch $f1 || error "creating std file $f1"
7528         $MULTIOP $f2 H2c || error "creating released file $f2"
7529
7530         # a directory can be raid0, so ask only for files
7531         res=$($LFS find $dir -L raid0 -type f | wc -l)
7532         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7533
7534         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7535         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7536
7537         # only files can be released, so no need to force file search
7538         res=$($LFS find $dir -L released)
7539         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7540
7541         res=$($LFS find $dir -type f \! -L released)
7542         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7543 }
7544 run_test 56y "lfs find -L raid0|released"
7545
7546 test_56z() { # LU-4824
7547         # This checks to make sure 'lfs find' continues after errors
7548         # There are two classes of errors that should be caught:
7549         # - If multiple paths are provided, all should be searched even if one
7550         #   errors out
7551         # - If errors are encountered during the search, it should not terminate
7552         #   early
7553         local dir=$DIR/$tdir
7554         local i
7555
7556         test_mkdir $dir
7557         for i in d{0..9}; do
7558                 test_mkdir $dir/$i
7559                 touch $dir/$i/$tfile
7560         done
7561         $LFS find $DIR/non_existent_dir $dir &&
7562                 error "$LFS find did not return an error"
7563         # Make a directory unsearchable. This should NOT be the last entry in
7564         # directory order.  Arbitrarily pick the 6th entry
7565         chmod 700 $($LFS find $dir -type d | sed '6!d')
7566
7567         $RUNAS $LFS find $DIR/non_existent $dir
7568         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7569
7570         # The user should be able to see 10 directories and 9 files
7571         (( count == 19 )) ||
7572                 error "$LFS find found $count != 19 entries after error"
7573 }
7574 run_test 56z "lfs find should continue after an error"
7575
7576 test_56aa() { # LU-5937
7577         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7578
7579         local dir=$DIR/$tdir
7580
7581         mkdir $dir
7582         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7583
7584         createmany -o $dir/striped_dir/${tfile}- 1024
7585         local dirs=$($LFS find --size +8k $dir/)
7586
7587         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7588 }
7589 run_test 56aa "lfs find --size under striped dir"
7590
7591 test_56ab() { # LU-10705
7592         test_mkdir $DIR/$tdir
7593         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7594         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7595         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7596         # Flush writes to ensure valid blocks.  Need to be more thorough for
7597         # ZFS, since blocks are not allocated/returned to client immediately.
7598         sync_all_data
7599         wait_zfs_commit ost1 2
7600         cancel_lru_locks osc
7601         ls -ls $DIR/$tdir
7602
7603         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7604
7605         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7606
7607         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7608         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7609
7610         rm -f $DIR/$tdir/$tfile.[123]
7611 }
7612 run_test 56ab "lfs find --blocks"
7613
7614 test_56ba() {
7615         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7616                 skip "Need MDS version at least 2.10.50"
7617
7618         # Create composite files with one component
7619         local dir=$DIR/$tdir
7620
7621         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7622         # Create composite files with three components
7623         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7624         # Create non-composite files
7625         createmany -o $dir/${tfile}- 10
7626
7627         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7628
7629         [[ $nfiles == 10 ]] ||
7630                 error "lfs find -E 1M found $nfiles != 10 files"
7631
7632         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7633         [[ $nfiles == 25 ]] ||
7634                 error "lfs find ! -E 1M found $nfiles != 25 files"
7635
7636         # All files have a component that starts at 0
7637         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7638         [[ $nfiles == 35 ]] ||
7639                 error "lfs find --component-start 0 - $nfiles != 35 files"
7640
7641         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7642         [[ $nfiles == 15 ]] ||
7643                 error "lfs find --component-start 2M - $nfiles != 15 files"
7644
7645         # All files created here have a componenet that does not starts at 2M
7646         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7647         [[ $nfiles == 35 ]] ||
7648                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7649
7650         # Find files with a specified number of components
7651         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7652         [[ $nfiles == 15 ]] ||
7653                 error "lfs find --component-count 3 - $nfiles != 15 files"
7654
7655         # Remember non-composite files have a component count of zero
7656         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7657         [[ $nfiles == 10 ]] ||
7658                 error "lfs find --component-count 0 - $nfiles != 10 files"
7659
7660         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7661         [[ $nfiles == 20 ]] ||
7662                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7663
7664         # All files have a flag called "init"
7665         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7666         [[ $nfiles == 35 ]] ||
7667                 error "lfs find --component-flags init - $nfiles != 35 files"
7668
7669         # Multi-component files will have a component not initialized
7670         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7671         [[ $nfiles == 15 ]] ||
7672                 error "lfs find !--component-flags init - $nfiles != 15 files"
7673
7674         rm -rf $dir
7675
7676 }
7677 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7678
7679 test_56ca() {
7680         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7681                 skip "Need MDS version at least 2.10.57"
7682
7683         local td=$DIR/$tdir
7684         local tf=$td/$tfile
7685         local dir
7686         local nfiles
7687         local cmd
7688         local i
7689         local j
7690
7691         # create mirrored directories and mirrored files
7692         mkdir $td || error "mkdir $td failed"
7693         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7694         createmany -o $tf- 10 || error "create $tf- failed"
7695
7696         for i in $(seq 2); do
7697                 dir=$td/dir$i
7698                 mkdir $dir || error "mkdir $dir failed"
7699                 $LFS mirror create -N$((3 + i)) $dir ||
7700                         error "create mirrored dir $dir failed"
7701                 createmany -o $dir/$tfile- 10 ||
7702                         error "create $dir/$tfile- failed"
7703         done
7704
7705         # change the states of some mirrored files
7706         echo foo > $tf-6
7707         for i in $(seq 2); do
7708                 dir=$td/dir$i
7709                 for j in $(seq 4 9); do
7710                         echo foo > $dir/$tfile-$j
7711                 done
7712         done
7713
7714         # find mirrored files with specific mirror count
7715         cmd="$LFS find --mirror-count 3 --type f $td"
7716         nfiles=$($cmd | wc -l)
7717         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7718
7719         cmd="$LFS find ! --mirror-count 3 --type f $td"
7720         nfiles=$($cmd | wc -l)
7721         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7722
7723         cmd="$LFS find --mirror-count +2 --type f $td"
7724         nfiles=$($cmd | wc -l)
7725         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7726
7727         cmd="$LFS find --mirror-count -6 --type f $td"
7728         nfiles=$($cmd | wc -l)
7729         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7730
7731         # find mirrored files with specific file state
7732         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7733         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7734
7735         cmd="$LFS find --mirror-state=ro --type f $td"
7736         nfiles=$($cmd | wc -l)
7737         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7738
7739         cmd="$LFS find ! --mirror-state=ro --type f $td"
7740         nfiles=$($cmd | wc -l)
7741         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7742
7743         cmd="$LFS find --mirror-state=wp --type f $td"
7744         nfiles=$($cmd | wc -l)
7745         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7746
7747         cmd="$LFS find ! --mirror-state=sp --type f $td"
7748         nfiles=$($cmd | wc -l)
7749         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7750 }
7751 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7752
7753 test_56da() { # LU-14179
7754         local path=$DIR/$tdir
7755
7756         test_mkdir $path
7757         cd $path
7758
7759         local longdir=$(str_repeat 'a' 255)
7760
7761         for i in {1..15}; do
7762                 path=$path/$longdir
7763                 test_mkdir $longdir
7764                 cd $longdir
7765         done
7766
7767         local len=${#path}
7768         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7769
7770         test_mkdir $lastdir
7771         cd $lastdir
7772         # PATH_MAX-1
7773         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7774
7775         # NAME_MAX
7776         touch $(str_repeat 'f' 255)
7777
7778         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7779                 error "lfs find reported an error"
7780
7781         rm -rf $DIR/$tdir
7782 }
7783 run_test 56da "test lfs find with long paths"
7784
7785 test_57a() {
7786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7787         # note test will not do anything if MDS is not local
7788         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7789                 skip_env "ldiskfs only test"
7790         fi
7791         remote_mds_nodsh && skip "remote MDS with nodsh"
7792
7793         local MNTDEV="osd*.*MDT*.mntdev"
7794         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7795         [ -z "$DEV" ] && error "can't access $MNTDEV"
7796         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7797                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7798                         error "can't access $DEV"
7799                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7800                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7801                 rm $TMP/t57a.dump
7802         done
7803 }
7804 run_test 57a "verify MDS filesystem created with large inodes =="
7805
7806 test_57b() {
7807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7808         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7809                 skip_env "ldiskfs only test"
7810         fi
7811         remote_mds_nodsh && skip "remote MDS with nodsh"
7812
7813         local dir=$DIR/$tdir
7814         local filecount=100
7815         local file1=$dir/f1
7816         local fileN=$dir/f$filecount
7817
7818         rm -rf $dir || error "removing $dir"
7819         test_mkdir -c1 $dir
7820         local mdtidx=$($LFS getstripe -m $dir)
7821         local mdtname=MDT$(printf %04x $mdtidx)
7822         local facet=mds$((mdtidx + 1))
7823
7824         echo "mcreating $filecount files"
7825         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7826
7827         # verify that files do not have EAs yet
7828         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7829                 error "$file1 has an EA"
7830         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7831                 error "$fileN has an EA"
7832
7833         sync
7834         sleep 1
7835         df $dir  #make sure we get new statfs data
7836         local mdsfree=$(do_facet $facet \
7837                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7838         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7839         local file
7840
7841         echo "opening files to create objects/EAs"
7842         for file in $(seq -f $dir/f%g 1 $filecount); do
7843                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7844                         error "opening $file"
7845         done
7846
7847         # verify that files have EAs now
7848         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7849         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7850
7851         sleep 1  #make sure we get new statfs data
7852         df $dir
7853         local mdsfree2=$(do_facet $facet \
7854                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7855         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7856
7857         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7858                 if [ "$mdsfree" != "$mdsfree2" ]; then
7859                         error "MDC before $mdcfree != after $mdcfree2"
7860                 else
7861                         echo "MDC before $mdcfree != after $mdcfree2"
7862                         echo "unable to confirm if MDS has large inodes"
7863                 fi
7864         fi
7865         rm -rf $dir
7866 }
7867 run_test 57b "default LOV EAs are stored inside large inodes ==="
7868
7869 test_58() {
7870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7871         [ -z "$(which wiretest 2>/dev/null)" ] &&
7872                         skip_env "could not find wiretest"
7873
7874         wiretest
7875 }
7876 run_test 58 "verify cross-platform wire constants =============="
7877
7878 test_59() {
7879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7880
7881         echo "touch 130 files"
7882         createmany -o $DIR/f59- 130
7883         echo "rm 130 files"
7884         unlinkmany $DIR/f59- 130
7885         sync
7886         # wait for commitment of removal
7887         wait_delete_completed
7888 }
7889 run_test 59 "verify cancellation of llog records async ========="
7890
7891 TEST60_HEAD="test_60 run $RANDOM"
7892 test_60a() {
7893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7894         remote_mgs_nodsh && skip "remote MGS with nodsh"
7895         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7896                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7897                         skip_env "missing subtest run-llog.sh"
7898
7899         log "$TEST60_HEAD - from kernel mode"
7900         do_facet mgs "$LCTL dk > /dev/null"
7901         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7902         do_facet mgs $LCTL dk > $TMP/$tfile
7903
7904         # LU-6388: test llog_reader
7905         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7906         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7907         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7908                         skip_env "missing llog_reader"
7909         local fstype=$(facet_fstype mgs)
7910         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7911                 skip_env "Only for ldiskfs or zfs type mgs"
7912
7913         local mntpt=$(facet_mntpt mgs)
7914         local mgsdev=$(mgsdevname 1)
7915         local fid_list
7916         local fid
7917         local rec_list
7918         local rec
7919         local rec_type
7920         local obj_file
7921         local path
7922         local seq
7923         local oid
7924         local pass=true
7925
7926         #get fid and record list
7927         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7928                 tail -n 4))
7929         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7930                 tail -n 4))
7931         #remount mgs as ldiskfs or zfs type
7932         stop mgs || error "stop mgs failed"
7933         mount_fstype mgs || error "remount mgs failed"
7934         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7935                 fid=${fid_list[i]}
7936                 rec=${rec_list[i]}
7937                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7938                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7939                 oid=$((16#$oid))
7940
7941                 case $fstype in
7942                         ldiskfs )
7943                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7944                         zfs )
7945                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7946                 esac
7947                 echo "obj_file is $obj_file"
7948                 do_facet mgs $llog_reader $obj_file
7949
7950                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7951                         awk '{ print $3 }' | sed -e "s/^type=//g")
7952                 if [ $rec_type != $rec ]; then
7953                         echo "FAILED test_60a wrong record type $rec_type," \
7954                               "should be $rec"
7955                         pass=false
7956                         break
7957                 fi
7958
7959                 #check obj path if record type is LLOG_LOGID_MAGIC
7960                 if [ "$rec" == "1064553b" ]; then
7961                         path=$(do_facet mgs $llog_reader $obj_file |
7962                                 grep "path=" | awk '{ print $NF }' |
7963                                 sed -e "s/^path=//g")
7964                         if [ $obj_file != $mntpt/$path ]; then
7965                                 echo "FAILED test_60a wrong obj path" \
7966                                       "$montpt/$path, should be $obj_file"
7967                                 pass=false
7968                                 break
7969                         fi
7970                 fi
7971         done
7972         rm -f $TMP/$tfile
7973         #restart mgs before "error", otherwise it will block the next test
7974         stop mgs || error "stop mgs failed"
7975         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7976         $pass || error "test failed, see FAILED test_60a messages for specifics"
7977 }
7978 run_test 60a "llog_test run from kernel module and test llog_reader"
7979
7980 test_60b() { # bug 6411
7981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7982
7983         dmesg > $DIR/$tfile
7984         LLOG_COUNT=$(do_facet mgs dmesg |
7985                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7986                           /llog_[a-z]*.c:[0-9]/ {
7987                                 if (marker)
7988                                         from_marker++
7989                                 from_begin++
7990                           }
7991                           END {
7992                                 if (marker)
7993                                         print from_marker
7994                                 else
7995                                         print from_begin
7996                           }")
7997
7998         [[ $LLOG_COUNT -gt 120 ]] &&
7999                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8000 }
8001 run_test 60b "limit repeated messages from CERROR/CWARN"
8002
8003 test_60c() {
8004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8005
8006         echo "create 5000 files"
8007         createmany -o $DIR/f60c- 5000
8008 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8009         lctl set_param fail_loc=0x80000137
8010         unlinkmany $DIR/f60c- 5000
8011         lctl set_param fail_loc=0
8012 }
8013 run_test 60c "unlink file when mds full"
8014
8015 test_60d() {
8016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8017
8018         SAVEPRINTK=$(lctl get_param -n printk)
8019         # verify "lctl mark" is even working"
8020         MESSAGE="test message ID $RANDOM $$"
8021         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8022         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8023
8024         lctl set_param printk=0 || error "set lnet.printk failed"
8025         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8026         MESSAGE="new test message ID $RANDOM $$"
8027         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8028         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8029         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8030
8031         lctl set_param -n printk="$SAVEPRINTK"
8032 }
8033 run_test 60d "test printk console message masking"
8034
8035 test_60e() {
8036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8037         remote_mds_nodsh && skip "remote MDS with nodsh"
8038
8039         touch $DIR/$tfile
8040 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8041         do_facet mds1 lctl set_param fail_loc=0x15b
8042         rm $DIR/$tfile
8043 }
8044 run_test 60e "no space while new llog is being created"
8045
8046 test_60f() {
8047         local old_path=$($LCTL get_param -n debug_path)
8048
8049         stack_trap "$LCTL set_param debug_path=$old_path"
8050         stack_trap "rm -f $TMP/$tfile*"
8051         rm -f $TMP/$tfile* 2> /dev/null
8052         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8053         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8054         test_mkdir $DIR/$tdir
8055         # retry in case the open is cached and not released
8056         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8057                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8058                 sleep 0.1
8059         done
8060         ls $TMP/$tfile*
8061         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8062 }
8063 run_test 60f "change debug_path works"
8064
8065 test_60g() {
8066         local pid
8067         local i
8068
8069         test_mkdir -c $MDSCOUNT $DIR/$tdir
8070
8071         (
8072                 local index=0
8073                 while true; do
8074                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8075                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8076                                 2>/dev/null
8077                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8078                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8079                         index=$((index + 1))
8080                 done
8081         ) &
8082
8083         pid=$!
8084
8085         for i in {0..100}; do
8086                 # define OBD_FAIL_OSD_TXN_START    0x19a
8087                 local index=$((i % MDSCOUNT + 1))
8088
8089                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8090                         > /dev/null
8091                 sleep 0.01
8092         done
8093
8094         kill -9 $pid
8095
8096         for i in $(seq $MDSCOUNT); do
8097                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8098         done
8099
8100         mkdir $DIR/$tdir/new || error "mkdir failed"
8101         rmdir $DIR/$tdir/new || error "rmdir failed"
8102
8103         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8104                 -t namespace
8105         for i in $(seq $MDSCOUNT); do
8106                 wait_update_facet mds$i "$LCTL get_param -n \
8107                         mdd.$(facet_svc mds$i).lfsck_namespace |
8108                         awk '/^status/ { print \\\$2 }'" "completed"
8109         done
8110
8111         ls -R $DIR/$tdir || error "ls failed"
8112         rm -rf $DIR/$tdir || error "rmdir failed"
8113 }
8114 run_test 60g "transaction abort won't cause MDT hung"
8115
8116 test_60h() {
8117         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8118                 skip "Need MDS version at least 2.12.52"
8119         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8120
8121         local f
8122
8123         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8124         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8125         for fail_loc in 0x80000188 0x80000189; do
8126                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8127                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8128                         error "mkdir $dir-$fail_loc failed"
8129                 for i in {0..10}; do
8130                         # create may fail on missing stripe
8131                         echo $i > $DIR/$tdir-$fail_loc/$i
8132                 done
8133                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8134                         error "getdirstripe $tdir-$fail_loc failed"
8135                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8136                         error "migrate $tdir-$fail_loc failed"
8137                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8138                         error "getdirstripe $tdir-$fail_loc failed"
8139                 pushd $DIR/$tdir-$fail_loc
8140                 for f in *; do
8141                         echo $f | cmp $f - || error "$f data mismatch"
8142                 done
8143                 popd
8144                 rm -rf $DIR/$tdir-$fail_loc
8145         done
8146 }
8147 run_test 60h "striped directory with missing stripes can be accessed"
8148
8149 test_61a() {
8150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8151
8152         f="$DIR/f61"
8153         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8154         cancel_lru_locks osc
8155         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8156         sync
8157 }
8158 run_test 61a "mmap() writes don't make sync hang ================"
8159
8160 test_61b() {
8161         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8162 }
8163 run_test 61b "mmap() of unstriped file is successful"
8164
8165 # bug 2330 - insufficient obd_match error checking causes LBUG
8166 test_62() {
8167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8168
8169         f="$DIR/f62"
8170         echo foo > $f
8171         cancel_lru_locks osc
8172         lctl set_param fail_loc=0x405
8173         cat $f && error "cat succeeded, expect -EIO"
8174         lctl set_param fail_loc=0
8175 }
8176 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8177 # match every page all of the time.
8178 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8179
8180 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8181 # Though this test is irrelevant anymore, it helped to reveal some
8182 # other grant bugs (LU-4482), let's keep it.
8183 test_63a() {   # was test_63
8184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8185
8186         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8187
8188         for i in `seq 10` ; do
8189                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8190                 sleep 5
8191                 kill $!
8192                 sleep 1
8193         done
8194
8195         rm -f $DIR/f63 || true
8196 }
8197 run_test 63a "Verify oig_wait interruption does not crash ======="
8198
8199 # bug 2248 - async write errors didn't return to application on sync
8200 # bug 3677 - async write errors left page locked
8201 test_63b() {
8202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8203
8204         debugsave
8205         lctl set_param debug=-1
8206
8207         # ensure we have a grant to do async writes
8208         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8209         rm $DIR/$tfile
8210
8211         sync    # sync lest earlier test intercept the fail_loc
8212
8213         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8214         lctl set_param fail_loc=0x80000406
8215         $MULTIOP $DIR/$tfile Owy && \
8216                 error "sync didn't return ENOMEM"
8217         sync; sleep 2; sync     # do a real sync this time to flush page
8218         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8219                 error "locked page left in cache after async error" || true
8220         debugrestore
8221 }
8222 run_test 63b "async write errors should be returned to fsync ==="
8223
8224 test_64a () {
8225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8226
8227         lfs df $DIR
8228         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8229 }
8230 run_test 64a "verify filter grant calculations (in kernel) ====="
8231
8232 test_64b () {
8233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8234
8235         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8236 }
8237 run_test 64b "check out-of-space detection on client"
8238
8239 test_64c() {
8240         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8241 }
8242 run_test 64c "verify grant shrink"
8243
8244 import_param() {
8245         local tgt=$1
8246         local param=$2
8247
8248         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8249 }
8250
8251 # this does exactly what osc_request.c:osc_announce_cached() does in
8252 # order to calculate max amount of grants to ask from server
8253 want_grant() {
8254         local tgt=$1
8255
8256         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8257         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8258
8259         ((rpc_in_flight++));
8260         nrpages=$((nrpages * rpc_in_flight))
8261
8262         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8263
8264         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8265
8266         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8267         local undirty=$((nrpages * PAGE_SIZE))
8268
8269         local max_extent_pages
8270         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8271         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8272         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8273         local grant_extent_tax
8274         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8275
8276         undirty=$((undirty + nrextents * grant_extent_tax))
8277
8278         echo $undirty
8279 }
8280
8281 # this is size of unit for grant allocation. It should be equal to
8282 # what tgt_grant.c:tgt_grant_chunk() calculates
8283 grant_chunk() {
8284         local tgt=$1
8285         local max_brw_size
8286         local grant_extent_tax
8287
8288         max_brw_size=$(import_param $tgt max_brw_size)
8289
8290         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8291
8292         echo $(((max_brw_size + grant_extent_tax) * 2))
8293 }
8294
8295 test_64d() {
8296         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8297                 skip "OST < 2.10.55 doesn't limit grants enough"
8298
8299         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8300
8301         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8302                 skip "no grant_param connect flag"
8303
8304         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8305
8306         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8307         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8308
8309
8310         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8311         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8312
8313         $LFS setstripe $DIR/$tfile -i 0 -c 1
8314         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8315         ddpid=$!
8316
8317         while kill -0 $ddpid; do
8318                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8319
8320                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8321                         kill $ddpid
8322                         error "cur_grant $cur_grant > $max_cur_granted"
8323                 fi
8324
8325                 sleep 1
8326         done
8327 }
8328 run_test 64d "check grant limit exceed"
8329
8330 check_grants() {
8331         local tgt=$1
8332         local expected=$2
8333         local msg=$3
8334         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8335
8336         ((cur_grants == expected)) ||
8337                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8338 }
8339
8340 round_up_p2() {
8341         echo $((($1 + $2 - 1) & ~($2 - 1)))
8342 }
8343
8344 test_64e() {
8345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8346         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8347                 skip "Need OSS version at least 2.11.56"
8348
8349         # Remount client to reset grant
8350         remount_client $MOUNT || error "failed to remount client"
8351         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8352
8353         local init_grants=$(import_param $osc_tgt initial_grant)
8354
8355         check_grants $osc_tgt $init_grants "init grants"
8356
8357         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8358         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8359         local gbs=$(import_param $osc_tgt grant_block_size)
8360
8361         # write random number of bytes from max_brw_size / 4 to max_brw_size
8362         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8363         # align for direct io
8364         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8365         # round to grant consumption unit
8366         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8367
8368         local grants=$((wb_round_up + extent_tax))
8369
8370         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8371
8372         # define OBD_FAIL_TGT_NO_GRANT 0x725
8373         # make the server not grant more back
8374         do_facet ost1 $LCTL set_param fail_loc=0x725
8375         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8376
8377         do_facet ost1 $LCTL set_param fail_loc=0
8378
8379         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8380
8381         rm -f $DIR/$tfile || error "rm failed"
8382
8383         # Remount client to reset grant
8384         remount_client $MOUNT || error "failed to remount client"
8385         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8386
8387         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8388
8389         # define OBD_FAIL_TGT_NO_GRANT 0x725
8390         # make the server not grant more back
8391         do_facet ost1 $LCTL set_param fail_loc=0x725
8392         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8393         do_facet ost1 $LCTL set_param fail_loc=0
8394
8395         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8396 }
8397 run_test 64e "check grant consumption (no grant allocation)"
8398
8399 test_64f() {
8400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8401
8402         # Remount client to reset grant
8403         remount_client $MOUNT || error "failed to remount client"
8404         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8405
8406         local init_grants=$(import_param $osc_tgt initial_grant)
8407         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8408         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8409         local gbs=$(import_param $osc_tgt grant_block_size)
8410         local chunk=$(grant_chunk $osc_tgt)
8411
8412         # write random number of bytes from max_brw_size / 4 to max_brw_size
8413         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8414         # align for direct io
8415         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8416         # round to grant consumption unit
8417         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8418
8419         local grants=$((wb_round_up + extent_tax))
8420
8421         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8422         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8423                 error "error writing to $DIR/$tfile"
8424
8425         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8426                 "direct io with grant allocation"
8427
8428         rm -f $DIR/$tfile || error "rm failed"
8429
8430         # Remount client to reset grant
8431         remount_client $MOUNT || error "failed to remount client"
8432         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8433
8434         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8435
8436         local cmd="oO_WRONLY:w${write_bytes}_yc"
8437
8438         $MULTIOP $DIR/$tfile $cmd &
8439         MULTIPID=$!
8440         sleep 1
8441
8442         check_grants $osc_tgt $((init_grants - grants)) \
8443                 "buffered io, not write rpc"
8444
8445         kill -USR1 $MULTIPID
8446         wait
8447
8448         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8449                 "buffered io, one RPC"
8450 }
8451 run_test 64f "check grant consumption (with grant allocation)"
8452
8453 # bug 1414 - set/get directories' stripe info
8454 test_65a() {
8455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8456
8457         test_mkdir $DIR/$tdir
8458         touch $DIR/$tdir/f1
8459         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8460 }
8461 run_test 65a "directory with no stripe info"
8462
8463 test_65b() {
8464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8465
8466         test_mkdir $DIR/$tdir
8467         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8468
8469         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8470                                                 error "setstripe"
8471         touch $DIR/$tdir/f2
8472         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8473 }
8474 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8475
8476 test_65c() {
8477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8478         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8479
8480         test_mkdir $DIR/$tdir
8481         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8482
8483         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8484                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8485         touch $DIR/$tdir/f3
8486         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8487 }
8488 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8489
8490 test_65d() {
8491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8492
8493         test_mkdir $DIR/$tdir
8494         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8495         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8496
8497         if [[ $STRIPECOUNT -le 0 ]]; then
8498                 sc=1
8499         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8500                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8501                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8502         else
8503                 sc=$(($STRIPECOUNT - 1))
8504         fi
8505         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8506         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8507         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8508                 error "lverify failed"
8509 }
8510 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8511
8512 test_65e() {
8513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8514
8515         test_mkdir $DIR/$tdir
8516
8517         $LFS setstripe $DIR/$tdir || error "setstripe"
8518         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8519                                         error "no stripe info failed"
8520         touch $DIR/$tdir/f6
8521         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8522 }
8523 run_test 65e "directory setstripe defaults"
8524
8525 test_65f() {
8526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8527
8528         test_mkdir $DIR/${tdir}f
8529         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8530                 error "setstripe succeeded" || true
8531 }
8532 run_test 65f "dir setstripe permission (should return error) ==="
8533
8534 test_65g() {
8535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8536
8537         test_mkdir $DIR/$tdir
8538         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8539
8540         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8541                 error "setstripe -S failed"
8542         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8543         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8544                 error "delete default stripe failed"
8545 }
8546 run_test 65g "directory setstripe -d"
8547
8548 test_65h() {
8549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8550
8551         test_mkdir $DIR/$tdir
8552         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8553
8554         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8555                 error "setstripe -S failed"
8556         test_mkdir $DIR/$tdir/dd1
8557         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8558                 error "stripe info inherit failed"
8559 }
8560 run_test 65h "directory stripe info inherit ===================="
8561
8562 test_65i() {
8563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8564
8565         save_layout_restore_at_exit $MOUNT
8566
8567         # bug6367: set non-default striping on root directory
8568         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8569
8570         # bug12836: getstripe on -1 default directory striping
8571         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8572
8573         # bug12836: getstripe -v on -1 default directory striping
8574         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8575
8576         # bug12836: new find on -1 default directory striping
8577         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8578 }
8579 run_test 65i "various tests to set root directory striping"
8580
8581 test_65j() { # bug6367
8582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8583
8584         sync; sleep 1
8585
8586         # if we aren't already remounting for each test, do so for this test
8587         if [ "$I_MOUNTED" = "yes" ]; then
8588                 cleanup || error "failed to unmount"
8589                 setup
8590         fi
8591
8592         save_layout_restore_at_exit $MOUNT
8593
8594         $LFS setstripe -d $MOUNT || error "setstripe failed"
8595 }
8596 run_test 65j "set default striping on root directory (bug 6367)="
8597
8598 cleanup_65k() {
8599         rm -rf $DIR/$tdir
8600         wait_delete_completed
8601         do_facet $SINGLEMDS "lctl set_param -n \
8602                 osp.$ost*MDT0000.max_create_count=$max_count"
8603         do_facet $SINGLEMDS "lctl set_param -n \
8604                 osp.$ost*MDT0000.create_count=$count"
8605         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8606         echo $INACTIVE_OSC "is Activate"
8607
8608         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8609 }
8610
8611 test_65k() { # bug11679
8612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8613         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8614         remote_mds_nodsh && skip "remote MDS with nodsh"
8615
8616         local disable_precreate=true
8617         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8618                 disable_precreate=false
8619
8620         echo "Check OST status: "
8621         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8622                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8623
8624         for OSC in $MDS_OSCS; do
8625                 echo $OSC "is active"
8626                 do_facet $SINGLEMDS lctl --device %$OSC activate
8627         done
8628
8629         for INACTIVE_OSC in $MDS_OSCS; do
8630                 local ost=$(osc_to_ost $INACTIVE_OSC)
8631                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8632                                lov.*md*.target_obd |
8633                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8634
8635                 mkdir -p $DIR/$tdir
8636                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8637                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8638
8639                 echo "Deactivate: " $INACTIVE_OSC
8640                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8641
8642                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8643                               osp.$ost*MDT0000.create_count")
8644                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8645                                   osp.$ost*MDT0000.max_create_count")
8646                 $disable_precreate &&
8647                         do_facet $SINGLEMDS "lctl set_param -n \
8648                                 osp.$ost*MDT0000.max_create_count=0"
8649
8650                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8651                         [ -f $DIR/$tdir/$idx ] && continue
8652                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8653                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8654                                 { cleanup_65k;
8655                                   error "setstripe $idx should succeed"; }
8656                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8657                 done
8658                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8659                 rmdir $DIR/$tdir
8660
8661                 do_facet $SINGLEMDS "lctl set_param -n \
8662                         osp.$ost*MDT0000.max_create_count=$max_count"
8663                 do_facet $SINGLEMDS "lctl set_param -n \
8664                         osp.$ost*MDT0000.create_count=$count"
8665                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8666                 echo $INACTIVE_OSC "is Activate"
8667
8668                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8669         done
8670 }
8671 run_test 65k "validate manual striping works properly with deactivated OSCs"
8672
8673 test_65l() { # bug 12836
8674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8675
8676         test_mkdir -p $DIR/$tdir/test_dir
8677         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8678         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8679 }
8680 run_test 65l "lfs find on -1 stripe dir ========================"
8681
8682 test_65m() {
8683         local layout=$(save_layout $MOUNT)
8684         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8685                 restore_layout $MOUNT $layout
8686                 error "setstripe should fail by non-root users"
8687         }
8688         true
8689 }
8690 run_test 65m "normal user can't set filesystem default stripe"
8691
8692 test_65n() {
8693         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8694         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8695                 skip "Need MDS version at least 2.12.50"
8696         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8697
8698         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8699         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8700         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8701
8702         local root_layout=$(save_layout $MOUNT)
8703         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8704
8705         # new subdirectory under root directory should not inherit
8706         # the default layout from root
8707         local dir1=$MOUNT/$tdir-1
8708         mkdir $dir1 || error "mkdir $dir1 failed"
8709         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8710                 error "$dir1 shouldn't have LOV EA"
8711
8712         # delete the default layout on root directory
8713         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8714
8715         local dir2=$MOUNT/$tdir-2
8716         mkdir $dir2 || error "mkdir $dir2 failed"
8717         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8718                 error "$dir2 shouldn't have LOV EA"
8719
8720         # set a new striping pattern on root directory
8721         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8722         local new_def_stripe_size=$((def_stripe_size * 2))
8723         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8724                 error "set stripe size on $MOUNT failed"
8725
8726         # new file created in $dir2 should inherit the new stripe size from
8727         # the filesystem default
8728         local file2=$dir2/$tfile-2
8729         touch $file2 || error "touch $file2 failed"
8730
8731         local file2_stripe_size=$($LFS getstripe -S $file2)
8732         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8733         {
8734                 echo "file2_stripe_size: '$file2_stripe_size'"
8735                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8736                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8737         }
8738
8739         local dir3=$MOUNT/$tdir-3
8740         mkdir $dir3 || error "mkdir $dir3 failed"
8741         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8742         # the root layout, which is the actual default layout that will be used
8743         # when new files are created in $dir3.
8744         local dir3_layout=$(get_layout_param $dir3)
8745         local root_dir_layout=$(get_layout_param $MOUNT)
8746         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8747         {
8748                 echo "dir3_layout: '$dir3_layout'"
8749                 echo "root_dir_layout: '$root_dir_layout'"
8750                 error "$dir3 should show the default layout from $MOUNT"
8751         }
8752
8753         # set OST pool on root directory
8754         local pool=$TESTNAME
8755         pool_add $pool || error "add $pool failed"
8756         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8757                 error "add targets to $pool failed"
8758
8759         $LFS setstripe -p $pool $MOUNT ||
8760                 error "set OST pool on $MOUNT failed"
8761
8762         # new file created in $dir3 should inherit the pool from
8763         # the filesystem default
8764         local file3=$dir3/$tfile-3
8765         touch $file3 || error "touch $file3 failed"
8766
8767         local file3_pool=$($LFS getstripe -p $file3)
8768         [[ "$file3_pool" = "$pool" ]] ||
8769                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8770
8771         local dir4=$MOUNT/$tdir-4
8772         mkdir $dir4 || error "mkdir $dir4 failed"
8773         local dir4_layout=$(get_layout_param $dir4)
8774         root_dir_layout=$(get_layout_param $MOUNT)
8775         echo "$LFS getstripe -d $dir4"
8776         $LFS getstripe -d $dir4
8777         echo "$LFS getstripe -d $MOUNT"
8778         $LFS getstripe -d $MOUNT
8779         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8780         {
8781                 echo "dir4_layout: '$dir4_layout'"
8782                 echo "root_dir_layout: '$root_dir_layout'"
8783                 error "$dir4 should show the default layout from $MOUNT"
8784         }
8785
8786         # new file created in $dir4 should inherit the pool from
8787         # the filesystem default
8788         local file4=$dir4/$tfile-4
8789         touch $file4 || error "touch $file4 failed"
8790
8791         local file4_pool=$($LFS getstripe -p $file4)
8792         [[ "$file4_pool" = "$pool" ]] ||
8793                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8794
8795         # new subdirectory under non-root directory should inherit
8796         # the default layout from its parent directory
8797         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8798                 error "set directory layout on $dir4 failed"
8799
8800         local dir5=$dir4/$tdir-5
8801         mkdir $dir5 || error "mkdir $dir5 failed"
8802
8803         dir4_layout=$(get_layout_param $dir4)
8804         local dir5_layout=$(get_layout_param $dir5)
8805         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8806         {
8807                 echo "dir4_layout: '$dir4_layout'"
8808                 echo "dir5_layout: '$dir5_layout'"
8809                 error "$dir5 should inherit the default layout from $dir4"
8810         }
8811
8812         # though subdir under ROOT doesn't inherit default layout, but
8813         # its sub dir/file should be created with default layout.
8814         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8815         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8816                 skip "Need MDS version at least 2.12.59"
8817
8818         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8819         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8820         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8821
8822         if [ $default_lmv_hash == "none" ]; then
8823                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8824         else
8825                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8826                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8827         fi
8828
8829         $LFS setdirstripe -D -c 2 $MOUNT ||
8830                 error "setdirstripe -D -c 2 failed"
8831         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8832         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8833         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8834 }
8835 run_test 65n "don't inherit default layout from root for new subdirectories"
8836
8837 # bug 2543 - update blocks count on client
8838 test_66() {
8839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8840
8841         COUNT=${COUNT:-8}
8842         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8843         sync; sync_all_data; sync; sync_all_data
8844         cancel_lru_locks osc
8845         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8846         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8847 }
8848 run_test 66 "update inode blocks count on client ==============="
8849
8850 meminfo() {
8851         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8852 }
8853
8854 swap_used() {
8855         swapon -s | awk '($1 == "'$1'") { print $4 }'
8856 }
8857
8858 # bug5265, obdfilter oa2dentry return -ENOENT
8859 # #define OBD_FAIL_SRV_ENOENT 0x217
8860 test_69() {
8861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8862         remote_ost_nodsh && skip "remote OST with nodsh"
8863
8864         f="$DIR/$tfile"
8865         $LFS setstripe -c 1 -i 0 $f
8866
8867         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8868
8869         do_facet ost1 lctl set_param fail_loc=0x217
8870         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8871         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8872
8873         do_facet ost1 lctl set_param fail_loc=0
8874         $DIRECTIO write $f 0 2 || error "write error"
8875
8876         cancel_lru_locks osc
8877         $DIRECTIO read $f 0 1 || error "read error"
8878
8879         do_facet ost1 lctl set_param fail_loc=0x217
8880         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8881
8882         do_facet ost1 lctl set_param fail_loc=0
8883         rm -f $f
8884 }
8885 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8886
8887 test_71() {
8888         test_mkdir $DIR/$tdir
8889         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8890         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8891 }
8892 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8893
8894 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8896         [ "$RUNAS_ID" = "$UID" ] &&
8897                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8898         # Check that testing environment is properly set up. Skip if not
8899         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8900                 skip_env "User $RUNAS_ID does not exist - skipping"
8901
8902         touch $DIR/$tfile
8903         chmod 777 $DIR/$tfile
8904         chmod ug+s $DIR/$tfile
8905         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8906                 error "$RUNAS dd $DIR/$tfile failed"
8907         # See if we are still setuid/sgid
8908         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8909                 error "S/gid is not dropped on write"
8910         # Now test that MDS is updated too
8911         cancel_lru_locks mdc
8912         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8913                 error "S/gid is not dropped on MDS"
8914         rm -f $DIR/$tfile
8915 }
8916 run_test 72a "Test that remove suid works properly (bug5695) ===="
8917
8918 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8919         local perm
8920
8921         [ "$RUNAS_ID" = "$UID" ] &&
8922                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8923         [ "$RUNAS_ID" -eq 0 ] &&
8924                 skip_env "RUNAS_ID = 0 -- skipping"
8925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8926         # Check that testing environment is properly set up. Skip if not
8927         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8928                 skip_env "User $RUNAS_ID does not exist - skipping"
8929
8930         touch $DIR/${tfile}-f{g,u}
8931         test_mkdir $DIR/${tfile}-dg
8932         test_mkdir $DIR/${tfile}-du
8933         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8934         chmod g+s $DIR/${tfile}-{f,d}g
8935         chmod u+s $DIR/${tfile}-{f,d}u
8936         for perm in 777 2777 4777; do
8937                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8938                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8939                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8940                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8941         done
8942         true
8943 }
8944 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8945
8946 # bug 3462 - multiple simultaneous MDC requests
8947 test_73() {
8948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8949
8950         test_mkdir $DIR/d73-1
8951         test_mkdir $DIR/d73-2
8952         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8953         pid1=$!
8954
8955         lctl set_param fail_loc=0x80000129
8956         $MULTIOP $DIR/d73-1/f73-2 Oc &
8957         sleep 1
8958         lctl set_param fail_loc=0
8959
8960         $MULTIOP $DIR/d73-2/f73-3 Oc &
8961         pid3=$!
8962
8963         kill -USR1 $pid1
8964         wait $pid1 || return 1
8965
8966         sleep 25
8967
8968         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8969         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8970         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8971
8972         rm -rf $DIR/d73-*
8973 }
8974 run_test 73 "multiple MDC requests (should not deadlock)"
8975
8976 test_74a() { # bug 6149, 6184
8977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8978
8979         touch $DIR/f74a
8980         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8981         #
8982         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8983         # will spin in a tight reconnection loop
8984         $LCTL set_param fail_loc=0x8000030e
8985         # get any lock that won't be difficult - lookup works.
8986         ls $DIR/f74a
8987         $LCTL set_param fail_loc=0
8988         rm -f $DIR/f74a
8989         true
8990 }
8991 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8992
8993 test_74b() { # bug 13310
8994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8995
8996         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8997         #
8998         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8999         # will spin in a tight reconnection loop
9000         $LCTL set_param fail_loc=0x8000030e
9001         # get a "difficult" lock
9002         touch $DIR/f74b
9003         $LCTL set_param fail_loc=0
9004         rm -f $DIR/f74b
9005         true
9006 }
9007 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9008
9009 test_74c() {
9010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9011
9012         #define OBD_FAIL_LDLM_NEW_LOCK
9013         $LCTL set_param fail_loc=0x319
9014         touch $DIR/$tfile && error "touch successful"
9015         $LCTL set_param fail_loc=0
9016         true
9017 }
9018 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9019
9020 slab_lic=/sys/kernel/slab/lustre_inode_cache
9021 num_objects() {
9022         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9023         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9024                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9025 }
9026
9027 test_76a() { # Now for b=20433, added originally in b=1443
9028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9029
9030         cancel_lru_locks osc
9031         # there may be some slab objects cached per core
9032         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9033         local before=$(num_objects)
9034         local count=$((512 * cpus))
9035         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9036         local margin=$((count / 10))
9037         if [[ -f $slab_lic/aliases ]]; then
9038                 local aliases=$(cat $slab_lic/aliases)
9039                 (( aliases > 0 )) && margin=$((margin * aliases))
9040         fi
9041
9042         echo "before slab objects: $before"
9043         for i in $(seq $count); do
9044                 touch $DIR/$tfile
9045                 rm -f $DIR/$tfile
9046         done
9047         cancel_lru_locks osc
9048         local after=$(num_objects)
9049         echo "created: $count, after slab objects: $after"
9050         # shared slab counts are not very accurate, allow significant margin
9051         # the main goal is that the cache growth is not permanently > $count
9052         while (( after > before + margin )); do
9053                 sleep 1
9054                 after=$(num_objects)
9055                 wait=$((wait + 1))
9056                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9057                 if (( wait > 60 )); then
9058                         error "inode slab grew from $before+$margin to $after"
9059                 fi
9060         done
9061 }
9062 run_test 76a "confirm clients recycle inodes properly ===="
9063
9064 test_76b() {
9065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9066         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9067
9068         local count=512
9069         local before=$(num_objects)
9070
9071         for i in $(seq $count); do
9072                 mkdir $DIR/$tdir
9073                 rmdir $DIR/$tdir
9074         done
9075
9076         local after=$(num_objects)
9077         local wait=0
9078
9079         while (( after > before )); do
9080                 sleep 1
9081                 after=$(num_objects)
9082                 wait=$((wait + 1))
9083                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9084                 if (( wait > 60 )); then
9085                         error "inode slab grew from $before to $after"
9086                 fi
9087         done
9088
9089         echo "slab objects before: $before, after: $after"
9090 }
9091 run_test 76b "confirm clients recycle directory inodes properly ===="
9092
9093 export ORIG_CSUM=""
9094 set_checksums()
9095 {
9096         # Note: in sptlrpc modes which enable its own bulk checksum, the
9097         # original crc32_le bulk checksum will be automatically disabled,
9098         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9099         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9100         # In this case set_checksums() will not be no-op, because sptlrpc
9101         # bulk checksum will be enabled all through the test.
9102
9103         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9104         lctl set_param -n osc.*.checksums $1
9105         return 0
9106 }
9107
9108 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9109                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9110 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9111                              tr -d [] | head -n1)}
9112 set_checksum_type()
9113 {
9114         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9115         rc=$?
9116         log "set checksum type to $1, rc = $rc"
9117         return $rc
9118 }
9119
9120 get_osc_checksum_type()
9121 {
9122         # arugment 1: OST name, like OST0000
9123         ost=$1
9124         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9125                         sed 's/.*\[\(.*\)\].*/\1/g')
9126         rc=$?
9127         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9128         echo $checksum_type
9129 }
9130
9131 F77_TMP=$TMP/f77-temp
9132 F77SZ=8
9133 setup_f77() {
9134         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9135                 error "error writing to $F77_TMP"
9136 }
9137
9138 test_77a() { # bug 10889
9139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9140         $GSS && skip_env "could not run with gss"
9141
9142         [ ! -f $F77_TMP ] && setup_f77
9143         set_checksums 1
9144         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9145         set_checksums 0
9146         rm -f $DIR/$tfile
9147 }
9148 run_test 77a "normal checksum read/write operation"
9149
9150 test_77b() { # bug 10889
9151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9152         $GSS && skip_env "could not run with gss"
9153
9154         [ ! -f $F77_TMP ] && setup_f77
9155         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9156         $LCTL set_param fail_loc=0x80000409
9157         set_checksums 1
9158
9159         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9160                 error "dd error: $?"
9161         $LCTL set_param fail_loc=0
9162
9163         for algo in $CKSUM_TYPES; do
9164                 cancel_lru_locks osc
9165                 set_checksum_type $algo
9166                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9167                 $LCTL set_param fail_loc=0x80000408
9168                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9169                 $LCTL set_param fail_loc=0
9170         done
9171         set_checksums 0
9172         set_checksum_type $ORIG_CSUM_TYPE
9173         rm -f $DIR/$tfile
9174 }
9175 run_test 77b "checksum error on client write, read"
9176
9177 cleanup_77c() {
9178         trap 0
9179         set_checksums 0
9180         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9181         $check_ost &&
9182                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9183         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9184         $check_ost && [ -n "$ost_file_prefix" ] &&
9185                 do_facet ost1 rm -f ${ost_file_prefix}\*
9186 }
9187
9188 test_77c() {
9189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9190         $GSS && skip_env "could not run with gss"
9191         remote_ost_nodsh && skip "remote OST with nodsh"
9192
9193         local bad1
9194         local osc_file_prefix
9195         local osc_file
9196         local check_ost=false
9197         local ost_file_prefix
9198         local ost_file
9199         local orig_cksum
9200         local dump_cksum
9201         local fid
9202
9203         # ensure corruption will occur on first OSS/OST
9204         $LFS setstripe -i 0 $DIR/$tfile
9205
9206         [ ! -f $F77_TMP ] && setup_f77
9207         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9208                 error "dd write error: $?"
9209         fid=$($LFS path2fid $DIR/$tfile)
9210
9211         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9212         then
9213                 check_ost=true
9214                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9215                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9216         else
9217                 echo "OSS do not support bulk pages dump upon error"
9218         fi
9219
9220         osc_file_prefix=$($LCTL get_param -n debug_path)
9221         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9222
9223         trap cleanup_77c EXIT
9224
9225         set_checksums 1
9226         # enable bulk pages dump upon error on Client
9227         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9228         # enable bulk pages dump upon error on OSS
9229         $check_ost &&
9230                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9231
9232         # flush Client cache to allow next read to reach OSS
9233         cancel_lru_locks osc
9234
9235         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9236         $LCTL set_param fail_loc=0x80000408
9237         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9238         $LCTL set_param fail_loc=0
9239
9240         rm -f $DIR/$tfile
9241
9242         # check cksum dump on Client
9243         osc_file=$(ls ${osc_file_prefix}*)
9244         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9245         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9246         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9247         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9248         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9249                      cksum)
9250         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9251         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9252                 error "dump content does not match on Client"
9253
9254         $check_ost || skip "No need to check cksum dump on OSS"
9255
9256         # check cksum dump on OSS
9257         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9258         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9259         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9260         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9261         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9262                 error "dump content does not match on OSS"
9263
9264         cleanup_77c
9265 }
9266 run_test 77c "checksum error on client read with debug"
9267
9268 test_77d() { # bug 10889
9269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9270         $GSS && skip_env "could not run with gss"
9271
9272         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9273         $LCTL set_param fail_loc=0x80000409
9274         set_checksums 1
9275         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9276                 error "direct write: rc=$?"
9277         $LCTL set_param fail_loc=0
9278         set_checksums 0
9279
9280         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9281         $LCTL set_param fail_loc=0x80000408
9282         set_checksums 1
9283         cancel_lru_locks osc
9284         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9285                 error "direct read: rc=$?"
9286         $LCTL set_param fail_loc=0
9287         set_checksums 0
9288 }
9289 run_test 77d "checksum error on OST direct write, read"
9290
9291 test_77f() { # bug 10889
9292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9293         $GSS && skip_env "could not run with gss"
9294
9295         set_checksums 1
9296         for algo in $CKSUM_TYPES; do
9297                 cancel_lru_locks osc
9298                 set_checksum_type $algo
9299                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9300                 $LCTL set_param fail_loc=0x409
9301                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9302                         error "direct write succeeded"
9303                 $LCTL set_param fail_loc=0
9304         done
9305         set_checksum_type $ORIG_CSUM_TYPE
9306         set_checksums 0
9307 }
9308 run_test 77f "repeat checksum error on write (expect error)"
9309
9310 test_77g() { # bug 10889
9311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9312         $GSS && skip_env "could not run with gss"
9313         remote_ost_nodsh && skip "remote OST with nodsh"
9314
9315         [ ! -f $F77_TMP ] && setup_f77
9316
9317         local file=$DIR/$tfile
9318         stack_trap "rm -f $file" EXIT
9319
9320         $LFS setstripe -c 1 -i 0 $file
9321         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9322         do_facet ost1 lctl set_param fail_loc=0x8000021a
9323         set_checksums 1
9324         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9325                 error "write error: rc=$?"
9326         do_facet ost1 lctl set_param fail_loc=0
9327         set_checksums 0
9328
9329         cancel_lru_locks osc
9330         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9331         do_facet ost1 lctl set_param fail_loc=0x8000021b
9332         set_checksums 1
9333         cmp $F77_TMP $file || error "file compare failed"
9334         do_facet ost1 lctl set_param fail_loc=0
9335         set_checksums 0
9336 }
9337 run_test 77g "checksum error on OST write, read"
9338
9339 test_77k() { # LU-10906
9340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9341         $GSS && skip_env "could not run with gss"
9342
9343         local cksum_param="osc.$FSNAME*.checksums"
9344         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9345         local checksum
9346         local i
9347
9348         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9349         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9350         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9351
9352         for i in 0 1; do
9353                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9354                         error "failed to set checksum=$i on MGS"
9355                 wait_update $HOSTNAME "$get_checksum" $i
9356                 #remount
9357                 echo "remount client, checksum should be $i"
9358                 remount_client $MOUNT || error "failed to remount client"
9359                 checksum=$(eval $get_checksum)
9360                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9361         done
9362         # remove persistent param to avoid races with checksum mountopt below
9363         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9364                 error "failed to delete checksum on MGS"
9365
9366         for opt in "checksum" "nochecksum"; do
9367                 #remount with mount option
9368                 echo "remount client with option $opt, checksum should be $i"
9369                 umount_client $MOUNT || error "failed to umount client"
9370                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9371                         error "failed to mount client with option '$opt'"
9372                 checksum=$(eval $get_checksum)
9373                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9374                 i=$((i - 1))
9375         done
9376
9377         remount_client $MOUNT || error "failed to remount client"
9378 }
9379 run_test 77k "enable/disable checksum correctly"
9380
9381 test_77l() {
9382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9383         $GSS && skip_env "could not run with gss"
9384
9385         set_checksums 1
9386         stack_trap "set_checksums $ORIG_CSUM" EXIT
9387         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9388
9389         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9390
9391         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9392         for algo in $CKSUM_TYPES; do
9393                 set_checksum_type $algo || error "fail to set checksum type $algo"
9394                 osc_algo=$(get_osc_checksum_type OST0000)
9395                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9396
9397                 # no locks, no reqs to let the connection idle
9398                 cancel_lru_locks osc
9399                 lru_resize_disable osc
9400                 wait_osc_import_state client ost1 IDLE
9401
9402                 # ensure ost1 is connected
9403                 stat $DIR/$tfile >/dev/null || error "can't stat"
9404                 wait_osc_import_state client ost1 FULL
9405
9406                 osc_algo=$(get_osc_checksum_type OST0000)
9407                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9408         done
9409         return 0
9410 }
9411 run_test 77l "preferred checksum type is remembered after reconnected"
9412
9413 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9414 rm -f $F77_TMP
9415 unset F77_TMP
9416
9417 cleanup_test_78() {
9418         trap 0
9419         rm -f $DIR/$tfile
9420 }
9421
9422 test_78() { # bug 10901
9423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9424         remote_ost || skip_env "local OST"
9425
9426         NSEQ=5
9427         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9428         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9429         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9430         echo "MemTotal: $MEMTOTAL"
9431
9432         # reserve 256MB of memory for the kernel and other running processes,
9433         # and then take 1/2 of the remaining memory for the read/write buffers.
9434         if [ $MEMTOTAL -gt 512 ] ;then
9435                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9436         else
9437                 # for those poor memory-starved high-end clusters...
9438                 MEMTOTAL=$((MEMTOTAL / 2))
9439         fi
9440         echo "Mem to use for directio: $MEMTOTAL"
9441
9442         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9443         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9444         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9445         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9446                 head -n1)
9447         echo "Smallest OST: $SMALLESTOST"
9448         [[ $SMALLESTOST -lt 10240 ]] &&
9449                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9450
9451         trap cleanup_test_78 EXIT
9452
9453         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9454                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9455
9456         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9457         echo "File size: $F78SIZE"
9458         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9459         for i in $(seq 1 $NSEQ); do
9460                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9461                 echo directIO rdwr round $i of $NSEQ
9462                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9463         done
9464
9465         cleanup_test_78
9466 }
9467 run_test 78 "handle large O_DIRECT writes correctly ============"
9468
9469 test_79() { # bug 12743
9470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9471
9472         wait_delete_completed
9473
9474         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9475         BKFREE=$(calc_osc_kbytes kbytesfree)
9476         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9477
9478         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9479         DFTOTAL=`echo $STRING | cut -d, -f1`
9480         DFUSED=`echo $STRING  | cut -d, -f2`
9481         DFAVAIL=`echo $STRING | cut -d, -f3`
9482         DFFREE=$(($DFTOTAL - $DFUSED))
9483
9484         ALLOWANCE=$((64 * $OSTCOUNT))
9485
9486         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9487            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9488                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9489         fi
9490         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9491            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9492                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9493         fi
9494         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9495            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9496                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9497         fi
9498 }
9499 run_test 79 "df report consistency check ======================="
9500
9501 test_80() { # bug 10718
9502         remote_ost_nodsh && skip "remote OST with nodsh"
9503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9504
9505         # relax strong synchronous semantics for slow backends like ZFS
9506         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9507                 local soc="obdfilter.*.sync_lock_cancel"
9508                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9509
9510                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9511                 if [ -z "$save" ]; then
9512                         soc="obdfilter.*.sync_on_lock_cancel"
9513                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9514                 fi
9515
9516                 if [ "$save" != "never" ]; then
9517                         local hosts=$(comma_list $(osts_nodes))
9518
9519                         do_nodes $hosts $LCTL set_param $soc=never
9520                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9521                 fi
9522         fi
9523
9524         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9525         sync; sleep 1; sync
9526         local before=$(date +%s)
9527         cancel_lru_locks osc
9528         local after=$(date +%s)
9529         local diff=$((after - before))
9530         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9531
9532         rm -f $DIR/$tfile
9533 }
9534 run_test 80 "Page eviction is equally fast at high offsets too"
9535
9536 test_81a() { # LU-456
9537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9538         remote_ost_nodsh && skip "remote OST with nodsh"
9539
9540         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9541         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9542         do_facet ost1 lctl set_param fail_loc=0x80000228
9543
9544         # write should trigger a retry and success
9545         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9546         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9547         RC=$?
9548         if [ $RC -ne 0 ] ; then
9549                 error "write should success, but failed for $RC"
9550         fi
9551 }
9552 run_test 81a "OST should retry write when get -ENOSPC ==============="
9553
9554 test_81b() { # LU-456
9555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9556         remote_ost_nodsh && skip "remote OST with nodsh"
9557
9558         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9559         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9560         do_facet ost1 lctl set_param fail_loc=0x228
9561
9562         # write should retry several times and return -ENOSPC finally
9563         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9564         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9565         RC=$?
9566         ENOSPC=28
9567         if [ $RC -ne $ENOSPC ] ; then
9568                 error "dd should fail for -ENOSPC, but succeed."
9569         fi
9570 }
9571 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9572
9573 test_99() {
9574         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9575
9576         test_mkdir $DIR/$tdir.cvsroot
9577         chown $RUNAS_ID $DIR/$tdir.cvsroot
9578
9579         cd $TMP
9580         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9581
9582         cd /etc/init.d
9583         # some versions of cvs import exit(1) when asked to import links or
9584         # files they can't read.  ignore those files.
9585         local toignore=$(find . -type l -printf '-I %f\n' -o \
9586                          ! -perm /4 -printf '-I %f\n')
9587         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9588                 $tdir.reposname vtag rtag
9589
9590         cd $DIR
9591         test_mkdir $DIR/$tdir.reposname
9592         chown $RUNAS_ID $DIR/$tdir.reposname
9593         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9594
9595         cd $DIR/$tdir.reposname
9596         $RUNAS touch foo99
9597         $RUNAS cvs add -m 'addmsg' foo99
9598         $RUNAS cvs update
9599         $RUNAS cvs commit -m 'nomsg' foo99
9600         rm -fr $DIR/$tdir.cvsroot
9601 }
9602 run_test 99 "cvs strange file/directory operations"
9603
9604 test_100() {
9605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9606         [[ "$NETTYPE" =~ tcp ]] ||
9607                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9608         remote_ost_nodsh && skip "remote OST with nodsh"
9609         remote_mds_nodsh && skip "remote MDS with nodsh"
9610         remote_servers ||
9611                 skip "useless for local single node setup"
9612
9613         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9614                 [ "$PROT" != "tcp" ] && continue
9615                 RPORT=$(echo $REMOTE | cut -d: -f2)
9616                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9617
9618                 rc=0
9619                 LPORT=`echo $LOCAL | cut -d: -f2`
9620                 if [ $LPORT -ge 1024 ]; then
9621                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9622                         netstat -tna
9623                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9624                 fi
9625         done
9626         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9627 }
9628 run_test 100 "check local port using privileged port ==========="
9629
9630 function get_named_value()
9631 {
9632     local tag=$1
9633
9634     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9635 }
9636
9637 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9638                    awk '/^max_cached_mb/ { print $2 }')
9639
9640 cleanup_101a() {
9641         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9642         trap 0
9643 }
9644
9645 test_101a() {
9646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9647
9648         local s
9649         local discard
9650         local nreads=10000
9651         local cache_limit=32
9652
9653         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9654         trap cleanup_101a EXIT
9655         $LCTL set_param -n llite.*.read_ahead_stats=0
9656         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9657
9658         #
9659         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9660         #
9661         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9662         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9663
9664         discard=0
9665         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9666                    get_named_value 'read.but.discarded'); do
9667                         discard=$(($discard + $s))
9668         done
9669         cleanup_101a
9670
9671         $LCTL get_param osc.*-osc*.rpc_stats
9672         $LCTL get_param llite.*.read_ahead_stats
9673
9674         # Discard is generally zero, but sometimes a few random reads line up
9675         # and trigger larger readahead, which is wasted & leads to discards.
9676         if [[ $(($discard)) -gt $nreads ]]; then
9677                 error "too many ($discard) discarded pages"
9678         fi
9679         rm -f $DIR/$tfile || true
9680 }
9681 run_test 101a "check read-ahead for random reads"
9682
9683 setup_test101bc() {
9684         test_mkdir $DIR/$tdir
9685         local ssize=$1
9686         local FILE_LENGTH=$2
9687         STRIPE_OFFSET=0
9688
9689         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9690
9691         local list=$(comma_list $(osts_nodes))
9692         set_osd_param $list '' read_cache_enable 0
9693         set_osd_param $list '' writethrough_cache_enable 0
9694
9695         trap cleanup_test101bc EXIT
9696         # prepare the read-ahead file
9697         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9698
9699         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9700                                 count=$FILE_SIZE_MB 2> /dev/null
9701
9702 }
9703
9704 cleanup_test101bc() {
9705         trap 0
9706         rm -rf $DIR/$tdir
9707         rm -f $DIR/$tfile
9708
9709         local list=$(comma_list $(osts_nodes))
9710         set_osd_param $list '' read_cache_enable 1
9711         set_osd_param $list '' writethrough_cache_enable 1
9712 }
9713
9714 calc_total() {
9715         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9716 }
9717
9718 ra_check_101() {
9719         local READ_SIZE=$1
9720         local STRIPE_SIZE=$2
9721         local FILE_LENGTH=$3
9722         local RA_INC=1048576
9723         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9724         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9725                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9726         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9727                   get_named_value 'read.but.discarded' | calc_total)
9728         if [[ $DISCARD -gt $discard_limit ]]; then
9729                 $LCTL get_param llite.*.read_ahead_stats
9730                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9731         else
9732                 echo "Read-ahead success for size ${READ_SIZE}"
9733         fi
9734 }
9735
9736 test_101b() {
9737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9738         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9739
9740         local STRIPE_SIZE=1048576
9741         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9742
9743         if [ $SLOW == "yes" ]; then
9744                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9745         else
9746                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9747         fi
9748
9749         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9750
9751         # prepare the read-ahead file
9752         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9753         cancel_lru_locks osc
9754         for BIDX in 2 4 8 16 32 64 128 256
9755         do
9756                 local BSIZE=$((BIDX*4096))
9757                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9758                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9759                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9760                 $LCTL set_param -n llite.*.read_ahead_stats=0
9761                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9762                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9763                 cancel_lru_locks osc
9764                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9765         done
9766         cleanup_test101bc
9767         true
9768 }
9769 run_test 101b "check stride-io mode read-ahead ================="
9770
9771 test_101c() {
9772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9773
9774         local STRIPE_SIZE=1048576
9775         local FILE_LENGTH=$((STRIPE_SIZE*100))
9776         local nreads=10000
9777         local rsize=65536
9778         local osc_rpc_stats
9779
9780         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9781
9782         cancel_lru_locks osc
9783         $LCTL set_param osc.*.rpc_stats=0
9784         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9785         $LCTL get_param osc.*.rpc_stats
9786         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9787                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9788                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9789                 local size
9790
9791                 if [ $lines -le 20 ]; then
9792                         echo "continue debug"
9793                         continue
9794                 fi
9795                 for size in 1 2 4 8; do
9796                         local rpc=$(echo "$stats" |
9797                                     awk '($1 == "'$size':") {print $2; exit; }')
9798                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9799                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9800                 done
9801                 echo "$osc_rpc_stats check passed!"
9802         done
9803         cleanup_test101bc
9804         true
9805 }
9806 run_test 101c "check stripe_size aligned read-ahead"
9807
9808 test_101d() {
9809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9810
9811         local file=$DIR/$tfile
9812         local sz_MB=${FILESIZE_101d:-80}
9813         local ra_MB=${READAHEAD_MB:-40}
9814
9815         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9816         [ $free_MB -lt $sz_MB ] &&
9817                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9818
9819         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9820         $LFS setstripe -c -1 $file || error "setstripe failed"
9821
9822         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9823         echo Cancel LRU locks on lustre client to flush the client cache
9824         cancel_lru_locks osc
9825
9826         echo Disable read-ahead
9827         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9828         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9829         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
9830         $LCTL get_param -n llite.*.max_read_ahead_mb
9831
9832         echo "Reading the test file $file with read-ahead disabled"
9833         local sz_KB=$((sz_MB * 1024 / 4))
9834         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9835         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9836         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9837                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9838
9839         echo "Cancel LRU locks on lustre client to flush the client cache"
9840         cancel_lru_locks osc
9841         echo Enable read-ahead with ${ra_MB}MB
9842         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9843
9844         echo "Reading the test file $file with read-ahead enabled"
9845         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9846                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9847
9848         echo "read-ahead disabled time read $raOFF"
9849         echo "read-ahead enabled time read $raON"
9850
9851         rm -f $file
9852         wait_delete_completed
9853
9854         # use awk for this check instead of bash because it handles decimals
9855         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9856                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9857 }
9858 run_test 101d "file read with and without read-ahead enabled"
9859
9860 test_101e() {
9861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9862
9863         local file=$DIR/$tfile
9864         local size_KB=500  #KB
9865         local count=100
9866         local bsize=1024
9867
9868         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9869         local need_KB=$((count * size_KB))
9870         [[ $free_KB -le $need_KB ]] &&
9871                 skip_env "Need free space $need_KB, have $free_KB"
9872
9873         echo "Creating $count ${size_KB}K test files"
9874         for ((i = 0; i < $count; i++)); do
9875                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9876         done
9877
9878         echo "Cancel LRU locks on lustre client to flush the client cache"
9879         cancel_lru_locks $OSC
9880
9881         echo "Reset readahead stats"
9882         $LCTL set_param -n llite.*.read_ahead_stats=0
9883
9884         for ((i = 0; i < $count; i++)); do
9885                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9886         done
9887
9888         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9889                      get_named_value 'misses' | calc_total)
9890
9891         for ((i = 0; i < $count; i++)); do
9892                 rm -rf $file.$i 2>/dev/null
9893         done
9894
9895         #10000 means 20% reads are missing in readahead
9896         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9897 }
9898 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9899
9900 test_101f() {
9901         which iozone || skip_env "no iozone installed"
9902
9903         local old_debug=$($LCTL get_param debug)
9904         old_debug=${old_debug#*=}
9905         $LCTL set_param debug="reada mmap"
9906
9907         # create a test file
9908         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9909
9910         echo Cancel LRU locks on lustre client to flush the client cache
9911         cancel_lru_locks osc
9912
9913         echo Reset readahead stats
9914         $LCTL set_param -n llite.*.read_ahead_stats=0
9915
9916         echo mmap read the file with small block size
9917         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9918                 > /dev/null 2>&1
9919
9920         echo checking missing pages
9921         $LCTL get_param llite.*.read_ahead_stats
9922         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9923                         get_named_value 'misses' | calc_total)
9924
9925         $LCTL set_param debug="$old_debug"
9926         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9927         rm -f $DIR/$tfile
9928 }
9929 run_test 101f "check mmap read performance"
9930
9931 test_101g_brw_size_test() {
9932         local mb=$1
9933         local pages=$((mb * 1048576 / PAGE_SIZE))
9934         local file=$DIR/$tfile
9935
9936         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9937                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9938         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9939                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9940                         return 2
9941         done
9942
9943         stack_trap "rm -f $file" EXIT
9944         $LCTL set_param -n osc.*.rpc_stats=0
9945
9946         # 10 RPCs should be enough for the test
9947         local count=10
9948         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9949                 { error "dd write ${mb} MB blocks failed"; return 3; }
9950         cancel_lru_locks osc
9951         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9952                 { error "dd write ${mb} MB blocks failed"; return 4; }
9953
9954         # calculate number of full-sized read and write RPCs
9955         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9956                 sed -n '/pages per rpc/,/^$/p' |
9957                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9958                 END { print reads,writes }'))
9959         # allow one extra full-sized read RPC for async readahead
9960         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9961                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9962         [[ ${rpcs[1]} == $count ]] ||
9963                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9964 }
9965
9966 test_101g() {
9967         remote_ost_nodsh && skip "remote OST with nodsh"
9968
9969         local rpcs
9970         local osts=$(get_facets OST)
9971         local list=$(comma_list $(osts_nodes))
9972         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9973         local brw_size="obdfilter.*.brw_size"
9974
9975         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9976
9977         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9978
9979         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9980                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9981                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9982            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9983                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9984                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9985
9986                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9987                         suffix="M"
9988
9989                 if [[ $orig_mb -lt 16 ]]; then
9990                         save_lustre_params $osts "$brw_size" > $p
9991                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9992                                 error "set 16MB RPC size failed"
9993
9994                         echo "remount client to enable new RPC size"
9995                         remount_client $MOUNT || error "remount_client failed"
9996                 fi
9997
9998                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9999                 # should be able to set brw_size=12, but no rpc_stats for that
10000                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10001         fi
10002
10003         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10004
10005         if [[ $orig_mb -lt 16 ]]; then
10006                 restore_lustre_params < $p
10007                 remount_client $MOUNT || error "remount_client restore failed"
10008         fi
10009
10010         rm -f $p $DIR/$tfile
10011 }
10012 run_test 101g "Big bulk(4/16 MiB) readahead"
10013
10014 test_101h() {
10015         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10016
10017         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10018                 error "dd 70M file failed"
10019         echo Cancel LRU locks on lustre client to flush the client cache
10020         cancel_lru_locks osc
10021
10022         echo "Reset readahead stats"
10023         $LCTL set_param -n llite.*.read_ahead_stats 0
10024
10025         echo "Read 10M of data but cross 64M bundary"
10026         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10027         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10028                      get_named_value 'misses' | calc_total)
10029         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10030         rm -f $p $DIR/$tfile
10031 }
10032 run_test 101h "Readahead should cover current read window"
10033
10034 test_101i() {
10035         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10036                 error "dd 10M file failed"
10037
10038         local max_per_file_mb=$($LCTL get_param -n \
10039                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10040         cancel_lru_locks osc
10041         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10042         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10043                 error "set max_read_ahead_per_file_mb to 1 failed"
10044
10045         echo "Reset readahead stats"
10046         $LCTL set_param llite.*.read_ahead_stats=0
10047
10048         dd if=$DIR/$tfile of=/dev/null bs=2M
10049
10050         $LCTL get_param llite.*.read_ahead_stats
10051         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10052                      awk '/misses/ { print $2 }')
10053         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10054         rm -f $DIR/$tfile
10055 }
10056 run_test 101i "allow current readahead to exceed reservation"
10057
10058 test_101j() {
10059         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10060                 error "setstripe $DIR/$tfile failed"
10061         local file_size=$((1048576 * 16))
10062         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10063         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10064
10065         echo Disable read-ahead
10066         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10067
10068         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10069         for blk in $PAGE_SIZE 1048576 $file_size; do
10070                 cancel_lru_locks osc
10071                 echo "Reset readahead stats"
10072                 $LCTL set_param -n llite.*.read_ahead_stats=0
10073                 local count=$(($file_size / $blk))
10074                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10075                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10076                              get_named_value 'failed.to.fast.read' | calc_total)
10077                 $LCTL get_param -n llite.*.read_ahead_stats
10078                 [ $miss -eq $count ] || error "expected $count got $miss"
10079         done
10080
10081         rm -f $p $DIR/$tfile
10082 }
10083 run_test 101j "A complete read block should be submitted when no RA"
10084
10085 setup_test102() {
10086         test_mkdir $DIR/$tdir
10087         chown $RUNAS_ID $DIR/$tdir
10088         STRIPE_SIZE=65536
10089         STRIPE_OFFSET=1
10090         STRIPE_COUNT=$OSTCOUNT
10091         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10092
10093         trap cleanup_test102 EXIT
10094         cd $DIR
10095         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10096         cd $DIR/$tdir
10097         for num in 1 2 3 4; do
10098                 for count in $(seq 1 $STRIPE_COUNT); do
10099                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10100                                 local size=`expr $STRIPE_SIZE \* $num`
10101                                 local file=file"$num-$idx-$count"
10102                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10103                         done
10104                 done
10105         done
10106
10107         cd $DIR
10108         $1 tar cf $TMP/f102.tar $tdir --xattrs
10109 }
10110
10111 cleanup_test102() {
10112         trap 0
10113         rm -f $TMP/f102.tar
10114         rm -rf $DIR/d0.sanity/d102
10115 }
10116
10117 test_102a() {
10118         [ "$UID" != 0 ] && skip "must run as root"
10119         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10120                 skip_env "must have user_xattr"
10121
10122         [ -z "$(which setfattr 2>/dev/null)" ] &&
10123                 skip_env "could not find setfattr"
10124
10125         local testfile=$DIR/$tfile
10126
10127         touch $testfile
10128         echo "set/get xattr..."
10129         setfattr -n trusted.name1 -v value1 $testfile ||
10130                 error "setfattr -n trusted.name1=value1 $testfile failed"
10131         getfattr -n trusted.name1 $testfile 2> /dev/null |
10132           grep "trusted.name1=.value1" ||
10133                 error "$testfile missing trusted.name1=value1"
10134
10135         setfattr -n user.author1 -v author1 $testfile ||
10136                 error "setfattr -n user.author1=author1 $testfile failed"
10137         getfattr -n user.author1 $testfile 2> /dev/null |
10138           grep "user.author1=.author1" ||
10139                 error "$testfile missing trusted.author1=author1"
10140
10141         echo "listxattr..."
10142         setfattr -n trusted.name2 -v value2 $testfile ||
10143                 error "$testfile unable to set trusted.name2"
10144         setfattr -n trusted.name3 -v value3 $testfile ||
10145                 error "$testfile unable to set trusted.name3"
10146         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10147             grep "trusted.name" | wc -l) -eq 3 ] ||
10148                 error "$testfile missing 3 trusted.name xattrs"
10149
10150         setfattr -n user.author2 -v author2 $testfile ||
10151                 error "$testfile unable to set user.author2"
10152         setfattr -n user.author3 -v author3 $testfile ||
10153                 error "$testfile unable to set user.author3"
10154         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10155             grep "user.author" | wc -l) -eq 3 ] ||
10156                 error "$testfile missing 3 user.author xattrs"
10157
10158         echo "remove xattr..."
10159         setfattr -x trusted.name1 $testfile ||
10160                 error "$testfile error deleting trusted.name1"
10161         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10162                 error "$testfile did not delete trusted.name1 xattr"
10163
10164         setfattr -x user.author1 $testfile ||
10165                 error "$testfile error deleting user.author1"
10166         echo "set lustre special xattr ..."
10167         $LFS setstripe -c1 $testfile
10168         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10169                 awk -F "=" '/trusted.lov/ { print $2 }' )
10170         setfattr -n "trusted.lov" -v $lovea $testfile ||
10171                 error "$testfile doesn't ignore setting trusted.lov again"
10172         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10173                 error "$testfile allow setting invalid trusted.lov"
10174         rm -f $testfile
10175 }
10176 run_test 102a "user xattr test =================================="
10177
10178 check_102b_layout() {
10179         local layout="$*"
10180         local testfile=$DIR/$tfile
10181
10182         echo "test layout '$layout'"
10183         $LFS setstripe $layout $testfile || error "setstripe failed"
10184         $LFS getstripe -y $testfile
10185
10186         echo "get/set/list trusted.lov xattr ..." # b=10930
10187         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10188         [[ "$value" =~ "trusted.lov" ]] ||
10189                 error "can't get trusted.lov from $testfile"
10190         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10191                 error "getstripe failed"
10192
10193         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10194
10195         value=$(cut -d= -f2 <<<$value)
10196         # LU-13168: truncated xattr should fail if short lov_user_md header
10197         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10198                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10199         for len in $lens; do
10200                 echo "setfattr $len $testfile.2"
10201                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10202                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10203         done
10204         local stripe_size=$($LFS getstripe -S $testfile.2)
10205         local stripe_count=$($LFS getstripe -c $testfile.2)
10206         [[ $stripe_size -eq 65536 ]] ||
10207                 error "stripe size $stripe_size != 65536"
10208         [[ $stripe_count -eq $stripe_count_orig ]] ||
10209                 error "stripe count $stripe_count != $stripe_count_orig"
10210         rm $testfile $testfile.2
10211 }
10212
10213 test_102b() {
10214         [ -z "$(which setfattr 2>/dev/null)" ] &&
10215                 skip_env "could not find setfattr"
10216         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10217
10218         # check plain layout
10219         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10220
10221         # and also check composite layout
10222         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10223
10224 }
10225 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10226
10227 test_102c() {
10228         [ -z "$(which setfattr 2>/dev/null)" ] &&
10229                 skip_env "could not find setfattr"
10230         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10231
10232         # b10930: get/set/list lustre.lov xattr
10233         echo "get/set/list lustre.lov xattr ..."
10234         test_mkdir $DIR/$tdir
10235         chown $RUNAS_ID $DIR/$tdir
10236         local testfile=$DIR/$tdir/$tfile
10237         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10238                 error "setstripe failed"
10239         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10240                 error "getstripe failed"
10241         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10242         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10243
10244         local testfile2=${testfile}2
10245         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10246                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10247
10248         $RUNAS $MCREATE $testfile2
10249         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10250         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10251         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10252         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10253         [ $stripe_count -eq $STRIPECOUNT ] ||
10254                 error "stripe count $stripe_count != $STRIPECOUNT"
10255 }
10256 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10257
10258 compare_stripe_info1() {
10259         local stripe_index_all_zero=true
10260
10261         for num in 1 2 3 4; do
10262                 for count in $(seq 1 $STRIPE_COUNT); do
10263                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10264                                 local size=$((STRIPE_SIZE * num))
10265                                 local file=file"$num-$offset-$count"
10266                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10267                                 [[ $stripe_size -ne $size ]] &&
10268                                     error "$file: size $stripe_size != $size"
10269                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10270                                 # allow fewer stripes to be created, ORI-601
10271                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10272                                     error "$file: count $stripe_count != $count"
10273                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10274                                 [[ $stripe_index -ne 0 ]] &&
10275                                         stripe_index_all_zero=false
10276                         done
10277                 done
10278         done
10279         $stripe_index_all_zero &&
10280                 error "all files are being extracted starting from OST index 0"
10281         return 0
10282 }
10283
10284 have_xattrs_include() {
10285         tar --help | grep -q xattrs-include &&
10286                 echo --xattrs-include="lustre.*"
10287 }
10288
10289 test_102d() {
10290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10291         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10292
10293         XINC=$(have_xattrs_include)
10294         setup_test102
10295         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10296         cd $DIR/$tdir/$tdir
10297         compare_stripe_info1
10298 }
10299 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10300
10301 test_102f() {
10302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10303         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10304
10305         XINC=$(have_xattrs_include)
10306         setup_test102
10307         test_mkdir $DIR/$tdir.restore
10308         cd $DIR
10309         tar cf - --xattrs $tdir | tar xf - \
10310                 -C $DIR/$tdir.restore --xattrs $XINC
10311         cd $DIR/$tdir.restore/$tdir
10312         compare_stripe_info1
10313 }
10314 run_test 102f "tar copy files, not keep osts"
10315
10316 grow_xattr() {
10317         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10318                 skip "must have user_xattr"
10319         [ -z "$(which setfattr 2>/dev/null)" ] &&
10320                 skip_env "could not find setfattr"
10321         [ -z "$(which getfattr 2>/dev/null)" ] &&
10322                 skip_env "could not find getfattr"
10323
10324         local xsize=${1:-1024}  # in bytes
10325         local file=$DIR/$tfile
10326         local value="$(generate_string $xsize)"
10327         local xbig=trusted.big
10328         local toobig=$2
10329
10330         touch $file
10331         log "save $xbig on $file"
10332         if [ -z "$toobig" ]
10333         then
10334                 setfattr -n $xbig -v $value $file ||
10335                         error "saving $xbig on $file failed"
10336         else
10337                 setfattr -n $xbig -v $value $file &&
10338                         error "saving $xbig on $file succeeded"
10339                 return 0
10340         fi
10341
10342         local orig=$(get_xattr_value $xbig $file)
10343         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10344
10345         local xsml=trusted.sml
10346         log "save $xsml on $file"
10347         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10348
10349         local new=$(get_xattr_value $xbig $file)
10350         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10351
10352         log "grow $xsml on $file"
10353         setfattr -n $xsml -v "$value" $file ||
10354                 error "growing $xsml on $file failed"
10355
10356         new=$(get_xattr_value $xbig $file)
10357         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10358         log "$xbig still valid after growing $xsml"
10359
10360         rm -f $file
10361 }
10362
10363 test_102h() { # bug 15777
10364         grow_xattr 1024
10365 }
10366 run_test 102h "grow xattr from inside inode to external block"
10367
10368 test_102ha() {
10369         large_xattr_enabled || skip_env "ea_inode feature disabled"
10370
10371         echo "setting xattr of max xattr size: $(max_xattr_size)"
10372         grow_xattr $(max_xattr_size)
10373
10374         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10375         echo "This should fail:"
10376         grow_xattr $(($(max_xattr_size) + 10)) 1
10377 }
10378 run_test 102ha "grow xattr from inside inode to external inode"
10379
10380 test_102i() { # bug 17038
10381         [ -z "$(which getfattr 2>/dev/null)" ] &&
10382                 skip "could not find getfattr"
10383
10384         touch $DIR/$tfile
10385         ln -s $DIR/$tfile $DIR/${tfile}link
10386         getfattr -n trusted.lov $DIR/$tfile ||
10387                 error "lgetxattr on $DIR/$tfile failed"
10388         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10389                 grep -i "no such attr" ||
10390                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10391         rm -f $DIR/$tfile $DIR/${tfile}link
10392 }
10393 run_test 102i "lgetxattr test on symbolic link ============"
10394
10395 test_102j() {
10396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10397         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10398
10399         XINC=$(have_xattrs_include)
10400         setup_test102 "$RUNAS"
10401         chown $RUNAS_ID $DIR/$tdir
10402         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10403         cd $DIR/$tdir/$tdir
10404         compare_stripe_info1 "$RUNAS"
10405 }
10406 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10407
10408 test_102k() {
10409         [ -z "$(which setfattr 2>/dev/null)" ] &&
10410                 skip "could not find setfattr"
10411
10412         touch $DIR/$tfile
10413         # b22187 just check that does not crash for regular file.
10414         setfattr -n trusted.lov $DIR/$tfile
10415         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10416         local test_kdir=$DIR/$tdir
10417         test_mkdir $test_kdir
10418         local default_size=$($LFS getstripe -S $test_kdir)
10419         local default_count=$($LFS getstripe -c $test_kdir)
10420         local default_offset=$($LFS getstripe -i $test_kdir)
10421         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10422                 error 'dir setstripe failed'
10423         setfattr -n trusted.lov $test_kdir
10424         local stripe_size=$($LFS getstripe -S $test_kdir)
10425         local stripe_count=$($LFS getstripe -c $test_kdir)
10426         local stripe_offset=$($LFS getstripe -i $test_kdir)
10427         [ $stripe_size -eq $default_size ] ||
10428                 error "stripe size $stripe_size != $default_size"
10429         [ $stripe_count -eq $default_count ] ||
10430                 error "stripe count $stripe_count != $default_count"
10431         [ $stripe_offset -eq $default_offset ] ||
10432                 error "stripe offset $stripe_offset != $default_offset"
10433         rm -rf $DIR/$tfile $test_kdir
10434 }
10435 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10436
10437 test_102l() {
10438         [ -z "$(which getfattr 2>/dev/null)" ] &&
10439                 skip "could not find getfattr"
10440
10441         # LU-532 trusted. xattr is invisible to non-root
10442         local testfile=$DIR/$tfile
10443
10444         touch $testfile
10445
10446         echo "listxattr as user..."
10447         chown $RUNAS_ID $testfile
10448         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10449             grep -q "trusted" &&
10450                 error "$testfile trusted xattrs are user visible"
10451
10452         return 0;
10453 }
10454 run_test 102l "listxattr size test =================================="
10455
10456 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10457         local path=$DIR/$tfile
10458         touch $path
10459
10460         listxattr_size_check $path || error "listattr_size_check $path failed"
10461 }
10462 run_test 102m "Ensure listxattr fails on small bufffer ========"
10463
10464 cleanup_test102
10465
10466 getxattr() { # getxattr path name
10467         # Return the base64 encoding of the value of xattr name on path.
10468         local path=$1
10469         local name=$2
10470
10471         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10472         # file: $path
10473         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10474         #
10475         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10476
10477         getfattr --absolute-names --encoding=base64 --name=$name $path |
10478                 awk -F= -v name=$name '$1 == name {
10479                         print substr($0, index($0, "=") + 1);
10480         }'
10481 }
10482
10483 test_102n() { # LU-4101 mdt: protect internal xattrs
10484         [ -z "$(which setfattr 2>/dev/null)" ] &&
10485                 skip "could not find setfattr"
10486         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10487         then
10488                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10489         fi
10490
10491         local file0=$DIR/$tfile.0
10492         local file1=$DIR/$tfile.1
10493         local xattr0=$TMP/$tfile.0
10494         local xattr1=$TMP/$tfile.1
10495         local namelist="lov lma lmv link fid version som hsm"
10496         local name
10497         local value
10498
10499         rm -rf $file0 $file1 $xattr0 $xattr1
10500         touch $file0 $file1
10501
10502         # Get 'before' xattrs of $file1.
10503         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10504
10505         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10506                 namelist+=" lfsck_namespace"
10507         for name in $namelist; do
10508                 # Try to copy xattr from $file0 to $file1.
10509                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10510
10511                 setfattr --name=trusted.$name --value="$value" $file1 ||
10512                         error "setxattr 'trusted.$name' failed"
10513
10514                 # Try to set a garbage xattr.
10515                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10516
10517                 if [[ x$name == "xlov" ]]; then
10518                         setfattr --name=trusted.lov --value="$value" $file1 &&
10519                         error "setxattr invalid 'trusted.lov' success"
10520                 else
10521                         setfattr --name=trusted.$name --value="$value" $file1 ||
10522                                 error "setxattr invalid 'trusted.$name' failed"
10523                 fi
10524
10525                 # Try to remove the xattr from $file1. We don't care if this
10526                 # appears to succeed or fail, we just don't want there to be
10527                 # any changes or crashes.
10528                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10529         done
10530
10531         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10532         then
10533                 name="lfsck_ns"
10534                 # Try to copy xattr from $file0 to $file1.
10535                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10536
10537                 setfattr --name=trusted.$name --value="$value" $file1 ||
10538                         error "setxattr 'trusted.$name' failed"
10539
10540                 # Try to set a garbage xattr.
10541                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10542
10543                 setfattr --name=trusted.$name --value="$value" $file1 ||
10544                         error "setxattr 'trusted.$name' failed"
10545
10546                 # Try to remove the xattr from $file1. We don't care if this
10547                 # appears to succeed or fail, we just don't want there to be
10548                 # any changes or crashes.
10549                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10550         fi
10551
10552         # Get 'after' xattrs of file1.
10553         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10554
10555         if ! diff $xattr0 $xattr1; then
10556                 error "before and after xattrs of '$file1' differ"
10557         fi
10558
10559         rm -rf $file0 $file1 $xattr0 $xattr1
10560
10561         return 0
10562 }
10563 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10564
10565 test_102p() { # LU-4703 setxattr did not check ownership
10566         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10567                 skip "MDS needs to be at least 2.5.56"
10568
10569         local testfile=$DIR/$tfile
10570
10571         touch $testfile
10572
10573         echo "setfacl as user..."
10574         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10575         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10576
10577         echo "setfattr as user..."
10578         setfacl -m "u:$RUNAS_ID:---" $testfile
10579         $RUNAS setfattr -x system.posix_acl_access $testfile
10580         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10581 }
10582 run_test 102p "check setxattr(2) correctly fails without permission"
10583
10584 test_102q() {
10585         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10586                 skip "MDS needs to be at least 2.6.92"
10587
10588         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10589 }
10590 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10591
10592 test_102r() {
10593         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10594                 skip "MDS needs to be at least 2.6.93"
10595
10596         touch $DIR/$tfile || error "touch"
10597         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10598         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10599         rm $DIR/$tfile || error "rm"
10600
10601         #normal directory
10602         mkdir -p $DIR/$tdir || error "mkdir"
10603         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10604         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10605         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10606                 error "$testfile error deleting user.author1"
10607         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10608                 grep "user.$(basename $tdir)" &&
10609                 error "$tdir did not delete user.$(basename $tdir)"
10610         rmdir $DIR/$tdir || error "rmdir"
10611
10612         #striped directory
10613         test_mkdir $DIR/$tdir
10614         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10615         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10616         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10617                 error "$testfile error deleting user.author1"
10618         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10619                 grep "user.$(basename $tdir)" &&
10620                 error "$tdir did not delete user.$(basename $tdir)"
10621         rmdir $DIR/$tdir || error "rm striped dir"
10622 }
10623 run_test 102r "set EAs with empty values"
10624
10625 test_102s() {
10626         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10627                 skip "MDS needs to be at least 2.11.52"
10628
10629         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10630
10631         save_lustre_params client "llite.*.xattr_cache" > $save
10632
10633         for cache in 0 1; do
10634                 lctl set_param llite.*.xattr_cache=$cache
10635
10636                 rm -f $DIR/$tfile
10637                 touch $DIR/$tfile || error "touch"
10638                 for prefix in lustre security system trusted user; do
10639                         # Note getxattr() may fail with 'Operation not
10640                         # supported' or 'No such attribute' depending
10641                         # on prefix and cache.
10642                         getfattr -n $prefix.n102s $DIR/$tfile &&
10643                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10644                 done
10645         done
10646
10647         restore_lustre_params < $save
10648 }
10649 run_test 102s "getting nonexistent xattrs should fail"
10650
10651 test_102t() {
10652         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10653                 skip "MDS needs to be at least 2.11.52"
10654
10655         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10656
10657         save_lustre_params client "llite.*.xattr_cache" > $save
10658
10659         for cache in 0 1; do
10660                 lctl set_param llite.*.xattr_cache=$cache
10661
10662                 for buf_size in 0 256; do
10663                         rm -f $DIR/$tfile
10664                         touch $DIR/$tfile || error "touch"
10665                         setfattr -n user.multiop $DIR/$tfile
10666                         $MULTIOP $DIR/$tfile oa$buf_size ||
10667                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10668                 done
10669         done
10670
10671         restore_lustre_params < $save
10672 }
10673 run_test 102t "zero length xattr values handled correctly"
10674
10675 run_acl_subtest()
10676 {
10677     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10678     return $?
10679 }
10680
10681 test_103a() {
10682         [ "$UID" != 0 ] && skip "must run as root"
10683         $GSS && skip_env "could not run under gss"
10684         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10685                 skip_env "must have acl enabled"
10686         [ -z "$(which setfacl 2>/dev/null)" ] &&
10687                 skip_env "could not find setfacl"
10688         remote_mds_nodsh && skip "remote MDS with nodsh"
10689
10690         gpasswd -a daemon bin                           # LU-5641
10691         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10692
10693         declare -a identity_old
10694
10695         for num in $(seq $MDSCOUNT); do
10696                 switch_identity $num true || identity_old[$num]=$?
10697         done
10698
10699         SAVE_UMASK=$(umask)
10700         umask 0022
10701         mkdir -p $DIR/$tdir
10702         cd $DIR/$tdir
10703
10704         echo "performing cp ..."
10705         run_acl_subtest cp || error "run_acl_subtest cp failed"
10706         echo "performing getfacl-noacl..."
10707         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10708         echo "performing misc..."
10709         run_acl_subtest misc || error  "misc test failed"
10710         echo "performing permissions..."
10711         run_acl_subtest permissions || error "permissions failed"
10712         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10713         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10714                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10715                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10716         then
10717                 echo "performing permissions xattr..."
10718                 run_acl_subtest permissions_xattr ||
10719                         error "permissions_xattr failed"
10720         fi
10721         echo "performing setfacl..."
10722         run_acl_subtest setfacl || error  "setfacl test failed"
10723
10724         # inheritance test got from HP
10725         echo "performing inheritance..."
10726         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10727         chmod +x make-tree || error "chmod +x failed"
10728         run_acl_subtest inheritance || error "inheritance test failed"
10729         rm -f make-tree
10730
10731         echo "LU-974 ignore umask when acl is enabled..."
10732         run_acl_subtest 974 || error "LU-974 umask test failed"
10733         if [ $MDSCOUNT -ge 2 ]; then
10734                 run_acl_subtest 974_remote ||
10735                         error "LU-974 umask test failed under remote dir"
10736         fi
10737
10738         echo "LU-2561 newly created file is same size as directory..."
10739         if [ "$mds1_FSTYPE" != "zfs" ]; then
10740                 run_acl_subtest 2561 || error "LU-2561 test failed"
10741         else
10742                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10743         fi
10744
10745         run_acl_subtest 4924 || error "LU-4924 test failed"
10746
10747         cd $SAVE_PWD
10748         umask $SAVE_UMASK
10749
10750         for num in $(seq $MDSCOUNT); do
10751                 if [ "${identity_old[$num]}" = 1 ]; then
10752                         switch_identity $num false || identity_old[$num]=$?
10753                 fi
10754         done
10755 }
10756 run_test 103a "acl test"
10757
10758 test_103b() {
10759         declare -a pids
10760         local U
10761
10762         for U in {0..511}; do
10763                 {
10764                 local O=$(printf "%04o" $U)
10765
10766                 umask $(printf "%04o" $((511 ^ $O)))
10767                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10768                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10769
10770                 (( $S == ($O & 0666) )) ||
10771                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10772
10773                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10774                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10775                 (( $S == ($O & 0666) )) ||
10776                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10777
10778                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10779                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10780                 (( $S == ($O & 0666) )) ||
10781                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10782                 rm -f $DIR/$tfile.[smp]$0
10783                 } &
10784                 local pid=$!
10785
10786                 # limit the concurrently running threads to 64. LU-11878
10787                 local idx=$((U % 64))
10788                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10789                 pids[idx]=$pid
10790         done
10791         wait
10792 }
10793 run_test 103b "umask lfs setstripe"
10794
10795 test_103c() {
10796         mkdir -p $DIR/$tdir
10797         cp -rp $DIR/$tdir $DIR/$tdir.bak
10798
10799         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10800                 error "$DIR/$tdir shouldn't contain default ACL"
10801         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10802                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10803         true
10804 }
10805 run_test 103c "'cp -rp' won't set empty acl"
10806
10807 test_103e() {
10808         (( $MDS1_VERSION >= $(version_code 2.13.59) )) ||
10809                 skip "MDS needs to be at least 2.13.59"
10810
10811         mkdir -p $DIR/$tdir
10812         # one default ACL will be created for the file owner
10813         for U in {2..256}; do
10814                 setfacl -m default:user:$U:rwx $DIR/$tdir
10815                 numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10816                 touch $DIR/$tdir/$tfile.$U ||
10817                         error "failed to create $tfile.$U with $numacl ACLs"
10818         done
10819 }
10820 run_test 103e "inheritance of big amount of default ACLs"
10821
10822 test_104a() {
10823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10824
10825         touch $DIR/$tfile
10826         lfs df || error "lfs df failed"
10827         lfs df -ih || error "lfs df -ih failed"
10828         lfs df -h $DIR || error "lfs df -h $DIR failed"
10829         lfs df -i $DIR || error "lfs df -i $DIR failed"
10830         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10831         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10832
10833         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10834         lctl --device %$OSC deactivate
10835         lfs df || error "lfs df with deactivated OSC failed"
10836         lctl --device %$OSC activate
10837         # wait the osc back to normal
10838         wait_osc_import_ready client ost
10839
10840         lfs df || error "lfs df with reactivated OSC failed"
10841         rm -f $DIR/$tfile
10842 }
10843 run_test 104a "lfs df [-ih] [path] test ========================="
10844
10845 test_104b() {
10846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10847         [ $RUNAS_ID -eq $UID ] &&
10848                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10849
10850         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10851                         grep "Permission denied" | wc -l)))
10852         if [ $denied_cnt -ne 0 ]; then
10853                 error "lfs check servers test failed"
10854         fi
10855 }
10856 run_test 104b "$RUNAS lfs check servers test ===================="
10857
10858 test_105a() {
10859         # doesn't work on 2.4 kernels
10860         touch $DIR/$tfile
10861         if $(flock_is_enabled); then
10862                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10863         else
10864                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10865         fi
10866         rm -f $DIR/$tfile
10867 }
10868 run_test 105a "flock when mounted without -o flock test ========"
10869
10870 test_105b() {
10871         touch $DIR/$tfile
10872         if $(flock_is_enabled); then
10873                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10874         else
10875                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10876         fi
10877         rm -f $DIR/$tfile
10878 }
10879 run_test 105b "fcntl when mounted without -o flock test ========"
10880
10881 test_105c() {
10882         touch $DIR/$tfile
10883         if $(flock_is_enabled); then
10884                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10885         else
10886                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10887         fi
10888         rm -f $DIR/$tfile
10889 }
10890 run_test 105c "lockf when mounted without -o flock test"
10891
10892 test_105d() { # bug 15924
10893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10894
10895         test_mkdir $DIR/$tdir
10896         flock_is_enabled || skip_env "mount w/o flock enabled"
10897         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10898         $LCTL set_param fail_loc=0x80000315
10899         flocks_test 2 $DIR/$tdir
10900 }
10901 run_test 105d "flock race (should not freeze) ========"
10902
10903 test_105e() { # bug 22660 && 22040
10904         flock_is_enabled || skip_env "mount w/o flock enabled"
10905
10906         touch $DIR/$tfile
10907         flocks_test 3 $DIR/$tfile
10908 }
10909 run_test 105e "Two conflicting flocks from same process"
10910
10911 test_106() { #bug 10921
10912         test_mkdir $DIR/$tdir
10913         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10914         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10915 }
10916 run_test 106 "attempt exec of dir followed by chown of that dir"
10917
10918 test_107() {
10919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10920
10921         CDIR=`pwd`
10922         local file=core
10923
10924         cd $DIR
10925         rm -f $file
10926
10927         local save_pattern=$(sysctl -n kernel.core_pattern)
10928         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10929         sysctl -w kernel.core_pattern=$file
10930         sysctl -w kernel.core_uses_pid=0
10931
10932         ulimit -c unlimited
10933         sleep 60 &
10934         SLEEPPID=$!
10935
10936         sleep 1
10937
10938         kill -s 11 $SLEEPPID
10939         wait $SLEEPPID
10940         if [ -e $file ]; then
10941                 size=`stat -c%s $file`
10942                 [ $size -eq 0 ] && error "Fail to create core file $file"
10943         else
10944                 error "Fail to create core file $file"
10945         fi
10946         rm -f $file
10947         sysctl -w kernel.core_pattern=$save_pattern
10948         sysctl -w kernel.core_uses_pid=$save_uses_pid
10949         cd $CDIR
10950 }
10951 run_test 107 "Coredump on SIG"
10952
10953 test_110() {
10954         test_mkdir $DIR/$tdir
10955         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10956         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10957                 error "mkdir with 256 char should fail, but did not"
10958         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10959                 error "create with 255 char failed"
10960         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10961                 error "create with 256 char should fail, but did not"
10962
10963         ls -l $DIR/$tdir
10964         rm -rf $DIR/$tdir
10965 }
10966 run_test 110 "filename length checking"
10967
10968 #
10969 # Purpose: To verify dynamic thread (OSS) creation.
10970 #
10971 test_115() {
10972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10973         remote_ost_nodsh && skip "remote OST with nodsh"
10974
10975         # Lustre does not stop service threads once they are started.
10976         # Reset number of running threads to default.
10977         stopall
10978         setupall
10979
10980         local OSTIO_pre
10981         local save_params="$TMP/sanity-$TESTNAME.parameters"
10982
10983         # Get ll_ost_io count before I/O
10984         OSTIO_pre=$(do_facet ost1 \
10985                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10986         # Exit if lustre is not running (ll_ost_io not running).
10987         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10988
10989         echo "Starting with $OSTIO_pre threads"
10990         local thread_max=$((OSTIO_pre * 2))
10991         local rpc_in_flight=$((thread_max * 2))
10992         # Number of I/O Process proposed to be started.
10993         local nfiles
10994         local facets=$(get_facets OST)
10995
10996         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10997         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10998
10999         # Set in_flight to $rpc_in_flight
11000         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11001                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11002         nfiles=${rpc_in_flight}
11003         # Set ost thread_max to $thread_max
11004         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11005
11006         # 5 Minutes should be sufficient for max number of OSS
11007         # threads(thread_max) to be created.
11008         local timeout=300
11009
11010         # Start I/O.
11011         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11012         test_mkdir $DIR/$tdir
11013         for i in $(seq $nfiles); do
11014                 local file=$DIR/$tdir/${tfile}-$i
11015                 $LFS setstripe -c -1 -i 0 $file
11016                 ($WTL $file $timeout)&
11017         done
11018
11019         # I/O Started - Wait for thread_started to reach thread_max or report
11020         # error if thread_started is more than thread_max.
11021         echo "Waiting for thread_started to reach thread_max"
11022         local thread_started=0
11023         local end_time=$((SECONDS + timeout))
11024
11025         while [ $SECONDS -le $end_time ] ; do
11026                 echo -n "."
11027                 # Get ost i/o thread_started count.
11028                 thread_started=$(do_facet ost1 \
11029                         "$LCTL get_param \
11030                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11031                 # Break out if thread_started is equal/greater than thread_max
11032                 if [[ $thread_started -ge $thread_max ]]; then
11033                         echo ll_ost_io thread_started $thread_started, \
11034                                 equal/greater than thread_max $thread_max
11035                         break
11036                 fi
11037                 sleep 1
11038         done
11039
11040         # Cleanup - We have the numbers, Kill i/o jobs if running.
11041         jobcount=($(jobs -p))
11042         for i in $(seq 0 $((${#jobcount[@]}-1)))
11043         do
11044                 kill -9 ${jobcount[$i]}
11045                 if [ $? -ne 0 ] ; then
11046                         echo Warning: \
11047                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11048                 fi
11049         done
11050
11051         # Cleanup files left by WTL binary.
11052         for i in $(seq $nfiles); do
11053                 local file=$DIR/$tdir/${tfile}-$i
11054                 rm -rf $file
11055                 if [ $? -ne 0 ] ; then
11056                         echo "Warning: Failed to delete file $file"
11057                 fi
11058         done
11059
11060         restore_lustre_params <$save_params
11061         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11062
11063         # Error out if no new thread has started or Thread started is greater
11064         # than thread max.
11065         if [[ $thread_started -le $OSTIO_pre ||
11066                         $thread_started -gt $thread_max ]]; then
11067                 error "ll_ost_io: thread_started $thread_started" \
11068                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11069                       "No new thread started or thread started greater " \
11070                       "than thread_max."
11071         fi
11072 }
11073 run_test 115 "verify dynamic thread creation===================="
11074
11075 free_min_max () {
11076         wait_delete_completed
11077         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11078         echo "OST kbytes available: ${AVAIL[@]}"
11079         MAXV=${AVAIL[0]}
11080         MAXI=0
11081         MINV=${AVAIL[0]}
11082         MINI=0
11083         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11084                 #echo OST $i: ${AVAIL[i]}kb
11085                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11086                         MAXV=${AVAIL[i]}
11087                         MAXI=$i
11088                 fi
11089                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11090                         MINV=${AVAIL[i]}
11091                         MINI=$i
11092                 fi
11093         done
11094         echo "Min free space: OST $MINI: $MINV"
11095         echo "Max free space: OST $MAXI: $MAXV"
11096 }
11097
11098 test_116a() { # was previously test_116()
11099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11100         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11101         remote_mds_nodsh && skip "remote MDS with nodsh"
11102
11103         echo -n "Free space priority "
11104         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11105                 head -n1
11106         declare -a AVAIL
11107         free_min_max
11108
11109         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11110         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11111         trap simple_cleanup_common EXIT
11112
11113         # Check if we need to generate uneven OSTs
11114         test_mkdir -p $DIR/$tdir/OST${MINI}
11115         local FILL=$((MINV / 4))
11116         local DIFF=$((MAXV - MINV))
11117         local DIFF2=$((DIFF * 100 / MINV))
11118
11119         local threshold=$(do_facet $SINGLEMDS \
11120                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11121         threshold=${threshold%%%}
11122         echo -n "Check for uneven OSTs: "
11123         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11124
11125         if [[ $DIFF2 -gt $threshold ]]; then
11126                 echo "ok"
11127                 echo "Don't need to fill OST$MINI"
11128         else
11129                 # generate uneven OSTs. Write 2% over the QOS threshold value
11130                 echo "no"
11131                 DIFF=$((threshold - DIFF2 + 2))
11132                 DIFF2=$((MINV * DIFF / 100))
11133                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11134                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11135                         error "setstripe failed"
11136                 DIFF=$((DIFF2 / 2048))
11137                 i=0
11138                 while [ $i -lt $DIFF ]; do
11139                         i=$((i + 1))
11140                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11141                                 bs=2M count=1 2>/dev/null
11142                         echo -n .
11143                 done
11144                 echo .
11145                 sync
11146                 sleep_maxage
11147                 free_min_max
11148         fi
11149
11150         DIFF=$((MAXV - MINV))
11151         DIFF2=$((DIFF * 100 / MINV))
11152         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11153         if [ $DIFF2 -gt $threshold ]; then
11154                 echo "ok"
11155         else
11156                 echo "failed - QOS mode won't be used"
11157                 simple_cleanup_common
11158                 skip "QOS imbalance criteria not met"
11159         fi
11160
11161         MINI1=$MINI
11162         MINV1=$MINV
11163         MAXI1=$MAXI
11164         MAXV1=$MAXV
11165
11166         # now fill using QOS
11167         $LFS setstripe -c 1 $DIR/$tdir
11168         FILL=$((FILL / 200))
11169         if [ $FILL -gt 600 ]; then
11170                 FILL=600
11171         fi
11172         echo "writing $FILL files to QOS-assigned OSTs"
11173         i=0
11174         while [ $i -lt $FILL ]; do
11175                 i=$((i + 1))
11176                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11177                         count=1 2>/dev/null
11178                 echo -n .
11179         done
11180         echo "wrote $i 200k files"
11181         sync
11182         sleep_maxage
11183
11184         echo "Note: free space may not be updated, so measurements might be off"
11185         free_min_max
11186         DIFF2=$((MAXV - MINV))
11187         echo "free space delta: orig $DIFF final $DIFF2"
11188         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11189         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11190         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11191         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11192         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11193         if [[ $DIFF -gt 0 ]]; then
11194                 FILL=$((DIFF2 * 100 / DIFF - 100))
11195                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11196         fi
11197
11198         # Figure out which files were written where
11199         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11200                awk '/'$MINI1': / {print $2; exit}')
11201         echo $UUID
11202         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11203         echo "$MINC files created on smaller OST $MINI1"
11204         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11205                awk '/'$MAXI1': / {print $2; exit}')
11206         echo $UUID
11207         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11208         echo "$MAXC files created on larger OST $MAXI1"
11209         if [[ $MINC -gt 0 ]]; then
11210                 FILL=$((MAXC * 100 / MINC - 100))
11211                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11212         fi
11213         [[ $MAXC -gt $MINC ]] ||
11214                 error_ignore LU-9 "stripe QOS didn't balance free space"
11215         simple_cleanup_common
11216 }
11217 run_test 116a "stripe QOS: free space balance ==================="
11218
11219 test_116b() { # LU-2093
11220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11221         remote_mds_nodsh && skip "remote MDS with nodsh"
11222
11223 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11224         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11225                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11226         [ -z "$old_rr" ] && skip "no QOS"
11227         do_facet $SINGLEMDS lctl set_param \
11228                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11229         mkdir -p $DIR/$tdir
11230         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11231         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11232         do_facet $SINGLEMDS lctl set_param fail_loc=0
11233         rm -rf $DIR/$tdir
11234         do_facet $SINGLEMDS lctl set_param \
11235                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11236 }
11237 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11238
11239 test_117() # bug 10891
11240 {
11241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11242
11243         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11244         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11245         lctl set_param fail_loc=0x21e
11246         > $DIR/$tfile || error "truncate failed"
11247         lctl set_param fail_loc=0
11248         echo "Truncate succeeded."
11249         rm -f $DIR/$tfile
11250 }
11251 run_test 117 "verify osd extend =========="
11252
11253 NO_SLOW_RESENDCOUNT=4
11254 export OLD_RESENDCOUNT=""
11255 set_resend_count () {
11256         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11257         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11258         lctl set_param -n $PROC_RESENDCOUNT $1
11259         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11260 }
11261
11262 # for reduce test_118* time (b=14842)
11263 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11264
11265 # Reset async IO behavior after error case
11266 reset_async() {
11267         FILE=$DIR/reset_async
11268
11269         # Ensure all OSCs are cleared
11270         $LFS setstripe -c -1 $FILE
11271         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11272         sync
11273         rm $FILE
11274 }
11275
11276 test_118a() #bug 11710
11277 {
11278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11279
11280         reset_async
11281
11282         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11283         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11284         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11285
11286         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11287                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11288                 return 1;
11289         fi
11290         rm -f $DIR/$tfile
11291 }
11292 run_test 118a "verify O_SYNC works =========="
11293
11294 test_118b()
11295 {
11296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11297         remote_ost_nodsh && skip "remote OST with nodsh"
11298
11299         reset_async
11300
11301         #define OBD_FAIL_SRV_ENOENT 0x217
11302         set_nodes_failloc "$(osts_nodes)" 0x217
11303         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11304         RC=$?
11305         set_nodes_failloc "$(osts_nodes)" 0
11306         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11307         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11308                     grep -c writeback)
11309
11310         if [[ $RC -eq 0 ]]; then
11311                 error "Must return error due to dropped pages, rc=$RC"
11312                 return 1;
11313         fi
11314
11315         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11316                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11317                 return 1;
11318         fi
11319
11320         echo "Dirty pages not leaked on ENOENT"
11321
11322         # Due to the above error the OSC will issue all RPCs syncronously
11323         # until a subsequent RPC completes successfully without error.
11324         $MULTIOP $DIR/$tfile Ow4096yc
11325         rm -f $DIR/$tfile
11326
11327         return 0
11328 }
11329 run_test 118b "Reclaim dirty pages on fatal error =========="
11330
11331 test_118c()
11332 {
11333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11334
11335         # for 118c, restore the original resend count, LU-1940
11336         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11337                                 set_resend_count $OLD_RESENDCOUNT
11338         remote_ost_nodsh && skip "remote OST with nodsh"
11339
11340         reset_async
11341
11342         #define OBD_FAIL_OST_EROFS               0x216
11343         set_nodes_failloc "$(osts_nodes)" 0x216
11344
11345         # multiop should block due to fsync until pages are written
11346         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11347         MULTIPID=$!
11348         sleep 1
11349
11350         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11351                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11352         fi
11353
11354         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11355                     grep -c writeback)
11356         if [[ $WRITEBACK -eq 0 ]]; then
11357                 error "No page in writeback, writeback=$WRITEBACK"
11358         fi
11359
11360         set_nodes_failloc "$(osts_nodes)" 0
11361         wait $MULTIPID
11362         RC=$?
11363         if [[ $RC -ne 0 ]]; then
11364                 error "Multiop fsync failed, rc=$RC"
11365         fi
11366
11367         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11368         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11369                     grep -c writeback)
11370         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11371                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11372         fi
11373
11374         rm -f $DIR/$tfile
11375         echo "Dirty pages flushed via fsync on EROFS"
11376         return 0
11377 }
11378 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11379
11380 # continue to use small resend count to reduce test_118* time (b=14842)
11381 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11382
11383 test_118d()
11384 {
11385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11386         remote_ost_nodsh && skip "remote OST with nodsh"
11387
11388         reset_async
11389
11390         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11391         set_nodes_failloc "$(osts_nodes)" 0x214
11392         # multiop should block due to fsync until pages are written
11393         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11394         MULTIPID=$!
11395         sleep 1
11396
11397         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11398                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11399         fi
11400
11401         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11402                     grep -c writeback)
11403         if [[ $WRITEBACK -eq 0 ]]; then
11404                 error "No page in writeback, writeback=$WRITEBACK"
11405         fi
11406
11407         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11408         set_nodes_failloc "$(osts_nodes)" 0
11409
11410         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11411         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11412                     grep -c writeback)
11413         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11414                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11415         fi
11416
11417         rm -f $DIR/$tfile
11418         echo "Dirty pages gaurenteed flushed via fsync"
11419         return 0
11420 }
11421 run_test 118d "Fsync validation inject a delay of the bulk =========="
11422
11423 test_118f() {
11424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11425
11426         reset_async
11427
11428         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11429         lctl set_param fail_loc=0x8000040a
11430
11431         # Should simulate EINVAL error which is fatal
11432         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11433         RC=$?
11434         if [[ $RC -eq 0 ]]; then
11435                 error "Must return error due to dropped pages, rc=$RC"
11436         fi
11437
11438         lctl set_param fail_loc=0x0
11439
11440         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11441         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11442         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11443                     grep -c writeback)
11444         if [[ $LOCKED -ne 0 ]]; then
11445                 error "Locked pages remain in cache, locked=$LOCKED"
11446         fi
11447
11448         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11449                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11450         fi
11451
11452         rm -f $DIR/$tfile
11453         echo "No pages locked after fsync"
11454
11455         reset_async
11456         return 0
11457 }
11458 run_test 118f "Simulate unrecoverable OSC side error =========="
11459
11460 test_118g() {
11461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11462
11463         reset_async
11464
11465         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11466         lctl set_param fail_loc=0x406
11467
11468         # simulate local -ENOMEM
11469         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11470         RC=$?
11471
11472         lctl set_param fail_loc=0
11473         if [[ $RC -eq 0 ]]; then
11474                 error "Must return error due to dropped pages, rc=$RC"
11475         fi
11476
11477         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11478         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11479         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11480                         grep -c writeback)
11481         if [[ $LOCKED -ne 0 ]]; then
11482                 error "Locked pages remain in cache, locked=$LOCKED"
11483         fi
11484
11485         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11486                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11487         fi
11488
11489         rm -f $DIR/$tfile
11490         echo "No pages locked after fsync"
11491
11492         reset_async
11493         return 0
11494 }
11495 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11496
11497 test_118h() {
11498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11499         remote_ost_nodsh && skip "remote OST with nodsh"
11500
11501         reset_async
11502
11503         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11504         set_nodes_failloc "$(osts_nodes)" 0x20e
11505         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11506         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11507         RC=$?
11508
11509         set_nodes_failloc "$(osts_nodes)" 0
11510         if [[ $RC -eq 0 ]]; then
11511                 error "Must return error due to dropped pages, rc=$RC"
11512         fi
11513
11514         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11515         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11516         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11517                     grep -c writeback)
11518         if [[ $LOCKED -ne 0 ]]; then
11519                 error "Locked pages remain in cache, locked=$LOCKED"
11520         fi
11521
11522         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11523                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11524         fi
11525
11526         rm -f $DIR/$tfile
11527         echo "No pages locked after fsync"
11528
11529         return 0
11530 }
11531 run_test 118h "Verify timeout in handling recoverables errors  =========="
11532
11533 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11534
11535 test_118i() {
11536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11537         remote_ost_nodsh && skip "remote OST with nodsh"
11538
11539         reset_async
11540
11541         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11542         set_nodes_failloc "$(osts_nodes)" 0x20e
11543
11544         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11545         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11546         PID=$!
11547         sleep 5
11548         set_nodes_failloc "$(osts_nodes)" 0
11549
11550         wait $PID
11551         RC=$?
11552         if [[ $RC -ne 0 ]]; then
11553                 error "got error, but should be not, rc=$RC"
11554         fi
11555
11556         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11557         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11558         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11559         if [[ $LOCKED -ne 0 ]]; then
11560                 error "Locked pages remain in cache, locked=$LOCKED"
11561         fi
11562
11563         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11564                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11565         fi
11566
11567         rm -f $DIR/$tfile
11568         echo "No pages locked after fsync"
11569
11570         return 0
11571 }
11572 run_test 118i "Fix error before timeout in recoverable error  =========="
11573
11574 [ "$SLOW" = "no" ] && set_resend_count 4
11575
11576 test_118j() {
11577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11578         remote_ost_nodsh && skip "remote OST with nodsh"
11579
11580         reset_async
11581
11582         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11583         set_nodes_failloc "$(osts_nodes)" 0x220
11584
11585         # return -EIO from OST
11586         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11587         RC=$?
11588         set_nodes_failloc "$(osts_nodes)" 0x0
11589         if [[ $RC -eq 0 ]]; then
11590                 error "Must return error due to dropped pages, rc=$RC"
11591         fi
11592
11593         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11594         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11595         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11596         if [[ $LOCKED -ne 0 ]]; then
11597                 error "Locked pages remain in cache, locked=$LOCKED"
11598         fi
11599
11600         # in recoverable error on OST we want resend and stay until it finished
11601         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11602                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11603         fi
11604
11605         rm -f $DIR/$tfile
11606         echo "No pages locked after fsync"
11607
11608         return 0
11609 }
11610 run_test 118j "Simulate unrecoverable OST side error =========="
11611
11612 test_118k()
11613 {
11614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11615         remote_ost_nodsh && skip "remote OSTs with nodsh"
11616
11617         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11618         set_nodes_failloc "$(osts_nodes)" 0x20e
11619         test_mkdir $DIR/$tdir
11620
11621         for ((i=0;i<10;i++)); do
11622                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11623                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11624                 SLEEPPID=$!
11625                 sleep 0.500s
11626                 kill $SLEEPPID
11627                 wait $SLEEPPID
11628         done
11629
11630         set_nodes_failloc "$(osts_nodes)" 0
11631         rm -rf $DIR/$tdir
11632 }
11633 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11634
11635 test_118l() # LU-646
11636 {
11637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11638
11639         test_mkdir $DIR/$tdir
11640         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11641         rm -rf $DIR/$tdir
11642 }
11643 run_test 118l "fsync dir"
11644
11645 test_118m() # LU-3066
11646 {
11647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11648
11649         test_mkdir $DIR/$tdir
11650         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11651         rm -rf $DIR/$tdir
11652 }
11653 run_test 118m "fdatasync dir ========="
11654
11655 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11656
11657 test_118n()
11658 {
11659         local begin
11660         local end
11661
11662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11663         remote_ost_nodsh && skip "remote OSTs with nodsh"
11664
11665         # Sleep to avoid a cached response.
11666         #define OBD_STATFS_CACHE_SECONDS 1
11667         sleep 2
11668
11669         # Inject a 10 second delay in the OST_STATFS handler.
11670         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11671         set_nodes_failloc "$(osts_nodes)" 0x242
11672
11673         begin=$SECONDS
11674         stat --file-system $MOUNT > /dev/null
11675         end=$SECONDS
11676
11677         set_nodes_failloc "$(osts_nodes)" 0
11678
11679         if ((end - begin > 20)); then
11680             error "statfs took $((end - begin)) seconds, expected 10"
11681         fi
11682 }
11683 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11684
11685 test_119a() # bug 11737
11686 {
11687         BSIZE=$((512 * 1024))
11688         directio write $DIR/$tfile 0 1 $BSIZE
11689         # We ask to read two blocks, which is more than a file size.
11690         # directio will indicate an error when requested and actual
11691         # sizes aren't equeal (a normal situation in this case) and
11692         # print actual read amount.
11693         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11694         if [ "$NOB" != "$BSIZE" ]; then
11695                 error "read $NOB bytes instead of $BSIZE"
11696         fi
11697         rm -f $DIR/$tfile
11698 }
11699 run_test 119a "Short directIO read must return actual read amount"
11700
11701 test_119b() # bug 11737
11702 {
11703         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11704
11705         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11706         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11707         sync
11708         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11709                 error "direct read failed"
11710         rm -f $DIR/$tfile
11711 }
11712 run_test 119b "Sparse directIO read must return actual read amount"
11713
11714 test_119c() # bug 13099
11715 {
11716         BSIZE=1048576
11717         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11718         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11719         rm -f $DIR/$tfile
11720 }
11721 run_test 119c "Testing for direct read hitting hole"
11722
11723 test_119d() # bug 15950
11724 {
11725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11726
11727         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11728         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11729         BSIZE=1048576
11730         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11731         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11732         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11733         lctl set_param fail_loc=0x40d
11734         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11735         pid_dio=$!
11736         sleep 1
11737         cat $DIR/$tfile > /dev/null &
11738         lctl set_param fail_loc=0
11739         pid_reads=$!
11740         wait $pid_dio
11741         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11742         sleep 2
11743         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11744         error "the read rpcs have not completed in 2s"
11745         rm -f $DIR/$tfile
11746         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11747 }
11748 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11749
11750 test_120a() {
11751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11752         remote_mds_nodsh && skip "remote MDS with nodsh"
11753         test_mkdir -i0 -c1 $DIR/$tdir
11754         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11755                 skip_env "no early lock cancel on server"
11756
11757         lru_resize_disable mdc
11758         lru_resize_disable osc
11759         cancel_lru_locks mdc
11760         # asynchronous object destroy at MDT could cause bl ast to client
11761         cancel_lru_locks osc
11762
11763         stat $DIR/$tdir > /dev/null
11764         can1=$(do_facet mds1 \
11765                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11766                awk '/ldlm_cancel/ {print $2}')
11767         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11768                awk '/ldlm_bl_callback/ {print $2}')
11769         test_mkdir -i0 -c1 $DIR/$tdir/d1
11770         can2=$(do_facet mds1 \
11771                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11772                awk '/ldlm_cancel/ {print $2}')
11773         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11774                awk '/ldlm_bl_callback/ {print $2}')
11775         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11776         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11777         lru_resize_enable mdc
11778         lru_resize_enable osc
11779 }
11780 run_test 120a "Early Lock Cancel: mkdir test"
11781
11782 test_120b() {
11783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11784         remote_mds_nodsh && skip "remote MDS with nodsh"
11785         test_mkdir $DIR/$tdir
11786         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11787                 skip_env "no early lock cancel on server"
11788
11789         lru_resize_disable mdc
11790         lru_resize_disable osc
11791         cancel_lru_locks mdc
11792         stat $DIR/$tdir > /dev/null
11793         can1=$(do_facet $SINGLEMDS \
11794                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11795                awk '/ldlm_cancel/ {print $2}')
11796         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11797                awk '/ldlm_bl_callback/ {print $2}')
11798         touch $DIR/$tdir/f1
11799         can2=$(do_facet $SINGLEMDS \
11800                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11801                awk '/ldlm_cancel/ {print $2}')
11802         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11803                awk '/ldlm_bl_callback/ {print $2}')
11804         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11805         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11806         lru_resize_enable mdc
11807         lru_resize_enable osc
11808 }
11809 run_test 120b "Early Lock Cancel: create test"
11810
11811 test_120c() {
11812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11813         remote_mds_nodsh && skip "remote MDS with nodsh"
11814         test_mkdir -i0 -c1 $DIR/$tdir
11815         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11816                 skip "no early lock cancel on server"
11817
11818         lru_resize_disable mdc
11819         lru_resize_disable osc
11820         test_mkdir -i0 -c1 $DIR/$tdir/d1
11821         test_mkdir -i0 -c1 $DIR/$tdir/d2
11822         touch $DIR/$tdir/d1/f1
11823         cancel_lru_locks mdc
11824         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11825         can1=$(do_facet mds1 \
11826                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11827                awk '/ldlm_cancel/ {print $2}')
11828         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11829                awk '/ldlm_bl_callback/ {print $2}')
11830         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11831         can2=$(do_facet mds1 \
11832                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11833                awk '/ldlm_cancel/ {print $2}')
11834         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11835                awk '/ldlm_bl_callback/ {print $2}')
11836         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11837         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11838         lru_resize_enable mdc
11839         lru_resize_enable osc
11840 }
11841 run_test 120c "Early Lock Cancel: link test"
11842
11843 test_120d() {
11844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11845         remote_mds_nodsh && skip "remote MDS with nodsh"
11846         test_mkdir -i0 -c1 $DIR/$tdir
11847         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11848                 skip_env "no early lock cancel on server"
11849
11850         lru_resize_disable mdc
11851         lru_resize_disable osc
11852         touch $DIR/$tdir
11853         cancel_lru_locks mdc
11854         stat $DIR/$tdir > /dev/null
11855         can1=$(do_facet mds1 \
11856                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11857                awk '/ldlm_cancel/ {print $2}')
11858         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11859                awk '/ldlm_bl_callback/ {print $2}')
11860         chmod a+x $DIR/$tdir
11861         can2=$(do_facet mds1 \
11862                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11863                awk '/ldlm_cancel/ {print $2}')
11864         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11865                awk '/ldlm_bl_callback/ {print $2}')
11866         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11867         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11868         lru_resize_enable mdc
11869         lru_resize_enable osc
11870 }
11871 run_test 120d "Early Lock Cancel: setattr test"
11872
11873 test_120e() {
11874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11875         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11876                 skip_env "no early lock cancel on server"
11877         remote_mds_nodsh && skip "remote MDS with nodsh"
11878
11879         local dlmtrace_set=false
11880
11881         test_mkdir -i0 -c1 $DIR/$tdir
11882         lru_resize_disable mdc
11883         lru_resize_disable osc
11884         ! $LCTL get_param debug | grep -q dlmtrace &&
11885                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11886         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11887         cancel_lru_locks mdc
11888         cancel_lru_locks osc
11889         dd if=$DIR/$tdir/f1 of=/dev/null
11890         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11891         # XXX client can not do early lock cancel of OST lock
11892         # during unlink (LU-4206), so cancel osc lock now.
11893         sleep 2
11894         cancel_lru_locks osc
11895         can1=$(do_facet mds1 \
11896                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11897                awk '/ldlm_cancel/ {print $2}')
11898         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11899                awk '/ldlm_bl_callback/ {print $2}')
11900         unlink $DIR/$tdir/f1
11901         sleep 5
11902         can2=$(do_facet mds1 \
11903                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11904                awk '/ldlm_cancel/ {print $2}')
11905         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11906                awk '/ldlm_bl_callback/ {print $2}')
11907         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11908                 $LCTL dk $TMP/cancel.debug.txt
11909         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11910                 $LCTL dk $TMP/blocking.debug.txt
11911         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11912         lru_resize_enable mdc
11913         lru_resize_enable osc
11914 }
11915 run_test 120e "Early Lock Cancel: unlink test"
11916
11917 test_120f() {
11918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11919         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11920                 skip_env "no early lock cancel on server"
11921         remote_mds_nodsh && skip "remote MDS with nodsh"
11922
11923         test_mkdir -i0 -c1 $DIR/$tdir
11924         lru_resize_disable mdc
11925         lru_resize_disable osc
11926         test_mkdir -i0 -c1 $DIR/$tdir/d1
11927         test_mkdir -i0 -c1 $DIR/$tdir/d2
11928         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11929         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11930         cancel_lru_locks mdc
11931         cancel_lru_locks osc
11932         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11933         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11934         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11935         # XXX client can not do early lock cancel of OST lock
11936         # during rename (LU-4206), so cancel osc lock now.
11937         sleep 2
11938         cancel_lru_locks osc
11939         can1=$(do_facet mds1 \
11940                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11941                awk '/ldlm_cancel/ {print $2}')
11942         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11943                awk '/ldlm_bl_callback/ {print $2}')
11944         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11945         sleep 5
11946         can2=$(do_facet mds1 \
11947                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11948                awk '/ldlm_cancel/ {print $2}')
11949         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11950                awk '/ldlm_bl_callback/ {print $2}')
11951         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11952         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11953         lru_resize_enable mdc
11954         lru_resize_enable osc
11955 }
11956 run_test 120f "Early Lock Cancel: rename test"
11957
11958 test_120g() {
11959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11960         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11961                 skip_env "no early lock cancel on server"
11962         remote_mds_nodsh && skip "remote MDS with nodsh"
11963
11964         lru_resize_disable mdc
11965         lru_resize_disable osc
11966         count=10000
11967         echo create $count files
11968         test_mkdir $DIR/$tdir
11969         cancel_lru_locks mdc
11970         cancel_lru_locks osc
11971         t0=$(date +%s)
11972
11973         can0=$(do_facet $SINGLEMDS \
11974                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11975                awk '/ldlm_cancel/ {print $2}')
11976         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11977                awk '/ldlm_bl_callback/ {print $2}')
11978         createmany -o $DIR/$tdir/f $count
11979         sync
11980         can1=$(do_facet $SINGLEMDS \
11981                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11982                awk '/ldlm_cancel/ {print $2}')
11983         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11984                awk '/ldlm_bl_callback/ {print $2}')
11985         t1=$(date +%s)
11986         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11987         echo rm $count files
11988         rm -r $DIR/$tdir
11989         sync
11990         can2=$(do_facet $SINGLEMDS \
11991                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11992                awk '/ldlm_cancel/ {print $2}')
11993         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11994                awk '/ldlm_bl_callback/ {print $2}')
11995         t2=$(date +%s)
11996         echo total: $count removes in $((t2-t1))
11997         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11998         sleep 2
11999         # wait for commitment of removal
12000         lru_resize_enable mdc
12001         lru_resize_enable osc
12002 }
12003 run_test 120g "Early Lock Cancel: performance test"
12004
12005 test_121() { #bug #10589
12006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12007
12008         rm -rf $DIR/$tfile
12009         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12010 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12011         lctl set_param fail_loc=0x310
12012         cancel_lru_locks osc > /dev/null
12013         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12014         lctl set_param fail_loc=0
12015         [[ $reads -eq $writes ]] ||
12016                 error "read $reads blocks, must be $writes blocks"
12017 }
12018 run_test 121 "read cancel race ========="
12019
12020 test_123a_base() { # was test 123, statahead(bug 11401)
12021         local lsx="$1"
12022
12023         SLOWOK=0
12024         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12025                 log "testing UP system. Performance may be lower than expected."
12026                 SLOWOK=1
12027         fi
12028
12029         rm -rf $DIR/$tdir
12030         test_mkdir $DIR/$tdir
12031         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12032         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12033         MULT=10
12034         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12035                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12036
12037                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12038                 lctl set_param -n llite.*.statahead_max 0
12039                 lctl get_param llite.*.statahead_max
12040                 cancel_lru_locks mdc
12041                 cancel_lru_locks osc
12042                 stime=$(date +%s)
12043                 time $lsx $DIR/$tdir | wc -l
12044                 etime=$(date +%s)
12045                 delta=$((etime - stime))
12046                 log "$lsx $i files without statahead: $delta sec"
12047                 lctl set_param llite.*.statahead_max=$max
12048
12049                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12050                         grep "statahead wrong:" | awk '{print $3}')
12051                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12052                 cancel_lru_locks mdc
12053                 cancel_lru_locks osc
12054                 stime=$(date +%s)
12055                 time $lsx $DIR/$tdir | wc -l
12056                 etime=$(date +%s)
12057                 delta_sa=$((etime - stime))
12058                 log "$lsx $i files with statahead: $delta_sa sec"
12059                 lctl get_param -n llite.*.statahead_stats
12060                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12061                         grep "statahead wrong:" | awk '{print $3}')
12062
12063                 [[ $swrong -lt $ewrong ]] &&
12064                         log "statahead was stopped, maybe too many locks held!"
12065                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12066
12067                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12068                         max=$(lctl get_param -n llite.*.statahead_max |
12069                                 head -n 1)
12070                         lctl set_param -n llite.*.statahead_max 0
12071                         lctl get_param llite.*.statahead_max
12072                         cancel_lru_locks mdc
12073                         cancel_lru_locks osc
12074                         stime=$(date +%s)
12075                         time $lsx $DIR/$tdir | wc -l
12076                         etime=$(date +%s)
12077                         delta=$((etime - stime))
12078                         log "$lsx $i files again without statahead: $delta sec"
12079                         lctl set_param llite.*.statahead_max=$max
12080                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12081                                 if [  $SLOWOK -eq 0 ]; then
12082                                         error "$lsx $i files is slower with statahead!"
12083                                 else
12084                                         log "$lsx $i files is slower with statahead!"
12085                                 fi
12086                                 break
12087                         fi
12088                 fi
12089
12090                 [ $delta -gt 20 ] && break
12091                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12092                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12093         done
12094         log "$lsx done"
12095
12096         stime=$(date +%s)
12097         rm -r $DIR/$tdir
12098         sync
12099         etime=$(date +%s)
12100         delta=$((etime - stime))
12101         log "rm -r $DIR/$tdir/: $delta seconds"
12102         log "rm done"
12103         lctl get_param -n llite.*.statahead_stats
12104 }
12105
12106 test_123aa() {
12107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12108
12109         test_123a_base "ls -l"
12110 }
12111 run_test 123aa "verify statahead work"
12112
12113 test_123ab() {
12114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12115
12116         statx_supported || skip_env "Test must be statx() syscall supported"
12117
12118         test_123a_base "$STATX -l"
12119 }
12120 run_test 123ab "verify statahead work by using statx"
12121
12122 test_123ac() {
12123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12124
12125         statx_supported || skip_env "Test must be statx() syscall supported"
12126
12127         local rpcs_before
12128         local rpcs_after
12129         local agl_before
12130         local agl_after
12131
12132         cancel_lru_locks $OSC
12133         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12134         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12135                 awk '/agl.total:/ {print $3}')
12136         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12137         test_123a_base "$STATX --cached=always -D"
12138         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12139                 awk '/agl.total:/ {print $3}')
12140         [ $agl_before -eq $agl_after ] ||
12141                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12142         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12143         [ $rpcs_after -eq $rpcs_before ] ||
12144                 error "$STATX should not send glimpse RPCs to $OSC"
12145 }
12146 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12147
12148 test_123b () { # statahead(bug 15027)
12149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12150
12151         test_mkdir $DIR/$tdir
12152         createmany -o $DIR/$tdir/$tfile-%d 1000
12153
12154         cancel_lru_locks mdc
12155         cancel_lru_locks osc
12156
12157 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12158         lctl set_param fail_loc=0x80000803
12159         ls -lR $DIR/$tdir > /dev/null
12160         log "ls done"
12161         lctl set_param fail_loc=0x0
12162         lctl get_param -n llite.*.statahead_stats
12163         rm -r $DIR/$tdir
12164         sync
12165
12166 }
12167 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12168
12169 test_123c() {
12170         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12171
12172         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12173         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12174         touch $DIR/$tdir.1/{1..3}
12175         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12176
12177         remount_client $MOUNT
12178
12179         $MULTIOP $DIR/$tdir.0 Q
12180
12181         # let statahead to complete
12182         ls -l $DIR/$tdir.0 > /dev/null
12183
12184         testid=$(echo $TESTNAME | tr '_' ' ')
12185         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12186                 error "statahead warning" || true
12187 }
12188 run_test 123c "Can not initialize inode warning on DNE statahead"
12189
12190 test_124a() {
12191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12192         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12193                 skip_env "no lru resize on server"
12194
12195         local NR=2000
12196
12197         test_mkdir $DIR/$tdir
12198
12199         log "create $NR files at $DIR/$tdir"
12200         createmany -o $DIR/$tdir/f $NR ||
12201                 error "failed to create $NR files in $DIR/$tdir"
12202
12203         cancel_lru_locks mdc
12204         ls -l $DIR/$tdir > /dev/null
12205
12206         local NSDIR=""
12207         local LRU_SIZE=0
12208         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12209                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12210                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12211                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12212                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12213                         log "NSDIR=$NSDIR"
12214                         log "NS=$(basename $NSDIR)"
12215                         break
12216                 fi
12217         done
12218
12219         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12220                 skip "Not enough cached locks created!"
12221         fi
12222         log "LRU=$LRU_SIZE"
12223
12224         local SLEEP=30
12225
12226         # We know that lru resize allows one client to hold $LIMIT locks
12227         # for 10h. After that locks begin to be killed by client.
12228         local MAX_HRS=10
12229         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12230         log "LIMIT=$LIMIT"
12231         if [ $LIMIT -lt $LRU_SIZE ]; then
12232                 skip "Limit is too small $LIMIT"
12233         fi
12234
12235         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12236         # killing locks. Some time was spent for creating locks. This means
12237         # that up to the moment of sleep finish we must have killed some of
12238         # them (10-100 locks). This depends on how fast ther were created.
12239         # Many of them were touched in almost the same moment and thus will
12240         # be killed in groups.
12241         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12242
12243         # Use $LRU_SIZE_B here to take into account real number of locks
12244         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12245         local LRU_SIZE_B=$LRU_SIZE
12246         log "LVF=$LVF"
12247         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12248         log "OLD_LVF=$OLD_LVF"
12249         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12250
12251         # Let's make sure that we really have some margin. Client checks
12252         # cached locks every 10 sec.
12253         SLEEP=$((SLEEP+20))
12254         log "Sleep ${SLEEP} sec"
12255         local SEC=0
12256         while ((SEC<$SLEEP)); do
12257                 echo -n "..."
12258                 sleep 5
12259                 SEC=$((SEC+5))
12260                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12261                 echo -n "$LRU_SIZE"
12262         done
12263         echo ""
12264         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12265         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12266
12267         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12268                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12269                 unlinkmany $DIR/$tdir/f $NR
12270                 return
12271         }
12272
12273         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12274         log "unlink $NR files at $DIR/$tdir"
12275         unlinkmany $DIR/$tdir/f $NR
12276 }
12277 run_test 124a "lru resize ======================================="
12278
12279 get_max_pool_limit()
12280 {
12281         local limit=$($LCTL get_param \
12282                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12283         local max=0
12284         for l in $limit; do
12285                 if [[ $l -gt $max ]]; then
12286                         max=$l
12287                 fi
12288         done
12289         echo $max
12290 }
12291
12292 test_124b() {
12293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12294         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12295                 skip_env "no lru resize on server"
12296
12297         LIMIT=$(get_max_pool_limit)
12298
12299         NR=$(($(default_lru_size)*20))
12300         if [[ $NR -gt $LIMIT ]]; then
12301                 log "Limit lock number by $LIMIT locks"
12302                 NR=$LIMIT
12303         fi
12304
12305         IFree=$(mdsrate_inodes_available)
12306         if [ $IFree -lt $NR ]; then
12307                 log "Limit lock number by $IFree inodes"
12308                 NR=$IFree
12309         fi
12310
12311         lru_resize_disable mdc
12312         test_mkdir -p $DIR/$tdir/disable_lru_resize
12313
12314         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12315         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12316         cancel_lru_locks mdc
12317         stime=`date +%s`
12318         PID=""
12319         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12320         PID="$PID $!"
12321         sleep 2
12322         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12323         PID="$PID $!"
12324         sleep 2
12325         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12326         PID="$PID $!"
12327         wait $PID
12328         etime=`date +%s`
12329         nolruresize_delta=$((etime-stime))
12330         log "ls -la time: $nolruresize_delta seconds"
12331         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12332         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12333
12334         lru_resize_enable mdc
12335         test_mkdir -p $DIR/$tdir/enable_lru_resize
12336
12337         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12338         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12339         cancel_lru_locks mdc
12340         stime=`date +%s`
12341         PID=""
12342         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12343         PID="$PID $!"
12344         sleep 2
12345         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12346         PID="$PID $!"
12347         sleep 2
12348         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12349         PID="$PID $!"
12350         wait $PID
12351         etime=`date +%s`
12352         lruresize_delta=$((etime-stime))
12353         log "ls -la time: $lruresize_delta seconds"
12354         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12355
12356         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12357                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12358         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12359                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12360         else
12361                 log "lru resize performs the same with no lru resize"
12362         fi
12363         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12364 }
12365 run_test 124b "lru resize (performance test) ======================="
12366
12367 test_124c() {
12368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12369         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12370                 skip_env "no lru resize on server"
12371
12372         # cache ununsed locks on client
12373         local nr=100
12374         cancel_lru_locks mdc
12375         test_mkdir $DIR/$tdir
12376         createmany -o $DIR/$tdir/f $nr ||
12377                 error "failed to create $nr files in $DIR/$tdir"
12378         ls -l $DIR/$tdir > /dev/null
12379
12380         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12381         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12382         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12383         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12384         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12385
12386         # set lru_max_age to 1 sec
12387         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12388         echo "sleep $((recalc_p * 2)) seconds..."
12389         sleep $((recalc_p * 2))
12390
12391         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12392         # restore lru_max_age
12393         $LCTL set_param -n $nsdir.lru_max_age $max_age
12394         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12395         unlinkmany $DIR/$tdir/f $nr
12396 }
12397 run_test 124c "LRUR cancel very aged locks"
12398
12399 test_124d() {
12400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12401         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12402                 skip_env "no lru resize on server"
12403
12404         # cache ununsed locks on client
12405         local nr=100
12406
12407         lru_resize_disable mdc
12408         stack_trap "lru_resize_enable mdc" EXIT
12409
12410         cancel_lru_locks mdc
12411
12412         # asynchronous object destroy at MDT could cause bl ast to client
12413         test_mkdir $DIR/$tdir
12414         createmany -o $DIR/$tdir/f $nr ||
12415                 error "failed to create $nr files in $DIR/$tdir"
12416         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12417
12418         ls -l $DIR/$tdir > /dev/null
12419
12420         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12421         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12422         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12423         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12424
12425         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12426
12427         # set lru_max_age to 1 sec
12428         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12429         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12430
12431         echo "sleep $((recalc_p * 2)) seconds..."
12432         sleep $((recalc_p * 2))
12433
12434         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12435
12436         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12437 }
12438 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12439
12440 test_125() { # 13358
12441         $LCTL get_param -n llite.*.client_type | grep -q local ||
12442                 skip "must run as local client"
12443         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12444                 skip_env "must have acl enabled"
12445         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12446
12447         test_mkdir $DIR/$tdir
12448         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12449         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12450         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12451 }
12452 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12453
12454 test_126() { # bug 12829/13455
12455         $GSS && skip_env "must run as gss disabled"
12456         $LCTL get_param -n llite.*.client_type | grep -q local ||
12457                 skip "must run as local client"
12458         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12459
12460         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12461         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12462         rm -f $DIR/$tfile
12463         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12464 }
12465 run_test 126 "check that the fsgid provided by the client is taken into account"
12466
12467 test_127a() { # bug 15521
12468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12469         local name count samp unit min max sum sumsq
12470
12471         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12472         echo "stats before reset"
12473         $LCTL get_param osc.*.stats
12474         $LCTL set_param osc.*.stats=0
12475         local fsize=$((2048 * 1024))
12476
12477         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12478         cancel_lru_locks osc
12479         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12480
12481         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12482         stack_trap "rm -f $TMP/$tfile.tmp"
12483         while read name count samp unit min max sum sumsq; do
12484                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12485                 [ ! $min ] && error "Missing min value for $name proc entry"
12486                 eval $name=$count || error "Wrong proc format"
12487
12488                 case $name in
12489                 read_bytes|write_bytes)
12490                         [[ "$unit" =~ "bytes" ]] ||
12491                                 error "unit is not 'bytes': $unit"
12492                         (( $min >= 4096 )) || error "min is too small: $min"
12493                         (( $min <= $fsize )) || error "min is too big: $min"
12494                         (( $max >= 4096 )) || error "max is too small: $max"
12495                         (( $max <= $fsize )) || error "max is too big: $max"
12496                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12497                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12498                                 error "sumsquare is too small: $sumsq"
12499                         (( $sumsq <= $fsize * $fsize )) ||
12500                                 error "sumsquare is too big: $sumsq"
12501                         ;;
12502                 ost_read|ost_write)
12503                         [[ "$unit" =~ "usec" ]] ||
12504                                 error "unit is not 'usec': $unit"
12505                         ;;
12506                 *)      ;;
12507                 esac
12508         done < $DIR/$tfile.tmp
12509
12510         #check that we actually got some stats
12511         [ "$read_bytes" ] || error "Missing read_bytes stats"
12512         [ "$write_bytes" ] || error "Missing write_bytes stats"
12513         [ "$read_bytes" != 0 ] || error "no read done"
12514         [ "$write_bytes" != 0 ] || error "no write done"
12515 }
12516 run_test 127a "verify the client stats are sane"
12517
12518 test_127b() { # bug LU-333
12519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12520         local name count samp unit min max sum sumsq
12521
12522         echo "stats before reset"
12523         $LCTL get_param llite.*.stats
12524         $LCTL set_param llite.*.stats=0
12525
12526         # perform 2 reads and writes so MAX is different from SUM.
12527         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12528         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12529         cancel_lru_locks osc
12530         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12531         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12532
12533         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12534         stack_trap "rm -f $TMP/$tfile.tmp"
12535         while read name count samp unit min max sum sumsq; do
12536                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12537                 eval $name=$count || error "Wrong proc format"
12538
12539                 case $name in
12540                 read_bytes|write_bytes)
12541                         [[ "$unit" =~ "bytes" ]] ||
12542                                 error "unit is not 'bytes': $unit"
12543                         (( $count == 2 )) || error "count is not 2: $count"
12544                         (( $min == $PAGE_SIZE )) ||
12545                                 error "min is not $PAGE_SIZE: $min"
12546                         (( $max == $PAGE_SIZE )) ||
12547                                 error "max is not $PAGE_SIZE: $max"
12548                         (( $sum == $PAGE_SIZE * 2 )) ||
12549                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12550                         ;;
12551                 read|write)
12552                         [[ "$unit" =~ "usec" ]] ||
12553                                 error "unit is not 'usec': $unit"
12554                         ;;
12555                 *)      ;;
12556                 esac
12557         done < $TMP/$tfile.tmp
12558
12559         #check that we actually got some stats
12560         [ "$read_bytes" ] || error "Missing read_bytes stats"
12561         [ "$write_bytes" ] || error "Missing write_bytes stats"
12562         [ "$read_bytes" != 0 ] || error "no read done"
12563         [ "$write_bytes" != 0 ] || error "no write done"
12564 }
12565 run_test 127b "verify the llite client stats are sane"
12566
12567 test_127c() { # LU-12394
12568         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12569         local size
12570         local bsize
12571         local reads
12572         local writes
12573         local count
12574
12575         $LCTL set_param llite.*.extents_stats=1
12576         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12577
12578         # Use two stripes so there is enough space in default config
12579         $LFS setstripe -c 2 $DIR/$tfile
12580
12581         # Extent stats start at 0-4K and go in power of two buckets
12582         # LL_HIST_START = 12 --> 2^12 = 4K
12583         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12584         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12585         # small configs
12586         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12587                 do
12588                 # Write and read, 2x each, second time at a non-zero offset
12589                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12590                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12591                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12592                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12593                 rm -f $DIR/$tfile
12594         done
12595
12596         $LCTL get_param llite.*.extents_stats
12597
12598         count=2
12599         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12600                 do
12601                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12602                                 grep -m 1 $bsize)
12603                 reads=$(echo $bucket | awk '{print $5}')
12604                 writes=$(echo $bucket | awk '{print $9}')
12605                 [ "$reads" -eq $count ] ||
12606                         error "$reads reads in < $bsize bucket, expect $count"
12607                 [ "$writes" -eq $count ] ||
12608                         error "$writes writes in < $bsize bucket, expect $count"
12609         done
12610
12611         # Test mmap write and read
12612         $LCTL set_param llite.*.extents_stats=c
12613         size=512
12614         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12615         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12616         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12617
12618         $LCTL get_param llite.*.extents_stats
12619
12620         count=$(((size*1024) / PAGE_SIZE))
12621
12622         bsize=$((2 * PAGE_SIZE / 1024))K
12623
12624         bucket=$($LCTL get_param -n llite.*.extents_stats |
12625                         grep -m 1 $bsize)
12626         reads=$(echo $bucket | awk '{print $5}')
12627         writes=$(echo $bucket | awk '{print $9}')
12628         # mmap writes fault in the page first, creating an additonal read
12629         [ "$reads" -eq $((2 * count)) ] ||
12630                 error "$reads reads in < $bsize bucket, expect $count"
12631         [ "$writes" -eq $count ] ||
12632                 error "$writes writes in < $bsize bucket, expect $count"
12633 }
12634 run_test 127c "test llite extent stats with regular & mmap i/o"
12635
12636 test_128() { # bug 15212
12637         touch $DIR/$tfile
12638         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12639                 find $DIR/$tfile
12640                 find $DIR/$tfile
12641         EOF
12642
12643         result=$(grep error $TMP/$tfile.log)
12644         rm -f $DIR/$tfile $TMP/$tfile.log
12645         [ -z "$result" ] ||
12646                 error "consecutive find's under interactive lfs failed"
12647 }
12648 run_test 128 "interactive lfs for 2 consecutive find's"
12649
12650 set_dir_limits () {
12651         local mntdev
12652         local canondev
12653         local node
12654
12655         local ldproc=/proc/fs/ldiskfs
12656         local facets=$(get_facets MDS)
12657
12658         for facet in ${facets//,/ }; do
12659                 canondev=$(ldiskfs_canon \
12660                            *.$(convert_facet2label $facet).mntdev $facet)
12661                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12662                         ldproc=/sys/fs/ldiskfs
12663                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12664                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12665         done
12666 }
12667
12668 check_mds_dmesg() {
12669         local facets=$(get_facets MDS)
12670         for facet in ${facets//,/ }; do
12671                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12672         done
12673         return 1
12674 }
12675
12676 test_129() {
12677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12678         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12679                 skip "Need MDS version with at least 2.5.56"
12680         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12681                 skip_env "ldiskfs only test"
12682         fi
12683         remote_mds_nodsh && skip "remote MDS with nodsh"
12684
12685         local ENOSPC=28
12686         local has_warning=false
12687
12688         rm -rf $DIR/$tdir
12689         mkdir -p $DIR/$tdir
12690
12691         # block size of mds1
12692         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12693         set_dir_limits $maxsize $((maxsize * 6 / 8))
12694         stack_trap "set_dir_limits 0 0"
12695         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12696         local dirsize=$(stat -c%s "$DIR/$tdir")
12697         local nfiles=0
12698         while (( $dirsize <= $maxsize )); do
12699                 $MCREATE $DIR/$tdir/file_base_$nfiles
12700                 rc=$?
12701                 # check two errors:
12702                 # ENOSPC for ext4 max_dir_size, which has been used since
12703                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12704                 if (( rc == ENOSPC )); then
12705                         set_dir_limits 0 0
12706                         echo "rc=$rc returned as expected after $nfiles files"
12707
12708                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12709                                 error "create failed w/o dir size limit"
12710
12711                         # messages may be rate limited if test is run repeatedly
12712                         check_mds_dmesg '"is approaching max"' ||
12713                                 echo "warning message should be output"
12714                         check_mds_dmesg '"has reached max"' ||
12715                                 echo "reached message should be output"
12716
12717                         dirsize=$(stat -c%s "$DIR/$tdir")
12718
12719                         [[ $dirsize -ge $maxsize ]] && return 0
12720                         error "dirsize $dirsize < $maxsize after $nfiles files"
12721                 elif (( rc != 0 )); then
12722                         break
12723                 fi
12724                 nfiles=$((nfiles + 1))
12725                 dirsize=$(stat -c%s "$DIR/$tdir")
12726         done
12727
12728         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12729 }
12730 run_test 129 "test directory size limit ========================"
12731
12732 OLDIFS="$IFS"
12733 cleanup_130() {
12734         trap 0
12735         IFS="$OLDIFS"
12736 }
12737
12738 test_130a() {
12739         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12740         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12741
12742         trap cleanup_130 EXIT RETURN
12743
12744         local fm_file=$DIR/$tfile
12745         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12746         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12747                 error "dd failed for $fm_file"
12748
12749         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12750         filefrag -ves $fm_file
12751         RC=$?
12752         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12753                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12754         [ $RC != 0 ] && error "filefrag $fm_file failed"
12755
12756         filefrag_op=$(filefrag -ve -k $fm_file |
12757                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12758         lun=$($LFS getstripe -i $fm_file)
12759
12760         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12761         IFS=$'\n'
12762         tot_len=0
12763         for line in $filefrag_op
12764         do
12765                 frag_lun=`echo $line | cut -d: -f5`
12766                 ext_len=`echo $line | cut -d: -f4`
12767                 if (( $frag_lun != $lun )); then
12768                         cleanup_130
12769                         error "FIEMAP on 1-stripe file($fm_file) failed"
12770                         return
12771                 fi
12772                 (( tot_len += ext_len ))
12773         done
12774
12775         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12776                 cleanup_130
12777                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12778                 return
12779         fi
12780
12781         cleanup_130
12782
12783         echo "FIEMAP on single striped file succeeded"
12784 }
12785 run_test 130a "FIEMAP (1-stripe file)"
12786
12787 test_130b() {
12788         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12789
12790         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12791         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12792
12793         trap cleanup_130 EXIT RETURN
12794
12795         local fm_file=$DIR/$tfile
12796         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12797                         error "setstripe on $fm_file"
12798         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12799                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12800
12801         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12802                 error "dd failed on $fm_file"
12803
12804         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12805         filefrag_op=$(filefrag -ve -k $fm_file |
12806                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12807
12808         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12809                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12810
12811         IFS=$'\n'
12812         tot_len=0
12813         num_luns=1
12814         for line in $filefrag_op
12815         do
12816                 frag_lun=$(echo $line | cut -d: -f5 |
12817                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12818                 ext_len=$(echo $line | cut -d: -f4)
12819                 if (( $frag_lun != $last_lun )); then
12820                         if (( tot_len != 1024 )); then
12821                                 cleanup_130
12822                                 error "FIEMAP on $fm_file failed; returned " \
12823                                 "len $tot_len for OST $last_lun instead of 1024"
12824                                 return
12825                         else
12826                                 (( num_luns += 1 ))
12827                                 tot_len=0
12828                         fi
12829                 fi
12830                 (( tot_len += ext_len ))
12831                 last_lun=$frag_lun
12832         done
12833         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12834                 cleanup_130
12835                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12836                         "luns or wrong len for OST $last_lun"
12837                 return
12838         fi
12839
12840         cleanup_130
12841
12842         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12843 }
12844 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12845
12846 test_130c() {
12847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12848
12849         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12850         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12851
12852         trap cleanup_130 EXIT RETURN
12853
12854         local fm_file=$DIR/$tfile
12855         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12856         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12857                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12858
12859         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12860                         error "dd failed on $fm_file"
12861
12862         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12863         filefrag_op=$(filefrag -ve -k $fm_file |
12864                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12865
12866         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12867                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12868
12869         IFS=$'\n'
12870         tot_len=0
12871         num_luns=1
12872         for line in $filefrag_op
12873         do
12874                 frag_lun=$(echo $line | cut -d: -f5 |
12875                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12876                 ext_len=$(echo $line | cut -d: -f4)
12877                 if (( $frag_lun != $last_lun )); then
12878                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12879                         if (( logical != 512 )); then
12880                                 cleanup_130
12881                                 error "FIEMAP on $fm_file failed; returned " \
12882                                 "logical start for lun $logical instead of 512"
12883                                 return
12884                         fi
12885                         if (( tot_len != 512 )); then
12886                                 cleanup_130
12887                                 error "FIEMAP on $fm_file failed; returned " \
12888                                 "len $tot_len for OST $last_lun instead of 1024"
12889                                 return
12890                         else
12891                                 (( num_luns += 1 ))
12892                                 tot_len=0
12893                         fi
12894                 fi
12895                 (( tot_len += ext_len ))
12896                 last_lun=$frag_lun
12897         done
12898         if (( num_luns != 2 || tot_len != 512 )); then
12899                 cleanup_130
12900                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12901                         "luns or wrong len for OST $last_lun"
12902                 return
12903         fi
12904
12905         cleanup_130
12906
12907         echo "FIEMAP on 2-stripe file with hole succeeded"
12908 }
12909 run_test 130c "FIEMAP (2-stripe file with hole)"
12910
12911 test_130d() {
12912         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12913
12914         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12915         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12916
12917         trap cleanup_130 EXIT RETURN
12918
12919         local fm_file=$DIR/$tfile
12920         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12921                         error "setstripe on $fm_file"
12922         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12923                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12924
12925         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12926         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12927                 error "dd failed on $fm_file"
12928
12929         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12930         filefrag_op=$(filefrag -ve -k $fm_file |
12931                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12932
12933         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12934                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12935
12936         IFS=$'\n'
12937         tot_len=0
12938         num_luns=1
12939         for line in $filefrag_op
12940         do
12941                 frag_lun=$(echo $line | cut -d: -f5 |
12942                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12943                 ext_len=$(echo $line | cut -d: -f4)
12944                 if (( $frag_lun != $last_lun )); then
12945                         if (( tot_len != 1024 )); then
12946                                 cleanup_130
12947                                 error "FIEMAP on $fm_file failed; returned " \
12948                                 "len $tot_len for OST $last_lun instead of 1024"
12949                                 return
12950                         else
12951                                 (( num_luns += 1 ))
12952                                 tot_len=0
12953                         fi
12954                 fi
12955                 (( tot_len += ext_len ))
12956                 last_lun=$frag_lun
12957         done
12958         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12959                 cleanup_130
12960                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12961                         "luns or wrong len for OST $last_lun"
12962                 return
12963         fi
12964
12965         cleanup_130
12966
12967         echo "FIEMAP on N-stripe file succeeded"
12968 }
12969 run_test 130d "FIEMAP (N-stripe file)"
12970
12971 test_130e() {
12972         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12973
12974         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12975         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12976
12977         trap cleanup_130 EXIT RETURN
12978
12979         local fm_file=$DIR/$tfile
12980         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12981
12982         NUM_BLKS=512
12983         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12984         for ((i = 0; i < $NUM_BLKS; i++)); do
12985                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
12986                         conv=notrunc > /dev/null 2>&1
12987         done
12988
12989         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12990         filefrag_op=$(filefrag -ve -k $fm_file |
12991                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12992
12993         last_lun=$(echo $filefrag_op | cut -d: -f5)
12994
12995         IFS=$'\n'
12996         tot_len=0
12997         num_luns=1
12998         for line in $filefrag_op; do
12999                 frag_lun=$(echo $line | cut -d: -f5)
13000                 ext_len=$(echo $line | cut -d: -f4)
13001                 if [[ "$frag_lun" != "$last_lun" ]]; then
13002                         if (( tot_len != $EXPECTED_LEN )); then
13003                                 cleanup_130
13004                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13005                         else
13006                                 (( num_luns += 1 ))
13007                                 tot_len=0
13008                         fi
13009                 fi
13010                 (( tot_len += ext_len ))
13011                 last_lun=$frag_lun
13012         done
13013         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13014                 cleanup_130
13015                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13016         fi
13017
13018         echo "FIEMAP with continuation calls succeeded"
13019 }
13020 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13021
13022 test_130f() {
13023         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13024         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13025
13026         local fm_file=$DIR/$tfile
13027         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13028                 error "multiop create with lov_delay_create on $fm_file"
13029
13030         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13031         filefrag_extents=$(filefrag -vek $fm_file |
13032                            awk '/extents? found/ { print $2 }')
13033         if [[ "$filefrag_extents" != "0" ]]; then
13034                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13035         fi
13036
13037         rm -f $fm_file
13038 }
13039 run_test 130f "FIEMAP (unstriped file)"
13040
13041 test_130g() {
13042         local file=$DIR/$tfile
13043         local nr=$((OSTCOUNT * 100))
13044
13045         $LFS setstripe -C $nr $file ||
13046                 error "failed to setstripe -C $nr $file"
13047
13048         dd if=/dev/zero of=$file count=$nr bs=1M
13049         sync
13050         nr=$($LFS getstripe -c $file)
13051
13052         local extents=$(filefrag -v $file |
13053                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13054
13055         echo "filefrag list $extents extents in file with stripecount $nr"
13056         if (( extents < nr )); then
13057                 $LFS getstripe $file
13058                 filefrag -v $file
13059                 error "filefrag printed $extents < $nr extents"
13060         fi
13061
13062         rm -f $file
13063 }
13064 run_test 130g "FIEMAP (overstripe file)"
13065
13066 # Test for writev/readv
13067 test_131a() {
13068         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13069                 error "writev test failed"
13070         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13071                 error "readv failed"
13072         rm -f $DIR/$tfile
13073 }
13074 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13075
13076 test_131b() {
13077         local fsize=$((524288 + 1048576 + 1572864))
13078         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13079                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13080                         error "append writev test failed"
13081
13082         ((fsize += 1572864 + 1048576))
13083         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13084                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13085                         error "append writev test failed"
13086         rm -f $DIR/$tfile
13087 }
13088 run_test 131b "test append writev"
13089
13090 test_131c() {
13091         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13092         error "NOT PASS"
13093 }
13094 run_test 131c "test read/write on file w/o objects"
13095
13096 test_131d() {
13097         rwv -f $DIR/$tfile -w -n 1 1572864
13098         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13099         if [ "$NOB" != 1572864 ]; then
13100                 error "Short read filed: read $NOB bytes instead of 1572864"
13101         fi
13102         rm -f $DIR/$tfile
13103 }
13104 run_test 131d "test short read"
13105
13106 test_131e() {
13107         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13108         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13109         error "read hitting hole failed"
13110         rm -f $DIR/$tfile
13111 }
13112 run_test 131e "test read hitting hole"
13113
13114 check_stats() {
13115         local facet=$1
13116         local op=$2
13117         local want=${3:-0}
13118         local res
13119
13120         case $facet in
13121         mds*) res=$(do_facet $facet \
13122                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13123                  ;;
13124         ost*) res=$(do_facet $facet \
13125                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13126                  ;;
13127         *) error "Wrong facet '$facet'" ;;
13128         esac
13129         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13130         # if the argument $3 is zero, it means any stat increment is ok.
13131         if [[ $want -gt 0 ]]; then
13132                 local count=$(echo $res | awk '{ print $2 }')
13133                 [[ $count -ne $want ]] &&
13134                         error "The $op counter on $facet is $count, not $want"
13135         fi
13136 }
13137
13138 test_133a() {
13139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13140         remote_ost_nodsh && skip "remote OST with nodsh"
13141         remote_mds_nodsh && skip "remote MDS with nodsh"
13142         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13143                 skip_env "MDS doesn't support rename stats"
13144
13145         local testdir=$DIR/${tdir}/stats_testdir
13146
13147         mkdir -p $DIR/${tdir}
13148
13149         # clear stats.
13150         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13151         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13152
13153         # verify mdt stats first.
13154         mkdir ${testdir} || error "mkdir failed"
13155         check_stats $SINGLEMDS "mkdir" 1
13156         touch ${testdir}/${tfile} || error "touch failed"
13157         check_stats $SINGLEMDS "open" 1
13158         check_stats $SINGLEMDS "close" 1
13159         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13160                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13161                 check_stats $SINGLEMDS "mknod" 2
13162         }
13163         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13164         check_stats $SINGLEMDS "unlink" 1
13165         rm -f ${testdir}/${tfile} || error "file remove failed"
13166         check_stats $SINGLEMDS "unlink" 2
13167
13168         # remove working dir and check mdt stats again.
13169         rmdir ${testdir} || error "rmdir failed"
13170         check_stats $SINGLEMDS "rmdir" 1
13171
13172         local testdir1=$DIR/${tdir}/stats_testdir1
13173         mkdir -p ${testdir}
13174         mkdir -p ${testdir1}
13175         touch ${testdir1}/test1
13176         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13177         check_stats $SINGLEMDS "crossdir_rename" 1
13178
13179         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13180         check_stats $SINGLEMDS "samedir_rename" 1
13181
13182         rm -rf $DIR/${tdir}
13183 }
13184 run_test 133a "Verifying MDT stats ========================================"
13185
13186 test_133b() {
13187         local res
13188
13189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13190         remote_ost_nodsh && skip "remote OST with nodsh"
13191         remote_mds_nodsh && skip "remote MDS with nodsh"
13192
13193         local testdir=$DIR/${tdir}/stats_testdir
13194
13195         mkdir -p ${testdir} || error "mkdir failed"
13196         touch ${testdir}/${tfile} || error "touch failed"
13197         cancel_lru_locks mdc
13198
13199         # clear stats.
13200         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13201         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13202
13203         # extra mdt stats verification.
13204         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13205         check_stats $SINGLEMDS "setattr" 1
13206         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13207         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13208         then            # LU-1740
13209                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13210                 check_stats $SINGLEMDS "getattr" 1
13211         fi
13212         rm -rf $DIR/${tdir}
13213
13214         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13215         # so the check below is not reliable
13216         [ $MDSCOUNT -eq 1 ] || return 0
13217
13218         # Sleep to avoid a cached response.
13219         #define OBD_STATFS_CACHE_SECONDS 1
13220         sleep 2
13221         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13222         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13223         $LFS df || error "lfs failed"
13224         check_stats $SINGLEMDS "statfs" 1
13225
13226         # check aggregated statfs (LU-10018)
13227         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13228                 return 0
13229         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13230                 return 0
13231         sleep 2
13232         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13233         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13234         df $DIR
13235         check_stats $SINGLEMDS "statfs" 1
13236
13237         # We want to check that the client didn't send OST_STATFS to
13238         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13239         # extra care is needed here.
13240         if remote_mds; then
13241                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13242                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13243
13244                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13245                 [ "$res" ] && error "OST got STATFS"
13246         fi
13247
13248         return 0
13249 }
13250 run_test 133b "Verifying extra MDT stats =================================="
13251
13252 test_133c() {
13253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13254         remote_ost_nodsh && skip "remote OST with nodsh"
13255         remote_mds_nodsh && skip "remote MDS with nodsh"
13256
13257         local testdir=$DIR/$tdir/stats_testdir
13258
13259         test_mkdir -p $testdir
13260
13261         # verify obdfilter stats.
13262         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13263         sync
13264         cancel_lru_locks osc
13265         wait_delete_completed
13266
13267         # clear stats.
13268         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13269         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13270
13271         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13272                 error "dd failed"
13273         sync
13274         cancel_lru_locks osc
13275         check_stats ost1 "write" 1
13276
13277         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13278         check_stats ost1 "read" 1
13279
13280         > $testdir/$tfile || error "truncate failed"
13281         check_stats ost1 "punch" 1
13282
13283         rm -f $testdir/$tfile || error "file remove failed"
13284         wait_delete_completed
13285         check_stats ost1 "destroy" 1
13286
13287         rm -rf $DIR/$tdir
13288 }
13289 run_test 133c "Verifying OST stats ========================================"
13290
13291 order_2() {
13292         local value=$1
13293         local orig=$value
13294         local order=1
13295
13296         while [ $value -ge 2 ]; do
13297                 order=$((order*2))
13298                 value=$((value/2))
13299         done
13300
13301         if [ $orig -gt $order ]; then
13302                 order=$((order*2))
13303         fi
13304         echo $order
13305 }
13306
13307 size_in_KMGT() {
13308     local value=$1
13309     local size=('K' 'M' 'G' 'T');
13310     local i=0
13311     local size_string=$value
13312
13313     while [ $value -ge 1024 ]; do
13314         if [ $i -gt 3 ]; then
13315             #T is the biggest unit we get here, if that is bigger,
13316             #just return XXXT
13317             size_string=${value}T
13318             break
13319         fi
13320         value=$((value >> 10))
13321         if [ $value -lt 1024 ]; then
13322             size_string=${value}${size[$i]}
13323             break
13324         fi
13325         i=$((i + 1))
13326     done
13327
13328     echo $size_string
13329 }
13330
13331 get_rename_size() {
13332         local size=$1
13333         local context=${2:-.}
13334         local sample=$(do_facet $SINGLEMDS $LCTL \
13335                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13336                 grep -A1 $context |
13337                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13338         echo $sample
13339 }
13340
13341 test_133d() {
13342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13343         remote_ost_nodsh && skip "remote OST with nodsh"
13344         remote_mds_nodsh && skip "remote MDS with nodsh"
13345         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13346                 skip_env "MDS doesn't support rename stats"
13347
13348         local testdir1=$DIR/${tdir}/stats_testdir1
13349         local testdir2=$DIR/${tdir}/stats_testdir2
13350         mkdir -p $DIR/${tdir}
13351
13352         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13353
13354         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13355         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13356
13357         createmany -o $testdir1/test 512 || error "createmany failed"
13358
13359         # check samedir rename size
13360         mv ${testdir1}/test0 ${testdir1}/test_0
13361
13362         local testdir1_size=$(ls -l $DIR/${tdir} |
13363                 awk '/stats_testdir1/ {print $5}')
13364         local testdir2_size=$(ls -l $DIR/${tdir} |
13365                 awk '/stats_testdir2/ {print $5}')
13366
13367         testdir1_size=$(order_2 $testdir1_size)
13368         testdir2_size=$(order_2 $testdir2_size)
13369
13370         testdir1_size=$(size_in_KMGT $testdir1_size)
13371         testdir2_size=$(size_in_KMGT $testdir2_size)
13372
13373         echo "source rename dir size: ${testdir1_size}"
13374         echo "target rename dir size: ${testdir2_size}"
13375
13376         local cmd="do_facet $SINGLEMDS $LCTL "
13377         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13378
13379         eval $cmd || error "$cmd failed"
13380         local samedir=$($cmd | grep 'same_dir')
13381         local same_sample=$(get_rename_size $testdir1_size)
13382         [ -z "$samedir" ] && error "samedir_rename_size count error"
13383         [[ $same_sample -eq 1 ]] ||
13384                 error "samedir_rename_size error $same_sample"
13385         echo "Check same dir rename stats success"
13386
13387         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13388
13389         # check crossdir rename size
13390         mv ${testdir1}/test_0 ${testdir2}/test_0
13391
13392         testdir1_size=$(ls -l $DIR/${tdir} |
13393                 awk '/stats_testdir1/ {print $5}')
13394         testdir2_size=$(ls -l $DIR/${tdir} |
13395                 awk '/stats_testdir2/ {print $5}')
13396
13397         testdir1_size=$(order_2 $testdir1_size)
13398         testdir2_size=$(order_2 $testdir2_size)
13399
13400         testdir1_size=$(size_in_KMGT $testdir1_size)
13401         testdir2_size=$(size_in_KMGT $testdir2_size)
13402
13403         echo "source rename dir size: ${testdir1_size}"
13404         echo "target rename dir size: ${testdir2_size}"
13405
13406         eval $cmd || error "$cmd failed"
13407         local crossdir=$($cmd | grep 'crossdir')
13408         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13409         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13410         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13411         [[ $src_sample -eq 1 ]] ||
13412                 error "crossdir_rename_size error $src_sample"
13413         [[ $tgt_sample -eq 1 ]] ||
13414                 error "crossdir_rename_size error $tgt_sample"
13415         echo "Check cross dir rename stats success"
13416         rm -rf $DIR/${tdir}
13417 }
13418 run_test 133d "Verifying rename_stats ========================================"
13419
13420 test_133e() {
13421         remote_mds_nodsh && skip "remote MDS with nodsh"
13422         remote_ost_nodsh && skip "remote OST with nodsh"
13423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13424
13425         local testdir=$DIR/${tdir}/stats_testdir
13426         local ctr f0 f1 bs=32768 count=42 sum
13427
13428         mkdir -p ${testdir} || error "mkdir failed"
13429
13430         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13431
13432         for ctr in {write,read}_bytes; do
13433                 sync
13434                 cancel_lru_locks osc
13435
13436                 do_facet ost1 $LCTL set_param -n \
13437                         "obdfilter.*.exports.clear=clear"
13438
13439                 if [ $ctr = write_bytes ]; then
13440                         f0=/dev/zero
13441                         f1=${testdir}/${tfile}
13442                 else
13443                         f0=${testdir}/${tfile}
13444                         f1=/dev/null
13445                 fi
13446
13447                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13448                         error "dd failed"
13449                 sync
13450                 cancel_lru_locks osc
13451
13452                 sum=$(do_facet ost1 $LCTL get_param \
13453                         "obdfilter.*.exports.*.stats" |
13454                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13455                                 $1 == ctr { sum += $7 }
13456                                 END { printf("%0.0f", sum) }')
13457
13458                 if ((sum != bs * count)); then
13459                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13460                 fi
13461         done
13462
13463         rm -rf $DIR/${tdir}
13464 }
13465 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13466
13467 test_133f() {
13468         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13469                 skip "too old lustre for get_param -R ($facet_ver)"
13470
13471         # verifying readability.
13472         $LCTL get_param -R '*' &> /dev/null
13473
13474         # Verifing writability with badarea_io.
13475         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13476                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13477                 error "client badarea_io failed"
13478
13479         # remount the FS in case writes/reads /proc break the FS
13480         cleanup || error "failed to unmount"
13481         setup || error "failed to setup"
13482 }
13483 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13484
13485 test_133g() {
13486         remote_mds_nodsh && skip "remote MDS with nodsh"
13487         remote_ost_nodsh && skip "remote OST with nodsh"
13488
13489         local facet
13490         for facet in mds1 ost1; do
13491                 local facet_ver=$(lustre_version_code $facet)
13492                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13493                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13494                 else
13495                         log "$facet: too old lustre for get_param -R"
13496                 fi
13497                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13498                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13499                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13500                                 xargs badarea_io" ||
13501                                         error "$facet badarea_io failed"
13502                 else
13503                         skip_noexit "$facet: too old lustre for get_param -R"
13504                 fi
13505         done
13506
13507         # remount the FS in case writes/reads /proc break the FS
13508         cleanup || error "failed to unmount"
13509         setup || error "failed to setup"
13510 }
13511 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13512
13513 test_133h() {
13514         remote_mds_nodsh && skip "remote MDS with nodsh"
13515         remote_ost_nodsh && skip "remote OST with nodsh"
13516         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13517                 skip "Need MDS version at least 2.9.54"
13518
13519         local facet
13520         for facet in client mds1 ost1; do
13521                 # Get the list of files that are missing the terminating newline
13522                 local plist=$(do_facet $facet
13523                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13524                 local ent
13525                 for ent in $plist; do
13526                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13527                                 awk -v FS='\v' -v RS='\v\v' \
13528                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13529                                         print FILENAME}'" 2>/dev/null)
13530                         [ -z $missing ] || {
13531                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13532                                 error "file does not end with newline: $facet-$ent"
13533                         }
13534                 done
13535         done
13536 }
13537 run_test 133h "Proc files should end with newlines"
13538
13539 test_134a() {
13540         remote_mds_nodsh && skip "remote MDS with nodsh"
13541         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13542                 skip "Need MDS version at least 2.7.54"
13543
13544         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13545         cancel_lru_locks mdc
13546
13547         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13548         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13549         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13550
13551         local nr=1000
13552         createmany -o $DIR/$tdir/f $nr ||
13553                 error "failed to create $nr files in $DIR/$tdir"
13554         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13555
13556         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13557         do_facet mds1 $LCTL set_param fail_loc=0x327
13558         do_facet mds1 $LCTL set_param fail_val=500
13559         touch $DIR/$tdir/m
13560
13561         echo "sleep 10 seconds ..."
13562         sleep 10
13563         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13564
13565         do_facet mds1 $LCTL set_param fail_loc=0
13566         do_facet mds1 $LCTL set_param fail_val=0
13567         [ $lck_cnt -lt $unused ] ||
13568                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13569
13570         rm $DIR/$tdir/m
13571         unlinkmany $DIR/$tdir/f $nr
13572 }
13573 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13574
13575 test_134b() {
13576         remote_mds_nodsh && skip "remote MDS with nodsh"
13577         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13578                 skip "Need MDS version at least 2.7.54"
13579
13580         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13581         cancel_lru_locks mdc
13582
13583         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13584                         ldlm.lock_reclaim_threshold_mb)
13585         # disable reclaim temporarily
13586         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13587
13588         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13589         do_facet mds1 $LCTL set_param fail_loc=0x328
13590         do_facet mds1 $LCTL set_param fail_val=500
13591
13592         $LCTL set_param debug=+trace
13593
13594         local nr=600
13595         createmany -o $DIR/$tdir/f $nr &
13596         local create_pid=$!
13597
13598         echo "Sleep $TIMEOUT seconds ..."
13599         sleep $TIMEOUT
13600         if ! ps -p $create_pid  > /dev/null 2>&1; then
13601                 do_facet mds1 $LCTL set_param fail_loc=0
13602                 do_facet mds1 $LCTL set_param fail_val=0
13603                 do_facet mds1 $LCTL set_param \
13604                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13605                 error "createmany finished incorrectly!"
13606         fi
13607         do_facet mds1 $LCTL set_param fail_loc=0
13608         do_facet mds1 $LCTL set_param fail_val=0
13609         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13610         wait $create_pid || return 1
13611
13612         unlinkmany $DIR/$tdir/f $nr
13613 }
13614 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13615
13616 test_135() {
13617         remote_mds_nodsh && skip "remote MDS with nodsh"
13618         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13619                 skip "Need MDS version at least 2.13.50"
13620         local fname
13621
13622         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13623
13624 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13625         #set only one record at plain llog
13626         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13627
13628         #fill already existed plain llog each 64767
13629         #wrapping whole catalog
13630         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13631
13632         createmany -o $DIR/$tdir/$tfile_ 64700
13633         for (( i = 0; i < 64700; i = i + 2 ))
13634         do
13635                 rm $DIR/$tdir/$tfile_$i &
13636                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13637                 local pid=$!
13638                 wait $pid
13639         done
13640
13641         #waiting osp synchronization
13642         wait_delete_completed
13643 }
13644 run_test 135 "Race catalog processing"
13645
13646 test_136() {
13647         remote_mds_nodsh && skip "remote MDS with nodsh"
13648         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13649                 skip "Need MDS version at least 2.13.50"
13650         local fname
13651
13652         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13653         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13654         #set only one record at plain llog
13655 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13656         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13657
13658         #fill already existed 2 plain llogs each 64767
13659         #wrapping whole catalog
13660         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13661         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13662         wait_delete_completed
13663
13664         createmany -o $DIR/$tdir/$tfile_ 10
13665         sleep 25
13666
13667         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13668         for (( i = 0; i < 10; i = i + 3 ))
13669         do
13670                 rm $DIR/$tdir/$tfile_$i &
13671                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13672                 local pid=$!
13673                 wait $pid
13674                 sleep 7
13675                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13676         done
13677
13678         #waiting osp synchronization
13679         wait_delete_completed
13680 }
13681 run_test 136 "Race catalog processing 2"
13682
13683 test_140() { #bug-17379
13684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13685
13686         test_mkdir $DIR/$tdir
13687         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13688         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13689
13690         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13691         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13692         local i=0
13693         while i=$((i + 1)); do
13694                 test_mkdir $i
13695                 cd $i || error "Changing to $i"
13696                 ln -s ../stat stat || error "Creating stat symlink"
13697                 # Read the symlink until ELOOP present,
13698                 # not LBUGing the system is considered success,
13699                 # we didn't overrun the stack.
13700                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13701                 if [ $ret -ne 0 ]; then
13702                         if [ $ret -eq 40 ]; then
13703                                 break  # -ELOOP
13704                         else
13705                                 error "Open stat symlink"
13706                                         return
13707                         fi
13708                 fi
13709         done
13710         i=$((i - 1))
13711         echo "The symlink depth = $i"
13712         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13713                 error "Invalid symlink depth"
13714
13715         # Test recursive symlink
13716         ln -s symlink_self symlink_self
13717         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13718         echo "open symlink_self returns $ret"
13719         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13720 }
13721 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13722
13723 test_150a() {
13724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13725
13726         local TF="$TMP/$tfile"
13727
13728         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13729         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13730         cp $TF $DIR/$tfile
13731         cancel_lru_locks $OSC
13732         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13733         remount_client $MOUNT
13734         df -P $MOUNT
13735         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13736
13737         $TRUNCATE $TF 6000
13738         $TRUNCATE $DIR/$tfile 6000
13739         cancel_lru_locks $OSC
13740         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13741
13742         echo "12345" >>$TF
13743         echo "12345" >>$DIR/$tfile
13744         cancel_lru_locks $OSC
13745         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13746
13747         echo "12345" >>$TF
13748         echo "12345" >>$DIR/$tfile
13749         cancel_lru_locks $OSC
13750         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13751 }
13752 run_test 150a "truncate/append tests"
13753
13754 test_150b() {
13755         check_set_fallocate_or_skip
13756
13757         touch $DIR/$tfile
13758         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13759         check_fallocate $DIR/$tfile || error "fallocate failed"
13760 }
13761 run_test 150b "Verify fallocate (prealloc) functionality"
13762
13763 test_150bb() {
13764         check_set_fallocate_or_skip
13765
13766         touch $DIR/$tfile
13767         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13768         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13769         > $DIR/$tfile
13770         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13771         # precomputed md5sum for 20MB of zeroes
13772         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13773         local sum=($(md5sum $DIR/$tfile))
13774
13775         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13776
13777         check_set_fallocate 1
13778
13779         > $DIR/$tfile
13780         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13781         sum=($(md5sum $DIR/$tfile))
13782
13783         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13784 }
13785 run_test 150bb "Verify fallocate modes both zero space"
13786
13787 test_150c() {
13788         check_set_fallocate_or_skip
13789
13790         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13791         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13792         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13793         sync; sync_all_data
13794         cancel_lru_locks $OSC
13795         sleep 5
13796         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13797         want=$((OSTCOUNT * 1048576))
13798
13799         # Must allocate all requested space, not more than 5% extra
13800         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13801                 error "bytes $bytes is not $want"
13802
13803         rm -f $DIR/$tfile
13804         # verify fallocate on PFL file
13805         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13806                 error "Create $DIR/$tfile failed"
13807         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13808                         error "fallocate failed"
13809         sync; sync_all_data
13810         cancel_lru_locks $OSC
13811         sleep 5
13812         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13813         local want=$((1024 * 1048576))
13814
13815         # Must allocate all requested space, not more than 5% extra
13816         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13817                 error "bytes $bytes is not $want"
13818 }
13819 run_test 150c "Verify fallocate Size and Blocks"
13820
13821 test_150d() {
13822         check_set_fallocate_or_skip
13823
13824         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13825         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13826         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13827         sync; sync_all_data
13828         cancel_lru_locks $OSC
13829         sleep 5
13830         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13831         local want=$((OSTCOUNT * 1048576))
13832
13833         # Must allocate all requested space, not more than 5% extra
13834         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13835                 error "bytes $bytes is not $want"
13836 }
13837 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13838
13839 test_150e() {
13840         check_set_fallocate_or_skip
13841
13842         echo "df before:"
13843         $LFS df
13844         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13845         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13846                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13847
13848         # Find OST with Minimum Size
13849         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13850                        sort -un | head -1)
13851
13852         # Get 100MB per OST of the available space to reduce run time
13853         # else 60% of the available space if we are running SLOW tests
13854         if [ $SLOW == "no" ]; then
13855                 local space=$((1024 * 100 * OSTCOUNT))
13856         else
13857                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
13858         fi
13859
13860         fallocate -l${space}k $DIR/$tfile ||
13861                 error "fallocate ${space}k $DIR/$tfile failed"
13862         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13863
13864         # get size immediately after fallocate. This should be correctly
13865         # updated
13866         local size=$(stat -c '%s' $DIR/$tfile)
13867         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13868
13869         # Sleep for a while for statfs to get updated. And not pull from cache.
13870         sleep 2
13871
13872         echo "df after fallocate:"
13873         $LFS df
13874
13875         (( size / 1024 == space )) || error "size $size != requested $space"
13876         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13877                 error "used $used < space $space"
13878
13879         rm $DIR/$tfile || error "rm failed"
13880         sync
13881         wait_delete_completed
13882
13883         echo "df after unlink:"
13884         $LFS df
13885 }
13886 run_test 150e "Verify 60% of available OST space consumed by fallocate"
13887
13888 test_150f() {
13889         local size
13890         local blocks
13891         local want_size_before=20480 # in bytes
13892         local want_blocks_before=40 # 512 sized blocks
13893         local want_blocks_after=24  # 512 sized blocks
13894         local length=$(((want_blocks_before - want_blocks_after) * 512))
13895
13896         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
13897                 skip "need at least 2.14.0 for fallocate punch"
13898
13899         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
13900                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
13901         fi
13902
13903         check_set_fallocate_or_skip
13904         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13905
13906         echo "Verify fallocate punch: Range within the file range"
13907         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
13908                 error "dd failed for bs 4096 and count 5"
13909
13910         # Call fallocate with punch range which is within the file range
13911         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
13912                 error "fallocate failed: offset 4096 and length $length"
13913         # client must see changes immediately after fallocate
13914         size=$(stat -c '%s' $DIR/$tfile)
13915         blocks=$(stat -c '%b' $DIR/$tfile)
13916
13917         # Verify punch worked.
13918         (( blocks == want_blocks_after )) ||
13919                 error "punch failed: blocks $blocks != $want_blocks_after"
13920
13921         (( size == want_size_before )) ||
13922                 error "punch failed: size $size != $want_size_before"
13923
13924         # Verify there is hole in file
13925         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
13926         # precomputed md5sum
13927         local expect="4a9a834a2db02452929c0a348273b4aa"
13928
13929         cksum=($(md5sum $DIR/$tfile))
13930         [[ "${cksum[0]}" == "$expect" ]] ||
13931                 error "unexpected MD5SUM after punch: ${cksum[0]}"
13932
13933         # Start second sub-case for fallocate punch.
13934         echo "Verify fallocate punch: Range overlapping and less than blocksize"
13935         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
13936                 error "dd failed for bs 4096 and count 5"
13937
13938         # Punch range less than block size will have no change in block count
13939         want_blocks_after=40  # 512 sized blocks
13940
13941         # Punch overlaps two blocks and less than blocksize
13942         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
13943                 error "fallocate failed: offset 4000 length 3000"
13944         size=$(stat -c '%s' $DIR/$tfile)
13945         blocks=$(stat -c '%b' $DIR/$tfile)
13946
13947         # Verify punch worked.
13948         (( blocks == want_blocks_after )) ||
13949                 error "punch failed: blocks $blocks != $want_blocks_after"
13950
13951         (( size == want_size_before )) ||
13952                 error "punch failed: size $size != $want_size_before"
13953
13954         # Verify if range is really zero'ed out. We expect Zeros.
13955         # precomputed md5sum
13956         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
13957         cksum=($(md5sum $DIR/$tfile))
13958         [[ "${cksum[0]}" == "$expect" ]] ||
13959                 error "unexpected MD5SUM after punch: ${cksum[0]}"
13960 }
13961 run_test 150f "Verify fallocate punch functionality"
13962
13963 test_150g() {
13964         local space
13965         local size
13966         local blocks
13967         local blocks_after
13968         local size_after
13969         local BS=4096 # Block size in bytes
13970
13971         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
13972                 skip "need at least 2.14.0 for fallocate punch"
13973
13974         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
13975                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
13976         fi
13977
13978         check_set_fallocate_or_skip
13979         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13980
13981         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13982                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13983
13984         # Get 100MB per OST of the available space to reduce run time
13985         # else 60% of the available space if we are running SLOW tests
13986         if [ $SLOW == "no" ]; then
13987                 space=$((1024 * 100 * OSTCOUNT))
13988         else
13989                 # Find OST with Minimum Size
13990                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13991                         sort -un | head -1)
13992                 echo "min size OST: $space"
13993                 space=$(((space * 60)/100 * OSTCOUNT))
13994         fi
13995         # space in 1k units, round to 4k blocks
13996         local blkcount=$((space * 1024 / $BS))
13997
13998         echo "Verify fallocate punch: Very large Range"
13999         fallocate -l${space}k $DIR/$tfile ||
14000                 error "fallocate ${space}k $DIR/$tfile failed"
14001         # write 1M at the end, start and in the middle
14002         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14003                 error "dd failed: bs $BS count 256"
14004         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14005                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14006         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14007                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14008
14009         # Gather stats.
14010         size=$(stat -c '%s' $DIR/$tfile)
14011
14012         # gather punch length.
14013         local punch_size=$((size - (BS * 2)))
14014
14015         echo "punch_size = $punch_size"
14016         echo "size - punch_size: $((size - punch_size))"
14017         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14018
14019         # Call fallocate to punch all except 2 blocks. We leave the
14020         # first and the last block
14021         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14022         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14023                 error "fallocate failed: offset $BS length $punch_size"
14024
14025         size_after=$(stat -c '%s' $DIR/$tfile)
14026         blocks_after=$(stat -c '%b' $DIR/$tfile)
14027
14028         # Verify punch worked.
14029         # Size should be kept
14030         (( size == size_after )) ||
14031                 error "punch failed: size $size != $size_after"
14032
14033         # two 4k data blocks to remain plus possible 1 extra extent block
14034         (( blocks_after <= ((BS / 512) * 3) )) ||
14035                 error "too many blocks remains: $blocks_after"
14036
14037         # Verify that file has hole between the first and the last blocks
14038         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14039         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14040
14041         echo "Hole at [$hole_start, $hole_end)"
14042         (( hole_start == BS )) ||
14043                 error "no hole at offset $BS after punch"
14044
14045         (( hole_end == BS + punch_size )) ||
14046                 error "data at offset $hole_end < $((BS + punch_size))"
14047 }
14048 run_test 150g "Verify fallocate punch on large range"
14049
14050 #LU-2902 roc_hit was not able to read all values from lproc
14051 function roc_hit_init() {
14052         local list=$(comma_list $(osts_nodes))
14053         local dir=$DIR/$tdir-check
14054         local file=$dir/$tfile
14055         local BEFORE
14056         local AFTER
14057         local idx
14058
14059         test_mkdir $dir
14060         #use setstripe to do a write to every ost
14061         for i in $(seq 0 $((OSTCOUNT-1))); do
14062                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14063                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14064                 idx=$(printf %04x $i)
14065                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14066                         awk '$1 == "cache_access" {sum += $7}
14067                                 END { printf("%0.0f", sum) }')
14068
14069                 cancel_lru_locks osc
14070                 cat $file >/dev/null
14071
14072                 AFTER=$(get_osd_param $list *OST*$idx stats |
14073                         awk '$1 == "cache_access" {sum += $7}
14074                                 END { printf("%0.0f", sum) }')
14075
14076                 echo BEFORE:$BEFORE AFTER:$AFTER
14077                 if ! let "AFTER - BEFORE == 4"; then
14078                         rm -rf $dir
14079                         error "roc_hit is not safe to use"
14080                 fi
14081                 rm $file
14082         done
14083
14084         rm -rf $dir
14085 }
14086
14087 function roc_hit() {
14088         local list=$(comma_list $(osts_nodes))
14089         echo $(get_osd_param $list '' stats |
14090                 awk '$1 == "cache_hit" {sum += $7}
14091                         END { printf("%0.0f", sum) }')
14092 }
14093
14094 function set_cache() {
14095         local on=1
14096
14097         if [ "$2" == "off" ]; then
14098                 on=0;
14099         fi
14100         local list=$(comma_list $(osts_nodes))
14101         set_osd_param $list '' $1_cache_enable $on
14102
14103         cancel_lru_locks osc
14104 }
14105
14106 test_151() {
14107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14108         remote_ost_nodsh && skip "remote OST with nodsh"
14109
14110         local CPAGES=3
14111         local list=$(comma_list $(osts_nodes))
14112
14113         # check whether obdfilter is cache capable at all
14114         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14115                 skip "not cache-capable obdfilter"
14116         fi
14117
14118         # check cache is enabled on all obdfilters
14119         if get_osd_param $list '' read_cache_enable | grep 0; then
14120                 skip "oss cache is disabled"
14121         fi
14122
14123         set_osd_param $list '' writethrough_cache_enable 1
14124
14125         # check write cache is enabled on all obdfilters
14126         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14127                 skip "oss write cache is NOT enabled"
14128         fi
14129
14130         roc_hit_init
14131
14132         #define OBD_FAIL_OBD_NO_LRU  0x609
14133         do_nodes $list $LCTL set_param fail_loc=0x609
14134
14135         # pages should be in the case right after write
14136         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14137                 error "dd failed"
14138
14139         local BEFORE=$(roc_hit)
14140         cancel_lru_locks osc
14141         cat $DIR/$tfile >/dev/null
14142         local AFTER=$(roc_hit)
14143
14144         do_nodes $list $LCTL set_param fail_loc=0
14145
14146         if ! let "AFTER - BEFORE == CPAGES"; then
14147                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14148         fi
14149
14150         cancel_lru_locks osc
14151         # invalidates OST cache
14152         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14153         set_osd_param $list '' read_cache_enable 0
14154         cat $DIR/$tfile >/dev/null
14155
14156         # now data shouldn't be found in the cache
14157         BEFORE=$(roc_hit)
14158         cancel_lru_locks osc
14159         cat $DIR/$tfile >/dev/null
14160         AFTER=$(roc_hit)
14161         if let "AFTER - BEFORE != 0"; then
14162                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14163         fi
14164
14165         set_osd_param $list '' read_cache_enable 1
14166         rm -f $DIR/$tfile
14167 }
14168 run_test 151 "test cache on oss and controls ==============================="
14169
14170 test_152() {
14171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14172
14173         local TF="$TMP/$tfile"
14174
14175         # simulate ENOMEM during write
14176 #define OBD_FAIL_OST_NOMEM      0x226
14177         lctl set_param fail_loc=0x80000226
14178         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14179         cp $TF $DIR/$tfile
14180         sync || error "sync failed"
14181         lctl set_param fail_loc=0
14182
14183         # discard client's cache
14184         cancel_lru_locks osc
14185
14186         # simulate ENOMEM during read
14187         lctl set_param fail_loc=0x80000226
14188         cmp $TF $DIR/$tfile || error "cmp failed"
14189         lctl set_param fail_loc=0
14190
14191         rm -f $TF
14192 }
14193 run_test 152 "test read/write with enomem ============================"
14194
14195 test_153() {
14196         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14197 }
14198 run_test 153 "test if fdatasync does not crash ======================="
14199
14200 dot_lustre_fid_permission_check() {
14201         local fid=$1
14202         local ffid=$MOUNT/.lustre/fid/$fid
14203         local test_dir=$2
14204
14205         echo "stat fid $fid"
14206         stat $ffid > /dev/null || error "stat $ffid failed."
14207         echo "touch fid $fid"
14208         touch $ffid || error "touch $ffid failed."
14209         echo "write to fid $fid"
14210         cat /etc/hosts > $ffid || error "write $ffid failed."
14211         echo "read fid $fid"
14212         diff /etc/hosts $ffid || error "read $ffid failed."
14213         echo "append write to fid $fid"
14214         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14215         echo "rename fid $fid"
14216         mv $ffid $test_dir/$tfile.1 &&
14217                 error "rename $ffid to $tfile.1 should fail."
14218         touch $test_dir/$tfile.1
14219         mv $test_dir/$tfile.1 $ffid &&
14220                 error "rename $tfile.1 to $ffid should fail."
14221         rm -f $test_dir/$tfile.1
14222         echo "truncate fid $fid"
14223         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14224         echo "link fid $fid"
14225         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14226         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14227                 echo "setfacl fid $fid"
14228                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14229                 echo "getfacl fid $fid"
14230                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14231         fi
14232         echo "unlink fid $fid"
14233         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14234         echo "mknod fid $fid"
14235         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14236
14237         fid=[0xf00000400:0x1:0x0]
14238         ffid=$MOUNT/.lustre/fid/$fid
14239
14240         echo "stat non-exist fid $fid"
14241         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14242         echo "write to non-exist fid $fid"
14243         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14244         echo "link new fid $fid"
14245         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14246
14247         mkdir -p $test_dir/$tdir
14248         touch $test_dir/$tdir/$tfile
14249         fid=$($LFS path2fid $test_dir/$tdir)
14250         rc=$?
14251         [ $rc -ne 0 ] &&
14252                 error "error: could not get fid for $test_dir/$dir/$tfile."
14253
14254         ffid=$MOUNT/.lustre/fid/$fid
14255
14256         echo "ls $fid"
14257         ls $ffid > /dev/null || error "ls $ffid failed."
14258         echo "touch $fid/$tfile.1"
14259         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14260
14261         echo "touch $MOUNT/.lustre/fid/$tfile"
14262         touch $MOUNT/.lustre/fid/$tfile && \
14263                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14264
14265         echo "setxattr to $MOUNT/.lustre/fid"
14266         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14267
14268         echo "listxattr for $MOUNT/.lustre/fid"
14269         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14270
14271         echo "delxattr from $MOUNT/.lustre/fid"
14272         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14273
14274         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14275         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14276                 error "touch invalid fid should fail."
14277
14278         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14279         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14280                 error "touch non-normal fid should fail."
14281
14282         echo "rename $tdir to $MOUNT/.lustre/fid"
14283         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14284                 error "rename to $MOUNT/.lustre/fid should fail."
14285
14286         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14287         then            # LU-3547
14288                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14289                 local new_obf_mode=777
14290
14291                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14292                 chmod $new_obf_mode $DIR/.lustre/fid ||
14293                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14294
14295                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14296                 [ $obf_mode -eq $new_obf_mode ] ||
14297                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14298
14299                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14300                 chmod $old_obf_mode $DIR/.lustre/fid ||
14301                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14302         fi
14303
14304         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14305         fid=$($LFS path2fid $test_dir/$tfile-2)
14306
14307         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14308         then # LU-5424
14309                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14310                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14311                         error "create lov data thru .lustre failed"
14312         fi
14313         echo "cp /etc/passwd $test_dir/$tfile-2"
14314         cp /etc/passwd $test_dir/$tfile-2 ||
14315                 error "copy to $test_dir/$tfile-2 failed."
14316         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14317         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14318                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14319
14320         rm -rf $test_dir/tfile.lnk
14321         rm -rf $test_dir/$tfile-2
14322 }
14323
14324 test_154A() {
14325         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14326                 skip "Need MDS version at least 2.4.1"
14327
14328         local tf=$DIR/$tfile
14329         touch $tf
14330
14331         local fid=$($LFS path2fid $tf)
14332         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14333
14334         # check that we get the same pathname back
14335         local rootpath
14336         local found
14337         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14338                 echo "$rootpath $fid"
14339                 found=$($LFS fid2path $rootpath "$fid")
14340                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14341                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14342         done
14343
14344         # check wrong root path format
14345         rootpath=$MOUNT"_wrong"
14346         found=$($LFS fid2path $rootpath "$fid")
14347         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14348 }
14349 run_test 154A "lfs path2fid and fid2path basic checks"
14350
14351 test_154B() {
14352         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14353                 skip "Need MDS version at least 2.4.1"
14354
14355         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14356         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14357         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14358         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14359
14360         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14361         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14362
14363         # check that we get the same pathname
14364         echo "PFID: $PFID, name: $name"
14365         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14366         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14367         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14368                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14369
14370         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14371 }
14372 run_test 154B "verify the ll_decode_linkea tool"
14373
14374 test_154a() {
14375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14376         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14377         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14378                 skip "Need MDS version at least 2.2.51"
14379         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14380
14381         cp /etc/hosts $DIR/$tfile
14382
14383         fid=$($LFS path2fid $DIR/$tfile)
14384         rc=$?
14385         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14386
14387         dot_lustre_fid_permission_check "$fid" $DIR ||
14388                 error "dot lustre permission check $fid failed"
14389
14390         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14391
14392         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14393
14394         touch $MOUNT/.lustre/file &&
14395                 error "creation is not allowed under .lustre"
14396
14397         mkdir $MOUNT/.lustre/dir &&
14398                 error "mkdir is not allowed under .lustre"
14399
14400         rm -rf $DIR/$tfile
14401 }
14402 run_test 154a "Open-by-FID"
14403
14404 test_154b() {
14405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14406         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14407         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14408         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14409                 skip "Need MDS version at least 2.2.51"
14410
14411         local remote_dir=$DIR/$tdir/remote_dir
14412         local MDTIDX=1
14413         local rc=0
14414
14415         mkdir -p $DIR/$tdir
14416         $LFS mkdir -i $MDTIDX $remote_dir ||
14417                 error "create remote directory failed"
14418
14419         cp /etc/hosts $remote_dir/$tfile
14420
14421         fid=$($LFS path2fid $remote_dir/$tfile)
14422         rc=$?
14423         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14424
14425         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14426                 error "dot lustre permission check $fid failed"
14427         rm -rf $DIR/$tdir
14428 }
14429 run_test 154b "Open-by-FID for remote directory"
14430
14431 test_154c() {
14432         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14433                 skip "Need MDS version at least 2.4.1"
14434
14435         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14436         local FID1=$($LFS path2fid $DIR/$tfile.1)
14437         local FID2=$($LFS path2fid $DIR/$tfile.2)
14438         local FID3=$($LFS path2fid $DIR/$tfile.3)
14439
14440         local N=1
14441         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14442                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14443                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14444                 local want=FID$N
14445                 [ "$FID" = "${!want}" ] ||
14446                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14447                 N=$((N + 1))
14448         done
14449
14450         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14451         do
14452                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14453                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14454                 N=$((N + 1))
14455         done
14456 }
14457 run_test 154c "lfs path2fid and fid2path multiple arguments"
14458
14459 test_154d() {
14460         remote_mds_nodsh && skip "remote MDS with nodsh"
14461         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14462                 skip "Need MDS version at least 2.5.53"
14463
14464         if remote_mds; then
14465                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14466         else
14467                 nid="0@lo"
14468         fi
14469         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14470         local fd
14471         local cmd
14472
14473         rm -f $DIR/$tfile
14474         touch $DIR/$tfile
14475
14476         local fid=$($LFS path2fid $DIR/$tfile)
14477         # Open the file
14478         fd=$(free_fd)
14479         cmd="exec $fd<$DIR/$tfile"
14480         eval $cmd
14481         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14482         echo "$fid_list" | grep "$fid"
14483         rc=$?
14484
14485         cmd="exec $fd>/dev/null"
14486         eval $cmd
14487         if [ $rc -ne 0 ]; then
14488                 error "FID $fid not found in open files list $fid_list"
14489         fi
14490 }
14491 run_test 154d "Verify open file fid"
14492
14493 test_154e()
14494 {
14495         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14496                 skip "Need MDS version at least 2.6.50"
14497
14498         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14499                 error ".lustre returned by readdir"
14500         fi
14501 }
14502 run_test 154e ".lustre is not returned by readdir"
14503
14504 test_154f() {
14505         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14506
14507         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14508         test_mkdir -p -c1 $DIR/$tdir/d
14509         # test dirs inherit from its stripe
14510         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14511         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14512         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14513         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14514         touch $DIR/f
14515
14516         # get fid of parents
14517         local FID0=$($LFS path2fid $DIR/$tdir/d)
14518         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14519         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14520         local FID3=$($LFS path2fid $DIR)
14521
14522         # check that path2fid --parents returns expected <parent_fid>/name
14523         # 1) test for a directory (single parent)
14524         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14525         [ "$parent" == "$FID0/foo1" ] ||
14526                 error "expected parent: $FID0/foo1, got: $parent"
14527
14528         # 2) test for a file with nlink > 1 (multiple parents)
14529         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14530         echo "$parent" | grep -F "$FID1/$tfile" ||
14531                 error "$FID1/$tfile not returned in parent list"
14532         echo "$parent" | grep -F "$FID2/link" ||
14533                 error "$FID2/link not returned in parent list"
14534
14535         # 3) get parent by fid
14536         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14537         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14538         echo "$parent" | grep -F "$FID1/$tfile" ||
14539                 error "$FID1/$tfile not returned in parent list (by fid)"
14540         echo "$parent" | grep -F "$FID2/link" ||
14541                 error "$FID2/link not returned in parent list (by fid)"
14542
14543         # 4) test for entry in root directory
14544         parent=$($LFS path2fid --parents $DIR/f)
14545         echo "$parent" | grep -F "$FID3/f" ||
14546                 error "$FID3/f not returned in parent list"
14547
14548         # 5) test it on root directory
14549         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14550                 error "$MOUNT should not have parents"
14551
14552         # enable xattr caching and check that linkea is correctly updated
14553         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14554         save_lustre_params client "llite.*.xattr_cache" > $save
14555         lctl set_param llite.*.xattr_cache 1
14556
14557         # 6.1) linkea update on rename
14558         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14559
14560         # get parents by fid
14561         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14562         # foo1 should no longer be returned in parent list
14563         echo "$parent" | grep -F "$FID1" &&
14564                 error "$FID1 should no longer be in parent list"
14565         # the new path should appear
14566         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14567                 error "$FID2/$tfile.moved is not in parent list"
14568
14569         # 6.2) linkea update on unlink
14570         rm -f $DIR/$tdir/d/foo2/link
14571         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14572         # foo2/link should no longer be returned in parent list
14573         echo "$parent" | grep -F "$FID2/link" &&
14574                 error "$FID2/link should no longer be in parent list"
14575         true
14576
14577         rm -f $DIR/f
14578         restore_lustre_params < $save
14579         rm -f $save
14580 }
14581 run_test 154f "get parent fids by reading link ea"
14582
14583 test_154g()
14584 {
14585         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14586         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14587            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14588                 skip "Need MDS version at least 2.6.92"
14589
14590         mkdir -p $DIR/$tdir
14591         llapi_fid_test -d $DIR/$tdir
14592 }
14593 run_test 154g "various llapi FID tests"
14594
14595 test_155_small_load() {
14596     local temp=$TMP/$tfile
14597     local file=$DIR/$tfile
14598
14599     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14600         error "dd of=$temp bs=6096 count=1 failed"
14601     cp $temp $file
14602     cancel_lru_locks $OSC
14603     cmp $temp $file || error "$temp $file differ"
14604
14605     $TRUNCATE $temp 6000
14606     $TRUNCATE $file 6000
14607     cmp $temp $file || error "$temp $file differ (truncate1)"
14608
14609     echo "12345" >>$temp
14610     echo "12345" >>$file
14611     cmp $temp $file || error "$temp $file differ (append1)"
14612
14613     echo "12345" >>$temp
14614     echo "12345" >>$file
14615     cmp $temp $file || error "$temp $file differ (append2)"
14616
14617     rm -f $temp $file
14618     true
14619 }
14620
14621 test_155_big_load() {
14622         remote_ost_nodsh && skip "remote OST with nodsh"
14623
14624         local temp=$TMP/$tfile
14625         local file=$DIR/$tfile
14626
14627         free_min_max
14628         local cache_size=$(do_facet ost$((MAXI+1)) \
14629                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14630         local large_file_size=$((cache_size * 2))
14631
14632         echo "OSS cache size: $cache_size KB"
14633         echo "Large file size: $large_file_size KB"
14634
14635         [ $MAXV -le $large_file_size ] &&
14636                 skip_env "max available OST size needs > $large_file_size KB"
14637
14638         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14639
14640         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14641                 error "dd of=$temp bs=$large_file_size count=1k failed"
14642         cp $temp $file
14643         ls -lh $temp $file
14644         cancel_lru_locks osc
14645         cmp $temp $file || error "$temp $file differ"
14646
14647         rm -f $temp $file
14648         true
14649 }
14650
14651 save_writethrough() {
14652         local facets=$(get_facets OST)
14653
14654         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14655 }
14656
14657 test_155a() {
14658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14659
14660         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14661
14662         save_writethrough $p
14663
14664         set_cache read on
14665         set_cache writethrough on
14666         test_155_small_load
14667         restore_lustre_params < $p
14668         rm -f $p
14669 }
14670 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14671
14672 test_155b() {
14673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14674
14675         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14676
14677         save_writethrough $p
14678
14679         set_cache read on
14680         set_cache writethrough off
14681         test_155_small_load
14682         restore_lustre_params < $p
14683         rm -f $p
14684 }
14685 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14686
14687 test_155c() {
14688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14689
14690         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14691
14692         save_writethrough $p
14693
14694         set_cache read off
14695         set_cache writethrough on
14696         test_155_small_load
14697         restore_lustre_params < $p
14698         rm -f $p
14699 }
14700 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14701
14702 test_155d() {
14703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14704
14705         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14706
14707         save_writethrough $p
14708
14709         set_cache read off
14710         set_cache writethrough off
14711         test_155_small_load
14712         restore_lustre_params < $p
14713         rm -f $p
14714 }
14715 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14716
14717 test_155e() {
14718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14719
14720         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14721
14722         save_writethrough $p
14723
14724         set_cache read on
14725         set_cache writethrough on
14726         test_155_big_load
14727         restore_lustre_params < $p
14728         rm -f $p
14729 }
14730 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14731
14732 test_155f() {
14733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14734
14735         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14736
14737         save_writethrough $p
14738
14739         set_cache read on
14740         set_cache writethrough off
14741         test_155_big_load
14742         restore_lustre_params < $p
14743         rm -f $p
14744 }
14745 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14746
14747 test_155g() {
14748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14749
14750         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14751
14752         save_writethrough $p
14753
14754         set_cache read off
14755         set_cache writethrough on
14756         test_155_big_load
14757         restore_lustre_params < $p
14758         rm -f $p
14759 }
14760 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14761
14762 test_155h() {
14763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14764
14765         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14766
14767         save_writethrough $p
14768
14769         set_cache read off
14770         set_cache writethrough off
14771         test_155_big_load
14772         restore_lustre_params < $p
14773         rm -f $p
14774 }
14775 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14776
14777 test_156() {
14778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14779         remote_ost_nodsh && skip "remote OST with nodsh"
14780         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14781                 skip "stats not implemented on old servers"
14782         [ "$ost1_FSTYPE" = "zfs" ] &&
14783                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14784
14785         local CPAGES=3
14786         local BEFORE
14787         local AFTER
14788         local file="$DIR/$tfile"
14789         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14790
14791         save_writethrough $p
14792         roc_hit_init
14793
14794         log "Turn on read and write cache"
14795         set_cache read on
14796         set_cache writethrough on
14797
14798         log "Write data and read it back."
14799         log "Read should be satisfied from the cache."
14800         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14801         BEFORE=$(roc_hit)
14802         cancel_lru_locks osc
14803         cat $file >/dev/null
14804         AFTER=$(roc_hit)
14805         if ! let "AFTER - BEFORE == CPAGES"; then
14806                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14807         else
14808                 log "cache hits: before: $BEFORE, after: $AFTER"
14809         fi
14810
14811         log "Read again; it should be satisfied from the cache."
14812         BEFORE=$AFTER
14813         cancel_lru_locks osc
14814         cat $file >/dev/null
14815         AFTER=$(roc_hit)
14816         if ! let "AFTER - BEFORE == CPAGES"; then
14817                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14818         else
14819                 log "cache hits:: before: $BEFORE, after: $AFTER"
14820         fi
14821
14822         log "Turn off the read cache and turn on the write cache"
14823         set_cache read off
14824         set_cache writethrough on
14825
14826         log "Read again; it should be satisfied from the cache."
14827         BEFORE=$(roc_hit)
14828         cancel_lru_locks osc
14829         cat $file >/dev/null
14830         AFTER=$(roc_hit)
14831         if ! let "AFTER - BEFORE == CPAGES"; then
14832                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14833         else
14834                 log "cache hits:: before: $BEFORE, after: $AFTER"
14835         fi
14836
14837         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14838                 # > 2.12.56 uses pagecache if cached
14839                 log "Read again; it should not be satisfied from the cache."
14840                 BEFORE=$AFTER
14841                 cancel_lru_locks osc
14842                 cat $file >/dev/null
14843                 AFTER=$(roc_hit)
14844                 if ! let "AFTER - BEFORE == 0"; then
14845                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14846                 else
14847                         log "cache hits:: before: $BEFORE, after: $AFTER"
14848                 fi
14849         fi
14850
14851         log "Write data and read it back."
14852         log "Read should be satisfied from the cache."
14853         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14854         BEFORE=$(roc_hit)
14855         cancel_lru_locks osc
14856         cat $file >/dev/null
14857         AFTER=$(roc_hit)
14858         if ! let "AFTER - BEFORE == CPAGES"; then
14859                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14860         else
14861                 log "cache hits:: before: $BEFORE, after: $AFTER"
14862         fi
14863
14864         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14865                 # > 2.12.56 uses pagecache if cached
14866                 log "Read again; it should not be satisfied from the cache."
14867                 BEFORE=$AFTER
14868                 cancel_lru_locks osc
14869                 cat $file >/dev/null
14870                 AFTER=$(roc_hit)
14871                 if ! let "AFTER - BEFORE == 0"; then
14872                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14873                 else
14874                         log "cache hits:: before: $BEFORE, after: $AFTER"
14875                 fi
14876         fi
14877
14878         log "Turn off read and write cache"
14879         set_cache read off
14880         set_cache writethrough off
14881
14882         log "Write data and read it back"
14883         log "It should not be satisfied from the cache."
14884         rm -f $file
14885         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14886         cancel_lru_locks osc
14887         BEFORE=$(roc_hit)
14888         cat $file >/dev/null
14889         AFTER=$(roc_hit)
14890         if ! let "AFTER - BEFORE == 0"; then
14891                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14892         else
14893                 log "cache hits:: before: $BEFORE, after: $AFTER"
14894         fi
14895
14896         log "Turn on the read cache and turn off the write cache"
14897         set_cache read on
14898         set_cache writethrough off
14899
14900         log "Write data and read it back"
14901         log "It should not be satisfied from the cache."
14902         rm -f $file
14903         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14904         BEFORE=$(roc_hit)
14905         cancel_lru_locks osc
14906         cat $file >/dev/null
14907         AFTER=$(roc_hit)
14908         if ! let "AFTER - BEFORE == 0"; then
14909                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14910         else
14911                 log "cache hits:: before: $BEFORE, after: $AFTER"
14912         fi
14913
14914         log "Read again; it should be satisfied from the cache."
14915         BEFORE=$(roc_hit)
14916         cancel_lru_locks osc
14917         cat $file >/dev/null
14918         AFTER=$(roc_hit)
14919         if ! let "AFTER - BEFORE == CPAGES"; then
14920                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14921         else
14922                 log "cache hits:: before: $BEFORE, after: $AFTER"
14923         fi
14924
14925         restore_lustre_params < $p
14926         rm -f $p $file
14927 }
14928 run_test 156 "Verification of tunables"
14929
14930 test_160a() {
14931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14932         remote_mds_nodsh && skip "remote MDS with nodsh"
14933         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14934                 skip "Need MDS version at least 2.2.0"
14935
14936         changelog_register || error "changelog_register failed"
14937         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14938         changelog_users $SINGLEMDS | grep -q $cl_user ||
14939                 error "User $cl_user not found in changelog_users"
14940
14941         # change something
14942         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14943         changelog_clear 0 || error "changelog_clear failed"
14944         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14945         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14946         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14947         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14948         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14949         rm $DIR/$tdir/pics/desktop.jpg
14950
14951         changelog_dump | tail -10
14952
14953         echo "verifying changelog mask"
14954         changelog_chmask "-MKDIR"
14955         changelog_chmask "-CLOSE"
14956
14957         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14958         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14959
14960         changelog_chmask "+MKDIR"
14961         changelog_chmask "+CLOSE"
14962
14963         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14964         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14965
14966         changelog_dump | tail -10
14967         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14968         CLOSES=$(changelog_dump | grep -c "CLOSE")
14969         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14970         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14971
14972         # verify contents
14973         echo "verifying target fid"
14974         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14975         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14976         [ "$fidc" == "$fidf" ] ||
14977                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14978         echo "verifying parent fid"
14979         # The FID returned from the Changelog may be the directory shard on
14980         # a different MDT, and not the FID returned by path2fid on the parent.
14981         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14982         # since this is what will matter when recreating this file in the tree.
14983         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14984         local pathp=$($LFS fid2path $MOUNT "$fidp")
14985         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14986                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14987
14988         echo "getting records for $cl_user"
14989         changelog_users $SINGLEMDS
14990         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14991         local nclr=3
14992         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14993                 error "changelog_clear failed"
14994         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14995         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14996         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14997                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14998
14999         local min0_rec=$(changelog_users $SINGLEMDS |
15000                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15001         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15002                           awk '{ print $1; exit; }')
15003
15004         changelog_dump | tail -n 5
15005         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15006         [ $first_rec == $((min0_rec + 1)) ] ||
15007                 error "first index should be $min0_rec + 1 not $first_rec"
15008
15009         # LU-3446 changelog index reset on MDT restart
15010         local cur_rec1=$(changelog_users $SINGLEMDS |
15011                          awk '/^current.index:/ { print $NF }')
15012         changelog_clear 0 ||
15013                 error "clear all changelog records for $cl_user failed"
15014         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15015         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15016                 error "Fail to start $SINGLEMDS"
15017         local cur_rec2=$(changelog_users $SINGLEMDS |
15018                          awk '/^current.index:/ { print $NF }')
15019         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15020         [ $cur_rec1 == $cur_rec2 ] ||
15021                 error "current index should be $cur_rec1 not $cur_rec2"
15022
15023         echo "verifying users from this test are deregistered"
15024         changelog_deregister || error "changelog_deregister failed"
15025         changelog_users $SINGLEMDS | grep -q $cl_user &&
15026                 error "User '$cl_user' still in changelog_users"
15027
15028         # lctl get_param -n mdd.*.changelog_users
15029         # current index: 144
15030         # ID    index (idle seconds)
15031         # cl3   144 (2)
15032         if ! changelog_users $SINGLEMDS | grep "^cl"; then
15033                 # this is the normal case where all users were deregistered
15034                 # make sure no new records are added when no users are present
15035                 local last_rec1=$(changelog_users $SINGLEMDS |
15036                                   awk '/^current.index:/ { print $NF }')
15037                 touch $DIR/$tdir/chloe
15038                 local last_rec2=$(changelog_users $SINGLEMDS |
15039                                   awk '/^current.index:/ { print $NF }')
15040                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15041                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15042         else
15043                 # any changelog users must be leftovers from a previous test
15044                 changelog_users $SINGLEMDS
15045                 echo "other changelog users; can't verify off"
15046         fi
15047 }
15048 run_test 160a "changelog sanity"
15049
15050 test_160b() { # LU-3587
15051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15052         remote_mds_nodsh && skip "remote MDS with nodsh"
15053         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15054                 skip "Need MDS version at least 2.2.0"
15055
15056         changelog_register || error "changelog_register failed"
15057         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15058         changelog_users $SINGLEMDS | grep -q $cl_user ||
15059                 error "User '$cl_user' not found in changelog_users"
15060
15061         local longname1=$(str_repeat a 255)
15062         local longname2=$(str_repeat b 255)
15063
15064         cd $DIR
15065         echo "creating very long named file"
15066         touch $longname1 || error "create of '$longname1' failed"
15067         echo "renaming very long named file"
15068         mv $longname1 $longname2
15069
15070         changelog_dump | grep RENME | tail -n 5
15071         rm -f $longname2
15072 }
15073 run_test 160b "Verify that very long rename doesn't crash in changelog"
15074
15075 test_160c() {
15076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15077         remote_mds_nodsh && skip "remote MDS with nodsh"
15078
15079         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15080                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15081                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15082                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15083
15084         local rc=0
15085
15086         # Registration step
15087         changelog_register || error "changelog_register failed"
15088
15089         rm -rf $DIR/$tdir
15090         mkdir -p $DIR/$tdir
15091         $MCREATE $DIR/$tdir/foo_160c
15092         changelog_chmask "-TRUNC"
15093         $TRUNCATE $DIR/$tdir/foo_160c 200
15094         changelog_chmask "+TRUNC"
15095         $TRUNCATE $DIR/$tdir/foo_160c 199
15096         changelog_dump | tail -n 5
15097         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15098         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15099 }
15100 run_test 160c "verify that changelog log catch the truncate event"
15101
15102 test_160d() {
15103         remote_mds_nodsh && skip "remote MDS with nodsh"
15104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15106         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15107                 skip "Need MDS version at least 2.7.60"
15108
15109         # Registration step
15110         changelog_register || error "changelog_register failed"
15111
15112         mkdir -p $DIR/$tdir/migrate_dir
15113         changelog_clear 0 || error "changelog_clear failed"
15114
15115         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15116         changelog_dump | tail -n 5
15117         local migrates=$(changelog_dump | grep -c "MIGRT")
15118         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15119 }
15120 run_test 160d "verify that changelog log catch the migrate event"
15121
15122 test_160e() {
15123         remote_mds_nodsh && skip "remote MDS with nodsh"
15124
15125         # Create a user
15126         changelog_register || error "changelog_register failed"
15127
15128         # Delete a future user (expect fail)
15129         local MDT0=$(facet_svc $SINGLEMDS)
15130         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15131         local rc=$?
15132
15133         if [ $rc -eq 0 ]; then
15134                 error "Deleted non-existant user cl77"
15135         elif [ $rc -ne 2 ]; then
15136                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15137         fi
15138
15139         # Clear to a bad index (1 billion should be safe)
15140         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15141         rc=$?
15142
15143         if [ $rc -eq 0 ]; then
15144                 error "Successfully cleared to invalid CL index"
15145         elif [ $rc -ne 22 ]; then
15146                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15147         fi
15148 }
15149 run_test 160e "changelog negative testing (should return errors)"
15150
15151 test_160f() {
15152         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15153         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15154                 skip "Need MDS version at least 2.10.56"
15155
15156         local mdts=$(comma_list $(mdts_nodes))
15157
15158         # Create a user
15159         changelog_register || error "first changelog_register failed"
15160         changelog_register || error "second changelog_register failed"
15161         local cl_users
15162         declare -A cl_user1
15163         declare -A cl_user2
15164         local user_rec1
15165         local user_rec2
15166         local i
15167
15168         # generate some changelog records to accumulate on each MDT
15169         # use all_char because created files should be evenly distributed
15170         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15171                 error "test_mkdir $tdir failed"
15172         log "$(date +%s): creating first files"
15173         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15174                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15175                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15176         done
15177
15178         # check changelogs have been generated
15179         local start=$SECONDS
15180         local idle_time=$((MDSCOUNT * 5 + 5))
15181         local nbcl=$(changelog_dump | wc -l)
15182         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15183
15184         for param in "changelog_max_idle_time=$idle_time" \
15185                      "changelog_gc=1" \
15186                      "changelog_min_gc_interval=2" \
15187                      "changelog_min_free_cat_entries=3"; do
15188                 local MDT0=$(facet_svc $SINGLEMDS)
15189                 local var="${param%=*}"
15190                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15191
15192                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15193                 do_nodes $mdts $LCTL set_param mdd.*.$param
15194         done
15195
15196         # force cl_user2 to be idle (1st part), but also cancel the
15197         # cl_user1 records so that it is not evicted later in the test.
15198         local sleep1=$((idle_time / 2))
15199         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15200         sleep $sleep1
15201
15202         # simulate changelog catalog almost full
15203         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15204         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15205
15206         for i in $(seq $MDSCOUNT); do
15207                 cl_users=(${CL_USERS[mds$i]})
15208                 cl_user1[mds$i]="${cl_users[0]}"
15209                 cl_user2[mds$i]="${cl_users[1]}"
15210
15211                 [ -n "${cl_user1[mds$i]}" ] ||
15212                         error "mds$i: no user registered"
15213                 [ -n "${cl_user2[mds$i]}" ] ||
15214                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15215
15216                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15217                 [ -n "$user_rec1" ] ||
15218                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15219                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15220                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15221                 [ -n "$user_rec2" ] ||
15222                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15223                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15224                      "$user_rec1 + 2 == $user_rec2"
15225                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15226                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15227                               "$user_rec1 + 2, but is $user_rec2"
15228                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15229                 [ -n "$user_rec2" ] ||
15230                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15231                 [ $user_rec1 == $user_rec2 ] ||
15232                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15233                               "$user_rec1, but is $user_rec2"
15234         done
15235
15236         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15237         local sleep2=$((idle_time - (SECONDS - start) + 1))
15238         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15239         sleep $sleep2
15240
15241         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15242         # cl_user1 should be OK because it recently processed records.
15243         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15244         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15245                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15246                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15247         done
15248
15249         # ensure gc thread is done
15250         for i in $(mdts_nodes); do
15251                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15252                         error "$i: GC-thread not done"
15253         done
15254
15255         local first_rec
15256         for (( i = 1; i <= MDSCOUNT; i++ )); do
15257                 # check cl_user1 still registered
15258                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15259                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15260                 # check cl_user2 unregistered
15261                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15262                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15263
15264                 # check changelogs are present and starting at $user_rec1 + 1
15265                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15266                 [ -n "$user_rec1" ] ||
15267                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15268                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15269                             awk '{ print $1; exit; }')
15270
15271                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15272                 [ $((user_rec1 + 1)) == $first_rec ] ||
15273                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15274         done
15275 }
15276 run_test 160f "changelog garbage collect (timestamped users)"
15277
15278 test_160g() {
15279         remote_mds_nodsh && skip "remote MDS with nodsh"
15280         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15281                 skip "Need MDS version at least 2.10.56"
15282
15283         local mdts=$(comma_list $(mdts_nodes))
15284
15285         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15286         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15287
15288         # Create a user
15289         changelog_register || error "first changelog_register failed"
15290         changelog_register || error "second changelog_register failed"
15291         local cl_users
15292         declare -A cl_user1
15293         declare -A cl_user2
15294         local user_rec1
15295         local user_rec2
15296         local i
15297
15298         # generate some changelog records to accumulate on each MDT
15299         # use all_char because created files should be evenly distributed
15300         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15301                 error "test_mkdir $tdir failed"
15302         for ((i = 0; i < MDSCOUNT; i++)); do
15303                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15304                         error "create $DIR/$tdir/d$i.1 failed"
15305         done
15306
15307         # check changelogs have been generated
15308         local nbcl=$(changelog_dump | wc -l)
15309         (( $nbcl > 0 )) || error "no changelogs found"
15310
15311         # reduce the max_idle_indexes value to make sure we exceed it
15312         for param in "changelog_max_idle_indexes=1" \
15313                      "changelog_gc=1" \
15314                      "changelog_min_gc_interval=2" \
15315                      "changelog_min_free_cat_entries=3"; do
15316                 local MDT0=$(facet_svc $SINGLEMDS)
15317                 local var="${param%=*}"
15318                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15319
15320                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15321                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15322                         error "unable to set mdd.*.$param"
15323         done
15324
15325         # simulate changelog catalog almost full
15326         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15327         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15328
15329         local start=$SECONDS
15330         for i in $(seq $MDSCOUNT); do
15331                 cl_users=(${CL_USERS[mds$i]})
15332                 cl_user1[mds$i]="${cl_users[0]}"
15333                 cl_user2[mds$i]="${cl_users[1]}"
15334
15335                 [ -n "${cl_user1[mds$i]}" ] ||
15336                         error "mds$i: no user registered"
15337                 [ -n "${cl_user2[mds$i]}" ] ||
15338                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15339
15340                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15341                 [ -n "$user_rec1" ] ||
15342                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15343                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15344                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15345                 [ -n "$user_rec2" ] ||
15346                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15347                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15348                      "$user_rec1 + 2 == $user_rec2"
15349                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15350                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15351                               "$user_rec1 + 2, but is $user_rec2"
15352                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15353                 [ -n "$user_rec2" ] ||
15354                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15355                 [ $user_rec1 == $user_rec2 ] ||
15356                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15357                               "$user_rec1, but is $user_rec2"
15358         done
15359
15360         # ensure we are past the previous changelog_min_gc_interval set above
15361         local sleep2=$((start + 2 - SECONDS))
15362         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15363
15364         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15365         # cl_user1 should be OK because it recently processed records.
15366         for ((i = 0; i < MDSCOUNT; i++)); do
15367                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15368                         error "create $DIR/$tdir/d$i.3 failed"
15369         done
15370
15371         # ensure gc thread is done
15372         for i in $(mdts_nodes); do
15373                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15374                         error "$i: GC-thread not done"
15375         done
15376
15377         local first_rec
15378         for (( i = 1; i <= MDSCOUNT; i++ )); do
15379                 # check cl_user1 still registered
15380                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15381                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15382                 # check cl_user2 unregistered
15383                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15384                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15385
15386                 # check changelogs are present and starting at $user_rec1 + 1
15387                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15388                 [ -n "$user_rec1" ] ||
15389                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15390                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15391                             awk '{ print $1; exit; }')
15392
15393                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15394                 [ $((user_rec1 + 1)) == $first_rec ] ||
15395                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15396         done
15397 }
15398 run_test 160g "changelog garbage collect (old users)"
15399
15400 test_160h() {
15401         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15402         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15403                 skip "Need MDS version at least 2.10.56"
15404
15405         local mdts=$(comma_list $(mdts_nodes))
15406
15407         # Create a user
15408         changelog_register || error "first changelog_register failed"
15409         changelog_register || error "second changelog_register failed"
15410         local cl_users
15411         declare -A cl_user1
15412         declare -A cl_user2
15413         local user_rec1
15414         local user_rec2
15415         local i
15416
15417         # generate some changelog records to accumulate on each MDT
15418         # use all_char because created files should be evenly distributed
15419         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15420                 error "test_mkdir $tdir failed"
15421         for ((i = 0; i < MDSCOUNT; i++)); do
15422                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15423                         error "create $DIR/$tdir/d$i.1 failed"
15424         done
15425
15426         # check changelogs have been generated
15427         local nbcl=$(changelog_dump | wc -l)
15428         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15429
15430         for param in "changelog_max_idle_time=10" \
15431                      "changelog_gc=1" \
15432                      "changelog_min_gc_interval=2"; do
15433                 local MDT0=$(facet_svc $SINGLEMDS)
15434                 local var="${param%=*}"
15435                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15436
15437                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15438                 do_nodes $mdts $LCTL set_param mdd.*.$param
15439         done
15440
15441         # force cl_user2 to be idle (1st part)
15442         sleep 9
15443
15444         for i in $(seq $MDSCOUNT); do
15445                 cl_users=(${CL_USERS[mds$i]})
15446                 cl_user1[mds$i]="${cl_users[0]}"
15447                 cl_user2[mds$i]="${cl_users[1]}"
15448
15449                 [ -n "${cl_user1[mds$i]}" ] ||
15450                         error "mds$i: no user registered"
15451                 [ -n "${cl_user2[mds$i]}" ] ||
15452                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15453
15454                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15455                 [ -n "$user_rec1" ] ||
15456                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15457                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15458                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15459                 [ -n "$user_rec2" ] ||
15460                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15461                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15462                      "$user_rec1 + 2 == $user_rec2"
15463                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15464                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15465                               "$user_rec1 + 2, but is $user_rec2"
15466                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15467                 [ -n "$user_rec2" ] ||
15468                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15469                 [ $user_rec1 == $user_rec2 ] ||
15470                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15471                               "$user_rec1, but is $user_rec2"
15472         done
15473
15474         # force cl_user2 to be idle (2nd part) and to reach
15475         # changelog_max_idle_time
15476         sleep 2
15477
15478         # force each GC-thread start and block then
15479         # one per MDT/MDD, set fail_val accordingly
15480         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15481         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15482
15483         # generate more changelogs to trigger fail_loc
15484         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15485                 error "create $DIR/$tdir/${tfile}bis failed"
15486
15487         # stop MDT to stop GC-thread, should be done in back-ground as it will
15488         # block waiting for the thread to be released and exit
15489         declare -A stop_pids
15490         for i in $(seq $MDSCOUNT); do
15491                 stop mds$i &
15492                 stop_pids[mds$i]=$!
15493         done
15494
15495         for i in $(mdts_nodes); do
15496                 local facet
15497                 local nb=0
15498                 local facets=$(facets_up_on_host $i)
15499
15500                 for facet in ${facets//,/ }; do
15501                         if [[ $facet == mds* ]]; then
15502                                 nb=$((nb + 1))
15503                         fi
15504                 done
15505                 # ensure each MDS's gc threads are still present and all in "R"
15506                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15507                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15508                         error "$i: expected $nb GC-thread"
15509                 wait_update $i \
15510                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15511                         "R" 20 ||
15512                         error "$i: GC-thread not found in R-state"
15513                 # check umounts of each MDT on MDS have reached kthread_stop()
15514                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15515                         error "$i: expected $nb umount"
15516                 wait_update $i \
15517                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15518                         error "$i: umount not found in D-state"
15519         done
15520
15521         # release all GC-threads
15522         do_nodes $mdts $LCTL set_param fail_loc=0
15523
15524         # wait for MDT stop to complete
15525         for i in $(seq $MDSCOUNT); do
15526                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15527         done
15528
15529         # XXX
15530         # may try to check if any orphan changelog records are present
15531         # via ldiskfs/zfs and llog_reader...
15532
15533         # re-start/mount MDTs
15534         for i in $(seq $MDSCOUNT); do
15535                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15536                         error "Fail to start mds$i"
15537         done
15538
15539         local first_rec
15540         for i in $(seq $MDSCOUNT); do
15541                 # check cl_user1 still registered
15542                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15543                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15544                 # check cl_user2 unregistered
15545                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15546                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15547
15548                 # check changelogs are present and starting at $user_rec1 + 1
15549                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15550                 [ -n "$user_rec1" ] ||
15551                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15552                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15553                             awk '{ print $1; exit; }')
15554
15555                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15556                 [ $((user_rec1 + 1)) == $first_rec ] ||
15557                         error "mds$i: first index should be $user_rec1 + 1, " \
15558                               "but is $first_rec"
15559         done
15560 }
15561 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15562               "during mount"
15563
15564 test_160i() {
15565
15566         local mdts=$(comma_list $(mdts_nodes))
15567
15568         changelog_register || error "first changelog_register failed"
15569
15570         # generate some changelog records to accumulate on each MDT
15571         # use all_char because created files should be evenly distributed
15572         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15573                 error "test_mkdir $tdir failed"
15574         for ((i = 0; i < MDSCOUNT; i++)); do
15575                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15576                         error "create $DIR/$tdir/d$i.1 failed"
15577         done
15578
15579         # check changelogs have been generated
15580         local nbcl=$(changelog_dump | wc -l)
15581         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15582
15583         # simulate race between register and unregister
15584         # XXX as fail_loc is set per-MDS, with DNE configs the race
15585         # simulation will only occur for one MDT per MDS and for the
15586         # others the normal race scenario will take place
15587         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15588         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15589         do_nodes $mdts $LCTL set_param fail_val=1
15590
15591         # unregister 1st user
15592         changelog_deregister &
15593         local pid1=$!
15594         # wait some time for deregister work to reach race rdv
15595         sleep 2
15596         # register 2nd user
15597         changelog_register || error "2nd user register failed"
15598
15599         wait $pid1 || error "1st user deregister failed"
15600
15601         local i
15602         local last_rec
15603         declare -A LAST_REC
15604         for i in $(seq $MDSCOUNT); do
15605                 if changelog_users mds$i | grep "^cl"; then
15606                         # make sure new records are added with one user present
15607                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15608                                           awk '/^current.index:/ { print $NF }')
15609                 else
15610                         error "mds$i has no user registered"
15611                 fi
15612         done
15613
15614         # generate more changelog records to accumulate on each MDT
15615         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15616                 error "create $DIR/$tdir/${tfile}bis failed"
15617
15618         for i in $(seq $MDSCOUNT); do
15619                 last_rec=$(changelog_users $SINGLEMDS |
15620                            awk '/^current.index:/ { print $NF }')
15621                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15622                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15623                         error "changelogs are off on mds$i"
15624         done
15625 }
15626 run_test 160i "changelog user register/unregister race"
15627
15628 test_160j() {
15629         remote_mds_nodsh && skip "remote MDS with nodsh"
15630         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15631                 skip "Need MDS version at least 2.12.56"
15632
15633         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15634         stack_trap "umount $MOUNT2" EXIT
15635
15636         changelog_register || error "first changelog_register failed"
15637         stack_trap "changelog_deregister" EXIT
15638
15639         # generate some changelog
15640         # use all_char because created files should be evenly distributed
15641         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15642                 error "mkdir $tdir failed"
15643         for ((i = 0; i < MDSCOUNT; i++)); do
15644                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15645                         error "create $DIR/$tdir/d$i.1 failed"
15646         done
15647
15648         # open the changelog device
15649         exec 3>/dev/changelog-$FSNAME-MDT0000
15650         stack_trap "exec 3>&-" EXIT
15651         exec 4</dev/changelog-$FSNAME-MDT0000
15652         stack_trap "exec 4<&-" EXIT
15653
15654         # umount the first lustre mount
15655         umount $MOUNT
15656         stack_trap "mount_client $MOUNT" EXIT
15657
15658         # read changelog, which may or may not fail, but should not crash
15659         cat <&4 >/dev/null
15660
15661         # clear changelog
15662         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15663         changelog_users $SINGLEMDS | grep -q $cl_user ||
15664                 error "User $cl_user not found in changelog_users"
15665
15666         printf 'clear:'$cl_user':0' >&3
15667 }
15668 run_test 160j "client can be umounted while its chanangelog is being used"
15669
15670 test_160k() {
15671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15672         remote_mds_nodsh && skip "remote MDS with nodsh"
15673
15674         mkdir -p $DIR/$tdir/1/1
15675
15676         changelog_register || error "changelog_register failed"
15677         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15678
15679         changelog_users $SINGLEMDS | grep -q $cl_user ||
15680                 error "User '$cl_user' not found in changelog_users"
15681 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15682         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15683         rmdir $DIR/$tdir/1/1 & sleep 1
15684         mkdir $DIR/$tdir/2
15685         touch $DIR/$tdir/2/2
15686         rm -rf $DIR/$tdir/2
15687
15688         wait
15689         sleep 4
15690
15691         changelog_dump | grep rmdir || error "rmdir not recorded"
15692 }
15693 run_test 160k "Verify that changelog records are not lost"
15694
15695 # Verifies that a file passed as a parameter has recently had an operation
15696 # performed on it that has generated an MTIME changelog which contains the
15697 # correct parent FID. As files might reside on a different MDT from the
15698 # parent directory in DNE configurations, the FIDs are translated to paths
15699 # before being compared, which should be identical
15700 compare_mtime_changelog() {
15701         local file="${1}"
15702         local mdtidx
15703         local mtime
15704         local cl_fid
15705         local pdir
15706         local dir
15707
15708         mdtidx=$($LFS getstripe --mdt-index $file)
15709         mdtidx=$(printf "%04x" $mdtidx)
15710
15711         # Obtain the parent FID from the MTIME changelog
15712         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15713         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15714
15715         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15716         [ -z "$cl_fid" ] && error "parent FID not present"
15717
15718         # Verify that the path for the parent FID is the same as the path for
15719         # the test directory
15720         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15721
15722         dir=$(dirname $1)
15723
15724         [[ "${pdir%/}" == "$dir" ]] ||
15725                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15726 }
15727
15728 test_160l() {
15729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15730
15731         remote_mds_nodsh && skip "remote MDS with nodsh"
15732         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15733                 skip "Need MDS version at least 2.13.55"
15734
15735         local cl_user
15736
15737         changelog_register || error "changelog_register failed"
15738         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15739
15740         changelog_users $SINGLEMDS | grep -q $cl_user ||
15741                 error "User '$cl_user' not found in changelog_users"
15742
15743         # Clear some types so that MTIME changelogs are generated
15744         changelog_chmask "-CREAT"
15745         changelog_chmask "-CLOSE"
15746
15747         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15748
15749         # Test CL_MTIME during setattr
15750         touch $DIR/$tdir/$tfile
15751         compare_mtime_changelog $DIR/$tdir/$tfile
15752
15753         # Test CL_MTIME during close
15754         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15755         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15756 }
15757 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15758
15759 test_161a() {
15760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15761
15762         test_mkdir -c1 $DIR/$tdir
15763         cp /etc/hosts $DIR/$tdir/$tfile
15764         test_mkdir -c1 $DIR/$tdir/foo1
15765         test_mkdir -c1 $DIR/$tdir/foo2
15766         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15767         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15768         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15769         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15770         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15771         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15772                 $LFS fid2path $DIR $FID
15773                 error "bad link ea"
15774         fi
15775         # middle
15776         rm $DIR/$tdir/foo2/zachary
15777         # last
15778         rm $DIR/$tdir/foo2/thor
15779         # first
15780         rm $DIR/$tdir/$tfile
15781         # rename
15782         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15783         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15784                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15785         rm $DIR/$tdir/foo2/maggie
15786
15787         # overflow the EA
15788         local longname=$tfile.avg_len_is_thirty_two_
15789         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15790                 error_noexit 'failed to unlink many hardlinks'" EXIT
15791         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15792                 error "failed to hardlink many files"
15793         links=$($LFS fid2path $DIR $FID | wc -l)
15794         echo -n "${links}/1000 links in link EA"
15795         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15796 }
15797 run_test 161a "link ea sanity"
15798
15799 test_161b() {
15800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15801         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15802
15803         local MDTIDX=1
15804         local remote_dir=$DIR/$tdir/remote_dir
15805
15806         mkdir -p $DIR/$tdir
15807         $LFS mkdir -i $MDTIDX $remote_dir ||
15808                 error "create remote directory failed"
15809
15810         cp /etc/hosts $remote_dir/$tfile
15811         mkdir -p $remote_dir/foo1
15812         mkdir -p $remote_dir/foo2
15813         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15814         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15815         ln $remote_dir/$tfile $remote_dir/foo1/luna
15816         ln $remote_dir/$tfile $remote_dir/foo2/thor
15817
15818         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15819                      tr -d ']')
15820         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15821                 $LFS fid2path $DIR $FID
15822                 error "bad link ea"
15823         fi
15824         # middle
15825         rm $remote_dir/foo2/zachary
15826         # last
15827         rm $remote_dir/foo2/thor
15828         # first
15829         rm $remote_dir/$tfile
15830         # rename
15831         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15832         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15833         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15834                 $LFS fid2path $DIR $FID
15835                 error "bad link rename"
15836         fi
15837         rm $remote_dir/foo2/maggie
15838
15839         # overflow the EA
15840         local longname=filename_avg_len_is_thirty_two_
15841         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15842                 error "failed to hardlink many files"
15843         links=$($LFS fid2path $DIR $FID | wc -l)
15844         echo -n "${links}/1000 links in link EA"
15845         [[ ${links} -gt 60 ]] ||
15846                 error "expected at least 60 links in link EA"
15847         unlinkmany $remote_dir/foo2/$longname 1000 ||
15848         error "failed to unlink many hardlinks"
15849 }
15850 run_test 161b "link ea sanity under remote directory"
15851
15852 test_161c() {
15853         remote_mds_nodsh && skip "remote MDS with nodsh"
15854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15855         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15856                 skip "Need MDS version at least 2.1.5"
15857
15858         # define CLF_RENAME_LAST 0x0001
15859         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15860         changelog_register || error "changelog_register failed"
15861
15862         rm -rf $DIR/$tdir
15863         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15864         touch $DIR/$tdir/foo_161c
15865         touch $DIR/$tdir/bar_161c
15866         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15867         changelog_dump | grep RENME | tail -n 5
15868         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15869         changelog_clear 0 || error "changelog_clear failed"
15870         if [ x$flags != "x0x1" ]; then
15871                 error "flag $flags is not 0x1"
15872         fi
15873
15874         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15875         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15876         touch $DIR/$tdir/foo_161c
15877         touch $DIR/$tdir/bar_161c
15878         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15879         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15880         changelog_dump | grep RENME | tail -n 5
15881         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15882         changelog_clear 0 || error "changelog_clear failed"
15883         if [ x$flags != "x0x0" ]; then
15884                 error "flag $flags is not 0x0"
15885         fi
15886         echo "rename overwrite a target having nlink > 1," \
15887                 "changelog record has flags of $flags"
15888
15889         # rename doesn't overwrite a target (changelog flag 0x0)
15890         touch $DIR/$tdir/foo_161c
15891         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15892         changelog_dump | grep RENME | tail -n 5
15893         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15894         changelog_clear 0 || error "changelog_clear failed"
15895         if [ x$flags != "x0x0" ]; then
15896                 error "flag $flags is not 0x0"
15897         fi
15898         echo "rename doesn't overwrite a target," \
15899                 "changelog record has flags of $flags"
15900
15901         # define CLF_UNLINK_LAST 0x0001
15902         # unlink a file having nlink = 1 (changelog flag 0x1)
15903         rm -f $DIR/$tdir/foo2_161c
15904         changelog_dump | grep UNLNK | tail -n 5
15905         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15906         changelog_clear 0 || error "changelog_clear failed"
15907         if [ x$flags != "x0x1" ]; then
15908                 error "flag $flags is not 0x1"
15909         fi
15910         echo "unlink a file having nlink = 1," \
15911                 "changelog record has flags of $flags"
15912
15913         # unlink a file having nlink > 1 (changelog flag 0x0)
15914         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15915         rm -f $DIR/$tdir/foobar_161c
15916         changelog_dump | grep UNLNK | tail -n 5
15917         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15918         changelog_clear 0 || error "changelog_clear failed"
15919         if [ x$flags != "x0x0" ]; then
15920                 error "flag $flags is not 0x0"
15921         fi
15922         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15923 }
15924 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15925
15926 test_161d() {
15927         remote_mds_nodsh && skip "remote MDS with nodsh"
15928         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15929
15930         local pid
15931         local fid
15932
15933         changelog_register || error "changelog_register failed"
15934
15935         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15936         # interfer with $MOUNT/.lustre/fid/ access
15937         mkdir $DIR/$tdir
15938         [[ $? -eq 0 ]] || error "mkdir failed"
15939
15940         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15941         $LCTL set_param fail_loc=0x8000140c
15942         # 5s pause
15943         $LCTL set_param fail_val=5
15944
15945         # create file
15946         echo foofoo > $DIR/$tdir/$tfile &
15947         pid=$!
15948
15949         # wait for create to be delayed
15950         sleep 2
15951
15952         ps -p $pid
15953         [[ $? -eq 0 ]] || error "create should be blocked"
15954
15955         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15956         stack_trap "rm -f $tempfile"
15957         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15958         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15959         # some delay may occur during ChangeLog publishing and file read just
15960         # above, that could allow file write to happen finally
15961         [[ -s $tempfile ]] && echo "file should be empty"
15962
15963         $LCTL set_param fail_loc=0
15964
15965         wait $pid
15966         [[ $? -eq 0 ]] || error "create failed"
15967 }
15968 run_test 161d "create with concurrent .lustre/fid access"
15969
15970 check_path() {
15971         local expected="$1"
15972         shift
15973         local fid="$2"
15974
15975         local path
15976         path=$($LFS fid2path "$@")
15977         local rc=$?
15978
15979         if [ $rc -ne 0 ]; then
15980                 error "path looked up of '$expected' failed: rc=$rc"
15981         elif [ "$path" != "$expected" ]; then
15982                 error "path looked up '$path' instead of '$expected'"
15983         else
15984                 echo "FID '$fid' resolves to path '$path' as expected"
15985         fi
15986 }
15987
15988 test_162a() { # was test_162
15989         test_mkdir -p -c1 $DIR/$tdir/d2
15990         touch $DIR/$tdir/d2/$tfile
15991         touch $DIR/$tdir/d2/x1
15992         touch $DIR/$tdir/d2/x2
15993         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15994         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15995         # regular file
15996         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15997         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15998
15999         # softlink
16000         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16001         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16002         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16003
16004         # softlink to wrong file
16005         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16006         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16007         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16008
16009         # hardlink
16010         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16011         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16012         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16013         # fid2path dir/fsname should both work
16014         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16015         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16016
16017         # hardlink count: check that there are 2 links
16018         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16019         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16020
16021         # hardlink indexing: remove the first link
16022         rm $DIR/$tdir/d2/p/q/r/hlink
16023         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16024 }
16025 run_test 162a "path lookup sanity"
16026
16027 test_162b() {
16028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16029         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16030
16031         mkdir $DIR/$tdir
16032         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16033                                 error "create striped dir failed"
16034
16035         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16036                                         tail -n 1 | awk '{print $2}')
16037         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16038
16039         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16040         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16041
16042         # regular file
16043         for ((i=0;i<5;i++)); do
16044                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16045                         error "get fid for f$i failed"
16046                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16047
16048                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16049                         error "get fid for d$i failed"
16050                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16051         done
16052
16053         return 0
16054 }
16055 run_test 162b "striped directory path lookup sanity"
16056
16057 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16058 test_162c() {
16059         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16060                 skip "Need MDS version at least 2.7.51"
16061
16062         local lpath=$tdir.local
16063         local rpath=$tdir.remote
16064
16065         test_mkdir $DIR/$lpath
16066         test_mkdir $DIR/$rpath
16067
16068         for ((i = 0; i <= 101; i++)); do
16069                 lpath="$lpath/$i"
16070                 mkdir $DIR/$lpath
16071                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16072                         error "get fid for local directory $DIR/$lpath failed"
16073                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16074
16075                 rpath="$rpath/$i"
16076                 test_mkdir $DIR/$rpath
16077                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16078                         error "get fid for remote directory $DIR/$rpath failed"
16079                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16080         done
16081
16082         return 0
16083 }
16084 run_test 162c "fid2path works with paths 100 or more directories deep"
16085
16086 oalr_event_count() {
16087         local event="${1}"
16088         local trace="${2}"
16089
16090         awk -v name="${FSNAME}-OST0000" \
16091             -v event="${event}" \
16092             '$1 == "TRACE" && $2 == event && $3 == name' \
16093             "${trace}" |
16094         wc -l
16095 }
16096
16097 oalr_expect_event_count() {
16098         local event="${1}"
16099         local trace="${2}"
16100         local expect="${3}"
16101         local count
16102
16103         count=$(oalr_event_count "${event}" "${trace}")
16104         if ((count == expect)); then
16105                 return 0
16106         fi
16107
16108         error_noexit "${event} event count was '${count}', expected ${expect}"
16109         cat "${trace}" >&2
16110         exit 1
16111 }
16112
16113 cleanup_165() {
16114         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16115         stop ost1
16116         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16117 }
16118
16119 setup_165() {
16120         sync # Flush previous IOs so we can count log entries.
16121         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16122         stack_trap cleanup_165 EXIT
16123 }
16124
16125 test_165a() {
16126         local trace="/tmp/${tfile}.trace"
16127         local rc
16128         local count
16129
16130         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16131                 skip "OFD access log unsupported"
16132
16133         setup_165
16134         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16135         sleep 5
16136
16137         do_facet ost1 ofd_access_log_reader --list
16138         stop ost1
16139
16140         do_facet ost1 killall -TERM ofd_access_log_reader
16141         wait
16142         rc=$?
16143
16144         if ((rc != 0)); then
16145                 error "ofd_access_log_reader exited with rc = '${rc}'"
16146         fi
16147
16148         # Parse trace file for discovery events:
16149         oalr_expect_event_count alr_log_add "${trace}" 1
16150         oalr_expect_event_count alr_log_eof "${trace}" 1
16151         oalr_expect_event_count alr_log_free "${trace}" 1
16152 }
16153 run_test 165a "ofd access log discovery"
16154
16155 test_165b() {
16156         local trace="/tmp/${tfile}.trace"
16157         local file="${DIR}/${tfile}"
16158         local pfid1
16159         local pfid2
16160         local -a entry
16161         local rc
16162         local count
16163         local size
16164         local flags
16165
16166         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16167                 skip "OFD access log unsupported"
16168
16169         setup_165
16170         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16171         sleep 5
16172
16173         do_facet ost1 ofd_access_log_reader --list
16174
16175         lfs setstripe -c 1 -i 0 "${file}"
16176         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16177                 error "cannot create '${file}'"
16178
16179         sleep 5
16180         do_facet ost1 killall -TERM ofd_access_log_reader
16181         wait
16182         rc=$?
16183
16184         if ((rc != 0)); then
16185                 error "ofd_access_log_reader exited with rc = '${rc}'"
16186         fi
16187
16188         oalr_expect_event_count alr_log_entry "${trace}" 1
16189
16190         pfid1=$($LFS path2fid "${file}")
16191
16192         # 1     2             3   4    5     6   7    8    9     10
16193         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16194         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16195
16196         echo "entry = '${entry[*]}'" >&2
16197
16198         pfid2=${entry[4]}
16199         if [[ "${pfid1}" != "${pfid2}" ]]; then
16200                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16201         fi
16202
16203         size=${entry[8]}
16204         if ((size != 1048576)); then
16205                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16206         fi
16207
16208         flags=${entry[10]}
16209         if [[ "${flags}" != "w" ]]; then
16210                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16211         fi
16212
16213         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16214         sleep 5
16215
16216         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16217                 error "cannot read '${file}'"
16218         sleep 5
16219
16220         do_facet ost1 killall -TERM ofd_access_log_reader
16221         wait
16222         rc=$?
16223
16224         if ((rc != 0)); then
16225                 error "ofd_access_log_reader exited with rc = '${rc}'"
16226         fi
16227
16228         oalr_expect_event_count alr_log_entry "${trace}" 1
16229
16230         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16231         echo "entry = '${entry[*]}'" >&2
16232
16233         pfid2=${entry[4]}
16234         if [[ "${pfid1}" != "${pfid2}" ]]; then
16235                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16236         fi
16237
16238         size=${entry[8]}
16239         if ((size != 524288)); then
16240                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16241         fi
16242
16243         flags=${entry[10]}
16244         if [[ "${flags}" != "r" ]]; then
16245                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16246         fi
16247 }
16248 run_test 165b "ofd access log entries are produced and consumed"
16249
16250 test_165c() {
16251         local trace="/tmp/${tfile}.trace"
16252         local file="${DIR}/${tdir}/${tfile}"
16253
16254         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16255                 skip "OFD access log unsupported"
16256
16257         test_mkdir "${DIR}/${tdir}"
16258
16259         setup_165
16260         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16261         sleep 5
16262
16263         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16264
16265         # 4096 / 64 = 64. Create twice as many entries.
16266         for ((i = 0; i < 128; i++)); do
16267                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16268                         error "cannot create file"
16269         done
16270
16271         sync
16272
16273         do_facet ost1 killall -TERM ofd_access_log_reader
16274         wait
16275         rc=$?
16276         if ((rc != 0)); then
16277                 error "ofd_access_log_reader exited with rc = '${rc}'"
16278         fi
16279
16280         unlinkmany  "${file}-%d" 128
16281 }
16282 run_test 165c "full ofd access logs do not block IOs"
16283
16284 oal_get_read_count() {
16285         local stats="$1"
16286
16287         # STATS lustre-OST0001 alr_read_count 1
16288
16289         do_facet ost1 cat "${stats}" |
16290         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16291              END { print count; }'
16292 }
16293
16294 oal_expect_read_count() {
16295         local stats="$1"
16296         local count
16297         local expect="$2"
16298
16299         # Ask ofd_access_log_reader to write stats.
16300         do_facet ost1 killall -USR1 ofd_access_log_reader
16301
16302         # Allow some time for things to happen.
16303         sleep 1
16304
16305         count=$(oal_get_read_count "${stats}")
16306         if ((count == expect)); then
16307                 return 0
16308         fi
16309
16310         error_noexit "bad read count, got ${count}, expected ${expect}"
16311         do_facet ost1 cat "${stats}" >&2
16312         exit 1
16313 }
16314
16315 test_165d() {
16316         local stats="/tmp/${tfile}.stats"
16317         local file="${DIR}/${tdir}/${tfile}"
16318         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16319
16320         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16321                 skip "OFD access log unsupported"
16322
16323         test_mkdir "${DIR}/${tdir}"
16324
16325         setup_165
16326         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16327         sleep 5
16328
16329         lfs setstripe -c 1 -i 0 "${file}"
16330
16331         do_facet ost1 lctl set_param "${param}=rw"
16332         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16333                 error "cannot create '${file}'"
16334         oal_expect_read_count "${stats}" 1
16335
16336         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16337                 error "cannot read '${file}'"
16338         oal_expect_read_count "${stats}" 2
16339
16340         do_facet ost1 lctl set_param "${param}=r"
16341         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16342                 error "cannot create '${file}'"
16343         oal_expect_read_count "${stats}" 2
16344
16345         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16346                 error "cannot read '${file}'"
16347         oal_expect_read_count "${stats}" 3
16348
16349         do_facet ost1 lctl set_param "${param}=w"
16350         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16351                 error "cannot create '${file}'"
16352         oal_expect_read_count "${stats}" 4
16353
16354         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16355                 error "cannot read '${file}'"
16356         oal_expect_read_count "${stats}" 4
16357
16358         do_facet ost1 lctl set_param "${param}=0"
16359         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16360                 error "cannot create '${file}'"
16361         oal_expect_read_count "${stats}" 4
16362
16363         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16364                 error "cannot read '${file}'"
16365         oal_expect_read_count "${stats}" 4
16366
16367         do_facet ost1 killall -TERM ofd_access_log_reader
16368         wait
16369         rc=$?
16370         if ((rc != 0)); then
16371                 error "ofd_access_log_reader exited with rc = '${rc}'"
16372         fi
16373 }
16374 run_test 165d "ofd_access_log mask works"
16375
16376 test_165e() {
16377         local stats="/tmp/${tfile}.stats"
16378         local file0="${DIR}/${tdir}-0/${tfile}"
16379         local file1="${DIR}/${tdir}-1/${tfile}"
16380
16381         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16382                 skip "OFD access log unsupported"
16383
16384         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16385
16386         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16387         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16388
16389         lfs setstripe -c 1 -i 0 "${file0}"
16390         lfs setstripe -c 1 -i 0 "${file1}"
16391
16392         setup_165
16393         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16394         sleep 5
16395
16396         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16397                 error "cannot create '${file0}'"
16398         sync
16399         oal_expect_read_count "${stats}" 0
16400
16401         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16402                 error "cannot create '${file1}'"
16403         sync
16404         oal_expect_read_count "${stats}" 1
16405
16406         do_facet ost1 killall -TERM ofd_access_log_reader
16407         wait
16408         rc=$?
16409         if ((rc != 0)); then
16410                 error "ofd_access_log_reader exited with rc = '${rc}'"
16411         fi
16412 }
16413 run_test 165e "ofd_access_log MDT index filter works"
16414
16415 test_165f() {
16416         local trace="/tmp/${tfile}.trace"
16417         local rc
16418         local count
16419
16420         setup_165
16421         do_facet ost1 timeout 60 ofd_access_log_reader \
16422                 --exit-on-close --debug=- --trace=- > "${trace}" &
16423         sleep 5
16424         stop ost1
16425
16426         wait
16427         rc=$?
16428
16429         if ((rc != 0)); then
16430                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16431                 cat "${trace}"
16432                 exit 1
16433         fi
16434 }
16435 run_test 165f "ofd_access_log_reader --exit-on-close works"
16436
16437 test_169() {
16438         # do directio so as not to populate the page cache
16439         log "creating a 10 Mb file"
16440         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16441                 error "multiop failed while creating a file"
16442         log "starting reads"
16443         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16444         log "truncating the file"
16445         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16446                 error "multiop failed while truncating the file"
16447         log "killing dd"
16448         kill %+ || true # reads might have finished
16449         echo "wait until dd is finished"
16450         wait
16451         log "removing the temporary file"
16452         rm -rf $DIR/$tfile || error "tmp file removal failed"
16453 }
16454 run_test 169 "parallel read and truncate should not deadlock"
16455
16456 test_170() {
16457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16458
16459         $LCTL clear     # bug 18514
16460         $LCTL debug_daemon start $TMP/${tfile}_log_good
16461         touch $DIR/$tfile
16462         $LCTL debug_daemon stop
16463         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16464                 error "sed failed to read log_good"
16465
16466         $LCTL debug_daemon start $TMP/${tfile}_log_good
16467         rm -rf $DIR/$tfile
16468         $LCTL debug_daemon stop
16469
16470         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16471                error "lctl df log_bad failed"
16472
16473         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16474         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16475
16476         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16477         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16478
16479         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16480                 error "bad_line good_line1 good_line2 are empty"
16481
16482         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16483         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16484         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16485
16486         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16487         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16488         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16489
16490         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16491                 error "bad_line_new good_line_new are empty"
16492
16493         local expected_good=$((good_line1 + good_line2*2))
16494
16495         rm -f $TMP/${tfile}*
16496         # LU-231, short malformed line may not be counted into bad lines
16497         if [ $bad_line -ne $bad_line_new ] &&
16498                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16499                 error "expected $bad_line bad lines, but got $bad_line_new"
16500                 return 1
16501         fi
16502
16503         if [ $expected_good -ne $good_line_new ]; then
16504                 error "expected $expected_good good lines, but got $good_line_new"
16505                 return 2
16506         fi
16507         true
16508 }
16509 run_test 170 "test lctl df to handle corrupted log ====================="
16510
16511 test_171() { # bug20592
16512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16513
16514         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16515         $LCTL set_param fail_loc=0x50e
16516         $LCTL set_param fail_val=3000
16517         multiop_bg_pause $DIR/$tfile O_s || true
16518         local MULTIPID=$!
16519         kill -USR1 $MULTIPID
16520         # cause log dump
16521         sleep 3
16522         wait $MULTIPID
16523         if dmesg | grep "recursive fault"; then
16524                 error "caught a recursive fault"
16525         fi
16526         $LCTL set_param fail_loc=0
16527         true
16528 }
16529 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16530
16531 # it would be good to share it with obdfilter-survey/iokit-libecho code
16532 setup_obdecho_osc () {
16533         local rc=0
16534         local ost_nid=$1
16535         local obdfilter_name=$2
16536         echo "Creating new osc for $obdfilter_name on $ost_nid"
16537         # make sure we can find loopback nid
16538         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16539
16540         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16541                            ${obdfilter_name}_osc_UUID || rc=2; }
16542         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16543                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16544         return $rc
16545 }
16546
16547 cleanup_obdecho_osc () {
16548         local obdfilter_name=$1
16549         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16550         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16551         return 0
16552 }
16553
16554 obdecho_test() {
16555         local OBD=$1
16556         local node=$2
16557         local pages=${3:-64}
16558         local rc=0
16559         local id
16560
16561         local count=10
16562         local obd_size=$(get_obd_size $node $OBD)
16563         local page_size=$(get_page_size $node)
16564         if [[ -n "$obd_size" ]]; then
16565                 local new_count=$((obd_size / (pages * page_size / 1024)))
16566                 [[ $new_count -ge $count ]] || count=$new_count
16567         fi
16568
16569         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16570         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16571                            rc=2; }
16572         if [ $rc -eq 0 ]; then
16573             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16574             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16575         fi
16576         echo "New object id is $id"
16577         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16578                            rc=4; }
16579         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16580                            "test_brw $count w v $pages $id" || rc=4; }
16581         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16582                            rc=4; }
16583         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16584                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16585         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16586                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16587         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16588         return $rc
16589 }
16590
16591 test_180a() {
16592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16593
16594         if ! [ -d /sys/fs/lustre/echo_client ] &&
16595            ! module_loaded obdecho; then
16596                 load_module obdecho/obdecho &&
16597                         stack_trap "rmmod obdecho" EXIT ||
16598                         error "unable to load obdecho on client"
16599         fi
16600
16601         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16602         local host=$($LCTL get_param -n osc.$osc.import |
16603                      awk '/current_connection:/ { print $2 }' )
16604         local target=$($LCTL get_param -n osc.$osc.import |
16605                        awk '/target:/ { print $2 }' )
16606         target=${target%_UUID}
16607
16608         if [ -n "$target" ]; then
16609                 setup_obdecho_osc $host $target &&
16610                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16611                         { error "obdecho setup failed with $?"; return; }
16612
16613                 obdecho_test ${target}_osc client ||
16614                         error "obdecho_test failed on ${target}_osc"
16615         else
16616                 $LCTL get_param osc.$osc.import
16617                 error "there is no osc.$osc.import target"
16618         fi
16619 }
16620 run_test 180a "test obdecho on osc"
16621
16622 test_180b() {
16623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16624         remote_ost_nodsh && skip "remote OST with nodsh"
16625
16626         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16627                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16628                 error "failed to load module obdecho"
16629
16630         local target=$(do_facet ost1 $LCTL dl |
16631                        awk '/obdfilter/ { print $4; exit; }')
16632
16633         if [ -n "$target" ]; then
16634                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16635         else
16636                 do_facet ost1 $LCTL dl
16637                 error "there is no obdfilter target on ost1"
16638         fi
16639 }
16640 run_test 180b "test obdecho directly on obdfilter"
16641
16642 test_180c() { # LU-2598
16643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16644         remote_ost_nodsh && skip "remote OST with nodsh"
16645         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16646                 skip "Need MDS version at least 2.4.0"
16647
16648         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16649                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16650                 error "failed to load module obdecho"
16651
16652         local target=$(do_facet ost1 $LCTL dl |
16653                        awk '/obdfilter/ { print $4; exit; }')
16654
16655         if [ -n "$target" ]; then
16656                 local pages=16384 # 64MB bulk I/O RPC size
16657
16658                 obdecho_test "$target" ost1 "$pages" ||
16659                         error "obdecho_test with pages=$pages failed with $?"
16660         else
16661                 do_facet ost1 $LCTL dl
16662                 error "there is no obdfilter target on ost1"
16663         fi
16664 }
16665 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16666
16667 test_181() { # bug 22177
16668         test_mkdir $DIR/$tdir
16669         # create enough files to index the directory
16670         createmany -o $DIR/$tdir/foobar 4000
16671         # print attributes for debug purpose
16672         lsattr -d .
16673         # open dir
16674         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16675         MULTIPID=$!
16676         # remove the files & current working dir
16677         unlinkmany $DIR/$tdir/foobar 4000
16678         rmdir $DIR/$tdir
16679         kill -USR1 $MULTIPID
16680         wait $MULTIPID
16681         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16682         return 0
16683 }
16684 run_test 181 "Test open-unlinked dir ========================"
16685
16686 test_182() {
16687         local fcount=1000
16688         local tcount=10
16689
16690         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16691
16692         $LCTL set_param mdc.*.rpc_stats=clear
16693
16694         for (( i = 0; i < $tcount; i++ )) ; do
16695                 mkdir $DIR/$tdir/$i
16696         done
16697
16698         for (( i = 0; i < $tcount; i++ )) ; do
16699                 createmany -o $DIR/$tdir/$i/f- $fcount &
16700         done
16701         wait
16702
16703         for (( i = 0; i < $tcount; i++ )) ; do
16704                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16705         done
16706         wait
16707
16708         $LCTL get_param mdc.*.rpc_stats
16709
16710         rm -rf $DIR/$tdir
16711 }
16712 run_test 182 "Test parallel modify metadata operations ================"
16713
16714 test_183() { # LU-2275
16715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16716         remote_mds_nodsh && skip "remote MDS with nodsh"
16717         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16718                 skip "Need MDS version at least 2.3.56"
16719
16720         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16721         echo aaa > $DIR/$tdir/$tfile
16722
16723 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16724         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16725
16726         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16727         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16728
16729         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16730
16731         # Flush negative dentry cache
16732         touch $DIR/$tdir/$tfile
16733
16734         # We are not checking for any leaked references here, they'll
16735         # become evident next time we do cleanup with module unload.
16736         rm -rf $DIR/$tdir
16737 }
16738 run_test 183 "No crash or request leak in case of strange dispositions ========"
16739
16740 # test suite 184 is for LU-2016, LU-2017
16741 test_184a() {
16742         check_swap_layouts_support
16743
16744         dir0=$DIR/$tdir/$testnum
16745         test_mkdir -p -c1 $dir0
16746         ref1=/etc/passwd
16747         ref2=/etc/group
16748         file1=$dir0/f1
16749         file2=$dir0/f2
16750         $LFS setstripe -c1 $file1
16751         cp $ref1 $file1
16752         $LFS setstripe -c2 $file2
16753         cp $ref2 $file2
16754         gen1=$($LFS getstripe -g $file1)
16755         gen2=$($LFS getstripe -g $file2)
16756
16757         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16758         gen=$($LFS getstripe -g $file1)
16759         [[ $gen1 != $gen ]] ||
16760                 "Layout generation on $file1 does not change"
16761         gen=$($LFS getstripe -g $file2)
16762         [[ $gen2 != $gen ]] ||
16763                 "Layout generation on $file2 does not change"
16764
16765         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16766         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16767
16768         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16769 }
16770 run_test 184a "Basic layout swap"
16771
16772 test_184b() {
16773         check_swap_layouts_support
16774
16775         dir0=$DIR/$tdir/$testnum
16776         mkdir -p $dir0 || error "creating dir $dir0"
16777         file1=$dir0/f1
16778         file2=$dir0/f2
16779         file3=$dir0/f3
16780         dir1=$dir0/d1
16781         dir2=$dir0/d2
16782         mkdir $dir1 $dir2
16783         $LFS setstripe -c1 $file1
16784         $LFS setstripe -c2 $file2
16785         $LFS setstripe -c1 $file3
16786         chown $RUNAS_ID $file3
16787         gen1=$($LFS getstripe -g $file1)
16788         gen2=$($LFS getstripe -g $file2)
16789
16790         $LFS swap_layouts $dir1 $dir2 &&
16791                 error "swap of directories layouts should fail"
16792         $LFS swap_layouts $dir1 $file1 &&
16793                 error "swap of directory and file layouts should fail"
16794         $RUNAS $LFS swap_layouts $file1 $file2 &&
16795                 error "swap of file we cannot write should fail"
16796         $LFS swap_layouts $file1 $file3 &&
16797                 error "swap of file with different owner should fail"
16798         /bin/true # to clear error code
16799 }
16800 run_test 184b "Forbidden layout swap (will generate errors)"
16801
16802 test_184c() {
16803         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16804         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16805         check_swap_layouts_support
16806         check_swap_layout_no_dom $DIR
16807
16808         local dir0=$DIR/$tdir/$testnum
16809         mkdir -p $dir0 || error "creating dir $dir0"
16810
16811         local ref1=$dir0/ref1
16812         local ref2=$dir0/ref2
16813         local file1=$dir0/file1
16814         local file2=$dir0/file2
16815         # create a file large enough for the concurrent test
16816         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16817         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16818         echo "ref file size: ref1($(stat -c %s $ref1))," \
16819              "ref2($(stat -c %s $ref2))"
16820
16821         cp $ref2 $file2
16822         dd if=$ref1 of=$file1 bs=16k &
16823         local DD_PID=$!
16824
16825         # Make sure dd starts to copy file, but wait at most 5 seconds
16826         local loops=0
16827         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16828
16829         $LFS swap_layouts $file1 $file2
16830         local rc=$?
16831         wait $DD_PID
16832         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16833         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16834
16835         # how many bytes copied before swapping layout
16836         local copied=$(stat -c %s $file2)
16837         local remaining=$(stat -c %s $ref1)
16838         remaining=$((remaining - copied))
16839         echo "Copied $copied bytes before swapping layout..."
16840
16841         cmp -n $copied $file1 $ref2 | grep differ &&
16842                 error "Content mismatch [0, $copied) of ref2 and file1"
16843         cmp -n $copied $file2 $ref1 ||
16844                 error "Content mismatch [0, $copied) of ref1 and file2"
16845         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16846                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16847
16848         # clean up
16849         rm -f $ref1 $ref2 $file1 $file2
16850 }
16851 run_test 184c "Concurrent write and layout swap"
16852
16853 test_184d() {
16854         check_swap_layouts_support
16855         check_swap_layout_no_dom $DIR
16856         [ -z "$(which getfattr 2>/dev/null)" ] &&
16857                 skip_env "no getfattr command"
16858
16859         local file1=$DIR/$tdir/$tfile-1
16860         local file2=$DIR/$tdir/$tfile-2
16861         local file3=$DIR/$tdir/$tfile-3
16862         local lovea1
16863         local lovea2
16864
16865         mkdir -p $DIR/$tdir
16866         touch $file1 || error "create $file1 failed"
16867         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16868                 error "create $file2 failed"
16869         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16870                 error "create $file3 failed"
16871         lovea1=$(get_layout_param $file1)
16872
16873         $LFS swap_layouts $file2 $file3 ||
16874                 error "swap $file2 $file3 layouts failed"
16875         $LFS swap_layouts $file1 $file2 ||
16876                 error "swap $file1 $file2 layouts failed"
16877
16878         lovea2=$(get_layout_param $file2)
16879         echo "$lovea1"
16880         echo "$lovea2"
16881         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16882
16883         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16884         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16885 }
16886 run_test 184d "allow stripeless layouts swap"
16887
16888 test_184e() {
16889         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16890                 skip "Need MDS version at least 2.6.94"
16891         check_swap_layouts_support
16892         check_swap_layout_no_dom $DIR
16893         [ -z "$(which getfattr 2>/dev/null)" ] &&
16894                 skip_env "no getfattr command"
16895
16896         local file1=$DIR/$tdir/$tfile-1
16897         local file2=$DIR/$tdir/$tfile-2
16898         local file3=$DIR/$tdir/$tfile-3
16899         local lovea
16900
16901         mkdir -p $DIR/$tdir
16902         touch $file1 || error "create $file1 failed"
16903         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16904                 error "create $file2 failed"
16905         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16906                 error "create $file3 failed"
16907
16908         $LFS swap_layouts $file1 $file2 ||
16909                 error "swap $file1 $file2 layouts failed"
16910
16911         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16912         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16913
16914         echo 123 > $file1 || error "Should be able to write into $file1"
16915
16916         $LFS swap_layouts $file1 $file3 ||
16917                 error "swap $file1 $file3 layouts failed"
16918
16919         echo 123 > $file1 || error "Should be able to write into $file1"
16920
16921         rm -rf $file1 $file2 $file3
16922 }
16923 run_test 184e "Recreate layout after stripeless layout swaps"
16924
16925 test_184f() {
16926         # Create a file with name longer than sizeof(struct stat) ==
16927         # 144 to see if we can get chars from the file name to appear
16928         # in the returned striping. Note that 'f' == 0x66.
16929         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16930
16931         mkdir -p $DIR/$tdir
16932         mcreate $DIR/$tdir/$file
16933         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16934                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16935         fi
16936 }
16937 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16938
16939 test_185() { # LU-2441
16940         # LU-3553 - no volatile file support in old servers
16941         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16942                 skip "Need MDS version at least 2.3.60"
16943
16944         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16945         touch $DIR/$tdir/spoo
16946         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16947         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16948                 error "cannot create/write a volatile file"
16949         [ "$FILESET" == "" ] &&
16950         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16951                 error "FID is still valid after close"
16952
16953         multiop_bg_pause $DIR/$tdir vVw4096_c
16954         local multi_pid=$!
16955
16956         local OLD_IFS=$IFS
16957         IFS=":"
16958         local fidv=($fid)
16959         IFS=$OLD_IFS
16960         # assume that the next FID for this client is sequential, since stdout
16961         # is unfortunately eaten by multiop_bg_pause
16962         local n=$((${fidv[1]} + 1))
16963         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16964         if [ "$FILESET" == "" ]; then
16965                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16966                         error "FID is missing before close"
16967         fi
16968         kill -USR1 $multi_pid
16969         # 1 second delay, so if mtime change we will see it
16970         sleep 1
16971         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16972         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16973 }
16974 run_test 185 "Volatile file support"
16975
16976 function create_check_volatile() {
16977         local idx=$1
16978         local tgt
16979
16980         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16981         local PID=$!
16982         sleep 1
16983         local FID=$(cat /tmp/${tfile}.fid)
16984         [ "$FID" == "" ] && error "can't get FID for volatile"
16985         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16986         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16987         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16988         kill -USR1 $PID
16989         wait
16990         sleep 1
16991         cancel_lru_locks mdc # flush opencache
16992         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16993         return 0
16994 }
16995
16996 test_185a(){
16997         # LU-12516 - volatile creation via .lustre
16998         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16999                 skip "Need MDS version at least 2.3.55"
17000
17001         create_check_volatile 0
17002         [ $MDSCOUNT -lt 2 ] && return 0
17003
17004         # DNE case
17005         create_check_volatile 1
17006
17007         return 0
17008 }
17009 run_test 185a "Volatile file creation in .lustre/fid/"
17010
17011 test_187a() {
17012         remote_mds_nodsh && skip "remote MDS with nodsh"
17013         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17014                 skip "Need MDS version at least 2.3.0"
17015
17016         local dir0=$DIR/$tdir/$testnum
17017         mkdir -p $dir0 || error "creating dir $dir0"
17018
17019         local file=$dir0/file1
17020         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17021         local dv1=$($LFS data_version $file)
17022         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17023         local dv2=$($LFS data_version $file)
17024         [[ $dv1 != $dv2 ]] ||
17025                 error "data version did not change on write $dv1 == $dv2"
17026
17027         # clean up
17028         rm -f $file1
17029 }
17030 run_test 187a "Test data version change"
17031
17032 test_187b() {
17033         remote_mds_nodsh && skip "remote MDS with nodsh"
17034         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17035                 skip "Need MDS version at least 2.3.0"
17036
17037         local dir0=$DIR/$tdir/$testnum
17038         mkdir -p $dir0 || error "creating dir $dir0"
17039
17040         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17041         [[ ${DV[0]} != ${DV[1]} ]] ||
17042                 error "data version did not change on write"\
17043                       " ${DV[0]} == ${DV[1]}"
17044
17045         # clean up
17046         rm -f $file1
17047 }
17048 run_test 187b "Test data version change on volatile file"
17049
17050 test_200() {
17051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17052         remote_mgs_nodsh && skip "remote MGS with nodsh"
17053         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17054
17055         local POOL=${POOL:-cea1}
17056         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17057         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17058         # Pool OST targets
17059         local first_ost=0
17060         local last_ost=$(($OSTCOUNT - 1))
17061         local ost_step=2
17062         local ost_list=$(seq $first_ost $ost_step $last_ost)
17063         local ost_range="$first_ost $last_ost $ost_step"
17064         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17065         local file_dir=$POOL_ROOT/file_tst
17066         local subdir=$test_path/subdir
17067         local rc=0
17068
17069         while : ; do
17070                 # former test_200a test_200b
17071                 pool_add $POOL                          || { rc=$? ; break; }
17072                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17073                 # former test_200c test_200d
17074                 mkdir -p $test_path
17075                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17076                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17077                 mkdir -p $subdir
17078                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17079                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17080                                                         || { rc=$? ; break; }
17081                 # former test_200e test_200f
17082                 local files=$((OSTCOUNT*3))
17083                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17084                                                         || { rc=$? ; break; }
17085                 pool_create_files $POOL $file_dir $files "$ost_list" \
17086                                                         || { rc=$? ; break; }
17087                 # former test_200g test_200h
17088                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17089                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17090
17091                 # former test_201a test_201b test_201c
17092                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17093
17094                 local f=$test_path/$tfile
17095                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17096                 pool_remove $POOL $f                    || { rc=$? ; break; }
17097                 break
17098         done
17099
17100         destroy_test_pools
17101
17102         return $rc
17103 }
17104 run_test 200 "OST pools"
17105
17106 # usage: default_attr <count | size | offset>
17107 default_attr() {
17108         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17109 }
17110
17111 # usage: check_default_stripe_attr
17112 check_default_stripe_attr() {
17113         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17114         case $1 in
17115         --stripe-count|-c)
17116                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17117         --stripe-size|-S)
17118                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17119         --stripe-index|-i)
17120                 EXPECTED=-1;;
17121         *)
17122                 error "unknown getstripe attr '$1'"
17123         esac
17124
17125         [ $ACTUAL == $EXPECTED ] ||
17126                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17127 }
17128
17129 test_204a() {
17130         test_mkdir $DIR/$tdir
17131         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17132
17133         check_default_stripe_attr --stripe-count
17134         check_default_stripe_attr --stripe-size
17135         check_default_stripe_attr --stripe-index
17136 }
17137 run_test 204a "Print default stripe attributes"
17138
17139 test_204b() {
17140         test_mkdir $DIR/$tdir
17141         $LFS setstripe --stripe-count 1 $DIR/$tdir
17142
17143         check_default_stripe_attr --stripe-size
17144         check_default_stripe_attr --stripe-index
17145 }
17146 run_test 204b "Print default stripe size and offset"
17147
17148 test_204c() {
17149         test_mkdir $DIR/$tdir
17150         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17151
17152         check_default_stripe_attr --stripe-count
17153         check_default_stripe_attr --stripe-index
17154 }
17155 run_test 204c "Print default stripe count and offset"
17156
17157 test_204d() {
17158         test_mkdir $DIR/$tdir
17159         $LFS setstripe --stripe-index 0 $DIR/$tdir
17160
17161         check_default_stripe_attr --stripe-count
17162         check_default_stripe_attr --stripe-size
17163 }
17164 run_test 204d "Print default stripe count and size"
17165
17166 test_204e() {
17167         test_mkdir $DIR/$tdir
17168         $LFS setstripe -d $DIR/$tdir
17169
17170         check_default_stripe_attr --stripe-count --raw
17171         check_default_stripe_attr --stripe-size --raw
17172         check_default_stripe_attr --stripe-index --raw
17173 }
17174 run_test 204e "Print raw stripe attributes"
17175
17176 test_204f() {
17177         test_mkdir $DIR/$tdir
17178         $LFS setstripe --stripe-count 1 $DIR/$tdir
17179
17180         check_default_stripe_attr --stripe-size --raw
17181         check_default_stripe_attr --stripe-index --raw
17182 }
17183 run_test 204f "Print raw stripe size and offset"
17184
17185 test_204g() {
17186         test_mkdir $DIR/$tdir
17187         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17188
17189         check_default_stripe_attr --stripe-count --raw
17190         check_default_stripe_attr --stripe-index --raw
17191 }
17192 run_test 204g "Print raw stripe count and offset"
17193
17194 test_204h() {
17195         test_mkdir $DIR/$tdir
17196         $LFS setstripe --stripe-index 0 $DIR/$tdir
17197
17198         check_default_stripe_attr --stripe-count --raw
17199         check_default_stripe_attr --stripe-size --raw
17200 }
17201 run_test 204h "Print raw stripe count and size"
17202
17203 # Figure out which job scheduler is being used, if any,
17204 # or use a fake one
17205 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17206         JOBENV=SLURM_JOB_ID
17207 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17208         JOBENV=LSB_JOBID
17209 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17210         JOBENV=PBS_JOBID
17211 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17212         JOBENV=LOADL_STEP_ID
17213 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17214         JOBENV=JOB_ID
17215 else
17216         $LCTL list_param jobid_name > /dev/null 2>&1
17217         if [ $? -eq 0 ]; then
17218                 JOBENV=nodelocal
17219         else
17220                 JOBENV=FAKE_JOBID
17221         fi
17222 fi
17223 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17224
17225 verify_jobstats() {
17226         local cmd=($1)
17227         shift
17228         local facets="$@"
17229
17230 # we don't really need to clear the stats for this test to work, since each
17231 # command has a unique jobid, but it makes debugging easier if needed.
17232 #       for facet in $facets; do
17233 #               local dev=$(convert_facet2label $facet)
17234 #               # clear old jobstats
17235 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17236 #       done
17237
17238         # use a new JobID for each test, or we might see an old one
17239         [ "$JOBENV" = "FAKE_JOBID" ] &&
17240                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17241
17242         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17243
17244         [ "$JOBENV" = "nodelocal" ] && {
17245                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17246                 $LCTL set_param jobid_name=$FAKE_JOBID
17247                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17248         }
17249
17250         log "Test: ${cmd[*]}"
17251         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17252
17253         if [ $JOBENV = "FAKE_JOBID" ]; then
17254                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17255         else
17256                 ${cmd[*]}
17257         fi
17258
17259         # all files are created on OST0000
17260         for facet in $facets; do
17261                 local stats="*.$(convert_facet2label $facet).job_stats"
17262
17263                 # strip out libtool wrappers for in-tree executables
17264                 if [ $(do_facet $facet lctl get_param $stats |
17265                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17266                         do_facet $facet lctl get_param $stats
17267                         error "No jobstats for $JOBVAL found on $facet::$stats"
17268                 fi
17269         done
17270 }
17271
17272 jobstats_set() {
17273         local new_jobenv=$1
17274
17275         set_persistent_param_and_check client "jobid_var" \
17276                 "$FSNAME.sys.jobid_var" $new_jobenv
17277 }
17278
17279 test_205a() { # Job stats
17280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17281         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17282                 skip "Need MDS version with at least 2.7.1"
17283         remote_mgs_nodsh && skip "remote MGS with nodsh"
17284         remote_mds_nodsh && skip "remote MDS with nodsh"
17285         remote_ost_nodsh && skip "remote OST with nodsh"
17286         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17287                 skip "Server doesn't support jobstats"
17288         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17289
17290         local old_jobenv=$($LCTL get_param -n jobid_var)
17291         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17292
17293         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17294                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17295         else
17296                 stack_trap "do_facet mgs $PERM_CMD \
17297                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17298         fi
17299         changelog_register
17300
17301         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17302                                 mdt.*.job_cleanup_interval | head -n 1)
17303         local new_interval=5
17304         do_facet $SINGLEMDS \
17305                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17306         stack_trap "do_facet $SINGLEMDS \
17307                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17308         local start=$SECONDS
17309
17310         local cmd
17311         # mkdir
17312         cmd="mkdir $DIR/$tdir"
17313         verify_jobstats "$cmd" "$SINGLEMDS"
17314         # rmdir
17315         cmd="rmdir $DIR/$tdir"
17316         verify_jobstats "$cmd" "$SINGLEMDS"
17317         # mkdir on secondary MDT
17318         if [ $MDSCOUNT -gt 1 ]; then
17319                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17320                 verify_jobstats "$cmd" "mds2"
17321         fi
17322         # mknod
17323         cmd="mknod $DIR/$tfile c 1 3"
17324         verify_jobstats "$cmd" "$SINGLEMDS"
17325         # unlink
17326         cmd="rm -f $DIR/$tfile"
17327         verify_jobstats "$cmd" "$SINGLEMDS"
17328         # create all files on OST0000 so verify_jobstats can find OST stats
17329         # open & close
17330         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17331         verify_jobstats "$cmd" "$SINGLEMDS"
17332         # setattr
17333         cmd="touch $DIR/$tfile"
17334         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17335         # write
17336         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17337         verify_jobstats "$cmd" "ost1"
17338         # read
17339         cancel_lru_locks osc
17340         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17341         verify_jobstats "$cmd" "ost1"
17342         # truncate
17343         cmd="$TRUNCATE $DIR/$tfile 0"
17344         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17345         # rename
17346         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17347         verify_jobstats "$cmd" "$SINGLEMDS"
17348         # jobstats expiry - sleep until old stats should be expired
17349         local left=$((new_interval + 5 - (SECONDS - start)))
17350         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17351                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17352                         "0" $left
17353         cmd="mkdir $DIR/$tdir.expire"
17354         verify_jobstats "$cmd" "$SINGLEMDS"
17355         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17356             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17357
17358         # Ensure that jobid are present in changelog (if supported by MDS)
17359         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17360                 changelog_dump | tail -10
17361                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17362                 [ $jobids -eq 9 ] ||
17363                         error "Wrong changelog jobid count $jobids != 9"
17364
17365                 # LU-5862
17366                 JOBENV="disable"
17367                 jobstats_set $JOBENV
17368                 touch $DIR/$tfile
17369                 changelog_dump | grep $tfile
17370                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17371                 [ $jobids -eq 0 ] ||
17372                         error "Unexpected jobids when jobid_var=$JOBENV"
17373         fi
17374
17375         # test '%j' access to environment variable - if supported
17376         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17377                 JOBENV="JOBCOMPLEX"
17378                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17379
17380                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17381         fi
17382
17383         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17384                 JOBENV="JOBCOMPLEX"
17385                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17386
17387                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17388         fi
17389
17390         # test '%j' access to per-session jobid - if supported
17391         if lctl list_param jobid_this_session > /dev/null 2>&1
17392         then
17393                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17394                 lctl set_param jobid_this_session=$USER
17395
17396                 JOBENV="JOBCOMPLEX"
17397                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17398
17399                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17400         fi
17401 }
17402 run_test 205a "Verify job stats"
17403
17404 # LU-13117, LU-13597
17405 test_205b() {
17406         job_stats="mdt.*.job_stats"
17407         $LCTL set_param $job_stats=clear
17408         # Setting jobid_var to USER might not be supported
17409         $LCTL set_param jobid_var=USER || true
17410         $LCTL set_param jobid_name="%e.%u"
17411         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17412         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17413                 grep "job_id:.*foolish" &&
17414                         error "Unexpected jobid found"
17415         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17416                 grep "open:.*min.*max.*sum" ||
17417                         error "wrong job_stats format found"
17418 }
17419 run_test 205b "Verify job stats jobid and output format"
17420
17421 # LU-13733
17422 test_205c() {
17423         $LCTL set_param llite.*.stats=0
17424         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17425         $LCTL get_param llite.*.stats
17426         $LCTL get_param llite.*.stats | grep \
17427                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17428                         error "wrong client stats format found"
17429 }
17430 run_test 205c "Verify client stats format"
17431
17432 # LU-1480, LU-1773 and LU-1657
17433 test_206() {
17434         mkdir -p $DIR/$tdir
17435         $LFS setstripe -c -1 $DIR/$tdir
17436 #define OBD_FAIL_LOV_INIT 0x1403
17437         $LCTL set_param fail_loc=0xa0001403
17438         $LCTL set_param fail_val=1
17439         touch $DIR/$tdir/$tfile || true
17440 }
17441 run_test 206 "fail lov_init_raid0() doesn't lbug"
17442
17443 test_207a() {
17444         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17445         local fsz=`stat -c %s $DIR/$tfile`
17446         cancel_lru_locks mdc
17447
17448         # do not return layout in getattr intent
17449 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17450         $LCTL set_param fail_loc=0x170
17451         local sz=`stat -c %s $DIR/$tfile`
17452
17453         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17454
17455         rm -rf $DIR/$tfile
17456 }
17457 run_test 207a "can refresh layout at glimpse"
17458
17459 test_207b() {
17460         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17461         local cksum=`md5sum $DIR/$tfile`
17462         local fsz=`stat -c %s $DIR/$tfile`
17463         cancel_lru_locks mdc
17464         cancel_lru_locks osc
17465
17466         # do not return layout in getattr intent
17467 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17468         $LCTL set_param fail_loc=0x171
17469
17470         # it will refresh layout after the file is opened but before read issues
17471         echo checksum is "$cksum"
17472         echo "$cksum" |md5sum -c --quiet || error "file differs"
17473
17474         rm -rf $DIR/$tfile
17475 }
17476 run_test 207b "can refresh layout at open"
17477
17478 test_208() {
17479         # FIXME: in this test suite, only RD lease is used. This is okay
17480         # for now as only exclusive open is supported. After generic lease
17481         # is done, this test suite should be revised. - Jinshan
17482
17483         remote_mds_nodsh && skip "remote MDS with nodsh"
17484         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17485                 skip "Need MDS version at least 2.4.52"
17486
17487         echo "==== test 1: verify get lease work"
17488         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17489
17490         echo "==== test 2: verify lease can be broken by upcoming open"
17491         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17492         local PID=$!
17493         sleep 1
17494
17495         $MULTIOP $DIR/$tfile oO_RDONLY:c
17496         kill -USR1 $PID && wait $PID || error "break lease error"
17497
17498         echo "==== test 3: verify lease can't be granted if an open already exists"
17499         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17500         local PID=$!
17501         sleep 1
17502
17503         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17504         kill -USR1 $PID && wait $PID || error "open file error"
17505
17506         echo "==== test 4: lease can sustain over recovery"
17507         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17508         PID=$!
17509         sleep 1
17510
17511         fail mds1
17512
17513         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17514
17515         echo "==== test 5: lease broken can't be regained by replay"
17516         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17517         PID=$!
17518         sleep 1
17519
17520         # open file to break lease and then recovery
17521         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17522         fail mds1
17523
17524         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17525
17526         rm -f $DIR/$tfile
17527 }
17528 run_test 208 "Exclusive open"
17529
17530 test_209() {
17531         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17532                 skip_env "must have disp_stripe"
17533
17534         touch $DIR/$tfile
17535         sync; sleep 5; sync;
17536
17537         echo 3 > /proc/sys/vm/drop_caches
17538         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17539                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17540         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17541
17542         # open/close 500 times
17543         for i in $(seq 500); do
17544                 cat $DIR/$tfile
17545         done
17546
17547         echo 3 > /proc/sys/vm/drop_caches
17548         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17549                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17550         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17551
17552         echo "before: $req_before, after: $req_after"
17553         [ $((req_after - req_before)) -ge 300 ] &&
17554                 error "open/close requests are not freed"
17555         return 0
17556 }
17557 run_test 209 "read-only open/close requests should be freed promptly"
17558
17559 test_210() {
17560         local pid
17561
17562         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17563         pid=$!
17564         sleep 1
17565
17566         $LFS getstripe $DIR/$tfile
17567         kill -USR1 $pid
17568         wait $pid || error "multiop failed"
17569
17570         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17571         pid=$!
17572         sleep 1
17573
17574         $LFS getstripe $DIR/$tfile
17575         kill -USR1 $pid
17576         wait $pid || error "multiop failed"
17577 }
17578 run_test 210 "lfs getstripe does not break leases"
17579
17580 test_212() {
17581         size=`date +%s`
17582         size=$((size % 8192 + 1))
17583         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17584         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17585         rm -f $DIR/f212 $DIR/f212.xyz
17586 }
17587 run_test 212 "Sendfile test ============================================"
17588
17589 test_213() {
17590         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17591         cancel_lru_locks osc
17592         lctl set_param fail_loc=0x8000040f
17593         # generate a read lock
17594         cat $DIR/$tfile > /dev/null
17595         # write to the file, it will try to cancel the above read lock.
17596         cat /etc/hosts >> $DIR/$tfile
17597 }
17598 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17599
17600 test_214() { # for bug 20133
17601         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17602         for (( i=0; i < 340; i++ )) ; do
17603                 touch $DIR/$tdir/d214c/a$i
17604         done
17605
17606         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17607         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17608         ls $DIR/d214c || error "ls $DIR/d214c failed"
17609         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17610         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17611 }
17612 run_test 214 "hash-indexed directory test - bug 20133"
17613
17614 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17615 create_lnet_proc_files() {
17616         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17617 }
17618
17619 # counterpart of create_lnet_proc_files
17620 remove_lnet_proc_files() {
17621         rm -f $TMP/lnet_$1.sys
17622 }
17623
17624 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17625 # 3rd arg as regexp for body
17626 check_lnet_proc_stats() {
17627         local l=$(cat "$TMP/lnet_$1" |wc -l)
17628         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17629
17630         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17631 }
17632
17633 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17634 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17635 # optional and can be regexp for 2nd line (lnet.routes case)
17636 check_lnet_proc_entry() {
17637         local blp=2          # blp stands for 'position of 1st line of body'
17638         [ -z "$5" ] || blp=3 # lnet.routes case
17639
17640         local l=$(cat "$TMP/lnet_$1" |wc -l)
17641         # subtracting one from $blp because the body can be empty
17642         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17643
17644         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17645                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17646
17647         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17648                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17649
17650         # bail out if any unexpected line happened
17651         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17652         [ "$?" != 0 ] || error "$2 misformatted"
17653 }
17654
17655 test_215() { # for bugs 18102, 21079, 21517
17656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17657
17658         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17659         local P='[1-9][0-9]*'           # positive numeric
17660         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17661         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17662         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17663         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17664
17665         local L1 # regexp for 1st line
17666         local L2 # regexp for 2nd line (optional)
17667         local BR # regexp for the rest (body)
17668
17669         # lnet.stats should look as 11 space-separated non-negative numerics
17670         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17671         create_lnet_proc_files "stats"
17672         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17673         remove_lnet_proc_files "stats"
17674
17675         # lnet.routes should look like this:
17676         # Routing disabled/enabled
17677         # net hops priority state router
17678         # where net is a string like tcp0, hops > 0, priority >= 0,
17679         # state is up/down,
17680         # router is a string like 192.168.1.1@tcp2
17681         L1="^Routing (disabled|enabled)$"
17682         L2="^net +hops +priority +state +router$"
17683         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17684         create_lnet_proc_files "routes"
17685         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17686         remove_lnet_proc_files "routes"
17687
17688         # lnet.routers should look like this:
17689         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17690         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17691         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17692         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17693         L1="^ref +rtr_ref +alive +router$"
17694         BR="^$P +$P +(up|down) +$NID$"
17695         create_lnet_proc_files "routers"
17696         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17697         remove_lnet_proc_files "routers"
17698
17699         # lnet.peers should look like this:
17700         # nid refs state last max rtr min tx min queue
17701         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17702         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17703         # numeric (0 or >0 or <0), queue >= 0.
17704         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17705         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17706         create_lnet_proc_files "peers"
17707         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17708         remove_lnet_proc_files "peers"
17709
17710         # lnet.buffers  should look like this:
17711         # pages count credits min
17712         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17713         L1="^pages +count +credits +min$"
17714         BR="^ +$N +$N +$I +$I$"
17715         create_lnet_proc_files "buffers"
17716         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17717         remove_lnet_proc_files "buffers"
17718
17719         # lnet.nis should look like this:
17720         # nid status alive refs peer rtr max tx min
17721         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17722         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17723         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17724         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17725         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17726         create_lnet_proc_files "nis"
17727         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17728         remove_lnet_proc_files "nis"
17729
17730         # can we successfully write to lnet.stats?
17731         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17732 }
17733 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17734
17735 test_216() { # bug 20317
17736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17737         remote_ost_nodsh && skip "remote OST with nodsh"
17738
17739         local node
17740         local facets=$(get_facets OST)
17741         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17742
17743         save_lustre_params client "osc.*.contention_seconds" > $p
17744         save_lustre_params $facets \
17745                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17746         save_lustre_params $facets \
17747                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17748         save_lustre_params $facets \
17749                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17750         clear_stats osc.*.osc_stats
17751
17752         # agressive lockless i/o settings
17753         do_nodes $(comma_list $(osts_nodes)) \
17754                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17755                         ldlm.namespaces.filter-*.contended_locks=0 \
17756                         ldlm.namespaces.filter-*.contention_seconds=60"
17757         lctl set_param -n osc.*.contention_seconds=60
17758
17759         $DIRECTIO write $DIR/$tfile 0 10 4096
17760         $CHECKSTAT -s 40960 $DIR/$tfile
17761
17762         # disable lockless i/o
17763         do_nodes $(comma_list $(osts_nodes)) \
17764                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17765                         ldlm.namespaces.filter-*.contended_locks=32 \
17766                         ldlm.namespaces.filter-*.contention_seconds=0"
17767         lctl set_param -n osc.*.contention_seconds=0
17768         clear_stats osc.*.osc_stats
17769
17770         dd if=/dev/zero of=$DIR/$tfile count=0
17771         $CHECKSTAT -s 0 $DIR/$tfile
17772
17773         restore_lustre_params <$p
17774         rm -f $p
17775         rm $DIR/$tfile
17776 }
17777 run_test 216 "check lockless direct write updates file size and kms correctly"
17778
17779 test_217() { # bug 22430
17780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17781
17782         local node
17783         local nid
17784
17785         for node in $(nodes_list); do
17786                 nid=$(host_nids_address $node $NETTYPE)
17787                 if [[ $nid = *-* ]] ; then
17788                         echo "lctl ping $(h2nettype $nid)"
17789                         lctl ping $(h2nettype $nid)
17790                 else
17791                         echo "skipping $node (no hyphen detected)"
17792                 fi
17793         done
17794 }
17795 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17796
17797 test_218() {
17798        # do directio so as not to populate the page cache
17799        log "creating a 10 Mb file"
17800        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17801        log "starting reads"
17802        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17803        log "truncating the file"
17804        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17805        log "killing dd"
17806        kill %+ || true # reads might have finished
17807        echo "wait until dd is finished"
17808        wait
17809        log "removing the temporary file"
17810        rm -rf $DIR/$tfile || error "tmp file removal failed"
17811 }
17812 run_test 218 "parallel read and truncate should not deadlock"
17813
17814 test_219() {
17815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17816
17817         # write one partial page
17818         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17819         # set no grant so vvp_io_commit_write will do sync write
17820         $LCTL set_param fail_loc=0x411
17821         # write a full page at the end of file
17822         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17823
17824         $LCTL set_param fail_loc=0
17825         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17826         $LCTL set_param fail_loc=0x411
17827         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17828
17829         # LU-4201
17830         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17831         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17832 }
17833 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17834
17835 test_220() { #LU-325
17836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17837         remote_ost_nodsh && skip "remote OST with nodsh"
17838         remote_mds_nodsh && skip "remote MDS with nodsh"
17839         remote_mgs_nodsh && skip "remote MGS with nodsh"
17840
17841         local OSTIDX=0
17842
17843         # create on MDT0000 so the last_id and next_id are correct
17844         mkdir $DIR/$tdir
17845         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17846         OST=${OST%_UUID}
17847
17848         # on the mdt's osc
17849         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17850         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17851                         osp.$mdtosc_proc1.prealloc_last_id)
17852         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17853                         osp.$mdtosc_proc1.prealloc_next_id)
17854
17855         $LFS df -i
17856
17857         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17858         #define OBD_FAIL_OST_ENOINO              0x229
17859         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17860         create_pool $FSNAME.$TESTNAME || return 1
17861         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17862
17863         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17864
17865         MDSOBJS=$((last_id - next_id))
17866         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17867
17868         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17869         echo "OST still has $count kbytes free"
17870
17871         echo "create $MDSOBJS files @next_id..."
17872         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17873
17874         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17875                         osp.$mdtosc_proc1.prealloc_last_id)
17876         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17877                         osp.$mdtosc_proc1.prealloc_next_id)
17878
17879         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17880         $LFS df -i
17881
17882         echo "cleanup..."
17883
17884         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17885         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17886
17887         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17888                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17889         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17890                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17891         echo "unlink $MDSOBJS files @$next_id..."
17892         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17893 }
17894 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17895
17896 test_221() {
17897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17898
17899         dd if=`which date` of=$MOUNT/date oflag=sync
17900         chmod +x $MOUNT/date
17901
17902         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17903         $LCTL set_param fail_loc=0x80001401
17904
17905         $MOUNT/date > /dev/null
17906         rm -f $MOUNT/date
17907 }
17908 run_test 221 "make sure fault and truncate race to not cause OOM"
17909
17910 test_222a () {
17911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17912
17913         rm -rf $DIR/$tdir
17914         test_mkdir $DIR/$tdir
17915         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17916         createmany -o $DIR/$tdir/$tfile 10
17917         cancel_lru_locks mdc
17918         cancel_lru_locks osc
17919         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17920         $LCTL set_param fail_loc=0x31a
17921         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17922         $LCTL set_param fail_loc=0
17923         rm -r $DIR/$tdir
17924 }
17925 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17926
17927 test_222b () {
17928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17929
17930         rm -rf $DIR/$tdir
17931         test_mkdir $DIR/$tdir
17932         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17933         createmany -o $DIR/$tdir/$tfile 10
17934         cancel_lru_locks mdc
17935         cancel_lru_locks osc
17936         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17937         $LCTL set_param fail_loc=0x31a
17938         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17939         $LCTL set_param fail_loc=0
17940 }
17941 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17942
17943 test_223 () {
17944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17945
17946         rm -rf $DIR/$tdir
17947         test_mkdir $DIR/$tdir
17948         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17949         createmany -o $DIR/$tdir/$tfile 10
17950         cancel_lru_locks mdc
17951         cancel_lru_locks osc
17952         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17953         $LCTL set_param fail_loc=0x31b
17954         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17955         $LCTL set_param fail_loc=0
17956         rm -r $DIR/$tdir
17957 }
17958 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17959
17960 test_224a() { # LU-1039, MRP-303
17961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17962
17963         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17964         $LCTL set_param fail_loc=0x508
17965         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17966         $LCTL set_param fail_loc=0
17967         df $DIR
17968 }
17969 run_test 224a "Don't panic on bulk IO failure"
17970
17971 test_224b() { # LU-1039, MRP-303
17972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17973
17974         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17975         cancel_lru_locks osc
17976         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17977         $LCTL set_param fail_loc=0x515
17978         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17979         $LCTL set_param fail_loc=0
17980         df $DIR
17981 }
17982 run_test 224b "Don't panic on bulk IO failure"
17983
17984 test_224c() { # LU-6441
17985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17986         remote_mds_nodsh && skip "remote MDS with nodsh"
17987
17988         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17989         save_writethrough $p
17990         set_cache writethrough on
17991
17992         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17993         local at_max=$($LCTL get_param -n at_max)
17994         local timeout=$($LCTL get_param -n timeout)
17995         local test_at="at_max"
17996         local param_at="$FSNAME.sys.at_max"
17997         local test_timeout="timeout"
17998         local param_timeout="$FSNAME.sys.timeout"
17999
18000         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18001
18002         set_persistent_param_and_check client "$test_at" "$param_at" 0
18003         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18004
18005         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18006         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18007         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18008         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18009         sync
18010         do_facet ost1 "$LCTL set_param fail_loc=0"
18011
18012         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18013         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18014                 $timeout
18015
18016         $LCTL set_param -n $pages_per_rpc
18017         restore_lustre_params < $p
18018         rm -f $p
18019 }
18020 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18021
18022 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18023 test_225a () {
18024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18025         if [ -z ${MDSSURVEY} ]; then
18026                 skip_env "mds-survey not found"
18027         fi
18028         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18029                 skip "Need MDS version at least 2.2.51"
18030
18031         local mds=$(facet_host $SINGLEMDS)
18032         local target=$(do_nodes $mds 'lctl dl' |
18033                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18034
18035         local cmd1="file_count=1000 thrhi=4"
18036         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18037         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18038         local cmd="$cmd1 $cmd2 $cmd3"
18039
18040         rm -f ${TMP}/mds_survey*
18041         echo + $cmd
18042         eval $cmd || error "mds-survey with zero-stripe failed"
18043         cat ${TMP}/mds_survey*
18044         rm -f ${TMP}/mds_survey*
18045 }
18046 run_test 225a "Metadata survey sanity with zero-stripe"
18047
18048 test_225b () {
18049         if [ -z ${MDSSURVEY} ]; then
18050                 skip_env "mds-survey not found"
18051         fi
18052         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18053                 skip "Need MDS version at least 2.2.51"
18054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18055         remote_mds_nodsh && skip "remote MDS with nodsh"
18056         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18057                 skip_env "Need to mount OST to test"
18058         fi
18059
18060         local mds=$(facet_host $SINGLEMDS)
18061         local target=$(do_nodes $mds 'lctl dl' |
18062                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18063
18064         local cmd1="file_count=1000 thrhi=4"
18065         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18066         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18067         local cmd="$cmd1 $cmd2 $cmd3"
18068
18069         rm -f ${TMP}/mds_survey*
18070         echo + $cmd
18071         eval $cmd || error "mds-survey with stripe_count failed"
18072         cat ${TMP}/mds_survey*
18073         rm -f ${TMP}/mds_survey*
18074 }
18075 run_test 225b "Metadata survey sanity with stripe_count = 1"
18076
18077 mcreate_path2fid () {
18078         local mode=$1
18079         local major=$2
18080         local minor=$3
18081         local name=$4
18082         local desc=$5
18083         local path=$DIR/$tdir/$name
18084         local fid
18085         local rc
18086         local fid_path
18087
18088         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18089                 error "cannot create $desc"
18090
18091         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18092         rc=$?
18093         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18094
18095         fid_path=$($LFS fid2path $MOUNT $fid)
18096         rc=$?
18097         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18098
18099         [ "$path" == "$fid_path" ] ||
18100                 error "fid2path returned $fid_path, expected $path"
18101
18102         echo "pass with $path and $fid"
18103 }
18104
18105 test_226a () {
18106         rm -rf $DIR/$tdir
18107         mkdir -p $DIR/$tdir
18108
18109         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18110         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18111         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18112         mcreate_path2fid 0040666 0 0 dir "directory"
18113         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18114         mcreate_path2fid 0100666 0 0 file "regular file"
18115         mcreate_path2fid 0120666 0 0 link "symbolic link"
18116         mcreate_path2fid 0140666 0 0 sock "socket"
18117 }
18118 run_test 226a "call path2fid and fid2path on files of all type"
18119
18120 test_226b () {
18121         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18122
18123         local MDTIDX=1
18124
18125         rm -rf $DIR/$tdir
18126         mkdir -p $DIR/$tdir
18127         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18128                 error "create remote directory failed"
18129         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18130         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18131                                 "character special file (null)"
18132         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18133                                 "character special file (no device)"
18134         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18135         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18136                                 "block special file (loop)"
18137         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18138         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18139         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18140 }
18141 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18142
18143 test_226c () {
18144         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18145         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18146                 skip "Need MDS version at least 2.13.55"
18147
18148         local submnt=/mnt/submnt
18149         local srcfile=/etc/passwd
18150         local dstfile=$submnt/passwd
18151         local path
18152         local fid
18153
18154         rm -rf $DIR/$tdir
18155         rm -rf $submnt
18156         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18157                 error "create remote directory failed"
18158         mkdir -p $submnt || error "create $submnt failed"
18159         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18160                 error "mount $submnt failed"
18161         stack_trap "umount $submnt" EXIT
18162
18163         cp $srcfile $dstfile
18164         fid=$($LFS path2fid $dstfile)
18165         path=$($LFS fid2path $submnt "$fid")
18166         [ "$path" = "$dstfile" ] ||
18167                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18168 }
18169 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18170
18171 # LU-1299 Executing or running ldd on a truncated executable does not
18172 # cause an out-of-memory condition.
18173 test_227() {
18174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18175         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18176
18177         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18178         chmod +x $MOUNT/date
18179
18180         $MOUNT/date > /dev/null
18181         ldd $MOUNT/date > /dev/null
18182         rm -f $MOUNT/date
18183 }
18184 run_test 227 "running truncated executable does not cause OOM"
18185
18186 # LU-1512 try to reuse idle OI blocks
18187 test_228a() {
18188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18189         remote_mds_nodsh && skip "remote MDS with nodsh"
18190         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18191
18192         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18193         local myDIR=$DIR/$tdir
18194
18195         mkdir -p $myDIR
18196         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18197         $LCTL set_param fail_loc=0x80001002
18198         createmany -o $myDIR/t- 10000
18199         $LCTL set_param fail_loc=0
18200         # The guard is current the largest FID holder
18201         touch $myDIR/guard
18202         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18203                     tr -d '[')
18204         local IDX=$(($SEQ % 64))
18205
18206         do_facet $SINGLEMDS sync
18207         # Make sure journal flushed.
18208         sleep 6
18209         local blk1=$(do_facet $SINGLEMDS \
18210                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18211                      grep Blockcount | awk '{print $4}')
18212
18213         # Remove old files, some OI blocks will become idle.
18214         unlinkmany $myDIR/t- 10000
18215         # Create new files, idle OI blocks should be reused.
18216         createmany -o $myDIR/t- 2000
18217         do_facet $SINGLEMDS sync
18218         # Make sure journal flushed.
18219         sleep 6
18220         local blk2=$(do_facet $SINGLEMDS \
18221                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18222                      grep Blockcount | awk '{print $4}')
18223
18224         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18225 }
18226 run_test 228a "try to reuse idle OI blocks"
18227
18228 test_228b() {
18229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18230         remote_mds_nodsh && skip "remote MDS with nodsh"
18231         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18232
18233         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18234         local myDIR=$DIR/$tdir
18235
18236         mkdir -p $myDIR
18237         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18238         $LCTL set_param fail_loc=0x80001002
18239         createmany -o $myDIR/t- 10000
18240         $LCTL set_param fail_loc=0
18241         # The guard is current the largest FID holder
18242         touch $myDIR/guard
18243         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18244                     tr -d '[')
18245         local IDX=$(($SEQ % 64))
18246
18247         do_facet $SINGLEMDS sync
18248         # Make sure journal flushed.
18249         sleep 6
18250         local blk1=$(do_facet $SINGLEMDS \
18251                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18252                      grep Blockcount | awk '{print $4}')
18253
18254         # Remove old files, some OI blocks will become idle.
18255         unlinkmany $myDIR/t- 10000
18256
18257         # stop the MDT
18258         stop $SINGLEMDS || error "Fail to stop MDT."
18259         # remount the MDT
18260         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18261
18262         df $MOUNT || error "Fail to df."
18263         # Create new files, idle OI blocks should be reused.
18264         createmany -o $myDIR/t- 2000
18265         do_facet $SINGLEMDS sync
18266         # Make sure journal flushed.
18267         sleep 6
18268         local blk2=$(do_facet $SINGLEMDS \
18269                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18270                      grep Blockcount | awk '{print $4}')
18271
18272         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18273 }
18274 run_test 228b "idle OI blocks can be reused after MDT restart"
18275
18276 #LU-1881
18277 test_228c() {
18278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18279         remote_mds_nodsh && skip "remote MDS with nodsh"
18280         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18281
18282         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18283         local myDIR=$DIR/$tdir
18284
18285         mkdir -p $myDIR
18286         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18287         $LCTL set_param fail_loc=0x80001002
18288         # 20000 files can guarantee there are index nodes in the OI file
18289         createmany -o $myDIR/t- 20000
18290         $LCTL set_param fail_loc=0
18291         # The guard is current the largest FID holder
18292         touch $myDIR/guard
18293         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18294                     tr -d '[')
18295         local IDX=$(($SEQ % 64))
18296
18297         do_facet $SINGLEMDS sync
18298         # Make sure journal flushed.
18299         sleep 6
18300         local blk1=$(do_facet $SINGLEMDS \
18301                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18302                      grep Blockcount | awk '{print $4}')
18303
18304         # Remove old files, some OI blocks will become idle.
18305         unlinkmany $myDIR/t- 20000
18306         rm -f $myDIR/guard
18307         # The OI file should become empty now
18308
18309         # Create new files, idle OI blocks should be reused.
18310         createmany -o $myDIR/t- 2000
18311         do_facet $SINGLEMDS sync
18312         # Make sure journal flushed.
18313         sleep 6
18314         local blk2=$(do_facet $SINGLEMDS \
18315                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18316                      grep Blockcount | awk '{print $4}')
18317
18318         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18319 }
18320 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18321
18322 test_229() { # LU-2482, LU-3448
18323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18324         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18325         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18326                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18327
18328         rm -f $DIR/$tfile
18329
18330         # Create a file with a released layout and stripe count 2.
18331         $MULTIOP $DIR/$tfile H2c ||
18332                 error "failed to create file with released layout"
18333
18334         $LFS getstripe -v $DIR/$tfile
18335
18336         local pattern=$($LFS getstripe -L $DIR/$tfile)
18337         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18338
18339         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18340                 error "getstripe"
18341         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18342         stat $DIR/$tfile || error "failed to stat released file"
18343
18344         chown $RUNAS_ID $DIR/$tfile ||
18345                 error "chown $RUNAS_ID $DIR/$tfile failed"
18346
18347         chgrp $RUNAS_ID $DIR/$tfile ||
18348                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18349
18350         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18351         rm $DIR/$tfile || error "failed to remove released file"
18352 }
18353 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18354
18355 test_230a() {
18356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18357         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18358         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18359                 skip "Need MDS version at least 2.11.52"
18360
18361         local MDTIDX=1
18362
18363         test_mkdir $DIR/$tdir
18364         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18365         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18366         [ $mdt_idx -ne 0 ] &&
18367                 error "create local directory on wrong MDT $mdt_idx"
18368
18369         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18370                         error "create remote directory failed"
18371         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18372         [ $mdt_idx -ne $MDTIDX ] &&
18373                 error "create remote directory on wrong MDT $mdt_idx"
18374
18375         createmany -o $DIR/$tdir/test_230/t- 10 ||
18376                 error "create files on remote directory failed"
18377         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18378         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18379         rm -r $DIR/$tdir || error "unlink remote directory failed"
18380 }
18381 run_test 230a "Create remote directory and files under the remote directory"
18382
18383 test_230b() {
18384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18385         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18386         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18387                 skip "Need MDS version at least 2.11.52"
18388
18389         local MDTIDX=1
18390         local mdt_index
18391         local i
18392         local file
18393         local pid
18394         local stripe_count
18395         local migrate_dir=$DIR/$tdir/migrate_dir
18396         local other_dir=$DIR/$tdir/other_dir
18397
18398         test_mkdir $DIR/$tdir
18399         test_mkdir -i0 -c1 $migrate_dir
18400         test_mkdir -i0 -c1 $other_dir
18401         for ((i=0; i<10; i++)); do
18402                 mkdir -p $migrate_dir/dir_${i}
18403                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18404                         error "create files under remote dir failed $i"
18405         done
18406
18407         cp /etc/passwd $migrate_dir/$tfile
18408         cp /etc/passwd $other_dir/$tfile
18409         chattr +SAD $migrate_dir
18410         chattr +SAD $migrate_dir/$tfile
18411
18412         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18413         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18414         local old_dir_mode=$(stat -c%f $migrate_dir)
18415         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18416
18417         mkdir -p $migrate_dir/dir_default_stripe2
18418         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18419         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18420
18421         mkdir -p $other_dir
18422         ln $migrate_dir/$tfile $other_dir/luna
18423         ln $migrate_dir/$tfile $migrate_dir/sofia
18424         ln $other_dir/$tfile $migrate_dir/david
18425         ln -s $migrate_dir/$tfile $other_dir/zachary
18426         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18427         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18428
18429         local len
18430         local lnktgt
18431
18432         # inline symlink
18433         for len in 58 59 60; do
18434                 lnktgt=$(str_repeat 'l' $len)
18435                 touch $migrate_dir/$lnktgt
18436                 ln -s $lnktgt $migrate_dir/${len}char_ln
18437         done
18438
18439         # PATH_MAX
18440         for len in 4094 4095; do
18441                 lnktgt=$(str_repeat 'l' $len)
18442                 ln -s $lnktgt $migrate_dir/${len}char_ln
18443         done
18444
18445         # NAME_MAX
18446         for len in 254 255; do
18447                 touch $migrate_dir/$(str_repeat 'l' $len)
18448         done
18449
18450         $LFS migrate -m $MDTIDX $migrate_dir ||
18451                 error "fails on migrating remote dir to MDT1"
18452
18453         echo "migratate to MDT1, then checking.."
18454         for ((i = 0; i < 10; i++)); do
18455                 for file in $(find $migrate_dir/dir_${i}); do
18456                         mdt_index=$($LFS getstripe -m $file)
18457                         # broken symlink getstripe will fail
18458                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18459                                 error "$file is not on MDT${MDTIDX}"
18460                 done
18461         done
18462
18463         # the multiple link file should still in MDT0
18464         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18465         [ $mdt_index == 0 ] ||
18466                 error "$file is not on MDT${MDTIDX}"
18467
18468         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18469         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18470                 error " expect $old_dir_flag get $new_dir_flag"
18471
18472         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18473         [ "$old_file_flag" = "$new_file_flag" ] ||
18474                 error " expect $old_file_flag get $new_file_flag"
18475
18476         local new_dir_mode=$(stat -c%f $migrate_dir)
18477         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18478                 error "expect mode $old_dir_mode get $new_dir_mode"
18479
18480         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18481         [ "$old_file_mode" = "$new_file_mode" ] ||
18482                 error "expect mode $old_file_mode get $new_file_mode"
18483
18484         diff /etc/passwd $migrate_dir/$tfile ||
18485                 error "$tfile different after migration"
18486
18487         diff /etc/passwd $other_dir/luna ||
18488                 error "luna different after migration"
18489
18490         diff /etc/passwd $migrate_dir/sofia ||
18491                 error "sofia different after migration"
18492
18493         diff /etc/passwd $migrate_dir/david ||
18494                 error "david different after migration"
18495
18496         diff /etc/passwd $other_dir/zachary ||
18497                 error "zachary different after migration"
18498
18499         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18500                 error "${tfile}_ln different after migration"
18501
18502         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18503                 error "${tfile}_ln_other different after migration"
18504
18505         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18506         [ $stripe_count = 2 ] ||
18507                 error "dir strpe_count $d != 2 after migration."
18508
18509         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18510         [ $stripe_count = 2 ] ||
18511                 error "file strpe_count $d != 2 after migration."
18512
18513         #migrate back to MDT0
18514         MDTIDX=0
18515
18516         $LFS migrate -m $MDTIDX $migrate_dir ||
18517                 error "fails on migrating remote dir to MDT0"
18518
18519         echo "migrate back to MDT0, checking.."
18520         for file in $(find $migrate_dir); do
18521                 mdt_index=$($LFS getstripe -m $file)
18522                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18523                         error "$file is not on MDT${MDTIDX}"
18524         done
18525
18526         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18527         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18528                 error " expect $old_dir_flag get $new_dir_flag"
18529
18530         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18531         [ "$old_file_flag" = "$new_file_flag" ] ||
18532                 error " expect $old_file_flag get $new_file_flag"
18533
18534         local new_dir_mode=$(stat -c%f $migrate_dir)
18535         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18536                 error "expect mode $old_dir_mode get $new_dir_mode"
18537
18538         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18539         [ "$old_file_mode" = "$new_file_mode" ] ||
18540                 error "expect mode $old_file_mode get $new_file_mode"
18541
18542         diff /etc/passwd ${migrate_dir}/$tfile ||
18543                 error "$tfile different after migration"
18544
18545         diff /etc/passwd ${other_dir}/luna ||
18546                 error "luna different after migration"
18547
18548         diff /etc/passwd ${migrate_dir}/sofia ||
18549                 error "sofia different after migration"
18550
18551         diff /etc/passwd ${other_dir}/zachary ||
18552                 error "zachary different after migration"
18553
18554         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18555                 error "${tfile}_ln different after migration"
18556
18557         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18558                 error "${tfile}_ln_other different after migration"
18559
18560         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18561         [ $stripe_count = 2 ] ||
18562                 error "dir strpe_count $d != 2 after migration."
18563
18564         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18565         [ $stripe_count = 2 ] ||
18566                 error "file strpe_count $d != 2 after migration."
18567
18568         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18569 }
18570 run_test 230b "migrate directory"
18571
18572 test_230c() {
18573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18574         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18575         remote_mds_nodsh && skip "remote MDS with nodsh"
18576         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18577                 skip "Need MDS version at least 2.11.52"
18578
18579         local MDTIDX=1
18580         local total=3
18581         local mdt_index
18582         local file
18583         local migrate_dir=$DIR/$tdir/migrate_dir
18584
18585         #If migrating directory fails in the middle, all entries of
18586         #the directory is still accessiable.
18587         test_mkdir $DIR/$tdir
18588         test_mkdir -i0 -c1 $migrate_dir
18589         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18590         stat $migrate_dir
18591         createmany -o $migrate_dir/f $total ||
18592                 error "create files under ${migrate_dir} failed"
18593
18594         # fail after migrating top dir, and this will fail only once, so the
18595         # first sub file migration will fail (currently f3), others succeed.
18596         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18597         do_facet mds1 lctl set_param fail_loc=0x1801
18598         local t=$(ls $migrate_dir | wc -l)
18599         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18600                 error "migrate should fail"
18601         local u=$(ls $migrate_dir | wc -l)
18602         [ "$u" == "$t" ] || error "$u != $t during migration"
18603
18604         # add new dir/file should succeed
18605         mkdir $migrate_dir/dir ||
18606                 error "mkdir failed under migrating directory"
18607         touch $migrate_dir/file ||
18608                 error "create file failed under migrating directory"
18609
18610         # add file with existing name should fail
18611         for file in $migrate_dir/f*; do
18612                 stat $file > /dev/null || error "stat $file failed"
18613                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18614                         error "open(O_CREAT|O_EXCL) $file should fail"
18615                 $MULTIOP $file m && error "create $file should fail"
18616                 touch $DIR/$tdir/remote_dir/$tfile ||
18617                         error "touch $tfile failed"
18618                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18619                         error "link $file should fail"
18620                 mdt_index=$($LFS getstripe -m $file)
18621                 if [ $mdt_index == 0 ]; then
18622                         # file failed to migrate is not allowed to rename to
18623                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18624                                 error "rename to $file should fail"
18625                 else
18626                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18627                                 error "rename to $file failed"
18628                 fi
18629                 echo hello >> $file || error "write $file failed"
18630         done
18631
18632         # resume migration with different options should fail
18633         $LFS migrate -m 0 $migrate_dir &&
18634                 error "migrate -m 0 $migrate_dir should fail"
18635
18636         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18637                 error "migrate -c 2 $migrate_dir should fail"
18638
18639         # resume migration should succeed
18640         $LFS migrate -m $MDTIDX $migrate_dir ||
18641                 error "migrate $migrate_dir failed"
18642
18643         echo "Finish migration, then checking.."
18644         for file in $(find $migrate_dir); do
18645                 mdt_index=$($LFS getstripe -m $file)
18646                 [ $mdt_index == $MDTIDX ] ||
18647                         error "$file is not on MDT${MDTIDX}"
18648         done
18649
18650         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18651 }
18652 run_test 230c "check directory accessiblity if migration failed"
18653
18654 test_230d() {
18655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18656         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18657         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18658                 skip "Need MDS version at least 2.11.52"
18659         # LU-11235
18660         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18661
18662         local migrate_dir=$DIR/$tdir/migrate_dir
18663         local old_index
18664         local new_index
18665         local old_count
18666         local new_count
18667         local new_hash
18668         local mdt_index
18669         local i
18670         local j
18671
18672         old_index=$((RANDOM % MDSCOUNT))
18673         old_count=$((MDSCOUNT - old_index))
18674         new_index=$((RANDOM % MDSCOUNT))
18675         new_count=$((MDSCOUNT - new_index))
18676         new_hash=1 # for all_char
18677
18678         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18679         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18680
18681         test_mkdir $DIR/$tdir
18682         test_mkdir -i $old_index -c $old_count $migrate_dir
18683
18684         for ((i=0; i<100; i++)); do
18685                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18686                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18687                         error "create files under remote dir failed $i"
18688         done
18689
18690         echo -n "Migrate from MDT$old_index "
18691         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18692         echo -n "to MDT$new_index"
18693         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18694         echo
18695
18696         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18697         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18698                 error "migrate remote dir error"
18699
18700         echo "Finish migration, then checking.."
18701         for file in $(find $migrate_dir); do
18702                 mdt_index=$($LFS getstripe -m $file)
18703                 if [ $mdt_index -lt $new_index ] ||
18704                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18705                         error "$file is on MDT$mdt_index"
18706                 fi
18707         done
18708
18709         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18710 }
18711 run_test 230d "check migrate big directory"
18712
18713 test_230e() {
18714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18715         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18716         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18717                 skip "Need MDS version at least 2.11.52"
18718
18719         local i
18720         local j
18721         local a_fid
18722         local b_fid
18723
18724         mkdir -p $DIR/$tdir
18725         mkdir $DIR/$tdir/migrate_dir
18726         mkdir $DIR/$tdir/other_dir
18727         touch $DIR/$tdir/migrate_dir/a
18728         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18729         ls $DIR/$tdir/other_dir
18730
18731         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18732                 error "migrate dir fails"
18733
18734         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18735         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18736
18737         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18738         [ $mdt_index == 0 ] || error "a is not on MDT0"
18739
18740         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18741                 error "migrate dir fails"
18742
18743         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18744         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18745
18746         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18747         [ $mdt_index == 1 ] || error "a is not on MDT1"
18748
18749         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18750         [ $mdt_index == 1 ] || error "b is not on MDT1"
18751
18752         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18753         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18754
18755         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18756
18757         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18758 }
18759 run_test 230e "migrate mulitple local link files"
18760
18761 test_230f() {
18762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18763         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18764         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18765                 skip "Need MDS version at least 2.11.52"
18766
18767         local a_fid
18768         local ln_fid
18769
18770         mkdir -p $DIR/$tdir
18771         mkdir $DIR/$tdir/migrate_dir
18772         $LFS mkdir -i1 $DIR/$tdir/other_dir
18773         touch $DIR/$tdir/migrate_dir/a
18774         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18775         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18776         ls $DIR/$tdir/other_dir
18777
18778         # a should be migrated to MDT1, since no other links on MDT0
18779         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18780                 error "#1 migrate dir fails"
18781         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18782         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18783         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18784         [ $mdt_index == 1 ] || error "a is not on MDT1"
18785
18786         # a should stay on MDT1, because it is a mulitple link file
18787         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18788                 error "#2 migrate dir fails"
18789         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18790         [ $mdt_index == 1 ] || error "a is not on MDT1"
18791
18792         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18793                 error "#3 migrate dir fails"
18794
18795         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18796         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18797         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18798
18799         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18800         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18801
18802         # a should be migrated to MDT0, since no other links on MDT1
18803         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18804                 error "#4 migrate dir fails"
18805         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18806         [ $mdt_index == 0 ] || error "a is not on MDT0"
18807
18808         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18809 }
18810 run_test 230f "migrate mulitple remote link files"
18811
18812 test_230g() {
18813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18814         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18815         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18816                 skip "Need MDS version at least 2.11.52"
18817
18818         mkdir -p $DIR/$tdir/migrate_dir
18819
18820         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18821                 error "migrating dir to non-exist MDT succeeds"
18822         true
18823 }
18824 run_test 230g "migrate dir to non-exist MDT"
18825
18826 test_230h() {
18827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18828         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18829         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18830                 skip "Need MDS version at least 2.11.52"
18831
18832         local mdt_index
18833
18834         mkdir -p $DIR/$tdir/migrate_dir
18835
18836         $LFS migrate -m1 $DIR &&
18837                 error "migrating mountpoint1 should fail"
18838
18839         $LFS migrate -m1 $DIR/$tdir/.. &&
18840                 error "migrating mountpoint2 should fail"
18841
18842         # same as mv
18843         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18844                 error "migrating $tdir/migrate_dir/.. should fail"
18845
18846         true
18847 }
18848 run_test 230h "migrate .. and root"
18849
18850 test_230i() {
18851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18852         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18853         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18854                 skip "Need MDS version at least 2.11.52"
18855
18856         mkdir -p $DIR/$tdir/migrate_dir
18857
18858         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18859                 error "migration fails with a tailing slash"
18860
18861         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18862                 error "migration fails with two tailing slashes"
18863 }
18864 run_test 230i "lfs migrate -m tolerates trailing slashes"
18865
18866 test_230j() {
18867         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18868         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18869                 skip "Need MDS version at least 2.11.52"
18870
18871         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18872         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18873                 error "create $tfile failed"
18874         cat /etc/passwd > $DIR/$tdir/$tfile
18875
18876         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18877
18878         cmp /etc/passwd $DIR/$tdir/$tfile ||
18879                 error "DoM file mismatch after migration"
18880 }
18881 run_test 230j "DoM file data not changed after dir migration"
18882
18883 test_230k() {
18884         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18885         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18886                 skip "Need MDS version at least 2.11.56"
18887
18888         local total=20
18889         local files_on_starting_mdt=0
18890
18891         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18892         $LFS getdirstripe $DIR/$tdir
18893         for i in $(seq $total); do
18894                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18895                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18896                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18897         done
18898
18899         echo "$files_on_starting_mdt files on MDT0"
18900
18901         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18902         $LFS getdirstripe $DIR/$tdir
18903
18904         files_on_starting_mdt=0
18905         for i in $(seq $total); do
18906                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18907                         error "file $tfile.$i mismatch after migration"
18908                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18909                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18910         done
18911
18912         echo "$files_on_starting_mdt files on MDT1 after migration"
18913         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18914
18915         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18916         $LFS getdirstripe $DIR/$tdir
18917
18918         files_on_starting_mdt=0
18919         for i in $(seq $total); do
18920                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18921                         error "file $tfile.$i mismatch after 2nd migration"
18922                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18923                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18924         done
18925
18926         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18927         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18928
18929         true
18930 }
18931 run_test 230k "file data not changed after dir migration"
18932
18933 test_230l() {
18934         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18935         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18936                 skip "Need MDS version at least 2.11.56"
18937
18938         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18939         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18940                 error "create files under remote dir failed $i"
18941         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18942 }
18943 run_test 230l "readdir between MDTs won't crash"
18944
18945 test_230m() {
18946         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18947         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18948                 skip "Need MDS version at least 2.11.56"
18949
18950         local MDTIDX=1
18951         local mig_dir=$DIR/$tdir/migrate_dir
18952         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18953         local shortstr="b"
18954         local val
18955
18956         echo "Creating files and dirs with xattrs"
18957         test_mkdir $DIR/$tdir
18958         test_mkdir -i0 -c1 $mig_dir
18959         mkdir $mig_dir/dir
18960         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18961                 error "cannot set xattr attr1 on dir"
18962         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18963                 error "cannot set xattr attr2 on dir"
18964         touch $mig_dir/dir/f0
18965         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18966                 error "cannot set xattr attr1 on file"
18967         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18968                 error "cannot set xattr attr2 on file"
18969         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18970         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18971         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18972         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18973         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18974         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18975         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18976         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18977         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18978
18979         echo "Migrating to MDT1"
18980         $LFS migrate -m $MDTIDX $mig_dir ||
18981                 error "fails on migrating dir to MDT1"
18982
18983         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18984         echo "Checking xattrs"
18985         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18986         [ "$val" = $longstr ] ||
18987                 error "expecting xattr1 $longstr on dir, found $val"
18988         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18989         [ "$val" = $shortstr ] ||
18990                 error "expecting xattr2 $shortstr on dir, found $val"
18991         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18992         [ "$val" = $longstr ] ||
18993                 error "expecting xattr1 $longstr on file, found $val"
18994         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18995         [ "$val" = $shortstr ] ||
18996                 error "expecting xattr2 $shortstr on file, found $val"
18997 }
18998 run_test 230m "xattrs not changed after dir migration"
18999
19000 test_230n() {
19001         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19002         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19003                 skip "Need MDS version at least 2.13.53"
19004
19005         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19006         cat /etc/hosts > $DIR/$tdir/$tfile
19007         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19008         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19009
19010         cmp /etc/hosts $DIR/$tdir/$tfile ||
19011                 error "File data mismatch after migration"
19012 }
19013 run_test 230n "Dir migration with mirrored file"
19014
19015 test_230o() {
19016         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19017         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19018                 skip "Need MDS version at least 2.13.52"
19019
19020         local mdts=$(comma_list $(mdts_nodes))
19021         local timeout=100
19022         local restripe_status
19023         local delta
19024         local i
19025
19026         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19027
19028         # in case "crush" hash type is not set
19029         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19030
19031         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19032                            mdt.*MDT0000.enable_dir_restripe)
19033         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19034         stack_trap "do_nodes $mdts $LCTL set_param \
19035                     mdt.*.enable_dir_restripe=$restripe_status"
19036
19037         mkdir $DIR/$tdir
19038         createmany -m $DIR/$tdir/f 100 ||
19039                 error "create files under remote dir failed $i"
19040         createmany -d $DIR/$tdir/d 100 ||
19041                 error "create dirs under remote dir failed $i"
19042
19043         for i in $(seq 2 $MDSCOUNT); do
19044                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19045                 $LFS setdirstripe -c $i $DIR/$tdir ||
19046                         error "split -c $i $tdir failed"
19047                 wait_update $HOSTNAME \
19048                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19049                         error "dir split not finished"
19050                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19051                         awk '/migrate/ {sum += $2} END { print sum }')
19052                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19053                 # delta is around total_files/stripe_count
19054                 (( $delta < 200 / (i - 1) + 4 )) ||
19055                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19056         done
19057 }
19058 run_test 230o "dir split"
19059
19060 test_230p() {
19061         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19062         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19063                 skip "Need MDS version at least 2.13.52"
19064
19065         local mdts=$(comma_list $(mdts_nodes))
19066         local timeout=100
19067         local restripe_status
19068         local delta
19069         local i
19070
19071         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19072
19073         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19074
19075         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19076                            mdt.*MDT0000.enable_dir_restripe)
19077         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19078         stack_trap "do_nodes $mdts $LCTL set_param \
19079                     mdt.*.enable_dir_restripe=$restripe_status"
19080
19081         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19082         createmany -m $DIR/$tdir/f 100 ||
19083                 error "create files under remote dir failed $i"
19084         createmany -d $DIR/$tdir/d 100 ||
19085                 error "create dirs under remote dir failed $i"
19086
19087         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19088                 local mdt_hash="crush"
19089
19090                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19091                 $LFS setdirstripe -c $i $DIR/$tdir ||
19092                         error "split -c $i $tdir failed"
19093                 [ $i -eq 1 ] && mdt_hash="none"
19094                 wait_update $HOSTNAME \
19095                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19096                         error "dir merge not finished"
19097                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19098                         awk '/migrate/ {sum += $2} END { print sum }')
19099                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19100                 # delta is around total_files/stripe_count
19101                 (( $delta < 200 / i + 4 )) ||
19102                         error "$delta files migrated >= $((200 / i + 4))"
19103         done
19104 }
19105 run_test 230p "dir merge"
19106
19107 test_230q() {
19108         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19109         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19110                 skip "Need MDS version at least 2.13.52"
19111
19112         local mdts=$(comma_list $(mdts_nodes))
19113         local saved_threshold=$(do_facet mds1 \
19114                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19115         local saved_delta=$(do_facet mds1 \
19116                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19117         local threshold=100
19118         local delta=2
19119         local total=0
19120         local stripe_count=0
19121         local stripe_index
19122         local nr_files
19123         local create
19124
19125         # test with fewer files on ZFS
19126         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19127
19128         stack_trap "do_nodes $mdts $LCTL set_param \
19129                     mdt.*.dir_split_count=$saved_threshold"
19130         stack_trap "do_nodes $mdts $LCTL set_param \
19131                     mdt.*.dir_split_delta=$saved_delta"
19132         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19133         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19134         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19135         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19136         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19137         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19138
19139         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19140         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19141
19142         create=$((threshold * 3 / 2))
19143         while [ $stripe_count -lt $MDSCOUNT ]; do
19144                 createmany -m $DIR/$tdir/f $total $create ||
19145                         error "create sub files failed"
19146                 stat $DIR/$tdir > /dev/null
19147                 total=$((total + create))
19148                 stripe_count=$((stripe_count + delta))
19149                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19150
19151                 wait_update $HOSTNAME \
19152                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19153                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19154
19155                 wait_update $HOSTNAME \
19156                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19157                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19158
19159                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19160                 echo "$nr_files/$total files on MDT$stripe_index after split"
19161                 # allow 10% margin of imbalance with crush hash
19162                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19163                         error "$nr_files files on MDT$stripe_index after split"
19164
19165                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19166                 [ $nr_files -eq $total ] ||
19167                         error "total sub files $nr_files != $total"
19168         done
19169 }
19170 run_test 230q "dir auto split"
19171
19172 test_230r() {
19173         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19174         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19175         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19176                 skip "Need MDS version at least 2.13.54"
19177
19178         # maximum amount of local locks:
19179         # parent striped dir - 2 locks
19180         # new stripe in parent to migrate to - 1 lock
19181         # source and target - 2 locks
19182         # Total 5 locks for regular file
19183         mkdir -p $DIR/$tdir
19184         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19185         touch $DIR/$tdir/dir1/eee
19186
19187         # create 4 hardlink for 4 more locks
19188         # Total: 9 locks > RS_MAX_LOCKS (8)
19189         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19190         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19191         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19192         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19193         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19194         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19195         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19196         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19197
19198         cancel_lru_locks mdc
19199
19200         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19201                 error "migrate dir fails"
19202
19203         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19204 }
19205 run_test 230r "migrate with too many local locks"
19206
19207 test_230s() {
19208         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19209                 skip "Need MDS version at least 2.13.57"
19210
19211         local mdts=$(comma_list $(mdts_nodes))
19212         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19213                                 mdt.*MDT0000.enable_dir_restripe)
19214
19215         stack_trap "do_nodes $mdts $LCTL set_param \
19216                     mdt.*.enable_dir_restripe=$restripe_status"
19217
19218         local st
19219         for st in 0 1; do
19220                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19221                 test_mkdir $DIR/$tdir
19222                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19223                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19224                 rmdir $DIR/$tdir
19225         done
19226 }
19227 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19228
19229 test_231a()
19230 {
19231         # For simplicity this test assumes that max_pages_per_rpc
19232         # is the same across all OSCs
19233         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19234         local bulk_size=$((max_pages * PAGE_SIZE))
19235         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19236                                        head -n 1)
19237
19238         mkdir -p $DIR/$tdir
19239         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19240                 error "failed to set stripe with -S ${brw_size}M option"
19241
19242         # clear the OSC stats
19243         $LCTL set_param osc.*.stats=0 &>/dev/null
19244         stop_writeback
19245
19246         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19247         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19248                 oflag=direct &>/dev/null || error "dd failed"
19249
19250         sync; sleep 1; sync # just to be safe
19251         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19252         if [ x$nrpcs != "x1" ]; then
19253                 $LCTL get_param osc.*.stats
19254                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19255         fi
19256
19257         start_writeback
19258         # Drop the OSC cache, otherwise we will read from it
19259         cancel_lru_locks osc
19260
19261         # clear the OSC stats
19262         $LCTL set_param osc.*.stats=0 &>/dev/null
19263
19264         # Client reads $bulk_size.
19265         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19266                 iflag=direct &>/dev/null || error "dd failed"
19267
19268         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19269         if [ x$nrpcs != "x1" ]; then
19270                 $LCTL get_param osc.*.stats
19271                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19272         fi
19273 }
19274 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19275
19276 test_231b() {
19277         mkdir -p $DIR/$tdir
19278         local i
19279         for i in {0..1023}; do
19280                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19281                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19282                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19283         done
19284         sync
19285 }
19286 run_test 231b "must not assert on fully utilized OST request buffer"
19287
19288 test_232a() {
19289         mkdir -p $DIR/$tdir
19290         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19291
19292         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19293         do_facet ost1 $LCTL set_param fail_loc=0x31c
19294
19295         # ignore dd failure
19296         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19297
19298         do_facet ost1 $LCTL set_param fail_loc=0
19299         umount_client $MOUNT || error "umount failed"
19300         mount_client $MOUNT || error "mount failed"
19301         stop ost1 || error "cannot stop ost1"
19302         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19303 }
19304 run_test 232a "failed lock should not block umount"
19305
19306 test_232b() {
19307         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19308                 skip "Need MDS version at least 2.10.58"
19309
19310         mkdir -p $DIR/$tdir
19311         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19312         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19313         sync
19314         cancel_lru_locks osc
19315
19316         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19317         do_facet ost1 $LCTL set_param fail_loc=0x31c
19318
19319         # ignore failure
19320         $LFS data_version $DIR/$tdir/$tfile || true
19321
19322         do_facet ost1 $LCTL set_param fail_loc=0
19323         umount_client $MOUNT || error "umount failed"
19324         mount_client $MOUNT || error "mount failed"
19325         stop ost1 || error "cannot stop ost1"
19326         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19327 }
19328 run_test 232b "failed data version lock should not block umount"
19329
19330 test_233a() {
19331         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19332                 skip "Need MDS version at least 2.3.64"
19333         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19334
19335         local fid=$($LFS path2fid $MOUNT)
19336
19337         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19338                 error "cannot access $MOUNT using its FID '$fid'"
19339 }
19340 run_test 233a "checking that OBF of the FS root succeeds"
19341
19342 test_233b() {
19343         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19344                 skip "Need MDS version at least 2.5.90"
19345         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19346
19347         local fid=$($LFS path2fid $MOUNT/.lustre)
19348
19349         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19350                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19351
19352         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19353         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19354                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19355 }
19356 run_test 233b "checking that OBF of the FS .lustre succeeds"
19357
19358 test_234() {
19359         local p="$TMP/sanityN-$TESTNAME.parameters"
19360         save_lustre_params client "llite.*.xattr_cache" > $p
19361         lctl set_param llite.*.xattr_cache 1 ||
19362                 skip_env "xattr cache is not supported"
19363
19364         mkdir -p $DIR/$tdir || error "mkdir failed"
19365         touch $DIR/$tdir/$tfile || error "touch failed"
19366         # OBD_FAIL_LLITE_XATTR_ENOMEM
19367         $LCTL set_param fail_loc=0x1405
19368         getfattr -n user.attr $DIR/$tdir/$tfile &&
19369                 error "getfattr should have failed with ENOMEM"
19370         $LCTL set_param fail_loc=0x0
19371         rm -rf $DIR/$tdir
19372
19373         restore_lustre_params < $p
19374         rm -f $p
19375 }
19376 run_test 234 "xattr cache should not crash on ENOMEM"
19377
19378 test_235() {
19379         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19380                 skip "Need MDS version at least 2.4.52"
19381
19382         flock_deadlock $DIR/$tfile
19383         local RC=$?
19384         case $RC in
19385                 0)
19386                 ;;
19387                 124) error "process hangs on a deadlock"
19388                 ;;
19389                 *) error "error executing flock_deadlock $DIR/$tfile"
19390                 ;;
19391         esac
19392 }
19393 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19394
19395 #LU-2935
19396 test_236() {
19397         check_swap_layouts_support
19398
19399         local ref1=/etc/passwd
19400         local ref2=/etc/group
19401         local file1=$DIR/$tdir/f1
19402         local file2=$DIR/$tdir/f2
19403
19404         test_mkdir -c1 $DIR/$tdir
19405         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19406         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19407         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19408         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19409         local fd=$(free_fd)
19410         local cmd="exec $fd<>$file2"
19411         eval $cmd
19412         rm $file2
19413         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19414                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19415         cmd="exec $fd>&-"
19416         eval $cmd
19417         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19418
19419         #cleanup
19420         rm -rf $DIR/$tdir
19421 }
19422 run_test 236 "Layout swap on open unlinked file"
19423
19424 # LU-4659 linkea consistency
19425 test_238() {
19426         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19427                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19428                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19429                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19430
19431         touch $DIR/$tfile
19432         ln $DIR/$tfile $DIR/$tfile.lnk
19433         touch $DIR/$tfile.new
19434         mv $DIR/$tfile.new $DIR/$tfile
19435         local fid1=$($LFS path2fid $DIR/$tfile)
19436         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19437         local path1=$($LFS fid2path $FSNAME "$fid1")
19438         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19439         local path2=$($LFS fid2path $FSNAME "$fid2")
19440         [ $tfile.lnk == $path2 ] ||
19441                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19442         rm -f $DIR/$tfile*
19443 }
19444 run_test 238 "Verify linkea consistency"
19445
19446 test_239A() { # was test_239
19447         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19448                 skip "Need MDS version at least 2.5.60"
19449
19450         local list=$(comma_list $(mdts_nodes))
19451
19452         mkdir -p $DIR/$tdir
19453         createmany -o $DIR/$tdir/f- 5000
19454         unlinkmany $DIR/$tdir/f- 5000
19455         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19456                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19457         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19458                         osp.*MDT*.sync_in_flight" | calc_sum)
19459         [ "$changes" -eq 0 ] || error "$changes not synced"
19460 }
19461 run_test 239A "osp_sync test"
19462
19463 test_239a() { #LU-5297
19464         remote_mds_nodsh && skip "remote MDS with nodsh"
19465
19466         touch $DIR/$tfile
19467         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19468         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19469         chgrp $RUNAS_GID $DIR/$tfile
19470         wait_delete_completed
19471 }
19472 run_test 239a "process invalid osp sync record correctly"
19473
19474 test_239b() { #LU-5297
19475         remote_mds_nodsh && skip "remote MDS with nodsh"
19476
19477         touch $DIR/$tfile1
19478         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19479         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19480         chgrp $RUNAS_GID $DIR/$tfile1
19481         wait_delete_completed
19482         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19483         touch $DIR/$tfile2
19484         chgrp $RUNAS_GID $DIR/$tfile2
19485         wait_delete_completed
19486 }
19487 run_test 239b "process osp sync record with ENOMEM error correctly"
19488
19489 test_240() {
19490         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19491         remote_mds_nodsh && skip "remote MDS with nodsh"
19492
19493         mkdir -p $DIR/$tdir
19494
19495         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19496                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19497         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19498                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19499
19500         umount_client $MOUNT || error "umount failed"
19501         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19502         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19503         mount_client $MOUNT || error "failed to mount client"
19504
19505         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19506         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19507 }
19508 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19509
19510 test_241_bio() {
19511         local count=$1
19512         local bsize=$2
19513
19514         for LOOP in $(seq $count); do
19515                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19516                 cancel_lru_locks $OSC || true
19517         done
19518 }
19519
19520 test_241_dio() {
19521         local count=$1
19522         local bsize=$2
19523
19524         for LOOP in $(seq $1); do
19525                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19526                         2>/dev/null
19527         done
19528 }
19529
19530 test_241a() { # was test_241
19531         local bsize=$PAGE_SIZE
19532
19533         (( bsize < 40960 )) && bsize=40960
19534         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19535         ls -la $DIR/$tfile
19536         cancel_lru_locks $OSC
19537         test_241_bio 1000 $bsize &
19538         PID=$!
19539         test_241_dio 1000 $bsize
19540         wait $PID
19541 }
19542 run_test 241a "bio vs dio"
19543
19544 test_241b() {
19545         local bsize=$PAGE_SIZE
19546
19547         (( bsize < 40960 )) && bsize=40960
19548         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19549         ls -la $DIR/$tfile
19550         test_241_dio 1000 $bsize &
19551         PID=$!
19552         test_241_dio 1000 $bsize
19553         wait $PID
19554 }
19555 run_test 241b "dio vs dio"
19556
19557 test_242() {
19558         remote_mds_nodsh && skip "remote MDS with nodsh"
19559
19560         mkdir -p $DIR/$tdir
19561         touch $DIR/$tdir/$tfile
19562
19563         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19564         do_facet mds1 lctl set_param fail_loc=0x105
19565         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19566
19567         do_facet mds1 lctl set_param fail_loc=0
19568         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19569 }
19570 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19571
19572 test_243()
19573 {
19574         test_mkdir $DIR/$tdir
19575         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19576 }
19577 run_test 243 "various group lock tests"
19578
19579 test_244a()
19580 {
19581         test_mkdir $DIR/$tdir
19582         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19583         sendfile_grouplock $DIR/$tdir/$tfile || \
19584                 error "sendfile+grouplock failed"
19585         rm -rf $DIR/$tdir
19586 }
19587 run_test 244a "sendfile with group lock tests"
19588
19589 test_244b()
19590 {
19591         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19592
19593         local threads=50
19594         local size=$((1024*1024))
19595
19596         test_mkdir $DIR/$tdir
19597         for i in $(seq 1 $threads); do
19598                 local file=$DIR/$tdir/file_$((i / 10))
19599                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19600                 local pids[$i]=$!
19601         done
19602         for i in $(seq 1 $threads); do
19603                 wait ${pids[$i]}
19604         done
19605 }
19606 run_test 244b "multi-threaded write with group lock"
19607
19608 test_245() {
19609         local flagname="multi_mod_rpcs"
19610         local connect_data_name="max_mod_rpcs"
19611         local out
19612
19613         # check if multiple modify RPCs flag is set
19614         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19615                 grep "connect_flags:")
19616         echo "$out"
19617
19618         echo "$out" | grep -qw $flagname
19619         if [ $? -ne 0 ]; then
19620                 echo "connect flag $flagname is not set"
19621                 return
19622         fi
19623
19624         # check if multiple modify RPCs data is set
19625         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19626         echo "$out"
19627
19628         echo "$out" | grep -qw $connect_data_name ||
19629                 error "import should have connect data $connect_data_name"
19630 }
19631 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19632
19633 cleanup_247() {
19634         local submount=$1
19635
19636         trap 0
19637         umount_client $submount
19638         rmdir $submount
19639 }
19640
19641 test_247a() {
19642         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19643                 grep -q subtree ||
19644                 skip_env "Fileset feature is not supported"
19645
19646         local submount=${MOUNT}_$tdir
19647
19648         mkdir $MOUNT/$tdir
19649         mkdir -p $submount || error "mkdir $submount failed"
19650         FILESET="$FILESET/$tdir" mount_client $submount ||
19651                 error "mount $submount failed"
19652         trap "cleanup_247 $submount" EXIT
19653         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19654         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19655                 error "read $MOUNT/$tdir/$tfile failed"
19656         cleanup_247 $submount
19657 }
19658 run_test 247a "mount subdir as fileset"
19659
19660 test_247b() {
19661         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19662                 skip_env "Fileset feature is not supported"
19663
19664         local submount=${MOUNT}_$tdir
19665
19666         rm -rf $MOUNT/$tdir
19667         mkdir -p $submount || error "mkdir $submount failed"
19668         SKIP_FILESET=1
19669         FILESET="$FILESET/$tdir" mount_client $submount &&
19670                 error "mount $submount should fail"
19671         rmdir $submount
19672 }
19673 run_test 247b "mount subdir that dose not exist"
19674
19675 test_247c() {
19676         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19677                 skip_env "Fileset feature is not supported"
19678
19679         local submount=${MOUNT}_$tdir
19680
19681         mkdir -p $MOUNT/$tdir/dir1
19682         mkdir -p $submount || error "mkdir $submount failed"
19683         trap "cleanup_247 $submount" EXIT
19684         FILESET="$FILESET/$tdir" mount_client $submount ||
19685                 error "mount $submount failed"
19686         local fid=$($LFS path2fid $MOUNT/)
19687         $LFS fid2path $submount $fid && error "fid2path should fail"
19688         cleanup_247 $submount
19689 }
19690 run_test 247c "running fid2path outside subdirectory root"
19691
19692 test_247d() {
19693         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19694                 skip "Fileset feature is not supported"
19695
19696         local submount=${MOUNT}_$tdir
19697
19698         mkdir -p $MOUNT/$tdir/dir1
19699         mkdir -p $submount || error "mkdir $submount failed"
19700         FILESET="$FILESET/$tdir" mount_client $submount ||
19701                 error "mount $submount failed"
19702         trap "cleanup_247 $submount" EXIT
19703
19704         local td=$submount/dir1
19705         local fid=$($LFS path2fid $td)
19706         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19707
19708         # check that we get the same pathname back
19709         local rootpath
19710         local found
19711         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19712                 echo "$rootpath $fid"
19713                 found=$($LFS fid2path $rootpath "$fid")
19714                 [ -n "found" ] || error "fid2path should succeed"
19715                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19716         done
19717         # check wrong root path format
19718         rootpath=$submount"_wrong"
19719         found=$($LFS fid2path $rootpath "$fid")
19720         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19721
19722         cleanup_247 $submount
19723 }
19724 run_test 247d "running fid2path inside subdirectory root"
19725
19726 # LU-8037
19727 test_247e() {
19728         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19729                 grep -q subtree ||
19730                 skip "Fileset feature is not supported"
19731
19732         local submount=${MOUNT}_$tdir
19733
19734         mkdir $MOUNT/$tdir
19735         mkdir -p $submount || error "mkdir $submount failed"
19736         FILESET="$FILESET/.." mount_client $submount &&
19737                 error "mount $submount should fail"
19738         rmdir $submount
19739 }
19740 run_test 247e "mount .. as fileset"
19741
19742 test_247f() {
19743         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19744         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19745                 skip "Need at least version 2.13.52"
19746         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
19747                 skip "Need at least version 2.14.50"
19748         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19749                 grep -q subtree ||
19750                 skip "Fileset feature is not supported"
19751
19752         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19753         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19754                 error "mkdir remote failed"
19755         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19756         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
19757                 error "mkdir striped failed"
19758         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19759
19760         local submount=${MOUNT}_$tdir
19761
19762         mkdir -p $submount || error "mkdir $submount failed"
19763         stack_trap "rmdir $submount"
19764
19765         local dir
19766         local stat
19767         local fileset=$FILESET
19768         local mdts=$(comma_list $(mdts_nodes))
19769
19770         stat=$(do_facet mds1 $LCTL get_param -n \
19771                 mdt.*MDT0000.enable_remote_subdir_mount)
19772         stack_trap "do_nodes $mdts $LCTL set_param \
19773                 mdt.*.enable_remote_subdir_mount=$stat"
19774
19775         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
19776         stack_trap "umount_client $submount"
19777         FILESET="$fileset/$tdir/remote" mount_client $submount &&
19778                 error "mount remote dir $dir should fail"
19779
19780         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
19781                 $tdir/striped/. ; do
19782                 FILESET="$fileset/$dir" mount_client $submount ||
19783                         error "mount $dir failed"
19784                 umount_client $submount
19785         done
19786
19787         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
19788         FILESET="$fileset/$tdir/remote" mount_client $submount ||
19789                 error "mount $tdir/remote failed"
19790 }
19791 run_test 247f "mount striped or remote directory as fileset"
19792
19793 test_247g() {
19794         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
19795         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
19796                 skip "Need at least version 2.14.50"
19797
19798         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
19799                 error "mkdir $tdir failed"
19800         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
19801
19802         local submount=${MOUNT}_$tdir
19803
19804         mkdir -p $submount || error "mkdir $submount failed"
19805         stack_trap "rmdir $submount"
19806
19807         FILESET="$fileset/$tdir" mount_client $submount ||
19808                 error "mount $dir failed"
19809         stack_trap "umount $submount"
19810
19811         local mdts=$(comma_list $(mdts_nodes))
19812
19813         local nrpcs
19814
19815         stat $submount > /dev/null
19816         cancel_lru_locks $MDC
19817         stat $submount > /dev/null
19818         stat $submount/$tfile > /dev/null
19819         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
19820         stat $submount/$tfile > /dev/null
19821         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
19822                 awk '/getattr/ {sum += $2} END {print sum}')
19823
19824         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
19825 }
19826 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
19827
19828 test_248a() {
19829         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19830         [ -z "$fast_read_sav" ] && skip "no fast read support"
19831
19832         # create a large file for fast read verification
19833         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19834
19835         # make sure the file is created correctly
19836         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19837                 { rm -f $DIR/$tfile; skip "file creation error"; }
19838
19839         echo "Test 1: verify that fast read is 4 times faster on cache read"
19840
19841         # small read with fast read enabled
19842         $LCTL set_param -n llite.*.fast_read=1
19843         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19844                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19845                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19846         # small read with fast read disabled
19847         $LCTL set_param -n llite.*.fast_read=0
19848         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19849                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19850                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19851
19852         # verify that fast read is 4 times faster for cache read
19853         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19854                 error_not_in_vm "fast read was not 4 times faster: " \
19855                            "$t_fast vs $t_slow"
19856
19857         echo "Test 2: verify the performance between big and small read"
19858         $LCTL set_param -n llite.*.fast_read=1
19859
19860         # 1k non-cache read
19861         cancel_lru_locks osc
19862         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19863                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19864                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19865
19866         # 1M non-cache read
19867         cancel_lru_locks osc
19868         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19869                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19870                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19871
19872         # verify that big IO is not 4 times faster than small IO
19873         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19874                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19875
19876         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19877         rm -f $DIR/$tfile
19878 }
19879 run_test 248a "fast read verification"
19880
19881 test_248b() {
19882         # Default short_io_bytes=16384, try both smaller and larger sizes.
19883         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19884         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19885         echo "bs=53248 count=113 normal buffered write"
19886         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19887                 error "dd of initial data file failed"
19888         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19889
19890         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19891         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19892                 error "dd with sync normal writes failed"
19893         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19894
19895         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19896         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19897                 error "dd with sync small writes failed"
19898         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19899
19900         cancel_lru_locks osc
19901
19902         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19903         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19904         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19905         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19906                 iflag=direct || error "dd with O_DIRECT small read failed"
19907         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19908         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19909                 error "compare $TMP/$tfile.1 failed"
19910
19911         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19912         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19913
19914         # just to see what the maximum tunable value is, and test parsing
19915         echo "test invalid parameter 2MB"
19916         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19917                 error "too-large short_io_bytes allowed"
19918         echo "test maximum parameter 512KB"
19919         # if we can set a larger short_io_bytes, run test regardless of version
19920         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19921                 # older clients may not allow setting it this large, that's OK
19922                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19923                         skip "Need at least client version 2.13.50"
19924                 error "medium short_io_bytes failed"
19925         fi
19926         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19927         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19928
19929         echo "test large parameter 64KB"
19930         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19931         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19932
19933         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19934         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19935                 error "dd with sync large writes failed"
19936         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19937
19938         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19939         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19940         num=$((113 * 4096 / PAGE_SIZE))
19941         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19942         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19943                 error "dd with O_DIRECT large writes failed"
19944         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19945                 error "compare $DIR/$tfile.3 failed"
19946
19947         cancel_lru_locks osc
19948
19949         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19950         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19951                 error "dd with O_DIRECT large read failed"
19952         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19953                 error "compare $TMP/$tfile.2 failed"
19954
19955         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19956         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19957                 error "dd with O_DIRECT large read failed"
19958         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19959                 error "compare $TMP/$tfile.3 failed"
19960 }
19961 run_test 248b "test short_io read and write for both small and large sizes"
19962
19963 test_249() { # LU-7890
19964         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19965                 skip "Need at least version 2.8.54"
19966
19967         rm -f $DIR/$tfile
19968         $LFS setstripe -c 1 $DIR/$tfile
19969         # Offset 2T == 4k * 512M
19970         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19971                 error "dd to 2T offset failed"
19972 }
19973 run_test 249 "Write above 2T file size"
19974
19975 test_250() {
19976         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19977          && skip "no 16TB file size limit on ZFS"
19978
19979         $LFS setstripe -c 1 $DIR/$tfile
19980         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19981         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19982         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19983         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19984                 conv=notrunc,fsync && error "append succeeded"
19985         return 0
19986 }
19987 run_test 250 "Write above 16T limit"
19988
19989 test_251() {
19990         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19991
19992         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19993         #Skip once - writing the first stripe will succeed
19994         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19995         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19996                 error "short write happened"
19997
19998         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19999         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20000                 error "short read happened"
20001
20002         rm -f $DIR/$tfile
20003 }
20004 run_test 251 "Handling short read and write correctly"
20005
20006 test_252() {
20007         remote_mds_nodsh && skip "remote MDS with nodsh"
20008         remote_ost_nodsh && skip "remote OST with nodsh"
20009         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20010                 skip_env "ldiskfs only test"
20011         fi
20012
20013         local tgt
20014         local dev
20015         local out
20016         local uuid
20017         local num
20018         local gen
20019
20020         # check lr_reader on OST0000
20021         tgt=ost1
20022         dev=$(facet_device $tgt)
20023         out=$(do_facet $tgt $LR_READER $dev)
20024         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20025         echo "$out"
20026         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20027         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20028                 error "Invalid uuid returned by $LR_READER on target $tgt"
20029         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20030
20031         # check lr_reader -c on MDT0000
20032         tgt=mds1
20033         dev=$(facet_device $tgt)
20034         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20035                 skip "$LR_READER does not support additional options"
20036         fi
20037         out=$(do_facet $tgt $LR_READER -c $dev)
20038         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20039         echo "$out"
20040         num=$(echo "$out" | grep -c "mdtlov")
20041         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20042                 error "Invalid number of mdtlov clients returned by $LR_READER"
20043         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20044
20045         # check lr_reader -cr on MDT0000
20046         out=$(do_facet $tgt $LR_READER -cr $dev)
20047         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20048         echo "$out"
20049         echo "$out" | grep -q "^reply_data:$" ||
20050                 error "$LR_READER should have returned 'reply_data' section"
20051         num=$(echo "$out" | grep -c "client_generation")
20052         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20053 }
20054 run_test 252 "check lr_reader tool"
20055
20056 test_253() {
20057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20058         remote_mds_nodsh && skip "remote MDS with nodsh"
20059         remote_mgs_nodsh && skip "remote MGS with nodsh"
20060
20061         local ostidx=0
20062         local rc=0
20063         local ost_name=$(ostname_from_index $ostidx)
20064
20065         # on the mdt's osc
20066         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20067         do_facet $SINGLEMDS $LCTL get_param -n \
20068                 osp.$mdtosc_proc1.reserved_mb_high ||
20069                 skip  "remote MDS does not support reserved_mb_high"
20070
20071         rm -rf $DIR/$tdir
20072         wait_mds_ost_sync
20073         wait_delete_completed
20074         mkdir $DIR/$tdir
20075
20076         pool_add $TESTNAME || error "Pool creation failed"
20077         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20078
20079         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20080                 error "Setstripe failed"
20081
20082         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20083
20084         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20085                     grep "watermarks")
20086         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20087
20088         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20089                         osp.$mdtosc_proc1.prealloc_status)
20090         echo "prealloc_status $oa_status"
20091
20092         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20093                 error "File creation should fail"
20094
20095         #object allocation was stopped, but we still able to append files
20096         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20097                 oflag=append || error "Append failed"
20098
20099         rm -f $DIR/$tdir/$tfile.0
20100
20101         # For this test, we want to delete the files we created to go out of
20102         # space but leave the watermark, so we remain nearly out of space
20103         ost_watermarks_enospc_delete_files $tfile $ostidx
20104
20105         wait_delete_completed
20106
20107         sleep_maxage
20108
20109         for i in $(seq 10 12); do
20110                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20111                         2>/dev/null || error "File creation failed after rm"
20112         done
20113
20114         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20115                         osp.$mdtosc_proc1.prealloc_status)
20116         echo "prealloc_status $oa_status"
20117
20118         if (( oa_status != 0 )); then
20119                 error "Object allocation still disable after rm"
20120         fi
20121 }
20122 run_test 253 "Check object allocation limit"
20123
20124 test_254() {
20125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20126         remote_mds_nodsh && skip "remote MDS with nodsh"
20127         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20128                 skip "MDS does not support changelog_size"
20129
20130         local cl_user
20131         local MDT0=$(facet_svc $SINGLEMDS)
20132
20133         changelog_register || error "changelog_register failed"
20134
20135         changelog_clear 0 || error "changelog_clear failed"
20136
20137         local size1=$(do_facet $SINGLEMDS \
20138                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20139         echo "Changelog size $size1"
20140
20141         rm -rf $DIR/$tdir
20142         $LFS mkdir -i 0 $DIR/$tdir
20143         # change something
20144         mkdir -p $DIR/$tdir/pics/2008/zachy
20145         touch $DIR/$tdir/pics/2008/zachy/timestamp
20146         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20147         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20148         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20149         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20150         rm $DIR/$tdir/pics/desktop.jpg
20151
20152         local size2=$(do_facet $SINGLEMDS \
20153                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20154         echo "Changelog size after work $size2"
20155
20156         (( $size2 > $size1 )) ||
20157                 error "new Changelog size=$size2 less than old size=$size1"
20158 }
20159 run_test 254 "Check changelog size"
20160
20161 ladvise_no_type()
20162 {
20163         local type=$1
20164         local file=$2
20165
20166         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20167                 awk -F: '{print $2}' | grep $type > /dev/null
20168         if [ $? -ne 0 ]; then
20169                 return 0
20170         fi
20171         return 1
20172 }
20173
20174 ladvise_no_ioctl()
20175 {
20176         local file=$1
20177
20178         lfs ladvise -a willread $file > /dev/null 2>&1
20179         if [ $? -eq 0 ]; then
20180                 return 1
20181         fi
20182
20183         lfs ladvise -a willread $file 2>&1 |
20184                 grep "Inappropriate ioctl for device" > /dev/null
20185         if [ $? -eq 0 ]; then
20186                 return 0
20187         fi
20188         return 1
20189 }
20190
20191 percent() {
20192         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20193 }
20194
20195 # run a random read IO workload
20196 # usage: random_read_iops <filename> <filesize> <iosize>
20197 random_read_iops() {
20198         local file=$1
20199         local fsize=$2
20200         local iosize=${3:-4096}
20201
20202         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20203                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20204 }
20205
20206 drop_file_oss_cache() {
20207         local file="$1"
20208         local nodes="$2"
20209
20210         $LFS ladvise -a dontneed $file 2>/dev/null ||
20211                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20212 }
20213
20214 ladvise_willread_performance()
20215 {
20216         local repeat=10
20217         local average_origin=0
20218         local average_cache=0
20219         local average_ladvise=0
20220
20221         for ((i = 1; i <= $repeat; i++)); do
20222                 echo "Iter $i/$repeat: reading without willread hint"
20223                 cancel_lru_locks osc
20224                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20225                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20226                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20227                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20228
20229                 cancel_lru_locks osc
20230                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20231                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20232                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20233
20234                 cancel_lru_locks osc
20235                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20236                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20237                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20238                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20239                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20240         done
20241         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20242         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20243         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20244
20245         speedup_cache=$(percent $average_cache $average_origin)
20246         speedup_ladvise=$(percent $average_ladvise $average_origin)
20247
20248         echo "Average uncached read: $average_origin"
20249         echo "Average speedup with OSS cached read: " \
20250                 "$average_cache = +$speedup_cache%"
20251         echo "Average speedup with ladvise willread: " \
20252                 "$average_ladvise = +$speedup_ladvise%"
20253
20254         local lowest_speedup=20
20255         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20256                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20257                         "got $average_cache%. Skipping ladvise willread check."
20258                 return 0
20259         fi
20260
20261         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20262         # it is still good to run until then to exercise 'ladvise willread'
20263         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20264                 [ "$ost1_FSTYPE" = "zfs" ] &&
20265                 echo "osd-zfs does not support dontneed or drop_caches" &&
20266                 return 0
20267
20268         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20269         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20270                 error_not_in_vm "Speedup with willread is less than " \
20271                         "$lowest_speedup%, got $average_ladvise%"
20272 }
20273
20274 test_255a() {
20275         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20276                 skip "lustre < 2.8.54 does not support ladvise "
20277         remote_ost_nodsh && skip "remote OST with nodsh"
20278
20279         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20280
20281         ladvise_no_type willread $DIR/$tfile &&
20282                 skip "willread ladvise is not supported"
20283
20284         ladvise_no_ioctl $DIR/$tfile &&
20285                 skip "ladvise ioctl is not supported"
20286
20287         local size_mb=100
20288         local size=$((size_mb * 1048576))
20289         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20290                 error "dd to $DIR/$tfile failed"
20291
20292         lfs ladvise -a willread $DIR/$tfile ||
20293                 error "Ladvise failed with no range argument"
20294
20295         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20296                 error "Ladvise failed with no -l or -e argument"
20297
20298         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20299                 error "Ladvise failed with only -e argument"
20300
20301         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20302                 error "Ladvise failed with only -l argument"
20303
20304         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20305                 error "End offset should not be smaller than start offset"
20306
20307         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20308                 error "End offset should not be equal to start offset"
20309
20310         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20311                 error "Ladvise failed with overflowing -s argument"
20312
20313         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20314                 error "Ladvise failed with overflowing -e argument"
20315
20316         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20317                 error "Ladvise failed with overflowing -l argument"
20318
20319         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20320                 error "Ladvise succeeded with conflicting -l and -e arguments"
20321
20322         echo "Synchronous ladvise should wait"
20323         local delay=4
20324 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20325         do_nodes $(comma_list $(osts_nodes)) \
20326                 $LCTL set_param fail_val=$delay fail_loc=0x237
20327
20328         local start_ts=$SECONDS
20329         lfs ladvise -a willread $DIR/$tfile ||
20330                 error "Ladvise failed with no range argument"
20331         local end_ts=$SECONDS
20332         local inteval_ts=$((end_ts - start_ts))
20333
20334         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20335                 error "Synchronous advice didn't wait reply"
20336         fi
20337
20338         echo "Asynchronous ladvise shouldn't wait"
20339         local start_ts=$SECONDS
20340         lfs ladvise -a willread -b $DIR/$tfile ||
20341                 error "Ladvise failed with no range argument"
20342         local end_ts=$SECONDS
20343         local inteval_ts=$((end_ts - start_ts))
20344
20345         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20346                 error "Asynchronous advice blocked"
20347         fi
20348
20349         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20350         ladvise_willread_performance
20351 }
20352 run_test 255a "check 'lfs ladvise -a willread'"
20353
20354 facet_meminfo() {
20355         local facet=$1
20356         local info=$2
20357
20358         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20359 }
20360
20361 test_255b() {
20362         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20363                 skip "lustre < 2.8.54 does not support ladvise "
20364         remote_ost_nodsh && skip "remote OST with nodsh"
20365
20366         lfs setstripe -c 1 -i 0 $DIR/$tfile
20367
20368         ladvise_no_type dontneed $DIR/$tfile &&
20369                 skip "dontneed ladvise is not supported"
20370
20371         ladvise_no_ioctl $DIR/$tfile &&
20372                 skip "ladvise ioctl is not supported"
20373
20374         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20375                 [ "$ost1_FSTYPE" = "zfs" ] &&
20376                 skip "zfs-osd does not support 'ladvise dontneed'"
20377
20378         local size_mb=100
20379         local size=$((size_mb * 1048576))
20380         # In order to prevent disturbance of other processes, only check 3/4
20381         # of the memory usage
20382         local kibibytes=$((size_mb * 1024 * 3 / 4))
20383
20384         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20385                 error "dd to $DIR/$tfile failed"
20386
20387         #force write to complete before dropping OST cache & checking memory
20388         sync
20389
20390         local total=$(facet_meminfo ost1 MemTotal)
20391         echo "Total memory: $total KiB"
20392
20393         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20394         local before_read=$(facet_meminfo ost1 Cached)
20395         echo "Cache used before read: $before_read KiB"
20396
20397         lfs ladvise -a willread $DIR/$tfile ||
20398                 error "Ladvise willread failed"
20399         local after_read=$(facet_meminfo ost1 Cached)
20400         echo "Cache used after read: $after_read KiB"
20401
20402         lfs ladvise -a dontneed $DIR/$tfile ||
20403                 error "Ladvise dontneed again failed"
20404         local no_read=$(facet_meminfo ost1 Cached)
20405         echo "Cache used after dontneed ladvise: $no_read KiB"
20406
20407         if [ $total -lt $((before_read + kibibytes)) ]; then
20408                 echo "Memory is too small, abort checking"
20409                 return 0
20410         fi
20411
20412         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20413                 error "Ladvise willread should use more memory" \
20414                         "than $kibibytes KiB"
20415         fi
20416
20417         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20418                 error "Ladvise dontneed should release more memory" \
20419                         "than $kibibytes KiB"
20420         fi
20421 }
20422 run_test 255b "check 'lfs ladvise -a dontneed'"
20423
20424 test_255c() {
20425         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20426                 skip "lustre < 2.10.50 does not support lockahead"
20427
20428         local ost1_imp=$(get_osc_import_name client ost1)
20429         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20430                          cut -d'.' -f2)
20431         local count
20432         local new_count
20433         local difference
20434         local i
20435         local rc
20436
20437         test_mkdir -p $DIR/$tdir
20438         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20439
20440         #test 10 returns only success/failure
20441         i=10
20442         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20443         rc=$?
20444         if [ $rc -eq 255 ]; then
20445                 error "Ladvise test${i} failed, ${rc}"
20446         fi
20447
20448         #test 11 counts lock enqueue requests, all others count new locks
20449         i=11
20450         count=$(do_facet ost1 \
20451                 $LCTL get_param -n ost.OSS.ost.stats)
20452         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20453
20454         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20455         rc=$?
20456         if [ $rc -eq 255 ]; then
20457                 error "Ladvise test${i} failed, ${rc}"
20458         fi
20459
20460         new_count=$(do_facet ost1 \
20461                 $LCTL get_param -n ost.OSS.ost.stats)
20462         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20463                    awk '{ print $2 }')
20464
20465         difference="$((new_count - count))"
20466         if [ $difference -ne $rc ]; then
20467                 error "Ladvise test${i}, bad enqueue count, returned " \
20468                       "${rc}, actual ${difference}"
20469         fi
20470
20471         for i in $(seq 12 21); do
20472                 # If we do not do this, we run the risk of having too many
20473                 # locks and starting lock cancellation while we are checking
20474                 # lock counts.
20475                 cancel_lru_locks osc
20476
20477                 count=$($LCTL get_param -n \
20478                        ldlm.namespaces.$imp_name.lock_unused_count)
20479
20480                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20481                 rc=$?
20482                 if [ $rc -eq 255 ]; then
20483                         error "Ladvise test ${i} failed, ${rc}"
20484                 fi
20485
20486                 new_count=$($LCTL get_param -n \
20487                        ldlm.namespaces.$imp_name.lock_unused_count)
20488                 difference="$((new_count - count))"
20489
20490                 # Test 15 output is divided by 100 to map down to valid return
20491                 if [ $i -eq 15 ]; then
20492                         rc="$((rc * 100))"
20493                 fi
20494
20495                 if [ $difference -ne $rc ]; then
20496                         error "Ladvise test ${i}, bad lock count, returned " \
20497                               "${rc}, actual ${difference}"
20498                 fi
20499         done
20500
20501         #test 22 returns only success/failure
20502         i=22
20503         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20504         rc=$?
20505         if [ $rc -eq 255 ]; then
20506                 error "Ladvise test${i} failed, ${rc}"
20507         fi
20508 }
20509 run_test 255c "suite of ladvise lockahead tests"
20510
20511 test_256() {
20512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20513         remote_mds_nodsh && skip "remote MDS with nodsh"
20514         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20515         changelog_users $SINGLEMDS | grep "^cl" &&
20516                 skip "active changelog user"
20517
20518         local cl_user
20519         local cat_sl
20520         local mdt_dev
20521
20522         mdt_dev=$(mdsdevname 1)
20523         echo $mdt_dev
20524
20525         changelog_register || error "changelog_register failed"
20526
20527         rm -rf $DIR/$tdir
20528         mkdir -p $DIR/$tdir
20529
20530         changelog_clear 0 || error "changelog_clear failed"
20531
20532         # change something
20533         touch $DIR/$tdir/{1..10}
20534
20535         # stop the MDT
20536         stop $SINGLEMDS || error "Fail to stop MDT"
20537
20538         # remount the MDT
20539
20540         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20541
20542         #after mount new plainllog is used
20543         touch $DIR/$tdir/{11..19}
20544         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20545         stack_trap "rm -f $tmpfile"
20546         cat_sl=$(do_facet $SINGLEMDS "sync; \
20547                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20548                  llog_reader $tmpfile | grep -c type=1064553b")
20549         do_facet $SINGLEMDS llog_reader $tmpfile
20550
20551         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20552
20553         changelog_clear 0 || error "changelog_clear failed"
20554
20555         cat_sl=$(do_facet $SINGLEMDS "sync; \
20556                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20557                  llog_reader $tmpfile | grep -c type=1064553b")
20558
20559         if (( cat_sl == 2 )); then
20560                 error "Empty plain llog was not deleted from changelog catalog"
20561         elif (( cat_sl != 1 )); then
20562                 error "Active plain llog shouldn't be deleted from catalog"
20563         fi
20564 }
20565 run_test 256 "Check llog delete for empty and not full state"
20566
20567 test_257() {
20568         remote_mds_nodsh && skip "remote MDS with nodsh"
20569         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20570                 skip "Need MDS version at least 2.8.55"
20571
20572         test_mkdir $DIR/$tdir
20573
20574         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20575                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20576         stat $DIR/$tdir
20577
20578 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20579         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20580         local facet=mds$((mdtidx + 1))
20581         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20582         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20583
20584         stop $facet || error "stop MDS failed"
20585         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20586                 error "start MDS fail"
20587         wait_recovery_complete $facet
20588 }
20589 run_test 257 "xattr locks are not lost"
20590
20591 # Verify we take the i_mutex when security requires it
20592 test_258a() {
20593 #define OBD_FAIL_IMUTEX_SEC 0x141c
20594         $LCTL set_param fail_loc=0x141c
20595         touch $DIR/$tfile
20596         chmod u+s $DIR/$tfile
20597         chmod a+rwx $DIR/$tfile
20598         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20599         RC=$?
20600         if [ $RC -ne 0 ]; then
20601                 error "error, failed to take i_mutex, rc=$?"
20602         fi
20603         rm -f $DIR/$tfile
20604 }
20605 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20606
20607 # Verify we do NOT take the i_mutex in the normal case
20608 test_258b() {
20609 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20610         $LCTL set_param fail_loc=0x141d
20611         touch $DIR/$tfile
20612         chmod a+rwx $DIR
20613         chmod a+rw $DIR/$tfile
20614         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20615         RC=$?
20616         if [ $RC -ne 0 ]; then
20617                 error "error, took i_mutex unnecessarily, rc=$?"
20618         fi
20619         rm -f $DIR/$tfile
20620
20621 }
20622 run_test 258b "verify i_mutex security behavior"
20623
20624 test_259() {
20625         local file=$DIR/$tfile
20626         local before
20627         local after
20628
20629         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20630
20631         stack_trap "rm -f $file" EXIT
20632
20633         wait_delete_completed
20634         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20635         echo "before: $before"
20636
20637         $LFS setstripe -i 0 -c 1 $file
20638         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20639         sync_all_data
20640         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20641         echo "after write: $after"
20642
20643 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20644         do_facet ost1 $LCTL set_param fail_loc=0x2301
20645         $TRUNCATE $file 0
20646         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20647         echo "after truncate: $after"
20648
20649         stop ost1
20650         do_facet ost1 $LCTL set_param fail_loc=0
20651         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20652         sleep 2
20653         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20654         echo "after restart: $after"
20655         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20656                 error "missing truncate?"
20657
20658         return 0
20659 }
20660 run_test 259 "crash at delayed truncate"
20661
20662 test_260() {
20663 #define OBD_FAIL_MDC_CLOSE               0x806
20664         $LCTL set_param fail_loc=0x80000806
20665         touch $DIR/$tfile
20666
20667 }
20668 run_test 260 "Check mdc_close fail"
20669
20670 ### Data-on-MDT sanity tests ###
20671 test_270a() {
20672         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20673                 skip "Need MDS version at least 2.10.55 for DoM"
20674
20675         # create DoM file
20676         local dom=$DIR/$tdir/dom_file
20677         local tmp=$DIR/$tdir/tmp_file
20678
20679         mkdir -p $DIR/$tdir
20680
20681         # basic checks for DoM component creation
20682         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20683                 error "Can set MDT layout to non-first entry"
20684
20685         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20686                 error "Can define multiple entries as MDT layout"
20687
20688         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20689
20690         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20691         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20692         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20693
20694         local mdtidx=$($LFS getstripe -m $dom)
20695         local mdtname=MDT$(printf %04x $mdtidx)
20696         local facet=mds$((mdtidx + 1))
20697         local space_check=1
20698
20699         # Skip free space checks with ZFS
20700         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20701
20702         # write
20703         sync
20704         local size_tmp=$((65536 * 3))
20705         local mdtfree1=$(do_facet $facet \
20706                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20707
20708         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20709         # check also direct IO along write
20710         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20711         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20712         sync
20713         cmp $tmp $dom || error "file data is different"
20714         [ $(stat -c%s $dom) == $size_tmp ] ||
20715                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20716         if [ $space_check == 1 ]; then
20717                 local mdtfree2=$(do_facet $facet \
20718                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20719
20720                 # increase in usage from by $size_tmp
20721                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20722                         error "MDT free space wrong after write: " \
20723                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20724         fi
20725
20726         # truncate
20727         local size_dom=10000
20728
20729         $TRUNCATE $dom $size_dom
20730         [ $(stat -c%s $dom) == $size_dom ] ||
20731                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20732         if [ $space_check == 1 ]; then
20733                 mdtfree1=$(do_facet $facet \
20734                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20735                 # decrease in usage from $size_tmp to new $size_dom
20736                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20737                   $(((size_tmp - size_dom) / 1024)) ] ||
20738                         error "MDT free space is wrong after truncate: " \
20739                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20740         fi
20741
20742         # append
20743         cat $tmp >> $dom
20744         sync
20745         size_dom=$((size_dom + size_tmp))
20746         [ $(stat -c%s $dom) == $size_dom ] ||
20747                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20748         if [ $space_check == 1 ]; then
20749                 mdtfree2=$(do_facet $facet \
20750                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20751                 # increase in usage by $size_tmp from previous
20752                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20753                         error "MDT free space is wrong after append: " \
20754                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20755         fi
20756
20757         # delete
20758         rm $dom
20759         if [ $space_check == 1 ]; then
20760                 mdtfree1=$(do_facet $facet \
20761                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20762                 # decrease in usage by $size_dom from previous
20763                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20764                         error "MDT free space is wrong after removal: " \
20765                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20766         fi
20767
20768         # combined striping
20769         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20770                 error "Can't create DoM + OST striping"
20771
20772         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20773         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20774         # check also direct IO along write
20775         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20776         sync
20777         cmp $tmp $dom || error "file data is different"
20778         [ $(stat -c%s $dom) == $size_tmp ] ||
20779                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20780         rm $dom $tmp
20781
20782         return 0
20783 }
20784 run_test 270a "DoM: basic functionality tests"
20785
20786 test_270b() {
20787         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20788                 skip "Need MDS version at least 2.10.55"
20789
20790         local dom=$DIR/$tdir/dom_file
20791         local max_size=1048576
20792
20793         mkdir -p $DIR/$tdir
20794         $LFS setstripe -E $max_size -L mdt $dom
20795
20796         # truncate over the limit
20797         $TRUNCATE $dom $(($max_size + 1)) &&
20798                 error "successful truncate over the maximum size"
20799         # write over the limit
20800         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20801                 error "successful write over the maximum size"
20802         # append over the limit
20803         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20804         echo "12345" >> $dom && error "successful append over the maximum size"
20805         rm $dom
20806
20807         return 0
20808 }
20809 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20810
20811 test_270c() {
20812         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20813                 skip "Need MDS version at least 2.10.55"
20814
20815         mkdir -p $DIR/$tdir
20816         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20817
20818         # check files inherit DoM EA
20819         touch $DIR/$tdir/first
20820         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20821                 error "bad pattern"
20822         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20823                 error "bad stripe count"
20824         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20825                 error "bad stripe size"
20826
20827         # check directory inherits DoM EA and uses it as default
20828         mkdir $DIR/$tdir/subdir
20829         touch $DIR/$tdir/subdir/second
20830         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20831                 error "bad pattern in sub-directory"
20832         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20833                 error "bad stripe count in sub-directory"
20834         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20835                 error "bad stripe size in sub-directory"
20836         return 0
20837 }
20838 run_test 270c "DoM: DoM EA inheritance tests"
20839
20840 test_270d() {
20841         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20842                 skip "Need MDS version at least 2.10.55"
20843
20844         mkdir -p $DIR/$tdir
20845         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20846
20847         # inherit default DoM striping
20848         mkdir $DIR/$tdir/subdir
20849         touch $DIR/$tdir/subdir/f1
20850
20851         # change default directory striping
20852         $LFS setstripe -c 1 $DIR/$tdir/subdir
20853         touch $DIR/$tdir/subdir/f2
20854         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20855                 error "wrong default striping in file 2"
20856         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20857                 error "bad pattern in file 2"
20858         return 0
20859 }
20860 run_test 270d "DoM: change striping from DoM to RAID0"
20861
20862 test_270e() {
20863         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20864                 skip "Need MDS version at least 2.10.55"
20865
20866         mkdir -p $DIR/$tdir/dom
20867         mkdir -p $DIR/$tdir/norm
20868         DOMFILES=20
20869         NORMFILES=10
20870         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20871         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20872
20873         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20874         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20875
20876         # find DoM files by layout
20877         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20878         [ $NUM -eq  $DOMFILES ] ||
20879                 error "lfs find -L: found $NUM, expected $DOMFILES"
20880         echo "Test 1: lfs find 20 DOM files by layout: OK"
20881
20882         # there should be 1 dir with default DOM striping
20883         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20884         [ $NUM -eq  1 ] ||
20885                 error "lfs find -L: found $NUM, expected 1 dir"
20886         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20887
20888         # find DoM files by stripe size
20889         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20890         [ $NUM -eq  $DOMFILES ] ||
20891                 error "lfs find -S: found $NUM, expected $DOMFILES"
20892         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20893
20894         # find files by stripe offset except DoM files
20895         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20896         [ $NUM -eq  $NORMFILES ] ||
20897                 error "lfs find -i: found $NUM, expected $NORMFILES"
20898         echo "Test 5: lfs find no DOM files by stripe index: OK"
20899         return 0
20900 }
20901 run_test 270e "DoM: lfs find with DoM files test"
20902
20903 test_270f() {
20904         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20905                 skip "Need MDS version at least 2.10.55"
20906
20907         local mdtname=${FSNAME}-MDT0000-mdtlov
20908         local dom=$DIR/$tdir/dom_file
20909         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20910                                                 lod.$mdtname.dom_stripesize)
20911         local dom_limit=131072
20912
20913         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20914         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20915                                                 lod.$mdtname.dom_stripesize)
20916         [ ${dom_limit} -eq ${dom_current} ] ||
20917                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20918
20919         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20920         $LFS setstripe -d $DIR/$tdir
20921         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20922                 error "Can't set directory default striping"
20923
20924         # exceed maximum stripe size
20925         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20926                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20927         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20928                 error "Able to create DoM component size more than LOD limit"
20929
20930         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20931         dom_current=$(do_facet mds1 $LCTL get_param -n \
20932                                                 lod.$mdtname.dom_stripesize)
20933         [ 0 -eq ${dom_current} ] ||
20934                 error "Can't set zero DoM stripe limit"
20935         rm $dom
20936
20937         # attempt to create DoM file on server with disabled DoM should
20938         # remove DoM entry from layout and be succeed
20939         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20940                 error "Can't create DoM file (DoM is disabled)"
20941         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20942                 error "File has DoM component while DoM is disabled"
20943         rm $dom
20944
20945         # attempt to create DoM file with only DoM stripe should return error
20946         $LFS setstripe -E $dom_limit -L mdt $dom &&
20947                 error "Able to create DoM-only file while DoM is disabled"
20948
20949         # too low values to be aligned with smallest stripe size 64K
20950         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20951         dom_current=$(do_facet mds1 $LCTL get_param -n \
20952                                                 lod.$mdtname.dom_stripesize)
20953         [ 30000 -eq ${dom_current} ] &&
20954                 error "Can set too small DoM stripe limit"
20955
20956         # 64K is a minimal stripe size in Lustre, expect limit of that size
20957         [ 65536 -eq ${dom_current} ] ||
20958                 error "Limit is not set to 64K but ${dom_current}"
20959
20960         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20961         dom_current=$(do_facet mds1 $LCTL get_param -n \
20962                                                 lod.$mdtname.dom_stripesize)
20963         echo $dom_current
20964         [ 2147483648 -eq ${dom_current} ] &&
20965                 error "Can set too large DoM stripe limit"
20966
20967         do_facet mds1 $LCTL set_param -n \
20968                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20969         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20970                 error "Can't create DoM component size after limit change"
20971         do_facet mds1 $LCTL set_param -n \
20972                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20973         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20974                 error "Can't create DoM file after limit decrease"
20975         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20976                 error "Can create big DoM component after limit decrease"
20977         touch ${dom}_def ||
20978                 error "Can't create file with old default layout"
20979
20980         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20981         return 0
20982 }
20983 run_test 270f "DoM: maximum DoM stripe size checks"
20984
20985 test_270g() {
20986         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20987                 skip "Need MDS version at least 2.13.52"
20988         local dom=$DIR/$tdir/$tfile
20989
20990         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20991         local lodname=${FSNAME}-MDT0000-mdtlov
20992
20993         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20994         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20995         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20996         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20997
20998         local dom_limit=1024
20999         local dom_threshold="50%"
21000
21001         $LFS setstripe -d $DIR/$tdir
21002         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21003                 error "Can't set directory default striping"
21004
21005         do_facet mds1 $LCTL set_param -n \
21006                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21007         # set 0 threshold and create DOM file to change tunable stripesize
21008         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21009         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21010                 error "Failed to create $dom file"
21011         # now tunable dom_cur_stripesize should reach maximum
21012         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21013                                         lod.${lodname}.dom_stripesize_cur_kb)
21014         [[ $dom_current == $dom_limit ]] ||
21015                 error "Current DOM stripesize is not maximum"
21016         rm $dom
21017
21018         # set threshold for further tests
21019         do_facet mds1 $LCTL set_param -n \
21020                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21021         echo "DOM threshold is $dom_threshold free space"
21022         local dom_def
21023         local dom_set
21024         # Spoof bfree to exceed threshold
21025         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21026         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21027         for spfree in 40 20 0 15 30 55; do
21028                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21029                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21030                         error "Failed to create $dom file"
21031                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21032                                         lod.${lodname}.dom_stripesize_cur_kb)
21033                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21034                 [[ $dom_def != $dom_current ]] ||
21035                         error "Default stripe size was not changed"
21036                 if [[ $spfree > 0 ]] ; then
21037                         dom_set=$($LFS getstripe -S $dom)
21038                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21039                                 error "DOM component size is still old"
21040                 else
21041                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21042                                 error "DoM component is set with no free space"
21043                 fi
21044                 rm $dom
21045                 dom_current=$dom_def
21046         done
21047 }
21048 run_test 270g "DoM: default DoM stripe size depends on free space"
21049
21050 test_270h() {
21051         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21052                 skip "Need MDS version at least 2.13.53"
21053
21054         local mdtname=${FSNAME}-MDT0000-mdtlov
21055         local dom=$DIR/$tdir/$tfile
21056         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21057
21058         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21059         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21060
21061         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21062         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21063                 error "can't create OST file"
21064         # mirrored file with DOM entry in the second mirror
21065         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21066                 error "can't create mirror with DoM component"
21067
21068         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21069
21070         # DOM component in the middle and has other enries in the same mirror,
21071         # should succeed but lost DoM component
21072         $LFS setstripe --copy=${dom}_1 $dom ||
21073                 error "Can't create file from OST|DOM mirror layout"
21074         # check new file has no DoM layout after all
21075         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21076                 error "File has DoM component while DoM is disabled"
21077 }
21078 run_test 270h "DoM: DoM stripe removal when disabled on server"
21079
21080 test_271a() {
21081         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21082                 skip "Need MDS version at least 2.10.55"
21083
21084         local dom=$DIR/$tdir/dom
21085
21086         mkdir -p $DIR/$tdir
21087
21088         $LFS setstripe -E 1024K -L mdt $dom
21089
21090         lctl set_param -n mdc.*.stats=clear
21091         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21092         cat $dom > /dev/null
21093         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21094         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21095         ls $dom
21096         rm -f $dom
21097 }
21098 run_test 271a "DoM: data is cached for read after write"
21099
21100 test_271b() {
21101         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21102                 skip "Need MDS version at least 2.10.55"
21103
21104         local dom=$DIR/$tdir/dom
21105
21106         mkdir -p $DIR/$tdir
21107
21108         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21109
21110         lctl set_param -n mdc.*.stats=clear
21111         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21112         cancel_lru_locks mdc
21113         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21114         # second stat to check size is cached on client
21115         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21116         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21117         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21118         rm -f $dom
21119 }
21120 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21121
21122 test_271ba() {
21123         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21124                 skip "Need MDS version at least 2.10.55"
21125
21126         local dom=$DIR/$tdir/dom
21127
21128         mkdir -p $DIR/$tdir
21129
21130         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21131
21132         lctl set_param -n mdc.*.stats=clear
21133         lctl set_param -n osc.*.stats=clear
21134         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21135         cancel_lru_locks mdc
21136         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21137         # second stat to check size is cached on client
21138         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21139         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21140         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21141         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21142         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21143         rm -f $dom
21144 }
21145 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21146
21147
21148 get_mdc_stats() {
21149         local mdtidx=$1
21150         local param=$2
21151         local mdt=MDT$(printf %04x $mdtidx)
21152
21153         if [ -z $param ]; then
21154                 lctl get_param -n mdc.*$mdt*.stats
21155         else
21156                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21157         fi
21158 }
21159
21160 test_271c() {
21161         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21162                 skip "Need MDS version at least 2.10.55"
21163
21164         local dom=$DIR/$tdir/dom
21165
21166         mkdir -p $DIR/$tdir
21167
21168         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21169
21170         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21171         local facet=mds$((mdtidx + 1))
21172
21173         cancel_lru_locks mdc
21174         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21175         createmany -o $dom 1000
21176         lctl set_param -n mdc.*.stats=clear
21177         smalliomany -w $dom 1000 200
21178         get_mdc_stats $mdtidx
21179         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21180         # Each file has 1 open, 1 IO enqueues, total 2000
21181         # but now we have also +1 getxattr for security.capability, total 3000
21182         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21183         unlinkmany $dom 1000
21184
21185         cancel_lru_locks mdc
21186         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21187         createmany -o $dom 1000
21188         lctl set_param -n mdc.*.stats=clear
21189         smalliomany -w $dom 1000 200
21190         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21191         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21192         # for OPEN and IO lock.
21193         [ $((enq - enq_2)) -ge 1000 ] ||
21194                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21195         unlinkmany $dom 1000
21196         return 0
21197 }
21198 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21199
21200 cleanup_271def_tests() {
21201         trap 0
21202         rm -f $1
21203 }
21204
21205 test_271d() {
21206         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21207                 skip "Need MDS version at least 2.10.57"
21208
21209         local dom=$DIR/$tdir/dom
21210         local tmp=$TMP/$tfile
21211         trap "cleanup_271def_tests $tmp" EXIT
21212
21213         mkdir -p $DIR/$tdir
21214
21215         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21216
21217         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21218
21219         cancel_lru_locks mdc
21220         dd if=/dev/urandom of=$tmp bs=1000 count=1
21221         dd if=$tmp of=$dom bs=1000 count=1
21222         cancel_lru_locks mdc
21223
21224         cat /etc/hosts >> $tmp
21225         lctl set_param -n mdc.*.stats=clear
21226
21227         # append data to the same file it should update local page
21228         echo "Append to the same page"
21229         cat /etc/hosts >> $dom
21230         local num=$(get_mdc_stats $mdtidx ost_read)
21231         local ra=$(get_mdc_stats $mdtidx req_active)
21232         local rw=$(get_mdc_stats $mdtidx req_waittime)
21233
21234         [ -z $num ] || error "$num READ RPC occured"
21235         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21236         echo "... DONE"
21237
21238         # compare content
21239         cmp $tmp $dom || error "file miscompare"
21240
21241         cancel_lru_locks mdc
21242         lctl set_param -n mdc.*.stats=clear
21243
21244         echo "Open and read file"
21245         cat $dom > /dev/null
21246         local num=$(get_mdc_stats $mdtidx ost_read)
21247         local ra=$(get_mdc_stats $mdtidx req_active)
21248         local rw=$(get_mdc_stats $mdtidx req_waittime)
21249
21250         [ -z $num ] || error "$num READ RPC occured"
21251         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21252         echo "... DONE"
21253
21254         # compare content
21255         cmp $tmp $dom || error "file miscompare"
21256
21257         return 0
21258 }
21259 run_test 271d "DoM: read on open (1K file in reply buffer)"
21260
21261 test_271f() {
21262         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21263                 skip "Need MDS version at least 2.10.57"
21264
21265         local dom=$DIR/$tdir/dom
21266         local tmp=$TMP/$tfile
21267         trap "cleanup_271def_tests $tmp" EXIT
21268
21269         mkdir -p $DIR/$tdir
21270
21271         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21272
21273         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21274
21275         cancel_lru_locks mdc
21276         dd if=/dev/urandom of=$tmp bs=265000 count=1
21277         dd if=$tmp of=$dom bs=265000 count=1
21278         cancel_lru_locks mdc
21279         cat /etc/hosts >> $tmp
21280         lctl set_param -n mdc.*.stats=clear
21281
21282         echo "Append to the same page"
21283         cat /etc/hosts >> $dom
21284         local num=$(get_mdc_stats $mdtidx ost_read)
21285         local ra=$(get_mdc_stats $mdtidx req_active)
21286         local rw=$(get_mdc_stats $mdtidx req_waittime)
21287
21288         [ -z $num ] || error "$num READ RPC occured"
21289         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21290         echo "... DONE"
21291
21292         # compare content
21293         cmp $tmp $dom || error "file miscompare"
21294
21295         cancel_lru_locks mdc
21296         lctl set_param -n mdc.*.stats=clear
21297
21298         echo "Open and read file"
21299         cat $dom > /dev/null
21300         local num=$(get_mdc_stats $mdtidx ost_read)
21301         local ra=$(get_mdc_stats $mdtidx req_active)
21302         local rw=$(get_mdc_stats $mdtidx req_waittime)
21303
21304         [ -z $num ] && num=0
21305         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21306         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21307         echo "... DONE"
21308
21309         # compare content
21310         cmp $tmp $dom || error "file miscompare"
21311
21312         return 0
21313 }
21314 run_test 271f "DoM: read on open (200K file and read tail)"
21315
21316 test_271g() {
21317         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21318                 skip "Skipping due to old client or server version"
21319
21320         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21321         # to get layout
21322         $CHECKSTAT -t file $DIR1/$tfile
21323
21324         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21325         MULTIOP_PID=$!
21326         sleep 1
21327         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21328         $LCTL set_param fail_loc=0x80000314
21329         rm $DIR1/$tfile || error "Unlink fails"
21330         RC=$?
21331         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21332         [ $RC -eq 0 ] || error "Failed write to stale object"
21333 }
21334 run_test 271g "Discard DoM data vs client flush race"
21335
21336 test_272a() {
21337         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21338                 skip "Need MDS version at least 2.11.50"
21339
21340         local dom=$DIR/$tdir/dom
21341         mkdir -p $DIR/$tdir
21342
21343         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21344         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21345                 error "failed to write data into $dom"
21346         local old_md5=$(md5sum $dom)
21347
21348         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21349                 error "failed to migrate to the same DoM component"
21350
21351         local new_md5=$(md5sum $dom)
21352
21353         [ "$old_md5" == "$new_md5" ] ||
21354                 error "md5sum differ: $old_md5, $new_md5"
21355
21356         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21357                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21358 }
21359 run_test 272a "DoM migration: new layout with the same DOM component"
21360
21361 test_272b() {
21362         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21363                 skip "Need MDS version at least 2.11.50"
21364
21365         local dom=$DIR/$tdir/dom
21366         mkdir -p $DIR/$tdir
21367         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21368
21369         local mdtidx=$($LFS getstripe -m $dom)
21370         local mdtname=MDT$(printf %04x $mdtidx)
21371         local facet=mds$((mdtidx + 1))
21372
21373         local mdtfree1=$(do_facet $facet \
21374                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21375         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21376                 error "failed to write data into $dom"
21377         local old_md5=$(md5sum $dom)
21378         cancel_lru_locks mdc
21379         local mdtfree1=$(do_facet $facet \
21380                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21381
21382         $LFS migrate -c2 $dom ||
21383                 error "failed to migrate to the new composite layout"
21384         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21385                 error "MDT stripe was not removed"
21386
21387         cancel_lru_locks mdc
21388         local new_md5=$(md5sum $dom)
21389         [ "$old_md5" == "$new_md5" ] ||
21390                 error "$old_md5 != $new_md5"
21391
21392         # Skip free space checks with ZFS
21393         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21394                 local mdtfree2=$(do_facet $facet \
21395                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21396                 [ $mdtfree2 -gt $mdtfree1 ] ||
21397                         error "MDT space is not freed after migration"
21398         fi
21399         return 0
21400 }
21401 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21402
21403 test_272c() {
21404         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21405                 skip "Need MDS version at least 2.11.50"
21406
21407         local dom=$DIR/$tdir/$tfile
21408         mkdir -p $DIR/$tdir
21409         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21410
21411         local mdtidx=$($LFS getstripe -m $dom)
21412         local mdtname=MDT$(printf %04x $mdtidx)
21413         local facet=mds$((mdtidx + 1))
21414
21415         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21416                 error "failed to write data into $dom"
21417         local old_md5=$(md5sum $dom)
21418         cancel_lru_locks mdc
21419         local mdtfree1=$(do_facet $facet \
21420                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21421
21422         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21423                 error "failed to migrate to the new composite layout"
21424         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21425                 error "MDT stripe was not removed"
21426
21427         cancel_lru_locks mdc
21428         local new_md5=$(md5sum $dom)
21429         [ "$old_md5" == "$new_md5" ] ||
21430                 error "$old_md5 != $new_md5"
21431
21432         # Skip free space checks with ZFS
21433         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21434                 local mdtfree2=$(do_facet $facet \
21435                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21436                 [ $mdtfree2 -gt $mdtfree1 ] ||
21437                         error "MDS space is not freed after migration"
21438         fi
21439         return 0
21440 }
21441 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21442
21443 test_272d() {
21444         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21445                 skip "Need MDS version at least 2.12.55"
21446
21447         local dom=$DIR/$tdir/$tfile
21448         mkdir -p $DIR/$tdir
21449         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21450
21451         local mdtidx=$($LFS getstripe -m $dom)
21452         local mdtname=MDT$(printf %04x $mdtidx)
21453         local facet=mds$((mdtidx + 1))
21454
21455         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21456                 error "failed to write data into $dom"
21457         local old_md5=$(md5sum $dom)
21458         cancel_lru_locks mdc
21459         local mdtfree1=$(do_facet $facet \
21460                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21461
21462         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21463                 error "failed mirroring to the new composite layout"
21464         $LFS mirror resync $dom ||
21465                 error "failed mirror resync"
21466         $LFS mirror split --mirror-id 1 -d $dom ||
21467                 error "failed mirror split"
21468
21469         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21470                 error "MDT stripe was not removed"
21471
21472         cancel_lru_locks mdc
21473         local new_md5=$(md5sum $dom)
21474         [ "$old_md5" == "$new_md5" ] ||
21475                 error "$old_md5 != $new_md5"
21476
21477         # Skip free space checks with ZFS
21478         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21479                 local mdtfree2=$(do_facet $facet \
21480                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21481                 [ $mdtfree2 -gt $mdtfree1 ] ||
21482                         error "MDS space is not freed after DOM mirror deletion"
21483         fi
21484         return 0
21485 }
21486 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21487
21488 test_272e() {
21489         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21490                 skip "Need MDS version at least 2.12.55"
21491
21492         local dom=$DIR/$tdir/$tfile
21493         mkdir -p $DIR/$tdir
21494         $LFS setstripe -c 2 $dom
21495
21496         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21497                 error "failed to write data into $dom"
21498         local old_md5=$(md5sum $dom)
21499         cancel_lru_locks mdc
21500
21501         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21502                 error "failed mirroring to the DOM layout"
21503         $LFS mirror resync $dom ||
21504                 error "failed mirror resync"
21505         $LFS mirror split --mirror-id 1 -d $dom ||
21506                 error "failed mirror split"
21507
21508         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21509                 error "MDT stripe was not removed"
21510
21511         cancel_lru_locks mdc
21512         local new_md5=$(md5sum $dom)
21513         [ "$old_md5" == "$new_md5" ] ||
21514                 error "$old_md5 != $new_md5"
21515
21516         return 0
21517 }
21518 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21519
21520 test_272f() {
21521         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21522                 skip "Need MDS version at least 2.12.55"
21523
21524         local dom=$DIR/$tdir/$tfile
21525         mkdir -p $DIR/$tdir
21526         $LFS setstripe -c 2 $dom
21527
21528         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21529                 error "failed to write data into $dom"
21530         local old_md5=$(md5sum $dom)
21531         cancel_lru_locks mdc
21532
21533         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21534                 error "failed migrating to the DOM file"
21535
21536         cancel_lru_locks mdc
21537         local new_md5=$(md5sum $dom)
21538         [ "$old_md5" != "$new_md5" ] &&
21539                 error "$old_md5 != $new_md5"
21540
21541         return 0
21542 }
21543 run_test 272f "DoM migration: OST-striped file to DOM file"
21544
21545 test_273a() {
21546         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21547                 skip "Need MDS version at least 2.11.50"
21548
21549         # Layout swap cannot be done if either file has DOM component,
21550         # this will never be supported, migration should be used instead
21551
21552         local dom=$DIR/$tdir/$tfile
21553         mkdir -p $DIR/$tdir
21554
21555         $LFS setstripe -c2 ${dom}_plain
21556         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21557         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21558                 error "can swap layout with DoM component"
21559         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21560                 error "can swap layout with DoM component"
21561
21562         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21563         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21564                 error "can swap layout with DoM component"
21565         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21566                 error "can swap layout with DoM component"
21567         return 0
21568 }
21569 run_test 273a "DoM: layout swapping should fail with DOM"
21570
21571 test_273b() {
21572         mkdir -p $DIR/$tdir
21573         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
21574
21575 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
21576         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
21577
21578         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
21579 }
21580 run_test 273b "DoM: race writeback and object destroy"
21581
21582 test_275() {
21583         remote_ost_nodsh && skip "remote OST with nodsh"
21584         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21585                 skip "Need OST version >= 2.10.57"
21586
21587         local file=$DIR/$tfile
21588         local oss
21589
21590         oss=$(comma_list $(osts_nodes))
21591
21592         dd if=/dev/urandom of=$file bs=1M count=2 ||
21593                 error "failed to create a file"
21594         cancel_lru_locks osc
21595
21596         #lock 1
21597         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21598                 error "failed to read a file"
21599
21600 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21601         $LCTL set_param fail_loc=0x8000031f
21602
21603         cancel_lru_locks osc &
21604         sleep 1
21605
21606 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21607         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21608         #IO takes another lock, but matches the PENDING one
21609         #and places it to the IO RPC
21610         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21611                 error "failed to read a file with PENDING lock"
21612 }
21613 run_test 275 "Read on a canceled duplicate lock"
21614
21615 test_276() {
21616         remote_ost_nodsh && skip "remote OST with nodsh"
21617         local pid
21618
21619         do_facet ost1 "(while true; do \
21620                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21621                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21622         pid=$!
21623
21624         for LOOP in $(seq 20); do
21625                 stop ost1
21626                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21627         done
21628         kill -9 $pid
21629         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21630                 rm $TMP/sanity_276_pid"
21631 }
21632 run_test 276 "Race between mount and obd_statfs"
21633
21634 test_277() {
21635         $LCTL set_param ldlm.namespaces.*.lru_size=0
21636         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21637         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21638                         grep ^used_mb | awk '{print $2}')
21639         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21640         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21641                 oflag=direct conv=notrunc
21642         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21643                         grep ^used_mb | awk '{print $2}')
21644         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21645 }
21646 run_test 277 "Direct IO shall drop page cache"
21647
21648 test_278() {
21649         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21650         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21651         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21652                 skip "needs the same host for mdt1 mdt2" && return
21653
21654         local pid1
21655         local pid2
21656
21657 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21658         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21659         stop mds2 &
21660         pid2=$!
21661
21662         stop mds1
21663
21664         echo "Starting MDTs"
21665         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21666         wait $pid2
21667 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21668 #will return NULL
21669         do_facet mds2 $LCTL set_param fail_loc=0
21670
21671         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21672         wait_recovery_complete mds2
21673 }
21674 run_test 278 "Race starting MDS between MDTs stop/start"
21675
21676 test_280() {
21677         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21678                 skip "Need MGS version at least 2.13.52"
21679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21680         combined_mgs_mds || skip "needs combined MGS/MDT"
21681
21682         umount_client $MOUNT
21683 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21684         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21685
21686         mount_client $MOUNT &
21687         sleep 1
21688         stop mgs || error "stop mgs failed"
21689         #for a race mgs would crash
21690         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21691         # make sure we unmount client before remounting
21692         wait
21693         umount_client $MOUNT
21694         mount_client $MOUNT || error "mount client failed"
21695 }
21696 run_test 280 "Race between MGS umount and client llog processing"
21697
21698 cleanup_test_300() {
21699         trap 0
21700         umask $SAVE_UMASK
21701 }
21702 test_striped_dir() {
21703         local mdt_index=$1
21704         local stripe_count
21705         local stripe_index
21706
21707         mkdir -p $DIR/$tdir
21708
21709         SAVE_UMASK=$(umask)
21710         trap cleanup_test_300 RETURN EXIT
21711
21712         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21713                                                 $DIR/$tdir/striped_dir ||
21714                 error "set striped dir error"
21715
21716         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21717         [ "$mode" = "755" ] || error "expect 755 got $mode"
21718
21719         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21720                 error "getdirstripe failed"
21721         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21722         if [ "$stripe_count" != "2" ]; then
21723                 error "1:stripe_count is $stripe_count, expect 2"
21724         fi
21725         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21726         if [ "$stripe_count" != "2" ]; then
21727                 error "2:stripe_count is $stripe_count, expect 2"
21728         fi
21729
21730         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21731         if [ "$stripe_index" != "$mdt_index" ]; then
21732                 error "stripe_index is $stripe_index, expect $mdt_index"
21733         fi
21734
21735         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21736                 error "nlink error after create striped dir"
21737
21738         mkdir $DIR/$tdir/striped_dir/a
21739         mkdir $DIR/$tdir/striped_dir/b
21740
21741         stat $DIR/$tdir/striped_dir/a ||
21742                 error "create dir under striped dir failed"
21743         stat $DIR/$tdir/striped_dir/b ||
21744                 error "create dir under striped dir failed"
21745
21746         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21747                 error "nlink error after mkdir"
21748
21749         rmdir $DIR/$tdir/striped_dir/a
21750         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21751                 error "nlink error after rmdir"
21752
21753         rmdir $DIR/$tdir/striped_dir/b
21754         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21755                 error "nlink error after rmdir"
21756
21757         chattr +i $DIR/$tdir/striped_dir
21758         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21759                 error "immutable flags not working under striped dir!"
21760         chattr -i $DIR/$tdir/striped_dir
21761
21762         rmdir $DIR/$tdir/striped_dir ||
21763                 error "rmdir striped dir error"
21764
21765         cleanup_test_300
21766
21767         true
21768 }
21769
21770 test_300a() {
21771         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21772                 skip "skipped for lustre < 2.7.0"
21773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21774         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21775
21776         test_striped_dir 0 || error "failed on striped dir on MDT0"
21777         test_striped_dir 1 || error "failed on striped dir on MDT0"
21778 }
21779 run_test 300a "basic striped dir sanity test"
21780
21781 test_300b() {
21782         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21783                 skip "skipped for lustre < 2.7.0"
21784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21785         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21786
21787         local i
21788         local mtime1
21789         local mtime2
21790         local mtime3
21791
21792         test_mkdir $DIR/$tdir || error "mkdir fail"
21793         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21794                 error "set striped dir error"
21795         for i in {0..9}; do
21796                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21797                 sleep 1
21798                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21799                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21800                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21801                 sleep 1
21802                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21803                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21804                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21805         done
21806         true
21807 }
21808 run_test 300b "check ctime/mtime for striped dir"
21809
21810 test_300c() {
21811         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21812                 skip "skipped for lustre < 2.7.0"
21813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21814         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21815
21816         local file_count
21817
21818         mkdir -p $DIR/$tdir
21819         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21820                 error "set striped dir error"
21821
21822         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21823                 error "chown striped dir failed"
21824
21825         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21826                 error "create 5k files failed"
21827
21828         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21829
21830         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21831
21832         rm -rf $DIR/$tdir
21833 }
21834 run_test 300c "chown && check ls under striped directory"
21835
21836 test_300d() {
21837         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21838                 skip "skipped for lustre < 2.7.0"
21839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21840         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21841
21842         local stripe_count
21843         local file
21844
21845         mkdir -p $DIR/$tdir
21846         $LFS setstripe -c 2 $DIR/$tdir
21847
21848         #local striped directory
21849         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21850                 error "set striped dir error"
21851         #look at the directories for debug purposes
21852         ls -l $DIR/$tdir
21853         $LFS getdirstripe $DIR/$tdir
21854         ls -l $DIR/$tdir/striped_dir
21855         $LFS getdirstripe $DIR/$tdir/striped_dir
21856         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21857                 error "create 10 files failed"
21858
21859         #remote striped directory
21860         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21861                 error "set striped dir error"
21862         #look at the directories for debug purposes
21863         ls -l $DIR/$tdir
21864         $LFS getdirstripe $DIR/$tdir
21865         ls -l $DIR/$tdir/remote_striped_dir
21866         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21867         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21868                 error "create 10 files failed"
21869
21870         for file in $(find $DIR/$tdir); do
21871                 stripe_count=$($LFS getstripe -c $file)
21872                 [ $stripe_count -eq 2 ] ||
21873                         error "wrong stripe $stripe_count for $file"
21874         done
21875
21876         rm -rf $DIR/$tdir
21877 }
21878 run_test 300d "check default stripe under striped directory"
21879
21880 test_300e() {
21881         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21882                 skip "Need MDS version at least 2.7.55"
21883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21884         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21885
21886         local stripe_count
21887         local file
21888
21889         mkdir -p $DIR/$tdir
21890
21891         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21892                 error "set striped dir error"
21893
21894         touch $DIR/$tdir/striped_dir/a
21895         touch $DIR/$tdir/striped_dir/b
21896         touch $DIR/$tdir/striped_dir/c
21897
21898         mkdir $DIR/$tdir/striped_dir/dir_a
21899         mkdir $DIR/$tdir/striped_dir/dir_b
21900         mkdir $DIR/$tdir/striped_dir/dir_c
21901
21902         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21903                 error "set striped adir under striped dir error"
21904
21905         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21906                 error "set striped bdir under striped dir error"
21907
21908         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21909                 error "set striped cdir under striped dir error"
21910
21911         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21912                 error "rename dir under striped dir fails"
21913
21914         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21915                 error "rename dir under different stripes fails"
21916
21917         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21918                 error "rename file under striped dir should succeed"
21919
21920         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21921                 error "rename dir under striped dir should succeed"
21922
21923         rm -rf $DIR/$tdir
21924 }
21925 run_test 300e "check rename under striped directory"
21926
21927 test_300f() {
21928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21929         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21930         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21931                 skip "Need MDS version at least 2.7.55"
21932
21933         local stripe_count
21934         local file
21935
21936         rm -rf $DIR/$tdir
21937         mkdir -p $DIR/$tdir
21938
21939         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21940                 error "set striped dir error"
21941
21942         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21943                 error "set striped dir error"
21944
21945         touch $DIR/$tdir/striped_dir/a
21946         mkdir $DIR/$tdir/striped_dir/dir_a
21947         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21948                 error "create striped dir under striped dir fails"
21949
21950         touch $DIR/$tdir/striped_dir1/b
21951         mkdir $DIR/$tdir/striped_dir1/dir_b
21952         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21953                 error "create striped dir under striped dir fails"
21954
21955         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21956                 error "rename dir under different striped dir should fail"
21957
21958         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21959                 error "rename striped dir under diff striped dir should fail"
21960
21961         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21962                 error "rename file under diff striped dirs fails"
21963
21964         rm -rf $DIR/$tdir
21965 }
21966 run_test 300f "check rename cross striped directory"
21967
21968 test_300_check_default_striped_dir()
21969 {
21970         local dirname=$1
21971         local default_count=$2
21972         local default_index=$3
21973         local stripe_count
21974         local stripe_index
21975         local dir_stripe_index
21976         local dir
21977
21978         echo "checking $dirname $default_count $default_index"
21979         $LFS setdirstripe -D -c $default_count -i $default_index \
21980                                 -H all_char $DIR/$tdir/$dirname ||
21981                 error "set default stripe on striped dir error"
21982         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21983         [ $stripe_count -eq $default_count ] ||
21984                 error "expect $default_count get $stripe_count for $dirname"
21985
21986         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21987         [ $stripe_index -eq $default_index ] ||
21988                 error "expect $default_index get $stripe_index for $dirname"
21989
21990         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21991                                                 error "create dirs failed"
21992
21993         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21994         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21995         for dir in $(find $DIR/$tdir/$dirname/*); do
21996                 stripe_count=$($LFS getdirstripe -c $dir)
21997                 (( $stripe_count == $default_count )) ||
21998                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
21999                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22000                 error "stripe count $default_count != $stripe_count for $dir"
22001
22002                 stripe_index=$($LFS getdirstripe -i $dir)
22003                 [ $default_index -eq -1 ] ||
22004                         [ $stripe_index -eq $default_index ] ||
22005                         error "$stripe_index != $default_index for $dir"
22006
22007                 #check default stripe
22008                 stripe_count=$($LFS getdirstripe -D -c $dir)
22009                 [ $stripe_count -eq $default_count ] ||
22010                 error "default count $default_count != $stripe_count for $dir"
22011
22012                 stripe_index=$($LFS getdirstripe -D -i $dir)
22013                 [ $stripe_index -eq $default_index ] ||
22014                 error "default index $default_index != $stripe_index for $dir"
22015         done
22016         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22017 }
22018
22019 test_300g() {
22020         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22021         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22022                 skip "Need MDS version at least 2.7.55"
22023
22024         local dir
22025         local stripe_count
22026         local stripe_index
22027
22028         mkdir $DIR/$tdir
22029         mkdir $DIR/$tdir/normal_dir
22030
22031         #Checking when client cache stripe index
22032         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22033         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22034                 error "create striped_dir failed"
22035
22036         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22037                 error "create dir0 fails"
22038         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22039         [ $stripe_index -eq 0 ] ||
22040                 error "dir0 expect index 0 got $stripe_index"
22041
22042         mkdir $DIR/$tdir/striped_dir/dir1 ||
22043                 error "create dir1 fails"
22044         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22045         [ $stripe_index -eq 1 ] ||
22046                 error "dir1 expect index 1 got $stripe_index"
22047
22048         #check default stripe count/stripe index
22049         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22050         test_300_check_default_striped_dir normal_dir 1 0
22051         test_300_check_default_striped_dir normal_dir -1 1
22052         test_300_check_default_striped_dir normal_dir 2 -1
22053
22054         #delete default stripe information
22055         echo "delete default stripeEA"
22056         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22057                 error "set default stripe on striped dir error"
22058
22059         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22060         for dir in $(find $DIR/$tdir/normal_dir/*); do
22061                 stripe_count=$($LFS getdirstripe -c $dir)
22062                 [ $stripe_count -eq 0 ] ||
22063                         error "expect 1 get $stripe_count for $dir"
22064                 stripe_index=$($LFS getdirstripe -i $dir)
22065                 [ $stripe_index -eq 0 ] ||
22066                         error "expect 0 get $stripe_index for $dir"
22067         done
22068 }
22069 run_test 300g "check default striped directory for normal directory"
22070
22071 test_300h() {
22072         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22073         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22074                 skip "Need MDS version at least 2.7.55"
22075
22076         local dir
22077         local stripe_count
22078
22079         mkdir $DIR/$tdir
22080         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22081                 error "set striped dir error"
22082
22083         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22084         test_300_check_default_striped_dir striped_dir 1 0
22085         test_300_check_default_striped_dir striped_dir -1 1
22086         test_300_check_default_striped_dir striped_dir 2 -1
22087
22088         #delete default stripe information
22089         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22090                 error "set default stripe on striped dir error"
22091
22092         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22093         for dir in $(find $DIR/$tdir/striped_dir/*); do
22094                 stripe_count=$($LFS getdirstripe -c $dir)
22095                 [ $stripe_count -eq 0 ] ||
22096                         error "expect 1 get $stripe_count for $dir"
22097         done
22098 }
22099 run_test 300h "check default striped directory for striped directory"
22100
22101 test_300i() {
22102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22103         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22104         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22105                 skip "Need MDS version at least 2.7.55"
22106
22107         local stripe_count
22108         local file
22109
22110         mkdir $DIR/$tdir
22111
22112         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22113                 error "set striped dir error"
22114
22115         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22116                 error "create files under striped dir failed"
22117
22118         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22119                 error "set striped hashdir error"
22120
22121         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22122                 error "create dir0 under hash dir failed"
22123         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22124                 error "create dir1 under hash dir failed"
22125         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22126                 error "create dir2 under hash dir failed"
22127
22128         # unfortunately, we need to umount to clear dir layout cache for now
22129         # once we fully implement dir layout, we can drop this
22130         umount_client $MOUNT || error "umount failed"
22131         mount_client $MOUNT || error "mount failed"
22132
22133         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22134         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22135         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22136
22137         #set the stripe to be unknown hash type
22138         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22139         $LCTL set_param fail_loc=0x1901
22140         for ((i = 0; i < 10; i++)); do
22141                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22142                         error "stat f-$i failed"
22143                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22144         done
22145
22146         touch $DIR/$tdir/striped_dir/f0 &&
22147                 error "create under striped dir with unknown hash should fail"
22148
22149         $LCTL set_param fail_loc=0
22150
22151         umount_client $MOUNT || error "umount failed"
22152         mount_client $MOUNT || error "mount failed"
22153
22154         return 0
22155 }
22156 run_test 300i "client handle unknown hash type striped directory"
22157
22158 test_300j() {
22159         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22161         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22162                 skip "Need MDS version at least 2.7.55"
22163
22164         local stripe_count
22165         local file
22166
22167         mkdir $DIR/$tdir
22168
22169         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22170         $LCTL set_param fail_loc=0x1702
22171         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22172                 error "set striped dir error"
22173
22174         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22175                 error "create files under striped dir failed"
22176
22177         $LCTL set_param fail_loc=0
22178
22179         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22180
22181         return 0
22182 }
22183 run_test 300j "test large update record"
22184
22185 test_300k() {
22186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22187         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22188         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22189                 skip "Need MDS version at least 2.7.55"
22190
22191         # this test needs a huge transaction
22192         local kb
22193         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22194              osd*.$FSNAME-MDT0000.kbytestotal")
22195         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22196
22197         local stripe_count
22198         local file
22199
22200         mkdir $DIR/$tdir
22201
22202         #define OBD_FAIL_LARGE_STRIPE   0x1703
22203         $LCTL set_param fail_loc=0x1703
22204         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22205                 error "set striped dir error"
22206         $LCTL set_param fail_loc=0
22207
22208         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22209                 error "getstripeddir fails"
22210         rm -rf $DIR/$tdir/striped_dir ||
22211                 error "unlink striped dir fails"
22212
22213         return 0
22214 }
22215 run_test 300k "test large striped directory"
22216
22217 test_300l() {
22218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22219         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22220         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22221                 skip "Need MDS version at least 2.7.55"
22222
22223         local stripe_index
22224
22225         test_mkdir -p $DIR/$tdir/striped_dir
22226         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22227                         error "chown $RUNAS_ID failed"
22228         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22229                 error "set default striped dir failed"
22230
22231         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22232         $LCTL set_param fail_loc=0x80000158
22233         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22234
22235         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22236         [ $stripe_index -eq 1 ] ||
22237                 error "expect 1 get $stripe_index for $dir"
22238 }
22239 run_test 300l "non-root user to create dir under striped dir with stale layout"
22240
22241 test_300m() {
22242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22243         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22244         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22245                 skip "Need MDS version at least 2.7.55"
22246
22247         mkdir -p $DIR/$tdir/striped_dir
22248         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22249                 error "set default stripes dir error"
22250
22251         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22252
22253         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22254         [ $stripe_count -eq 0 ] ||
22255                         error "expect 0 get $stripe_count for a"
22256
22257         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22258                 error "set default stripes dir error"
22259
22260         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22261
22262         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22263         [ $stripe_count -eq 0 ] ||
22264                         error "expect 0 get $stripe_count for b"
22265
22266         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22267                 error "set default stripes dir error"
22268
22269         mkdir $DIR/$tdir/striped_dir/c &&
22270                 error "default stripe_index is invalid, mkdir c should fails"
22271
22272         rm -rf $DIR/$tdir || error "rmdir fails"
22273 }
22274 run_test 300m "setstriped directory on single MDT FS"
22275
22276 cleanup_300n() {
22277         local list=$(comma_list $(mdts_nodes))
22278
22279         trap 0
22280         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22281 }
22282
22283 test_300n() {
22284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22285         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22286         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22287                 skip "Need MDS version at least 2.7.55"
22288         remote_mds_nodsh && skip "remote MDS with nodsh"
22289
22290         local stripe_index
22291         local list=$(comma_list $(mdts_nodes))
22292
22293         trap cleanup_300n RETURN EXIT
22294         mkdir -p $DIR/$tdir
22295         chmod 777 $DIR/$tdir
22296         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22297                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22298                 error "create striped dir succeeds with gid=0"
22299
22300         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22301         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22302                 error "create striped dir fails with gid=-1"
22303
22304         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22305         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22306                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22307                 error "set default striped dir succeeds with gid=0"
22308
22309
22310         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22311         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22312                 error "set default striped dir fails with gid=-1"
22313
22314
22315         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22316         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22317                                         error "create test_dir fails"
22318         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22319                                         error "create test_dir1 fails"
22320         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22321                                         error "create test_dir2 fails"
22322         cleanup_300n
22323 }
22324 run_test 300n "non-root user to create dir under striped dir with default EA"
22325
22326 test_300o() {
22327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22328         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22329         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22330                 skip "Need MDS version at least 2.7.55"
22331
22332         local numfree1
22333         local numfree2
22334
22335         mkdir -p $DIR/$tdir
22336
22337         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22338         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22339         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22340                 skip "not enough free inodes $numfree1 $numfree2"
22341         fi
22342
22343         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22344         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22345         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22346                 skip "not enough free space $numfree1 $numfree2"
22347         fi
22348
22349         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22350                 error "setdirstripe fails"
22351
22352         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22353                 error "create dirs fails"
22354
22355         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22356         ls $DIR/$tdir/striped_dir > /dev/null ||
22357                 error "ls striped dir fails"
22358         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22359                 error "unlink big striped dir fails"
22360 }
22361 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22362
22363 test_300p() {
22364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22366         remote_mds_nodsh && skip "remote MDS with nodsh"
22367
22368         mkdir -p $DIR/$tdir
22369
22370         #define OBD_FAIL_OUT_ENOSPC     0x1704
22371         do_facet mds2 lctl set_param fail_loc=0x80001704
22372         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22373                  && error "create striped directory should fail"
22374
22375         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22376
22377         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22378         true
22379 }
22380 run_test 300p "create striped directory without space"
22381
22382 test_300q() {
22383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22384         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22385
22386         local fd=$(free_fd)
22387         local cmd="exec $fd<$tdir"
22388         cd $DIR
22389         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22390         eval $cmd
22391         cmd="exec $fd<&-"
22392         trap "eval $cmd" EXIT
22393         cd $tdir || error "cd $tdir fails"
22394         rmdir  ../$tdir || error "rmdir $tdir fails"
22395         mkdir local_dir && error "create dir succeeds"
22396         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22397         eval $cmd
22398         return 0
22399 }
22400 run_test 300q "create remote directory under orphan directory"
22401
22402 test_300r() {
22403         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22404                 skip "Need MDS version at least 2.7.55" && return
22405         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22406
22407         mkdir $DIR/$tdir
22408
22409         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22410                 error "set striped dir error"
22411
22412         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22413                 error "getstripeddir fails"
22414
22415         local stripe_count
22416         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22417                       awk '/lmv_stripe_count:/ { print $2 }')
22418
22419         [ $MDSCOUNT -ne $stripe_count ] &&
22420                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22421
22422         rm -rf $DIR/$tdir/striped_dir ||
22423                 error "unlink striped dir fails"
22424 }
22425 run_test 300r "test -1 striped directory"
22426
22427 test_300s_helper() {
22428         local count=$1
22429
22430         local stripe_dir=$DIR/$tdir/striped_dir.$count
22431
22432         $LFS mkdir -c $count $stripe_dir ||
22433                 error "lfs mkdir -c error"
22434
22435         $LFS getdirstripe $stripe_dir ||
22436                 error "lfs getdirstripe fails"
22437
22438         local stripe_count
22439         stripe_count=$($LFS getdirstripe $stripe_dir |
22440                       awk '/lmv_stripe_count:/ { print $2 }')
22441
22442         [ $count -ne $stripe_count ] &&
22443                 error_noexit "bad stripe count $stripe_count expected $count"
22444
22445         local dupe_stripes
22446         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22447                 awk '/0x/ {count[$1] += 1}; END {
22448                         for (idx in count) {
22449                                 if (count[idx]>1) {
22450                                         print "index " idx " count " count[idx]
22451                                 }
22452                         }
22453                 }')
22454
22455         if [[ -n "$dupe_stripes" ]] ; then
22456                 lfs getdirstripe $stripe_dir
22457                 error_noexit "Dupe MDT above: $dupe_stripes "
22458         fi
22459
22460         rm -rf $stripe_dir ||
22461                 error_noexit "unlink $stripe_dir fails"
22462 }
22463
22464 test_300s() {
22465         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22466                 skip "Need MDS version at least 2.7.55" && return
22467         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22468
22469         mkdir $DIR/$tdir
22470         for count in $(seq 2 $MDSCOUNT); do
22471                 test_300s_helper $count
22472         done
22473 }
22474 run_test 300s "test lfs mkdir -c without -i"
22475
22476
22477 prepare_remote_file() {
22478         mkdir $DIR/$tdir/src_dir ||
22479                 error "create remote source failed"
22480
22481         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22482                  error "cp to remote source failed"
22483         touch $DIR/$tdir/src_dir/a
22484
22485         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22486                 error "create remote target dir failed"
22487
22488         touch $DIR/$tdir/tgt_dir/b
22489
22490         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22491                 error "rename dir cross MDT failed!"
22492
22493         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22494                 error "src_child still exists after rename"
22495
22496         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22497                 error "missing file(a) after rename"
22498
22499         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22500                 error "diff after rename"
22501 }
22502
22503 test_310a() {
22504         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22506
22507         local remote_file=$DIR/$tdir/tgt_dir/b
22508
22509         mkdir -p $DIR/$tdir
22510
22511         prepare_remote_file || error "prepare remote file failed"
22512
22513         #open-unlink file
22514         $OPENUNLINK $remote_file $remote_file ||
22515                 error "openunlink $remote_file failed"
22516         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22517 }
22518 run_test 310a "open unlink remote file"
22519
22520 test_310b() {
22521         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22523
22524         local remote_file=$DIR/$tdir/tgt_dir/b
22525
22526         mkdir -p $DIR/$tdir
22527
22528         prepare_remote_file || error "prepare remote file failed"
22529
22530         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22531         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22532         $CHECKSTAT -t file $remote_file || error "check file failed"
22533 }
22534 run_test 310b "unlink remote file with multiple links while open"
22535
22536 test_310c() {
22537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22538         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22539
22540         local remote_file=$DIR/$tdir/tgt_dir/b
22541
22542         mkdir -p $DIR/$tdir
22543
22544         prepare_remote_file || error "prepare remote file failed"
22545
22546         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22547         multiop_bg_pause $remote_file O_uc ||
22548                         error "mulitop failed for remote file"
22549         MULTIPID=$!
22550         $MULTIOP $DIR/$tfile Ouc
22551         kill -USR1 $MULTIPID
22552         wait $MULTIPID
22553 }
22554 run_test 310c "open-unlink remote file with multiple links"
22555
22556 #LU-4825
22557 test_311() {
22558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22559         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22560         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22561                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22562         remote_mds_nodsh && skip "remote MDS with nodsh"
22563
22564         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22565         local mdts=$(comma_list $(mdts_nodes))
22566
22567         mkdir -p $DIR/$tdir
22568         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22569         createmany -o $DIR/$tdir/$tfile. 1000
22570
22571         # statfs data is not real time, let's just calculate it
22572         old_iused=$((old_iused + 1000))
22573
22574         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22575                         osp.*OST0000*MDT0000.create_count")
22576         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22577                                 osp.*OST0000*MDT0000.max_create_count")
22578         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22579
22580         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22581         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22582         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22583
22584         unlinkmany $DIR/$tdir/$tfile. 1000
22585
22586         do_nodes $mdts "$LCTL set_param -n \
22587                         osp.*OST0000*.max_create_count=$max_count"
22588         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22589                 do_nodes $mdts "$LCTL set_param -n \
22590                                 osp.*OST0000*.create_count=$count"
22591         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22592                         grep "=0" && error "create_count is zero"
22593
22594         local new_iused
22595         for i in $(seq 120); do
22596                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22597                 # system may be too busy to destroy all objs in time, use
22598                 # a somewhat small value to not fail autotest
22599                 [ $((old_iused - new_iused)) -gt 400 ] && break
22600                 sleep 1
22601         done
22602
22603         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22604         [ $((old_iused - new_iused)) -gt 400 ] ||
22605                 error "objs not destroyed after unlink"
22606 }
22607 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22608
22609 zfs_oid_to_objid()
22610 {
22611         local ost=$1
22612         local objid=$2
22613
22614         local vdevdir=$(dirname $(facet_vdevice $ost))
22615         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22616         local zfs_zapid=$(do_facet $ost $cmd |
22617                           grep -w "/O/0/d$((objid%32))" -C 5 |
22618                           awk '/Object/{getline; print $1}')
22619         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22620                           awk "/$objid = /"'{printf $3}')
22621
22622         echo $zfs_objid
22623 }
22624
22625 zfs_object_blksz() {
22626         local ost=$1
22627         local objid=$2
22628
22629         local vdevdir=$(dirname $(facet_vdevice $ost))
22630         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22631         local blksz=$(do_facet $ost $cmd $objid |
22632                       awk '/dblk/{getline; printf $4}')
22633
22634         case "${blksz: -1}" in
22635                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22636                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22637                 *) ;;
22638         esac
22639
22640         echo $blksz
22641 }
22642
22643 test_312() { # LU-4856
22644         remote_ost_nodsh && skip "remote OST with nodsh"
22645         [ "$ost1_FSTYPE" = "zfs" ] ||
22646                 skip_env "the test only applies to zfs"
22647
22648         local max_blksz=$(do_facet ost1 \
22649                           $ZFS get -p recordsize $(facet_device ost1) |
22650                           awk '!/VALUE/{print $3}')
22651
22652         # to make life a little bit easier
22653         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22654         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22655
22656         local tf=$DIR/$tdir/$tfile
22657         touch $tf
22658         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22659
22660         # Get ZFS object id
22661         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22662         # block size change by sequential overwrite
22663         local bs
22664
22665         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22666                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22667
22668                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22669                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22670         done
22671         rm -f $tf
22672
22673         # block size change by sequential append write
22674         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22675         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22676         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22677         local count
22678
22679         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22680                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22681                         oflag=sync conv=notrunc
22682
22683                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22684                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22685                         error "blksz error, actual $blksz, " \
22686                                 "expected: 2 * $count * $PAGE_SIZE"
22687         done
22688         rm -f $tf
22689
22690         # random write
22691         touch $tf
22692         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22693         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22694
22695         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22696         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22697         [ $blksz -eq $PAGE_SIZE ] ||
22698                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22699
22700         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22701         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22702         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22703
22704         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22705         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22706         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22707 }
22708 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22709
22710 test_313() {
22711         remote_ost_nodsh && skip "remote OST with nodsh"
22712
22713         local file=$DIR/$tfile
22714
22715         rm -f $file
22716         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22717
22718         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22719         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22720         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22721                 error "write should failed"
22722         do_facet ost1 "$LCTL set_param fail_loc=0"
22723         rm -f $file
22724 }
22725 run_test 313 "io should fail after last_rcvd update fail"
22726
22727 test_314() {
22728         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22729
22730         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22731         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22732         rm -f $DIR/$tfile
22733         wait_delete_completed
22734         do_facet ost1 "$LCTL set_param fail_loc=0"
22735 }
22736 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22737
22738 test_315() { # LU-618
22739         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22740
22741         local file=$DIR/$tfile
22742         rm -f $file
22743
22744         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22745                 error "multiop file write failed"
22746         $MULTIOP $file oO_RDONLY:r4063232_c &
22747         PID=$!
22748
22749         sleep 2
22750
22751         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22752         kill -USR1 $PID
22753
22754         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22755         rm -f $file
22756 }
22757 run_test 315 "read should be accounted"
22758
22759 test_316() {
22760         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22761         large_xattr_enabled || skip_env "ea_inode feature disabled"
22762
22763         rm -rf $DIR/$tdir/d
22764         mkdir -p $DIR/$tdir/d
22765         chown nobody $DIR/$tdir/d
22766         touch $DIR/$tdir/d/file
22767
22768         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22769 }
22770 run_test 316 "lfs mv"
22771
22772 test_317() {
22773         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22774                 skip "Need MDS version at least 2.11.53"
22775         if [ "$ost1_FSTYPE" == "zfs" ]; then
22776                 skip "LU-10370: no implementation for ZFS"
22777         fi
22778
22779         local trunc_sz
22780         local grant_blk_size
22781
22782         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22783                         awk '/grant_block_size:/ { print $2; exit; }')
22784         #
22785         # Create File of size 5M. Truncate it to below size's and verify
22786         # blocks count.
22787         #
22788         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22789                 error "Create file $DIR/$tfile failed"
22790         stack_trap "rm -f $DIR/$tfile" EXIT
22791
22792         for trunc_sz in 2097152 4097 4000 509 0; do
22793                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22794                         error "truncate $tfile to $trunc_sz failed"
22795                 local sz=$(stat --format=%s $DIR/$tfile)
22796                 local blk=$(stat --format=%b $DIR/$tfile)
22797                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22798                                      grant_blk_size) * 8))
22799
22800                 if [[ $blk -ne $trunc_blk ]]; then
22801                         $(which stat) $DIR/$tfile
22802                         error "Expected Block $trunc_blk got $blk for $tfile"
22803                 fi
22804
22805                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22806                         error "Expected Size $trunc_sz got $sz for $tfile"
22807         done
22808
22809         #
22810         # sparse file test
22811         # Create file with a hole and write actual two blocks. Block count
22812         # must be 16.
22813         #
22814         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22815                 conv=fsync || error "Create file : $DIR/$tfile"
22816
22817         # Calculate the final truncate size.
22818         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22819
22820         #
22821         # truncate to size $trunc_sz bytes. Strip the last block
22822         # The block count must drop to 8
22823         #
22824         $TRUNCATE $DIR/$tfile $trunc_sz ||
22825                 error "truncate $tfile to $trunc_sz failed"
22826
22827         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22828         sz=$(stat --format=%s $DIR/$tfile)
22829         blk=$(stat --format=%b $DIR/$tfile)
22830
22831         if [[ $blk -ne $trunc_bsz ]]; then
22832                 $(which stat) $DIR/$tfile
22833                 error "Expected Block $trunc_bsz got $blk for $tfile"
22834         fi
22835
22836         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22837                 error "Expected Size $trunc_sz got $sz for $tfile"
22838 }
22839 run_test 317 "Verify blocks get correctly update after truncate"
22840
22841 test_318() {
22842         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
22843         local old_max_active=$($LCTL get_param -n \
22844                             ${llite_name}.max_read_ahead_async_active \
22845                             2>/dev/null)
22846
22847         $LCTL set_param llite.*.max_read_ahead_async_active=256
22848         local max_active=$($LCTL get_param -n \
22849                            ${llite_name}.max_read_ahead_async_active \
22850                            2>/dev/null)
22851         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22852
22853         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22854                 error "set max_read_ahead_async_active should succeed"
22855
22856         $LCTL set_param llite.*.max_read_ahead_async_active=512
22857         max_active=$($LCTL get_param -n \
22858                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
22859         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22860
22861         # restore @max_active
22862         [ $old_max_active -ne 0 ] && $LCTL set_param \
22863                 llite.*.max_read_ahead_async_active=$old_max_active
22864
22865         local old_threshold=$($LCTL get_param -n \
22866                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
22867         local max_per_file_mb=$($LCTL get_param -n \
22868                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
22869
22870         local invalid=$(($max_per_file_mb + 1))
22871         $LCTL set_param \
22872                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22873                         && error "set $invalid should fail"
22874
22875         local valid=$(($invalid - 1))
22876         $LCTL set_param \
22877                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22878                         error "set $valid should succeed"
22879         local threshold=$($LCTL get_param -n \
22880                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
22881         [ $threshold -eq $valid ] || error \
22882                 "expect threshold $valid got $threshold"
22883         $LCTL set_param \
22884                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22885 }
22886 run_test 318 "Verify async readahead tunables"
22887
22888 test_319() {
22889         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22890
22891         local before=$(date +%s)
22892         local evict
22893         local mdir=$DIR/$tdir
22894         local file=$mdir/xxx
22895
22896         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22897         touch $file
22898
22899 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22900         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22901         $LFS mv -m1 $file &
22902
22903         sleep 1
22904         dd if=$file of=/dev/null
22905         wait
22906         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22907           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22908
22909         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22910 }
22911 run_test 319 "lost lease lock on migrate error"
22912
22913 test_398a() { # LU-4198
22914         local ost1_imp=$(get_osc_import_name client ost1)
22915         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22916                          cut -d'.' -f2)
22917
22918         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22919         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22920
22921         # request a new lock on client
22922         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22923
22924         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22925         local lock_count=$($LCTL get_param -n \
22926                            ldlm.namespaces.$imp_name.lru_size)
22927         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22928
22929         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22930
22931         # no lock cached, should use lockless IO and not enqueue new lock
22932         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22933         lock_count=$($LCTL get_param -n \
22934                      ldlm.namespaces.$imp_name.lru_size)
22935         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22936 }
22937 run_test 398a "direct IO should cancel lock otherwise lockless"
22938
22939 test_398b() { # LU-4198
22940         which fio || skip_env "no fio installed"
22941         $LFS setstripe -c -1 $DIR/$tfile
22942
22943         local size=12
22944         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22945
22946         local njobs=4
22947         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22948         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22949                 --numjobs=$njobs --fallocate=none \
22950                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22951                 --filename=$DIR/$tfile &
22952         bg_pid=$!
22953
22954         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22955         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22956                 --numjobs=$njobs --fallocate=none \
22957                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22958                 --filename=$DIR/$tfile || true
22959         wait $bg_pid
22960
22961         rm -rf $DIR/$tfile
22962 }
22963 run_test 398b "DIO and buffer IO race"
22964
22965 test_398c() { # LU-4198
22966         local ost1_imp=$(get_osc_import_name client ost1)
22967         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22968                          cut -d'.' -f2)
22969
22970         which fio || skip_env "no fio installed"
22971
22972         saved_debug=$($LCTL get_param -n debug)
22973         $LCTL set_param debug=0
22974
22975         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22976         ((size /= 1024)) # by megabytes
22977         ((size /= 2)) # write half of the OST at most
22978         [ $size -gt 40 ] && size=40 #reduce test time anyway
22979
22980         $LFS setstripe -c 1 $DIR/$tfile
22981
22982         # it seems like ldiskfs reserves more space than necessary if the
22983         # writing blocks are not mapped, so it extends the file firstly
22984         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22985         cancel_lru_locks osc
22986
22987         # clear and verify rpc_stats later
22988         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22989
22990         local njobs=4
22991         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22992         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22993                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22994                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22995                 --filename=$DIR/$tfile
22996         [ $? -eq 0 ] || error "fio write error"
22997
22998         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
22999                 error "Locks were requested while doing AIO"
23000
23001         # get the percentage of 1-page I/O
23002         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23003                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23004                 awk '{print $7}')
23005         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23006
23007         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23008         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23009                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23010                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23011                 --filename=$DIR/$tfile
23012         [ $? -eq 0 ] || error "fio mixed read write error"
23013
23014         echo "AIO with large block size ${size}M"
23015         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23016                 --numjobs=1 --fallocate=none --ioengine=libaio \
23017                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23018                 --filename=$DIR/$tfile
23019         [ $? -eq 0 ] || error "fio large block size failed"
23020
23021         rm -rf $DIR/$tfile
23022         $LCTL set_param debug="$saved_debug"
23023 }
23024 run_test 398c "run fio to test AIO"
23025
23026 test_398d() { #  LU-13846
23027         test -f aiocp || skip_env "no aiocp installed"
23028         local aio_file=$DIR/aio_file
23029
23030         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23031
23032         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23033         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23034
23035         diff $DIR/$tfile $aio_file || "file diff after aiocp"
23036
23037         # make sure we don't crash and fail properly
23038         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23039                 error "aio not aligned with PAGE SIZE should fail"
23040
23041         rm -rf $DIR/$tfile $aio_file
23042 }
23043 run_test 398d "run aiocp to verify block size > stripe size"
23044
23045 test_398e() {
23046         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23047         touch $DIR/$tfile.new
23048         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23049 }
23050 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23051
23052 test_fake_rw() {
23053         local read_write=$1
23054         if [ "$read_write" = "write" ]; then
23055                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23056         elif [ "$read_write" = "read" ]; then
23057                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23058         else
23059                 error "argument error"
23060         fi
23061
23062         # turn off debug for performance testing
23063         local saved_debug=$($LCTL get_param -n debug)
23064         $LCTL set_param debug=0
23065
23066         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23067
23068         # get ost1 size - $FSNAME-OST0000
23069         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23070         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23071         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23072
23073         if [ "$read_write" = "read" ]; then
23074                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23075         fi
23076
23077         local start_time=$(date +%s.%N)
23078         $dd_cmd bs=1M count=$blocks oflag=sync ||
23079                 error "real dd $read_write error"
23080         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23081
23082         if [ "$read_write" = "write" ]; then
23083                 rm -f $DIR/$tfile
23084         fi
23085
23086         # define OBD_FAIL_OST_FAKE_RW           0x238
23087         do_facet ost1 $LCTL set_param fail_loc=0x238
23088
23089         local start_time=$(date +%s.%N)
23090         $dd_cmd bs=1M count=$blocks oflag=sync ||
23091                 error "fake dd $read_write error"
23092         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23093
23094         if [ "$read_write" = "write" ]; then
23095                 # verify file size
23096                 cancel_lru_locks osc
23097                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23098                         error "$tfile size not $blocks MB"
23099         fi
23100         do_facet ost1 $LCTL set_param fail_loc=0
23101
23102         echo "fake $read_write $duration_fake vs. normal $read_write" \
23103                 "$duration in seconds"
23104         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23105                 error_not_in_vm "fake write is slower"
23106
23107         $LCTL set_param -n debug="$saved_debug"
23108         rm -f $DIR/$tfile
23109 }
23110 test_399a() { # LU-7655 for OST fake write
23111         remote_ost_nodsh && skip "remote OST with nodsh"
23112
23113         test_fake_rw write
23114 }
23115 run_test 399a "fake write should not be slower than normal write"
23116
23117 test_399b() { # LU-8726 for OST fake read
23118         remote_ost_nodsh && skip "remote OST with nodsh"
23119         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23120                 skip_env "ldiskfs only test"
23121         fi
23122
23123         test_fake_rw read
23124 }
23125 run_test 399b "fake read should not be slower than normal read"
23126
23127 test_400a() { # LU-1606, was conf-sanity test_74
23128         if ! which $CC > /dev/null 2>&1; then
23129                 skip_env "$CC is not installed"
23130         fi
23131
23132         local extra_flags=''
23133         local out=$TMP/$tfile
23134         local prefix=/usr/include/lustre
23135         local prog
23136
23137         # Oleg removes c files in his test rig so test if any c files exist
23138         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23139                 skip_env "Needed c test files are missing"
23140
23141         if ! [[ -d $prefix ]]; then
23142                 # Assume we're running in tree and fixup the include path.
23143                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23144                 extra_flags+=" -L$LUSTRE/utils/.lib"
23145         fi
23146
23147         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23148                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
23149                         error "client api broken"
23150         done
23151         rm -f $out
23152 }
23153 run_test 400a "Lustre client api program can compile and link"
23154
23155 test_400b() { # LU-1606, LU-5011
23156         local header
23157         local out=$TMP/$tfile
23158         local prefix=/usr/include/linux/lustre
23159
23160         # We use a hard coded prefix so that this test will not fail
23161         # when run in tree. There are headers in lustre/include/lustre/
23162         # that are not packaged (like lustre_idl.h) and have more
23163         # complicated include dependencies (like config.h and lnet/types.h).
23164         # Since this test about correct packaging we just skip them when
23165         # they don't exist (see below) rather than try to fixup cppflags.
23166
23167         if ! which $CC > /dev/null 2>&1; then
23168                 skip_env "$CC is not installed"
23169         fi
23170
23171         for header in $prefix/*.h; do
23172                 if ! [[ -f "$header" ]]; then
23173                         continue
23174                 fi
23175
23176                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
23177                         continue # lustre_ioctl.h is internal header
23178                 fi
23179
23180                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
23181                         error "cannot compile '$header'"
23182         done
23183         rm -f $out
23184 }
23185 run_test 400b "packaged headers can be compiled"
23186
23187 test_401a() { #LU-7437
23188         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23189         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23190
23191         #count the number of parameters by "list_param -R"
23192         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23193         #count the number of parameters by listing proc files
23194         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23195         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23196         echo "proc_dirs='$proc_dirs'"
23197         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23198         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23199                       sort -u | wc -l)
23200
23201         [ $params -eq $procs ] ||
23202                 error "found $params parameters vs. $procs proc files"
23203
23204         # test the list_param -D option only returns directories
23205         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23206         #count the number of parameters by listing proc directories
23207         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23208                 sort -u | wc -l)
23209
23210         [ $params -eq $procs ] ||
23211                 error "found $params parameters vs. $procs proc files"
23212 }
23213 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23214
23215 test_401b() {
23216         # jobid_var may not allow arbitrary values, so use jobid_name
23217         # if available
23218         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23219                 local testname=jobid_name tmp='testing%p'
23220         else
23221                 local testname=jobid_var tmp=testing
23222         fi
23223
23224         local save=$($LCTL get_param -n $testname)
23225
23226         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23227                 error "no error returned when setting bad parameters"
23228
23229         local jobid_new=$($LCTL get_param -n foe $testname baz)
23230         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23231
23232         $LCTL set_param -n fog=bam $testname=$save bat=fog
23233         local jobid_old=$($LCTL get_param -n foe $testname bag)
23234         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23235 }
23236 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23237
23238 test_401c() {
23239         # jobid_var may not allow arbitrary values, so use jobid_name
23240         # if available
23241         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23242                 local testname=jobid_name
23243         else
23244                 local testname=jobid_var
23245         fi
23246
23247         local jobid_var_old=$($LCTL get_param -n $testname)
23248         local jobid_var_new
23249
23250         $LCTL set_param $testname= &&
23251                 error "no error returned for 'set_param a='"
23252
23253         jobid_var_new=$($LCTL get_param -n $testname)
23254         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23255                 error "$testname was changed by setting without value"
23256
23257         $LCTL set_param $testname &&
23258                 error "no error returned for 'set_param a'"
23259
23260         jobid_var_new=$($LCTL get_param -n $testname)
23261         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23262                 error "$testname was changed by setting without value"
23263 }
23264 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23265
23266 test_401d() {
23267         # jobid_var may not allow arbitrary values, so use jobid_name
23268         # if available
23269         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23270                 local testname=jobid_name new_value='foo=bar%p'
23271         else
23272                 local testname=jobid_var new_valuie=foo=bar
23273         fi
23274
23275         local jobid_var_old=$($LCTL get_param -n $testname)
23276         local jobid_var_new
23277
23278         $LCTL set_param $testname=$new_value ||
23279                 error "'set_param a=b' did not accept a value containing '='"
23280
23281         jobid_var_new=$($LCTL get_param -n $testname)
23282         [[ "$jobid_var_new" == "$new_value" ]] ||
23283                 error "'set_param a=b' failed on a value containing '='"
23284
23285         # Reset the $testname to test the other format
23286         $LCTL set_param $testname=$jobid_var_old
23287         jobid_var_new=$($LCTL get_param -n $testname)
23288         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23289                 error "failed to reset $testname"
23290
23291         $LCTL set_param $testname $new_value ||
23292                 error "'set_param a b' did not accept a value containing '='"
23293
23294         jobid_var_new=$($LCTL get_param -n $testname)
23295         [[ "$jobid_var_new" == "$new_value" ]] ||
23296                 error "'set_param a b' failed on a value containing '='"
23297
23298         $LCTL set_param $testname $jobid_var_old
23299         jobid_var_new=$($LCTL get_param -n $testname)
23300         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23301                 error "failed to reset $testname"
23302 }
23303 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23304
23305 test_402() {
23306         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23307         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23308                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23309         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23310                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23311                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23312         remote_mds_nodsh && skip "remote MDS with nodsh"
23313
23314         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23315 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23316         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23317         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23318                 echo "Touch failed - OK"
23319 }
23320 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23321
23322 test_403() {
23323         local file1=$DIR/$tfile.1
23324         local file2=$DIR/$tfile.2
23325         local tfile=$TMP/$tfile
23326
23327         rm -f $file1 $file2 $tfile
23328
23329         touch $file1
23330         ln $file1 $file2
23331
23332         # 30 sec OBD_TIMEOUT in ll_getattr()
23333         # right before populating st_nlink
23334         $LCTL set_param fail_loc=0x80001409
23335         stat -c %h $file1 > $tfile &
23336
23337         # create an alias, drop all locks and reclaim the dentry
23338         < $file2
23339         cancel_lru_locks mdc
23340         cancel_lru_locks osc
23341         sysctl -w vm.drop_caches=2
23342
23343         wait
23344
23345         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23346
23347         rm -f $tfile $file1 $file2
23348 }
23349 run_test 403 "i_nlink should not drop to zero due to aliasing"
23350
23351 test_404() { # LU-6601
23352         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23353                 skip "Need server version newer than 2.8.52"
23354         remote_mds_nodsh && skip "remote MDS with nodsh"
23355
23356         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23357                 awk '/osp .*-osc-MDT/ { print $4}')
23358
23359         local osp
23360         for osp in $mosps; do
23361                 echo "Deactivate: " $osp
23362                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23363                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23364                         awk -vp=$osp '$4 == p { print $2 }')
23365                 [ $stat = IN ] || {
23366                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23367                         error "deactivate error"
23368                 }
23369                 echo "Activate: " $osp
23370                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23371                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23372                         awk -vp=$osp '$4 == p { print $2 }')
23373                 [ $stat = UP ] || {
23374                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23375                         error "activate error"
23376                 }
23377         done
23378 }
23379 run_test 404 "validate manual {de}activated works properly for OSPs"
23380
23381 test_405() {
23382         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23383         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23384                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23385                         skip "Layout swap lock is not supported"
23386
23387         check_swap_layouts_support
23388         check_swap_layout_no_dom $DIR
23389
23390         test_mkdir $DIR/$tdir
23391         swap_lock_test -d $DIR/$tdir ||
23392                 error "One layout swap locked test failed"
23393 }
23394 run_test 405 "Various layout swap lock tests"
23395
23396 test_406() {
23397         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23398         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23399         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23401         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23402                 skip "Need MDS version at least 2.8.50"
23403
23404         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23405         local test_pool=$TESTNAME
23406
23407         pool_add $test_pool || error "pool_add failed"
23408         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23409                 error "pool_add_targets failed"
23410
23411         save_layout_restore_at_exit $MOUNT
23412
23413         # parent set default stripe count only, child will stripe from both
23414         # parent and fs default
23415         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23416                 error "setstripe $MOUNT failed"
23417         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23418         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23419         for i in $(seq 10); do
23420                 local f=$DIR/$tdir/$tfile.$i
23421                 touch $f || error "touch failed"
23422                 local count=$($LFS getstripe -c $f)
23423                 [ $count -eq $OSTCOUNT ] ||
23424                         error "$f stripe count $count != $OSTCOUNT"
23425                 local offset=$($LFS getstripe -i $f)
23426                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23427                 local size=$($LFS getstripe -S $f)
23428                 [ $size -eq $((def_stripe_size * 2)) ] ||
23429                         error "$f stripe size $size != $((def_stripe_size * 2))"
23430                 local pool=$($LFS getstripe -p $f)
23431                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23432         done
23433
23434         # change fs default striping, delete parent default striping, now child
23435         # will stripe from new fs default striping only
23436         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23437                 error "change $MOUNT default stripe failed"
23438         $LFS setstripe -c 0 $DIR/$tdir ||
23439                 error "delete $tdir default stripe failed"
23440         for i in $(seq 11 20); do
23441                 local f=$DIR/$tdir/$tfile.$i
23442                 touch $f || error "touch $f failed"
23443                 local count=$($LFS getstripe -c $f)
23444                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23445                 local offset=$($LFS getstripe -i $f)
23446                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23447                 local size=$($LFS getstripe -S $f)
23448                 [ $size -eq $def_stripe_size ] ||
23449                         error "$f stripe size $size != $def_stripe_size"
23450                 local pool=$($LFS getstripe -p $f)
23451                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23452         done
23453
23454         unlinkmany $DIR/$tdir/$tfile. 1 20
23455
23456         local f=$DIR/$tdir/$tfile
23457         pool_remove_all_targets $test_pool $f
23458         pool_remove $test_pool $f
23459 }
23460 run_test 406 "DNE support fs default striping"
23461
23462 test_407() {
23463         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23464         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23465                 skip "Need MDS version at least 2.8.55"
23466         remote_mds_nodsh && skip "remote MDS with nodsh"
23467
23468         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23469                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23470         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23471                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23472         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23473
23474         #define OBD_FAIL_DT_TXN_STOP    0x2019
23475         for idx in $(seq $MDSCOUNT); do
23476                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23477         done
23478         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23479         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23480                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23481         true
23482 }
23483 run_test 407 "transaction fail should cause operation fail"
23484
23485 test_408() {
23486         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23487
23488         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23489         lctl set_param fail_loc=0x8000040a
23490         # let ll_prepare_partial_page() fail
23491         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23492
23493         rm -f $DIR/$tfile
23494
23495         # create at least 100 unused inodes so that
23496         # shrink_icache_memory(0) should not return 0
23497         touch $DIR/$tfile-{0..100}
23498         rm -f $DIR/$tfile-{0..100}
23499         sync
23500
23501         echo 2 > /proc/sys/vm/drop_caches
23502 }
23503 run_test 408 "drop_caches should not hang due to page leaks"
23504
23505 test_409()
23506 {
23507         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23508
23509         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23510         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23511         touch $DIR/$tdir/guard || error "(2) Fail to create"
23512
23513         local PREFIX=$(str_repeat 'A' 128)
23514         echo "Create 1K hard links start at $(date)"
23515         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23516                 error "(3) Fail to hard link"
23517
23518         echo "Links count should be right although linkEA overflow"
23519         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23520         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23521         [ $linkcount -eq 1001 ] ||
23522                 error "(5) Unexpected hard links count: $linkcount"
23523
23524         echo "List all links start at $(date)"
23525         ls -l $DIR/$tdir/foo > /dev/null ||
23526                 error "(6) Fail to list $DIR/$tdir/foo"
23527
23528         echo "Unlink hard links start at $(date)"
23529         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23530                 error "(7) Fail to unlink"
23531         echo "Unlink hard links finished at $(date)"
23532 }
23533 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23534
23535 test_410()
23536 {
23537         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23538                 skip "Need client version at least 2.9.59"
23539         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23540                 skip "Need MODULES build"
23541
23542         # Create a file, and stat it from the kernel
23543         local testfile=$DIR/$tfile
23544         touch $testfile
23545
23546         local run_id=$RANDOM
23547         local my_ino=$(stat --format "%i" $testfile)
23548
23549         # Try to insert the module. This will always fail as the
23550         # module is designed to not be inserted.
23551         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23552             &> /dev/null
23553
23554         # Anything but success is a test failure
23555         dmesg | grep -q \
23556             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23557             error "no inode match"
23558 }
23559 run_test 410 "Test inode number returned from kernel thread"
23560
23561 cleanup_test411_cgroup() {
23562         trap 0
23563         rmdir "$1"
23564 }
23565
23566 test_411() {
23567         local cg_basedir=/sys/fs/cgroup/memory
23568         # LU-9966
23569         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23570                 skip "no setup for cgroup"
23571
23572         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23573                 error "test file creation failed"
23574         cancel_lru_locks osc
23575
23576         # Create a very small memory cgroup to force a slab allocation error
23577         local cgdir=$cg_basedir/osc_slab_alloc
23578         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23579         trap "cleanup_test411_cgroup $cgdir" EXIT
23580         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23581         echo 1M > $cgdir/memory.limit_in_bytes
23582
23583         # Should not LBUG, just be killed by oom-killer
23584         # dd will return 0 even allocation failure in some environment.
23585         # So don't check return value
23586         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23587         cleanup_test411_cgroup $cgdir
23588
23589         return 0
23590 }
23591 run_test 411 "Slab allocation error with cgroup does not LBUG"
23592
23593 test_412() {
23594         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23595         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23596                 skip "Need server version at least 2.10.55"
23597         fi
23598
23599         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23600                 error "mkdir failed"
23601         $LFS getdirstripe $DIR/$tdir
23602         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23603         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23604                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23605         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23606         [ $stripe_count -eq 2 ] ||
23607                 error "expect 2 get $stripe_count"
23608 }
23609 run_test 412 "mkdir on specific MDTs"
23610
23611 test_qos_mkdir() {
23612         local mkdir_cmd=$1
23613         local stripe_count=$2
23614         local mdts=$(comma_list $(mdts_nodes))
23615
23616         local testdir
23617         local lmv_qos_prio_free
23618         local lmv_qos_threshold_rr
23619         local lmv_qos_maxage
23620         local lod_qos_prio_free
23621         local lod_qos_threshold_rr
23622         local lod_qos_maxage
23623         local count
23624         local i
23625
23626         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23627         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23628         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23629                 head -n1)
23630         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23631         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23632         stack_trap "$LCTL set_param \
23633                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23634         stack_trap "$LCTL set_param \
23635                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23636         stack_trap "$LCTL set_param \
23637                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23638
23639         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23640                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23641         lod_qos_prio_free=${lod_qos_prio_free%%%}
23642         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23643                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23644         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23645         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23646                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23647         stack_trap "do_nodes $mdts $LCTL set_param \
23648                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23649         stack_trap "do_nodes $mdts $LCTL set_param \
23650                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23651                 EXIT
23652         stack_trap "do_nodes $mdts $LCTL set_param \
23653                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23654
23655         echo
23656         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23657
23658         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23659         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23660
23661         testdir=$DIR/$tdir-s$stripe_count/rr
23662
23663         for i in $(seq $((100 * MDSCOUNT))); do
23664                 eval $mkdir_cmd $testdir/subdir$i ||
23665                         error "$mkdir_cmd subdir$i failed"
23666         done
23667
23668         for i in $(seq $MDSCOUNT); do
23669                 count=$($LFS getdirstripe -i $testdir/* |
23670                                 grep ^$((i - 1))$ | wc -l)
23671                 echo "$count directories created on MDT$((i - 1))"
23672                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23673
23674                 if [ $stripe_count -gt 1 ]; then
23675                         count=$($LFS getdirstripe $testdir/* |
23676                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23677                         echo "$count stripes created on MDT$((i - 1))"
23678                         # deviation should < 5% of average
23679                         [ $count -lt $((95 * stripe_count)) ] ||
23680                         [ $count -gt $((105 * stripe_count)) ] &&
23681                                 error "stripes are not evenly distributed"
23682                 fi
23683         done
23684
23685         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23686         do_nodes $mdts $LCTL set_param \
23687                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23688
23689         echo
23690         echo "Check for uneven MDTs: "
23691
23692         local ffree
23693         local bavail
23694         local max
23695         local min
23696         local max_index
23697         local min_index
23698         local tmp
23699
23700         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23701         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23702         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23703
23704         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23705         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23706         max_index=0
23707         min_index=0
23708         for ((i = 1; i < ${#ffree[@]}; i++)); do
23709                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23710                 if [ $tmp -gt $max ]; then
23711                         max=$tmp
23712                         max_index=$i
23713                 fi
23714                 if [ $tmp -lt $min ]; then
23715                         min=$tmp
23716                         min_index=$i
23717                 fi
23718         done
23719
23720         [ ${ffree[min_index]} -eq 0 ] &&
23721                 skip "no free files in MDT$min_index"
23722         [ ${ffree[min_index]} -gt 100000000 ] &&
23723                 skip "too much free files in MDT$min_index"
23724
23725         # Check if we need to generate uneven MDTs
23726         local threshold=50
23727         local diff=$(((max - min) * 100 / min))
23728         local value="$(generate_string 1024)"
23729
23730         while [ $diff -lt $threshold ]; do
23731                 # generate uneven MDTs, create till $threshold% diff
23732                 echo -n "weight diff=$diff% must be > $threshold% ..."
23733                 count=$((${ffree[min_index]} / 10))
23734                 # 50 sec per 10000 files in vm
23735                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23736                         skip "$count files to create"
23737                 echo "Fill MDT$min_index with $count files"
23738                 [ -d $DIR/$tdir-MDT$min_index ] ||
23739                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23740                         error "mkdir $tdir-MDT$min_index failed"
23741                 for i in $(seq $count); do
23742                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23743                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23744                                 error "create f$j_$i failed"
23745                         setfattr -n user.413b -v $value \
23746                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23747                                 error "setfattr f$j_$i failed"
23748                 done
23749
23750                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23751                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23752                 max=$(((${ffree[max_index]} >> 8) * \
23753                         (${bavail[max_index]} * bsize >> 16)))
23754                 min=$(((${ffree[min_index]} >> 8) * \
23755                         (${bavail[min_index]} * bsize >> 16)))
23756                 diff=$(((max - min) * 100 / min))
23757         done
23758
23759         echo "MDT filesfree available: ${ffree[@]}"
23760         echo "MDT blocks available: ${bavail[@]}"
23761         echo "weight diff=$diff%"
23762
23763         echo
23764         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23765
23766         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23767         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23768         # decrease statfs age, so that it can be updated in time
23769         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23770         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23771
23772         sleep 1
23773
23774         testdir=$DIR/$tdir-s$stripe_count/qos
23775
23776         for i in $(seq $((100 * MDSCOUNT))); do
23777                 eval $mkdir_cmd $testdir/subdir$i ||
23778                         error "$mkdir_cmd subdir$i failed"
23779         done
23780
23781         for i in $(seq $MDSCOUNT); do
23782                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23783                         wc -l)
23784                 echo "$count directories created on MDT$((i - 1))"
23785
23786                 if [ $stripe_count -gt 1 ]; then
23787                         count=$($LFS getdirstripe $testdir/* |
23788                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23789                         echo "$count stripes created on MDT$((i - 1))"
23790                 fi
23791         done
23792
23793         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23794         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23795
23796         # D-value should > 10% of averge
23797         [ $((max - min)) -lt 10 ] &&
23798                 error "subdirs shouldn't be evenly distributed"
23799
23800         # ditto
23801         if [ $stripe_count -gt 1 ]; then
23802                 max=$($LFS getdirstripe $testdir/* |
23803                         grep -P "^\s+$max_index\t" | wc -l)
23804                 min=$($LFS getdirstripe $testdir/* |
23805                         grep -P "^\s+$min_index\t" | wc -l)
23806                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23807                         error "stripes shouldn't be evenly distributed"|| true
23808         fi
23809 }
23810
23811 test_413a() {
23812         [ $MDSCOUNT -lt 2 ] &&
23813                 skip "We need at least 2 MDTs for this test"
23814
23815         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23816                 skip "Need server version at least 2.12.52"
23817
23818         local stripe_count
23819
23820         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23821                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23822                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23823                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23824                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23825         done
23826 }
23827 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23828
23829 test_413b() {
23830         [ $MDSCOUNT -lt 2 ] &&
23831                 skip "We need at least 2 MDTs for this test"
23832
23833         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23834                 skip "Need server version at least 2.12.52"
23835
23836         local stripe_count
23837
23838         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23839                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23840                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23841                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23842                 $LFS setdirstripe -D -c $stripe_count \
23843                         $DIR/$tdir-s$stripe_count/rr ||
23844                         error "setdirstripe failed"
23845                 $LFS setdirstripe -D -c $stripe_count \
23846                         $DIR/$tdir-s$stripe_count/qos ||
23847                         error "setdirstripe failed"
23848                 test_qos_mkdir "mkdir" $stripe_count
23849         done
23850 }
23851 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23852
23853 test_414() {
23854 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23855         $LCTL set_param fail_loc=0x80000521
23856         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23857         rm -f $DIR/$tfile
23858 }
23859 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23860
23861 test_415() {
23862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23863         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23864                 skip "Need server version at least 2.11.52"
23865
23866         # LU-11102
23867         local total
23868         local setattr_pid
23869         local start_time
23870         local end_time
23871         local duration
23872
23873         total=500
23874         # this test may be slow on ZFS
23875         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23876
23877         # though this test is designed for striped directory, let's test normal
23878         # directory too since lock is always saved as CoS lock.
23879         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23880         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23881
23882         (
23883                 while true; do
23884                         touch $DIR/$tdir
23885                 done
23886         ) &
23887         setattr_pid=$!
23888
23889         start_time=$(date +%s)
23890         for i in $(seq $total); do
23891                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23892                         > /dev/null
23893         done
23894         end_time=$(date +%s)
23895         duration=$((end_time - start_time))
23896
23897         kill -9 $setattr_pid
23898
23899         echo "rename $total files took $duration sec"
23900         [ $duration -lt 100 ] || error "rename took $duration sec"
23901 }
23902 run_test 415 "lock revoke is not missing"
23903
23904 test_416() {
23905         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23906                 skip "Need server version at least 2.11.55"
23907
23908         # define OBD_FAIL_OSD_TXN_START    0x19a
23909         do_facet mds1 lctl set_param fail_loc=0x19a
23910
23911         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23912
23913         true
23914 }
23915 run_test 416 "transaction start failure won't cause system hung"
23916
23917 cleanup_417() {
23918         trap 0
23919         do_nodes $(comma_list $(mdts_nodes)) \
23920                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23921         do_nodes $(comma_list $(mdts_nodes)) \
23922                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23923         do_nodes $(comma_list $(mdts_nodes)) \
23924                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23925 }
23926
23927 test_417() {
23928         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23929         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23930                 skip "Need MDS version at least 2.11.56"
23931
23932         trap cleanup_417 RETURN EXIT
23933
23934         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23935         do_nodes $(comma_list $(mdts_nodes)) \
23936                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23937         $LFS migrate -m 0 $DIR/$tdir.1 &&
23938                 error "migrate dir $tdir.1 should fail"
23939
23940         do_nodes $(comma_list $(mdts_nodes)) \
23941                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23942         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23943                 error "create remote dir $tdir.2 should fail"
23944
23945         do_nodes $(comma_list $(mdts_nodes)) \
23946                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23947         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23948                 error "create striped dir $tdir.3 should fail"
23949         true
23950 }
23951 run_test 417 "disable remote dir, striped dir and dir migration"
23952
23953 # Checks that the outputs of df [-i] and lfs df [-i] match
23954 #
23955 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23956 check_lfs_df() {
23957         local dir=$2
23958         local inodes
23959         local df_out
23960         local lfs_df_out
23961         local count
23962         local passed=false
23963
23964         # blocks or inodes
23965         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23966
23967         for count in {1..100}; do
23968                 cancel_lru_locks
23969                 sync; sleep 0.2
23970
23971                 # read the lines of interest
23972                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23973                         error "df $inodes $dir | tail -n +2 failed"
23974                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23975                         error "lfs df $inodes $dir | grep summary: failed"
23976
23977                 # skip first substrings of each output as they are different
23978                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23979                 # compare the two outputs
23980                 passed=true
23981                 for i in {1..5}; do
23982                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23983                 done
23984                 $passed && break
23985         done
23986
23987         if ! $passed; then
23988                 df -P $inodes $dir
23989                 echo
23990                 lfs df $inodes $dir
23991                 error "df and lfs df $1 output mismatch: "      \
23992                       "df ${inodes}: ${df_out[*]}, "            \
23993                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23994         fi
23995 }
23996
23997 test_418() {
23998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23999
24000         local dir=$DIR/$tdir
24001         local numfiles=$((RANDOM % 4096 + 2))
24002         local numblocks=$((RANDOM % 256 + 1))
24003
24004         wait_delete_completed
24005         test_mkdir $dir
24006
24007         # check block output
24008         check_lfs_df blocks $dir
24009         # check inode output
24010         check_lfs_df inodes $dir
24011
24012         # create a single file and retest
24013         echo "Creating a single file and testing"
24014         createmany -o $dir/$tfile- 1 &>/dev/null ||
24015                 error "creating 1 file in $dir failed"
24016         check_lfs_df blocks $dir
24017         check_lfs_df inodes $dir
24018
24019         # create a random number of files
24020         echo "Creating $((numfiles - 1)) files and testing"
24021         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24022                 error "creating $((numfiles - 1)) files in $dir failed"
24023
24024         # write a random number of blocks to the first test file
24025         echo "Writing $numblocks 4K blocks and testing"
24026         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24027                 count=$numblocks &>/dev/null ||
24028                 error "dd to $dir/${tfile}-0 failed"
24029
24030         # retest
24031         check_lfs_df blocks $dir
24032         check_lfs_df inodes $dir
24033
24034         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24035                 error "unlinking $numfiles files in $dir failed"
24036 }
24037 run_test 418 "df and lfs df outputs match"
24038
24039 test_419()
24040 {
24041         local dir=$DIR/$tdir
24042
24043         mkdir -p $dir
24044         touch $dir/file
24045
24046         cancel_lru_locks mdc
24047
24048         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24049         $LCTL set_param fail_loc=0x1410
24050         cat $dir/file
24051         $LCTL set_param fail_loc=0
24052         rm -rf $dir
24053 }
24054 run_test 419 "Verify open file by name doesn't crash kernel"
24055
24056 test_420()
24057 {
24058         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24059                 skip "Need MDS version at least 2.12.53"
24060
24061         local SAVE_UMASK=$(umask)
24062         local dir=$DIR/$tdir
24063         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24064
24065         mkdir -p $dir
24066         umask 0000
24067         mkdir -m03777 $dir/testdir
24068         ls -dn $dir/testdir
24069         # Need to remove trailing '.' when SELinux is enabled
24070         local dirperms=$(ls -dn $dir/testdir |
24071                          awk '{ sub(/\.$/, "", $1); print $1}')
24072         [ $dirperms == "drwxrwsrwt" ] ||
24073                 error "incorrect perms on $dir/testdir"
24074
24075         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24076                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24077         ls -n $dir/testdir/testfile
24078         local fileperms=$(ls -n $dir/testdir/testfile |
24079                           awk '{ sub(/\.$/, "", $1); print $1}')
24080         [ $fileperms == "-rwxr-xr-x" ] ||
24081                 error "incorrect perms on $dir/testdir/testfile"
24082
24083         umask $SAVE_UMASK
24084 }
24085 run_test 420 "clear SGID bit on non-directories for non-members"
24086
24087 test_421a() {
24088         local cnt
24089         local fid1
24090         local fid2
24091
24092         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24093                 skip "Need MDS version at least 2.12.54"
24094
24095         test_mkdir $DIR/$tdir
24096         createmany -o $DIR/$tdir/f 3
24097         cnt=$(ls -1 $DIR/$tdir | wc -l)
24098         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24099
24100         fid1=$(lfs path2fid $DIR/$tdir/f1)
24101         fid2=$(lfs path2fid $DIR/$tdir/f2)
24102         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
24103
24104         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
24105         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
24106
24107         cnt=$(ls -1 $DIR/$tdir | wc -l)
24108         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24109
24110         rm -f $DIR/$tdir/f3 || error "can't remove f3"
24111         createmany -o $DIR/$tdir/f 3
24112         cnt=$(ls -1 $DIR/$tdir | wc -l)
24113         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24114
24115         fid1=$(lfs path2fid $DIR/$tdir/f1)
24116         fid2=$(lfs path2fid $DIR/$tdir/f2)
24117         echo "remove using fsname $FSNAME"
24118         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
24119
24120         cnt=$(ls -1 $DIR/$tdir | wc -l)
24121         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24122 }
24123 run_test 421a "simple rm by fid"
24124
24125 test_421b() {
24126         local cnt
24127         local FID1
24128         local FID2
24129
24130         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24131                 skip "Need MDS version at least 2.12.54"
24132
24133         test_mkdir $DIR/$tdir
24134         createmany -o $DIR/$tdir/f 3
24135         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
24136         MULTIPID=$!
24137
24138         FID1=$(lfs path2fid $DIR/$tdir/f1)
24139         FID2=$(lfs path2fid $DIR/$tdir/f2)
24140         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
24141
24142         kill -USR1 $MULTIPID
24143         wait
24144
24145         cnt=$(ls $DIR/$tdir | wc -l)
24146         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
24147 }
24148 run_test 421b "rm by fid on open file"
24149
24150 test_421c() {
24151         local cnt
24152         local FIDS
24153
24154         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24155                 skip "Need MDS version at least 2.12.54"
24156
24157         test_mkdir $DIR/$tdir
24158         createmany -o $DIR/$tdir/f 3
24159         touch $DIR/$tdir/$tfile
24160         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
24161         cnt=$(ls -1 $DIR/$tdir | wc -l)
24162         [ $cnt != 184 ] && error "unexpected #files: $cnt"
24163
24164         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
24165         $LFS rmfid $DIR $FID1 || error "rmfid failed"
24166
24167         cnt=$(ls $DIR/$tdir | wc -l)
24168         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
24169 }
24170 run_test 421c "rm by fid against hardlinked files"
24171
24172 test_421d() {
24173         local cnt
24174         local FIDS
24175
24176         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24177                 skip "Need MDS version at least 2.12.54"
24178
24179         test_mkdir $DIR/$tdir
24180         createmany -o $DIR/$tdir/f 4097
24181         cnt=$(ls -1 $DIR/$tdir | wc -l)
24182         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
24183
24184         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
24185         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24186
24187         cnt=$(ls $DIR/$tdir | wc -l)
24188         rm -rf $DIR/$tdir
24189         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24190 }
24191 run_test 421d "rmfid en masse"
24192
24193 test_421e() {
24194         local cnt
24195         local FID
24196
24197         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24198         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24199                 skip "Need MDS version at least 2.12.54"
24200
24201         mkdir -p $DIR/$tdir
24202         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24203         createmany -o $DIR/$tdir/striped_dir/f 512
24204         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24205         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24206
24207         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24208                 sed "s/[/][^:]*://g")
24209         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24210
24211         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24212         rm -rf $DIR/$tdir
24213         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24214 }
24215 run_test 421e "rmfid in DNE"
24216
24217 test_421f() {
24218         local cnt
24219         local FID
24220
24221         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24222                 skip "Need MDS version at least 2.12.54"
24223
24224         test_mkdir $DIR/$tdir
24225         touch $DIR/$tdir/f
24226         cnt=$(ls -1 $DIR/$tdir | wc -l)
24227         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24228
24229         FID=$(lfs path2fid $DIR/$tdir/f)
24230         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24231         # rmfid should fail
24232         cnt=$(ls -1 $DIR/$tdir | wc -l)
24233         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24234
24235         chmod a+rw $DIR/$tdir
24236         ls -la $DIR/$tdir
24237         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24238         # rmfid should fail
24239         cnt=$(ls -1 $DIR/$tdir | wc -l)
24240         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24241
24242         rm -f $DIR/$tdir/f
24243         $RUNAS touch $DIR/$tdir/f
24244         FID=$(lfs path2fid $DIR/$tdir/f)
24245         echo "rmfid as root"
24246         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24247         cnt=$(ls -1 $DIR/$tdir | wc -l)
24248         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24249
24250         rm -f $DIR/$tdir/f
24251         $RUNAS touch $DIR/$tdir/f
24252         cnt=$(ls -1 $DIR/$tdir | wc -l)
24253         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24254         FID=$(lfs path2fid $DIR/$tdir/f)
24255         # rmfid w/o user_fid2path mount option should fail
24256         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24257         cnt=$(ls -1 $DIR/$tdir | wc -l)
24258         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24259
24260         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24261         stack_trap "rmdir $tmpdir"
24262         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24263                 error "failed to mount client'"
24264         stack_trap "umount_client $tmpdir"
24265
24266         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24267         # rmfid should succeed
24268         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24269         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24270
24271         # rmfid shouldn't allow to remove files due to dir's permission
24272         chmod a+rwx $tmpdir/$tdir
24273         touch $tmpdir/$tdir/f
24274         ls -la $tmpdir/$tdir
24275         FID=$(lfs path2fid $tmpdir/$tdir/f)
24276         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24277         return 0
24278 }
24279 run_test 421f "rmfid checks permissions"
24280
24281 test_421g() {
24282         local cnt
24283         local FIDS
24284
24285         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24286         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24287                 skip "Need MDS version at least 2.12.54"
24288
24289         mkdir -p $DIR/$tdir
24290         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24291         createmany -o $DIR/$tdir/striped_dir/f 512
24292         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24293         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24294
24295         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24296                 sed "s/[/][^:]*://g")
24297
24298         rm -f $DIR/$tdir/striped_dir/f1*
24299         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24300         removed=$((512 - cnt))
24301
24302         # few files have been just removed, so we expect
24303         # rmfid to fail on their fids
24304         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24305         [ $removed != $errors ] && error "$errors != $removed"
24306
24307         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24308         rm -rf $DIR/$tdir
24309         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24310 }
24311 run_test 421g "rmfid to return errors properly"
24312
24313 test_422() {
24314         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24315         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24316         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24317         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24318         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24319
24320         local amc=$(at_max_get client)
24321         local amo=$(at_max_get mds1)
24322         local timeout=`lctl get_param -n timeout`
24323
24324         at_max_set 0 client
24325         at_max_set 0 mds1
24326
24327 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24328         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24329                         fail_val=$(((2*timeout + 10)*1000))
24330         touch $DIR/$tdir/d3/file &
24331         sleep 2
24332 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24333         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24334                         fail_val=$((2*timeout + 5))
24335         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24336         local pid=$!
24337         sleep 1
24338         kill -9 $pid
24339         sleep $((2 * timeout))
24340         echo kill $pid
24341         kill -9 $pid
24342         lctl mark touch
24343         touch $DIR/$tdir/d2/file3
24344         touch $DIR/$tdir/d2/file4
24345         touch $DIR/$tdir/d2/file5
24346
24347         wait
24348         at_max_set $amc client
24349         at_max_set $amo mds1
24350
24351         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24352         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24353                 error "Watchdog is always throttled"
24354 }
24355 run_test 422 "kill a process with RPC in progress"
24356
24357 stat_test() {
24358     df -h $MOUNT &
24359     df -h $MOUNT &
24360     df -h $MOUNT &
24361     df -h $MOUNT &
24362     df -h $MOUNT &
24363     df -h $MOUNT &
24364 }
24365
24366 test_423() {
24367     local _stats
24368     # ensure statfs cache is expired
24369     sleep 2;
24370
24371     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24372     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24373
24374     return 0
24375 }
24376 run_test 423 "statfs should return a right data"
24377
24378 test_424() {
24379 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24380         $LCTL set_param fail_loc=0x80000522
24381         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24382         rm -f $DIR/$tfile
24383 }
24384 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24385
24386 test_425() {
24387         test_mkdir -c -1 $DIR/$tdir
24388         $LFS setstripe -c -1 $DIR/$tdir
24389
24390         lru_resize_disable "" 100
24391         stack_trap "lru_resize_enable" EXIT
24392
24393         sleep 5
24394
24395         for i in $(seq $((MDSCOUNT * 125))); do
24396                 local t=$DIR/$tdir/$tfile_$i
24397
24398                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24399                         error_noexit "Create file $t"
24400         done
24401         stack_trap "rm -rf $DIR/$tdir" EXIT
24402
24403         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24404                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24405                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24406
24407                 [ $lock_count -le $lru_size ] ||
24408                         error "osc lock count $lock_count > lru size $lru_size"
24409         done
24410
24411         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24412                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24413                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24414
24415                 [ $lock_count -le $lru_size ] ||
24416                         error "mdc lock count $lock_count > lru size $lru_size"
24417         done
24418 }
24419 run_test 425 "lock count should not exceed lru size"
24420
24421 test_426() {
24422         splice-test -r $DIR/$tfile
24423         splice-test -rd $DIR/$tfile
24424         splice-test $DIR/$tfile
24425         splice-test -d $DIR/$tfile
24426 }
24427 run_test 426 "splice test on Lustre"
24428
24429 test_427() {
24430         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24431         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24432                 skip "Need MDS version at least 2.12.4"
24433         local log
24434
24435         mkdir $DIR/$tdir
24436         mkdir $DIR/$tdir/1
24437         mkdir $DIR/$tdir/2
24438         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24439         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24440
24441         $LFS getdirstripe $DIR/$tdir/1/dir
24442
24443         #first setfattr for creating updatelog
24444         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24445
24446 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24447         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24448         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24449         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24450
24451         sleep 2
24452         fail mds2
24453         wait_recovery_complete mds2 $((2*TIMEOUT))
24454
24455         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24456         echo $log | grep "get update log failed" &&
24457                 error "update log corruption is detected" || true
24458 }
24459 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24460
24461 test_428() {
24462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24463         local cache_limit=$CACHE_MAX
24464
24465         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
24466         $LCTL set_param -n llite.*.max_cached_mb=64
24467
24468         mkdir $DIR/$tdir
24469         $LFS setstripe -c 1 $DIR/$tdir
24470         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
24471         stack_trap "rm -f $DIR/$tdir/$tfile.*"
24472         #test write
24473         for f in $(seq 4); do
24474                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
24475         done
24476         wait
24477
24478         cancel_lru_locks osc
24479         # Test read
24480         for f in $(seq 4); do
24481                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
24482         done
24483         wait
24484 }
24485 run_test 428 "large block size IO should not hang"
24486
24487 lseek_test_430() {
24488         local offset
24489         local file=$1
24490
24491         # data at [200K, 400K)
24492         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24493                 error "256K->512K dd fails"
24494         # data at [2M, 3M)
24495         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24496                 error "2M->3M dd fails"
24497         # data at [4M, 5M)
24498         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24499                 error "4M->5M dd fails"
24500         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24501         # start at first component hole #1
24502         printf "Seeking hole from 1000 ... "
24503         offset=$(lseek_test -l 1000 $file)
24504         echo $offset
24505         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24506         printf "Seeking data from 1000 ... "
24507         offset=$(lseek_test -d 1000 $file)
24508         echo $offset
24509         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24510
24511         # start at first component data block
24512         printf "Seeking hole from 300000 ... "
24513         offset=$(lseek_test -l 300000 $file)
24514         echo $offset
24515         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24516         printf "Seeking data from 300000 ... "
24517         offset=$(lseek_test -d 300000 $file)
24518         echo $offset
24519         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24520
24521         # start at the first component but beyond end of object size
24522         printf "Seeking hole from 1000000 ... "
24523         offset=$(lseek_test -l 1000000 $file)
24524         echo $offset
24525         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24526         printf "Seeking data from 1000000 ... "
24527         offset=$(lseek_test -d 1000000 $file)
24528         echo $offset
24529         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24530
24531         # start at second component stripe 2 (empty file)
24532         printf "Seeking hole from 1500000 ... "
24533         offset=$(lseek_test -l 1500000 $file)
24534         echo $offset
24535         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
24536         printf "Seeking data from 1500000 ... "
24537         offset=$(lseek_test -d 1500000 $file)
24538         echo $offset
24539         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24540
24541         # start at second component stripe 1 (all data)
24542         printf "Seeking hole from 3000000 ... "
24543         offset=$(lseek_test -l 3000000 $file)
24544         echo $offset
24545         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
24546         printf "Seeking data from 3000000 ... "
24547         offset=$(lseek_test -d 3000000 $file)
24548         echo $offset
24549         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
24550
24551         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
24552                 error "2nd dd fails"
24553         echo "Add data block at 640K...1280K"
24554
24555         # start at before new data block, in hole
24556         printf "Seeking hole from 600000 ... "
24557         offset=$(lseek_test -l 600000 $file)
24558         echo $offset
24559         [[ $offset == 600000 ]] || error "offset $offset != 600000"
24560         printf "Seeking data from 600000 ... "
24561         offset=$(lseek_test -d 600000 $file)
24562         echo $offset
24563         [[ $offset == 655360 ]] || error "offset $offset != 655360"
24564
24565         # start at the first component new data block
24566         printf "Seeking hole from 1000000 ... "
24567         offset=$(lseek_test -l 1000000 $file)
24568         echo $offset
24569         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24570         printf "Seeking data from 1000000 ... "
24571         offset=$(lseek_test -d 1000000 $file)
24572         echo $offset
24573         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24574
24575         # start at second component stripe 2, new data
24576         printf "Seeking hole from 1200000 ... "
24577         offset=$(lseek_test -l 1200000 $file)
24578         echo $offset
24579         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24580         printf "Seeking data from 1200000 ... "
24581         offset=$(lseek_test -d 1200000 $file)
24582         echo $offset
24583         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
24584
24585         # start beyond file end
24586         printf "Using offset > filesize ... "
24587         lseek_test -l 4000000 $file && error "lseek should fail"
24588         printf "Using offset > filesize ... "
24589         lseek_test -d 4000000 $file && error "lseek should fail"
24590
24591         printf "Done\n\n"
24592 }
24593
24594 test_430a() {
24595         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
24596                 skip "MDT does not support SEEK_HOLE"
24597
24598         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24599                 skip "OST does not support SEEK_HOLE"
24600
24601         local file=$DIR/$tdir/$tfile
24602
24603         mkdir -p $DIR/$tdir
24604
24605         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
24606         # OST stripe #1 will have continuous data at [1M, 3M)
24607         # OST stripe #2 is empty
24608         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
24609         lseek_test_430 $file
24610         rm $file
24611         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
24612         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
24613         lseek_test_430 $file
24614         rm $file
24615         $LFS setstripe -c2 -S 512K $file
24616         echo "Two stripes, stripe size 512K"
24617         lseek_test_430 $file
24618         rm $file
24619         # FLR with stale mirror
24620         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
24621                        -N -c2 -S 1M $file
24622         echo "Mirrored file:"
24623         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
24624         echo "Plain 2 stripes 1M"
24625         lseek_test_430 $file
24626         rm $file
24627 }
24628 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
24629
24630 test_430b() {
24631         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24632                 skip "OST does not support SEEK_HOLE"
24633
24634         local offset
24635         local file=$DIR/$tdir/$tfile
24636
24637         mkdir -p $DIR/$tdir
24638         # Empty layout lseek should fail
24639         $MCREATE $file
24640         # seek from 0
24641         printf "Seeking hole from 0 ... "
24642         lseek_test -l 0 $file && error "lseek should fail"
24643         printf "Seeking data from 0 ... "
24644         lseek_test -d 0 $file && error "lseek should fail"
24645         rm $file
24646
24647         # 1M-hole file
24648         $LFS setstripe -E 1M -c2 -E eof $file
24649         $TRUNCATE $file 1048576
24650         printf "Seeking hole from 1000000 ... "
24651         offset=$(lseek_test -l 1000000 $file)
24652         echo $offset
24653         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24654         printf "Seeking data from 1000000 ... "
24655         lseek_test -d 1000000 $file && error "lseek should fail"
24656         rm $file
24657
24658         # full component followed by non-inited one
24659         $LFS setstripe -E 1M -c2 -E eof $file
24660         dd if=/dev/urandom of=$file bs=1M count=1
24661         printf "Seeking hole from 1000000 ... "
24662         offset=$(lseek_test -l 1000000 $file)
24663         echo $offset
24664         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24665         printf "Seeking hole from 1048576 ... "
24666         lseek_test -l 1048576 $file && error "lseek should fail"
24667         # init second component and truncate back
24668         echo "123" >> $file
24669         $TRUNCATE $file 1048576
24670         printf "Seeking hole from 1000000 ... "
24671         offset=$(lseek_test -l 1000000 $file)
24672         echo $offset
24673         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
24674         printf "Seeking hole from 1048576 ... "
24675         lseek_test -l 1048576 $file && error "lseek should fail"
24676         # boundary checks for big values
24677         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
24678         offset=$(lseek_test -d 0 $file.10g)
24679         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
24680         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
24681         offset=$(lseek_test -d 0 $file.100g)
24682         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
24683         return 0
24684 }
24685 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
24686
24687 test_430c() {
24688         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24689                 skip "OST does not support SEEK_HOLE"
24690
24691         local file=$DIR/$tdir/$tfile
24692         local start
24693
24694         mkdir -p $DIR/$tdir
24695         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
24696
24697         # cp version 8.33+ prefers lseek over fiemap
24698         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
24699                 start=$SECONDS
24700                 time cp $file /dev/null
24701                 (( SECONDS - start < 5 )) ||
24702                         error "cp: too long runtime $((SECONDS - start))"
24703
24704         fi
24705         # tar version 1.29+ supports SEEK_HOLE/DATA
24706         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
24707                 start=$SECONDS
24708                 time tar cS $file - | cat > /dev/null
24709                 (( SECONDS - start < 5 )) ||
24710                         error "tar: too long runtime $((SECONDS - start))"
24711         fi
24712 }
24713 run_test 430c "lseek: external tools check"
24714
24715 test_431() { # LU-14187
24716         local file=$DIR/$tdir/$tfile
24717
24718         mkdir -p $DIR/$tdir
24719         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
24720         dd if=/dev/urandom of=$file bs=4k count=1
24721         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
24722         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
24723         #define OBD_FAIL_OST_RESTART_IO 0x251
24724         do_facet ost1 "$LCTL set_param fail_loc=0x251"
24725         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
24726         cp $file $file.0
24727         cancel_lru_locks
24728         sync_all_data
24729         echo 3 > /proc/sys/vm/drop_caches
24730         diff  $file $file.0 || error "data diff"
24731 }
24732 run_test 431 "Restart transaction for IO"
24733
24734 prep_801() {
24735         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24736         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24737                 skip "Need server version at least 2.9.55"
24738
24739         start_full_debug_logging
24740 }
24741
24742 post_801() {
24743         stop_full_debug_logging
24744 }
24745
24746 barrier_stat() {
24747         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24748                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24749                            awk '/The barrier for/ { print $7 }')
24750                 echo $st
24751         else
24752                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24753                 echo \'$st\'
24754         fi
24755 }
24756
24757 barrier_expired() {
24758         local expired
24759
24760         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24761                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24762                           awk '/will be expired/ { print $7 }')
24763         else
24764                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24765         fi
24766
24767         echo $expired
24768 }
24769
24770 test_801a() {
24771         prep_801
24772
24773         echo "Start barrier_freeze at: $(date)"
24774         #define OBD_FAIL_BARRIER_DELAY          0x2202
24775         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24776         # Do not reduce barrier time - See LU-11873
24777         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24778
24779         sleep 2
24780         local b_status=$(barrier_stat)
24781         echo "Got barrier status at: $(date)"
24782         [ "$b_status" = "'freezing_p1'" ] ||
24783                 error "(1) unexpected barrier status $b_status"
24784
24785         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24786         wait
24787         b_status=$(barrier_stat)
24788         [ "$b_status" = "'frozen'" ] ||
24789                 error "(2) unexpected barrier status $b_status"
24790
24791         local expired=$(barrier_expired)
24792         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24793         sleep $((expired + 3))
24794
24795         b_status=$(barrier_stat)
24796         [ "$b_status" = "'expired'" ] ||
24797                 error "(3) unexpected barrier status $b_status"
24798
24799         # Do not reduce barrier time - See LU-11873
24800         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24801                 error "(4) fail to freeze barrier"
24802
24803         b_status=$(barrier_stat)
24804         [ "$b_status" = "'frozen'" ] ||
24805                 error "(5) unexpected barrier status $b_status"
24806
24807         echo "Start barrier_thaw at: $(date)"
24808         #define OBD_FAIL_BARRIER_DELAY          0x2202
24809         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24810         do_facet mgs $LCTL barrier_thaw $FSNAME &
24811
24812         sleep 2
24813         b_status=$(barrier_stat)
24814         echo "Got barrier status at: $(date)"
24815         [ "$b_status" = "'thawing'" ] ||
24816                 error "(6) unexpected barrier status $b_status"
24817
24818         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24819         wait
24820         b_status=$(barrier_stat)
24821         [ "$b_status" = "'thawed'" ] ||
24822                 error "(7) unexpected barrier status $b_status"
24823
24824         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24825         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24826         do_facet mgs $LCTL barrier_freeze $FSNAME
24827
24828         b_status=$(barrier_stat)
24829         [ "$b_status" = "'failed'" ] ||
24830                 error "(8) unexpected barrier status $b_status"
24831
24832         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24833         do_facet mgs $LCTL barrier_thaw $FSNAME
24834
24835         post_801
24836 }
24837 run_test 801a "write barrier user interfaces and stat machine"
24838
24839 test_801b() {
24840         prep_801
24841
24842         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24843         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24844         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24845         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24846         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24847
24848         cancel_lru_locks mdc
24849
24850         # 180 seconds should be long enough
24851         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24852
24853         local b_status=$(barrier_stat)
24854         [ "$b_status" = "'frozen'" ] ||
24855                 error "(6) unexpected barrier status $b_status"
24856
24857         mkdir $DIR/$tdir/d0/d10 &
24858         mkdir_pid=$!
24859
24860         touch $DIR/$tdir/d1/f13 &
24861         touch_pid=$!
24862
24863         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24864         ln_pid=$!
24865
24866         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24867         mv_pid=$!
24868
24869         rm -f $DIR/$tdir/d4/f12 &
24870         rm_pid=$!
24871
24872         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24873
24874         # To guarantee taht the 'stat' is not blocked
24875         b_status=$(barrier_stat)
24876         [ "$b_status" = "'frozen'" ] ||
24877                 error "(8) unexpected barrier status $b_status"
24878
24879         # let above commands to run at background
24880         sleep 5
24881
24882         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24883         ps -p $touch_pid || error "(10) touch should be blocked"
24884         ps -p $ln_pid || error "(11) link should be blocked"
24885         ps -p $mv_pid || error "(12) rename should be blocked"
24886         ps -p $rm_pid || error "(13) unlink should be blocked"
24887
24888         b_status=$(barrier_stat)
24889         [ "$b_status" = "'frozen'" ] ||
24890                 error "(14) unexpected barrier status $b_status"
24891
24892         do_facet mgs $LCTL barrier_thaw $FSNAME
24893         b_status=$(barrier_stat)
24894         [ "$b_status" = "'thawed'" ] ||
24895                 error "(15) unexpected barrier status $b_status"
24896
24897         wait $mkdir_pid || error "(16) mkdir should succeed"
24898         wait $touch_pid || error "(17) touch should succeed"
24899         wait $ln_pid || error "(18) link should succeed"
24900         wait $mv_pid || error "(19) rename should succeed"
24901         wait $rm_pid || error "(20) unlink should succeed"
24902
24903         post_801
24904 }
24905 run_test 801b "modification will be blocked by write barrier"
24906
24907 test_801c() {
24908         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24909
24910         prep_801
24911
24912         stop mds2 || error "(1) Fail to stop mds2"
24913
24914         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24915
24916         local b_status=$(barrier_stat)
24917         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24918                 do_facet mgs $LCTL barrier_thaw $FSNAME
24919                 error "(2) unexpected barrier status $b_status"
24920         }
24921
24922         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24923                 error "(3) Fail to rescan barrier bitmap"
24924
24925         # Do not reduce barrier time - See LU-11873
24926         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24927
24928         b_status=$(barrier_stat)
24929         [ "$b_status" = "'frozen'" ] ||
24930                 error "(4) unexpected barrier status $b_status"
24931
24932         do_facet mgs $LCTL barrier_thaw $FSNAME
24933         b_status=$(barrier_stat)
24934         [ "$b_status" = "'thawed'" ] ||
24935                 error "(5) unexpected barrier status $b_status"
24936
24937         local devname=$(mdsdevname 2)
24938
24939         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24940
24941         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24942                 error "(7) Fail to rescan barrier bitmap"
24943
24944         post_801
24945 }
24946 run_test 801c "rescan barrier bitmap"
24947
24948 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24949 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24950 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24951 saved_MOUNT_OPTS=$MOUNT_OPTS
24952
24953 cleanup_802a() {
24954         trap 0
24955
24956         stopall
24957         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24958         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24959         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24960         MOUNT_OPTS=$saved_MOUNT_OPTS
24961         setupall
24962 }
24963
24964 test_802a() {
24965         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24966         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24967         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24968                 skip "Need server version at least 2.9.55"
24969
24970         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24971
24972         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24973
24974         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24975                 error "(2) Fail to copy"
24976
24977         trap cleanup_802a EXIT
24978
24979         # sync by force before remount as readonly
24980         sync; sync_all_data; sleep 3; sync_all_data
24981
24982         stopall
24983
24984         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24985         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24986         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24987
24988         echo "Mount the server as read only"
24989         setupall server_only || error "(3) Fail to start servers"
24990
24991         echo "Mount client without ro should fail"
24992         mount_client $MOUNT &&
24993                 error "(4) Mount client without 'ro' should fail"
24994
24995         echo "Mount client with ro should succeed"
24996         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24997         mount_client $MOUNT ||
24998                 error "(5) Mount client with 'ro' should succeed"
24999
25000         echo "Modify should be refused"
25001         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25002
25003         echo "Read should be allowed"
25004         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25005                 error "(7) Read should succeed under ro mode"
25006
25007         cleanup_802a
25008 }
25009 run_test 802a "simulate readonly device"
25010
25011 test_802b() {
25012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25013         remote_mds_nodsh && skip "remote MDS with nodsh"
25014
25015         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25016                 skip "readonly option not available"
25017
25018         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25019
25020         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25021                 error "(2) Fail to copy"
25022
25023         # write back all cached data before setting MDT to readonly
25024         cancel_lru_locks
25025         sync_all_data
25026
25027         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25028         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25029
25030         echo "Modify should be refused"
25031         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25032
25033         echo "Read should be allowed"
25034         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25035                 error "(7) Read should succeed under ro mode"
25036
25037         # disable readonly
25038         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25039 }
25040 run_test 802b "be able to set MDTs to readonly"
25041
25042 test_803a() {
25043         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25044         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25045                 skip "MDS needs to be newer than 2.10.54"
25046
25047         mkdir -p $DIR/$tdir
25048         # Create some objects on all MDTs to trigger related logs objects
25049         for idx in $(seq $MDSCOUNT); do
25050                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
25051                         $DIR/$tdir/dir${idx} ||
25052                         error "Fail to create $DIR/$tdir/dir${idx}"
25053         done
25054
25055         sync; sleep 3
25056         wait_delete_completed # ensure old test cleanups are finished
25057         echo "before create:"
25058         $LFS df -i $MOUNT
25059         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25060
25061         for i in {1..10}; do
25062                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
25063                         error "Fail to create $DIR/$tdir/foo$i"
25064         done
25065
25066         sync; sleep 3
25067         echo "after create:"
25068         $LFS df -i $MOUNT
25069         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25070
25071         # allow for an llog to be cleaned up during the test
25072         [ $after_used -ge $((before_used + 10 - 1)) ] ||
25073                 error "before ($before_used) + 10 > after ($after_used)"
25074
25075         for i in {1..10}; do
25076                 rm -rf $DIR/$tdir/foo$i ||
25077                         error "Fail to remove $DIR/$tdir/foo$i"
25078         done
25079
25080         sleep 3 # avoid MDT return cached statfs
25081         wait_delete_completed
25082         echo "after unlink:"
25083         $LFS df -i $MOUNT
25084         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25085
25086         # allow for an llog to be created during the test
25087         [ $after_used -le $((before_used + 1)) ] ||
25088                 error "after ($after_used) > before ($before_used) + 1"
25089 }
25090 run_test 803a "verify agent object for remote object"
25091
25092 test_803b() {
25093         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25094         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
25095                 skip "MDS needs to be newer than 2.13.56"
25096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25097
25098         for i in $(seq 0 $((MDSCOUNT - 1))); do
25099                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
25100         done
25101
25102         local before=0
25103         local after=0
25104
25105         local tmp
25106
25107         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25108         for i in $(seq 0 $((MDSCOUNT - 1))); do
25109                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25110                         awk '/getattr/ { print $2 }')
25111                 before=$((before + tmp))
25112         done
25113         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25114         for i in $(seq 0 $((MDSCOUNT - 1))); do
25115                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25116                         awk '/getattr/ { print $2 }')
25117                 after=$((after + tmp))
25118         done
25119
25120         [ $before -eq $after ] || error "getattr count $before != $after"
25121 }
25122 run_test 803b "remote object can getattr from cache"
25123
25124 test_804() {
25125         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25126         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25127                 skip "MDS needs to be newer than 2.10.54"
25128         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
25129
25130         mkdir -p $DIR/$tdir
25131         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
25132                 error "Fail to create $DIR/$tdir/dir0"
25133
25134         local fid=$($LFS path2fid $DIR/$tdir/dir0)
25135         local dev=$(mdsdevname 2)
25136
25137         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25138                 grep ${fid} || error "NOT found agent entry for dir0"
25139
25140         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
25141                 error "Fail to create $DIR/$tdir/dir1"
25142
25143         touch $DIR/$tdir/dir1/foo0 ||
25144                 error "Fail to create $DIR/$tdir/dir1/foo0"
25145         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
25146         local rc=0
25147
25148         for idx in $(seq $MDSCOUNT); do
25149                 dev=$(mdsdevname $idx)
25150                 do_facet mds${idx} \
25151                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25152                         grep ${fid} && rc=$idx
25153         done
25154
25155         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
25156                 error "Fail to rename foo0 to foo1"
25157         if [ $rc -eq 0 ]; then
25158                 for idx in $(seq $MDSCOUNT); do
25159                         dev=$(mdsdevname $idx)
25160                         do_facet mds${idx} \
25161                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25162                         grep ${fid} && rc=$idx
25163                 done
25164         fi
25165
25166         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
25167                 error "Fail to rename foo1 to foo2"
25168         if [ $rc -eq 0 ]; then
25169                 for idx in $(seq $MDSCOUNT); do
25170                         dev=$(mdsdevname $idx)
25171                         do_facet mds${idx} \
25172                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25173                         grep ${fid} && rc=$idx
25174                 done
25175         fi
25176
25177         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
25178
25179         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
25180                 error "Fail to link to $DIR/$tdir/dir1/foo2"
25181         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
25182                 error "Fail to rename foo2 to foo0"
25183         unlink $DIR/$tdir/dir1/foo0 ||
25184                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
25185         rm -rf $DIR/$tdir/dir0 ||
25186                 error "Fail to rm $DIR/$tdir/dir0"
25187
25188         for idx in $(seq $MDSCOUNT); do
25189                 dev=$(mdsdevname $idx)
25190                 rc=0
25191
25192                 stop mds${idx}
25193                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25194                         rc=$?
25195                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25196                         error "mount mds$idx failed"
25197                 df $MOUNT > /dev/null 2>&1
25198
25199                 # e2fsck should not return error
25200                 [ $rc -eq 0 ] ||
25201                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25202         done
25203 }
25204 run_test 804 "verify agent entry for remote entry"
25205
25206 cleanup_805() {
25207         do_facet $SINGLEMDS zfs set quota=$old $fsset
25208         unlinkmany $DIR/$tdir/f- 1000000
25209         trap 0
25210 }
25211
25212 test_805() {
25213         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25214         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25215         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25216                 skip "netfree not implemented before 0.7"
25217         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25218                 skip "Need MDS version at least 2.10.57"
25219
25220         local fsset
25221         local freekb
25222         local usedkb
25223         local old
25224         local quota
25225         local pref="osd-zfs.$FSNAME-MDT0000."
25226
25227         # limit available space on MDS dataset to meet nospace issue
25228         # quickly. then ZFS 0.7.2 can use reserved space if asked
25229         # properly (using netfree flag in osd_declare_destroy()
25230         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25231         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25232                 gawk '{print $3}')
25233         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25234         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25235         let "usedkb=usedkb-freekb"
25236         let "freekb=freekb/2"
25237         if let "freekb > 5000"; then
25238                 let "freekb=5000"
25239         fi
25240         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25241         trap cleanup_805 EXIT
25242         mkdir $DIR/$tdir
25243         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25244                 error "Can't set PFL layout"
25245         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25246         rm -rf $DIR/$tdir || error "not able to remove"
25247         do_facet $SINGLEMDS zfs set quota=$old $fsset
25248         trap 0
25249 }
25250 run_test 805 "ZFS can remove from full fs"
25251
25252 # Size-on-MDS test
25253 check_lsom_data()
25254 {
25255         local file=$1
25256         local size=$($LFS getsom -s $file)
25257         local expect=$(stat -c %s $file)
25258
25259         [[ $size == $expect ]] ||
25260                 error "$file expected size: $expect, got: $size"
25261
25262         local blocks=$($LFS getsom -b $file)
25263         expect=$(stat -c %b $file)
25264         [[ $blocks == $expect ]] ||
25265                 error "$file expected blocks: $expect, got: $blocks"
25266 }
25267
25268 check_lsom_size()
25269 {
25270         local size=$($LFS getsom -s $1)
25271         local expect=$2
25272
25273         [[ $size == $expect ]] ||
25274                 error "$file expected size: $expect, got: $size"
25275 }
25276
25277 test_806() {
25278         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25279                 skip "Need MDS version at least 2.11.52"
25280
25281         local bs=1048576
25282
25283         touch $DIR/$tfile || error "touch $tfile failed"
25284
25285         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25286         save_lustre_params client "llite.*.xattr_cache" > $save
25287         lctl set_param llite.*.xattr_cache=0
25288         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25289
25290         # single-threaded write
25291         echo "Test SOM for single-threaded write"
25292         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25293                 error "write $tfile failed"
25294         check_lsom_size $DIR/$tfile $bs
25295
25296         local num=32
25297         local size=$(($num * $bs))
25298         local offset=0
25299         local i
25300
25301         echo "Test SOM for single client multi-threaded($num) write"
25302         $TRUNCATE $DIR/$tfile 0
25303         for ((i = 0; i < $num; i++)); do
25304                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25305                 local pids[$i]=$!
25306                 offset=$((offset + $bs))
25307         done
25308         for (( i=0; i < $num; i++ )); do
25309                 wait ${pids[$i]}
25310         done
25311         check_lsom_size $DIR/$tfile $size
25312
25313         $TRUNCATE $DIR/$tfile 0
25314         for ((i = 0; i < $num; i++)); do
25315                 offset=$((offset - $bs))
25316                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25317                 local pids[$i]=$!
25318         done
25319         for (( i=0; i < $num; i++ )); do
25320                 wait ${pids[$i]}
25321         done
25322         check_lsom_size $DIR/$tfile $size
25323
25324         # multi-client writes
25325         num=$(get_node_count ${CLIENTS//,/ })
25326         size=$(($num * $bs))
25327         offset=0
25328         i=0
25329
25330         echo "Test SOM for multi-client ($num) writes"
25331         $TRUNCATE $DIR/$tfile 0
25332         for client in ${CLIENTS//,/ }; do
25333                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25334                 local pids[$i]=$!
25335                 i=$((i + 1))
25336                 offset=$((offset + $bs))
25337         done
25338         for (( i=0; i < $num; i++ )); do
25339                 wait ${pids[$i]}
25340         done
25341         check_lsom_size $DIR/$tfile $offset
25342
25343         i=0
25344         $TRUNCATE $DIR/$tfile 0
25345         for client in ${CLIENTS//,/ }; do
25346                 offset=$((offset - $bs))
25347                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25348                 local pids[$i]=$!
25349                 i=$((i + 1))
25350         done
25351         for (( i=0; i < $num; i++ )); do
25352                 wait ${pids[$i]}
25353         done
25354         check_lsom_size $DIR/$tfile $size
25355
25356         # verify truncate
25357         echo "Test SOM for truncate"
25358         $TRUNCATE $DIR/$tfile 1048576
25359         check_lsom_size $DIR/$tfile 1048576
25360         $TRUNCATE $DIR/$tfile 1234
25361         check_lsom_size $DIR/$tfile 1234
25362
25363         # verify SOM blocks count
25364         echo "Verify SOM block count"
25365         $TRUNCATE $DIR/$tfile 0
25366         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25367                 error "failed to write file $tfile"
25368         check_lsom_data $DIR/$tfile
25369 }
25370 run_test 806 "Verify Lazy Size on MDS"
25371
25372 test_807() {
25373         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25374         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25375                 skip "Need MDS version at least 2.11.52"
25376
25377         # Registration step
25378         changelog_register || error "changelog_register failed"
25379         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25380         changelog_users $SINGLEMDS | grep -q $cl_user ||
25381                 error "User $cl_user not found in changelog_users"
25382
25383         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25384         save_lustre_params client "llite.*.xattr_cache" > $save
25385         lctl set_param llite.*.xattr_cache=0
25386         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25387
25388         rm -rf $DIR/$tdir || error "rm $tdir failed"
25389         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25390         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25391         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25392         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25393                 error "truncate $tdir/trunc failed"
25394
25395         local bs=1048576
25396         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25397                 error "write $tfile failed"
25398
25399         # multi-client wirtes
25400         local num=$(get_node_count ${CLIENTS//,/ })
25401         local offset=0
25402         local i=0
25403
25404         echo "Test SOM for multi-client ($num) writes"
25405         touch $DIR/$tfile || error "touch $tfile failed"
25406         $TRUNCATE $DIR/$tfile 0
25407         for client in ${CLIENTS//,/ }; do
25408                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25409                 local pids[$i]=$!
25410                 i=$((i + 1))
25411                 offset=$((offset + $bs))
25412         done
25413         for (( i=0; i < $num; i++ )); do
25414                 wait ${pids[$i]}
25415         done
25416
25417         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25418         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25419         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25420         check_lsom_data $DIR/$tdir/trunc
25421         check_lsom_data $DIR/$tdir/single_dd
25422         check_lsom_data $DIR/$tfile
25423
25424         rm -rf $DIR/$tdir
25425         # Deregistration step
25426         changelog_deregister || error "changelog_deregister failed"
25427 }
25428 run_test 807 "verify LSOM syncing tool"
25429
25430 check_som_nologged()
25431 {
25432         local lines=$($LFS changelog $FSNAME-MDT0000 |
25433                 grep 'x=trusted.som' | wc -l)
25434         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25435 }
25436
25437 test_808() {
25438         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25439                 skip "Need MDS version at least 2.11.55"
25440
25441         # Registration step
25442         changelog_register || error "changelog_register failed"
25443
25444         touch $DIR/$tfile || error "touch $tfile failed"
25445         check_som_nologged
25446
25447         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25448                 error "write $tfile failed"
25449         check_som_nologged
25450
25451         $TRUNCATE $DIR/$tfile 1234
25452         check_som_nologged
25453
25454         $TRUNCATE $DIR/$tfile 1048576
25455         check_som_nologged
25456
25457         # Deregistration step
25458         changelog_deregister || error "changelog_deregister failed"
25459 }
25460 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25461
25462 check_som_nodata()
25463 {
25464         $LFS getsom $1
25465         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25466 }
25467
25468 test_809() {
25469         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25470                 skip "Need MDS version at least 2.11.56"
25471
25472         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25473                 error "failed to create DoM-only file $DIR/$tfile"
25474         touch $DIR/$tfile || error "touch $tfile failed"
25475         check_som_nodata $DIR/$tfile
25476
25477         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25478                 error "write $tfile failed"
25479         check_som_nodata $DIR/$tfile
25480
25481         $TRUNCATE $DIR/$tfile 1234
25482         check_som_nodata $DIR/$tfile
25483
25484         $TRUNCATE $DIR/$tfile 4097
25485         check_som_nodata $DIR/$file
25486 }
25487 run_test 809 "Verify no SOM xattr store for DoM-only files"
25488
25489 test_810() {
25490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25491         $GSS && skip_env "could not run with gss"
25492         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25493                 skip "OST < 2.12.58 doesn't align checksum"
25494
25495         set_checksums 1
25496         stack_trap "set_checksums $ORIG_CSUM" EXIT
25497         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25498
25499         local csum
25500         local before
25501         local after
25502         for csum in $CKSUM_TYPES; do
25503                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25504                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25505                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25506                         eval set -- $i
25507                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25508                         before=$(md5sum $DIR/$tfile)
25509                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25510                         after=$(md5sum $DIR/$tfile)
25511                         [ "$before" == "$after" ] ||
25512                                 error "$csum: $before != $after bs=$1 seek=$2"
25513                 done
25514         done
25515 }
25516 run_test 810 "partial page writes on ZFS (LU-11663)"
25517
25518 test_812a() {
25519         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25520                 skip "OST < 2.12.51 doesn't support this fail_loc"
25521
25522         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25523         # ensure ost1 is connected
25524         stat $DIR/$tfile >/dev/null || error "can't stat"
25525         wait_osc_import_state client ost1 FULL
25526         # no locks, no reqs to let the connection idle
25527         cancel_lru_locks osc
25528
25529         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25530 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25531         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25532         wait_osc_import_state client ost1 CONNECTING
25533         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25534
25535         stat $DIR/$tfile >/dev/null || error "can't stat file"
25536 }
25537 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
25538
25539 test_812b() { # LU-12378
25540         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25541                 skip "OST < 2.12.51 doesn't support this fail_loc"
25542
25543         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
25544         # ensure ost1 is connected
25545         stat $DIR/$tfile >/dev/null || error "can't stat"
25546         wait_osc_import_state client ost1 FULL
25547         # no locks, no reqs to let the connection idle
25548         cancel_lru_locks osc
25549
25550         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25551 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25552         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25553         wait_osc_import_state client ost1 CONNECTING
25554         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25555
25556         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
25557         wait_osc_import_state client ost1 IDLE
25558 }
25559 run_test 812b "do not drop no resend request for idle connect"
25560
25561 test_813() {
25562         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
25563         [ -z "$file_heat_sav" ] && skip "no file heat support"
25564
25565         local readsample
25566         local writesample
25567         local readbyte
25568         local writebyte
25569         local readsample1
25570         local writesample1
25571         local readbyte1
25572         local writebyte1
25573
25574         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
25575         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
25576
25577         $LCTL set_param -n llite.*.file_heat=1
25578         echo "Turn on file heat"
25579         echo "Period second: $period_second, Decay percentage: $decay_pct"
25580
25581         echo "QQQQ" > $DIR/$tfile
25582         echo "QQQQ" > $DIR/$tfile
25583         echo "QQQQ" > $DIR/$tfile
25584         cat $DIR/$tfile > /dev/null
25585         cat $DIR/$tfile > /dev/null
25586         cat $DIR/$tfile > /dev/null
25587         cat $DIR/$tfile > /dev/null
25588
25589         local out=$($LFS heat_get $DIR/$tfile)
25590
25591         $LFS heat_get $DIR/$tfile
25592         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25593         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25594         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25595         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25596
25597         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
25598         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
25599         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
25600         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
25601
25602         sleep $((period_second + 3))
25603         echo "Sleep $((period_second + 3)) seconds..."
25604         # The recursion formula to calculate the heat of the file f is as
25605         # follow:
25606         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
25607         # Where Hi is the heat value in the period between time points i*I and
25608         # (i+1)*I; Ci is the access count in the period; the symbol P refers
25609         # to the weight of Ci.
25610         out=$($LFS heat_get $DIR/$tfile)
25611         $LFS heat_get $DIR/$tfile
25612         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25613         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25614         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25615         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25616
25617         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
25618                 error "read sample ($readsample) is wrong"
25619         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
25620                 error "write sample ($writesample) is wrong"
25621         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
25622                 error "read bytes ($readbyte) is wrong"
25623         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
25624                 error "write bytes ($writebyte) is wrong"
25625
25626         echo "QQQQ" > $DIR/$tfile
25627         echo "QQQQ" > $DIR/$tfile
25628         echo "QQQQ" > $DIR/$tfile
25629         cat $DIR/$tfile > /dev/null
25630         cat $DIR/$tfile > /dev/null
25631         cat $DIR/$tfile > /dev/null
25632         cat $DIR/$tfile > /dev/null
25633
25634         sleep $((period_second + 3))
25635         echo "Sleep $((period_second + 3)) seconds..."
25636
25637         out=$($LFS heat_get $DIR/$tfile)
25638         $LFS heat_get $DIR/$tfile
25639         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25640         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25641         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25642         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25643
25644         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
25645                 4 * $decay_pct) / 100") -eq 1 ] ||
25646                 error "read sample ($readsample1) is wrong"
25647         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
25648                 3 * $decay_pct) / 100") -eq 1 ] ||
25649                 error "write sample ($writesample1) is wrong"
25650         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
25651                 20 * $decay_pct) / 100") -eq 1 ] ||
25652                 error "read bytes ($readbyte1) is wrong"
25653         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
25654                 15 * $decay_pct) / 100") -eq 1 ] ||
25655                 error "write bytes ($writebyte1) is wrong"
25656
25657         echo "Turn off file heat for the file $DIR/$tfile"
25658         $LFS heat_set -o $DIR/$tfile
25659
25660         echo "QQQQ" > $DIR/$tfile
25661         echo "QQQQ" > $DIR/$tfile
25662         echo "QQQQ" > $DIR/$tfile
25663         cat $DIR/$tfile > /dev/null
25664         cat $DIR/$tfile > /dev/null
25665         cat $DIR/$tfile > /dev/null
25666         cat $DIR/$tfile > /dev/null
25667
25668         out=$($LFS heat_get $DIR/$tfile)
25669         $LFS heat_get $DIR/$tfile
25670         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25671         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25672         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25673         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25674
25675         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25676         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25677         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25678         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25679
25680         echo "Trun on file heat for the file $DIR/$tfile"
25681         $LFS heat_set -O $DIR/$tfile
25682
25683         echo "QQQQ" > $DIR/$tfile
25684         echo "QQQQ" > $DIR/$tfile
25685         echo "QQQQ" > $DIR/$tfile
25686         cat $DIR/$tfile > /dev/null
25687         cat $DIR/$tfile > /dev/null
25688         cat $DIR/$tfile > /dev/null
25689         cat $DIR/$tfile > /dev/null
25690
25691         out=$($LFS heat_get $DIR/$tfile)
25692         $LFS heat_get $DIR/$tfile
25693         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25694         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25695         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25696         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25697
25698         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
25699         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
25700         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
25701         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
25702
25703         $LFS heat_set -c $DIR/$tfile
25704         $LCTL set_param -n llite.*.file_heat=0
25705         echo "Turn off file heat support for the Lustre filesystem"
25706
25707         echo "QQQQ" > $DIR/$tfile
25708         echo "QQQQ" > $DIR/$tfile
25709         echo "QQQQ" > $DIR/$tfile
25710         cat $DIR/$tfile > /dev/null
25711         cat $DIR/$tfile > /dev/null
25712         cat $DIR/$tfile > /dev/null
25713         cat $DIR/$tfile > /dev/null
25714
25715         out=$($LFS heat_get $DIR/$tfile)
25716         $LFS heat_get $DIR/$tfile
25717         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25718         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25719         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25720         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25721
25722         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25723         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25724         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25725         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25726
25727         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
25728         rm -f $DIR/$tfile
25729 }
25730 run_test 813 "File heat verfication"
25731
25732 test_814()
25733 {
25734         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25735         echo -n y >> $DIR/$tfile
25736         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25737         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25738 }
25739 run_test 814 "sparse cp works as expected (LU-12361)"
25740
25741 test_815()
25742 {
25743         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25744         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25745 }
25746 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25747
25748 test_816() {
25749         local ost1_imp=$(get_osc_import_name client ost1)
25750         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25751                          cut -d'.' -f2)
25752
25753         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25754         # ensure ost1 is connected
25755
25756         stat $DIR/$tfile >/dev/null || error "can't stat"
25757         wait_osc_import_state client ost1 FULL
25758         # no locks, no reqs to let the connection idle
25759         cancel_lru_locks osc
25760         lru_resize_disable osc
25761         local before
25762         local now
25763         before=$($LCTL get_param -n \
25764                  ldlm.namespaces.$imp_name.lru_size)
25765
25766         wait_osc_import_state client ost1 IDLE
25767         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25768         now=$($LCTL get_param -n \
25769               ldlm.namespaces.$imp_name.lru_size)
25770         [ $before == $now ] || error "lru_size changed $before != $now"
25771 }
25772 run_test 816 "do not reset lru_resize on idle reconnect"
25773
25774 cleanup_817() {
25775         umount $tmpdir
25776         exportfs -u localhost:$DIR/nfsexp
25777         rm -rf $DIR/nfsexp
25778 }
25779
25780 test_817() {
25781         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25782
25783         mkdir -p $DIR/nfsexp
25784         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25785                 error "failed to export nfs"
25786
25787         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25788         stack_trap cleanup_817 EXIT
25789
25790         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25791                 error "failed to mount nfs to $tmpdir"
25792
25793         cp /bin/true $tmpdir
25794         $DIR/nfsexp/true || error "failed to execute 'true' command"
25795 }
25796 run_test 817 "nfsd won't cache write lock for exec file"
25797
25798 test_818() {
25799         mkdir $DIR/$tdir
25800         $LFS setstripe -c1 -i0 $DIR/$tfile
25801         $LFS setstripe -c1 -i1 $DIR/$tfile
25802         stop $SINGLEMDS
25803         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25804         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25805         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25806                 error "start $SINGLEMDS failed"
25807         rm -rf $DIR/$tdir
25808 }
25809 run_test 818 "unlink with failed llog"
25810
25811 test_819a() {
25812         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25813         cancel_lru_locks osc
25814         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25815         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25816         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25817         rm -f $TDIR/$tfile
25818 }
25819 run_test 819a "too big niobuf in read"
25820
25821 test_819b() {
25822         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25823         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25824         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25825         cancel_lru_locks osc
25826         sleep 1
25827         rm -f $TDIR/$tfile
25828 }
25829 run_test 819b "too big niobuf in write"
25830
25831
25832 function test_820_start_ost() {
25833         sleep 5
25834
25835         for num in $(seq $OSTCOUNT); do
25836                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25837         done
25838 }
25839
25840 test_820() {
25841         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25842
25843         mkdir $DIR/$tdir
25844         umount_client $MOUNT || error "umount failed"
25845         for num in $(seq $OSTCOUNT); do
25846                 stop ost$num
25847         done
25848
25849         # mount client with no active OSTs
25850         # so that the client can't initialize max LOV EA size
25851         # from OSC notifications
25852         mount_client $MOUNT || error "mount failed"
25853         # delay OST starting to keep this 0 max EA size for a while
25854         test_820_start_ost &
25855
25856         # create a directory on MDS2
25857         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25858                 error "Failed to create directory"
25859         # open intent should update default EA size
25860         # see mdc_update_max_ea_from_body()
25861         # notice this is the very first RPC to MDS2
25862         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25863         ret=$?
25864         echo $out
25865         # With SSK, this situation can lead to -EPERM being returned.
25866         # In that case, simply retry.
25867         if [ $ret -ne 0 ] && $SHARED_KEY; then
25868                 if echo "$out" | grep -q "not permitted"; then
25869                         cp /etc/services $DIR/$tdir/mds2
25870                         ret=$?
25871                 fi
25872         fi
25873         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25874 }
25875 run_test 820 "update max EA from open intent"
25876
25877 test_822() {
25878         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
25879
25880         save_lustre_params mds1 \
25881                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
25882         do_facet $SINGLEMDS "$LCTL set_param -n \
25883                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
25884         do_facet $SINGLEMDS "$LCTL set_param -n \
25885                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
25886
25887         # wait for statfs update to clear OS_STATFS_NOPRECREATE
25888         local maxage=$(do_facet mds1 $LCTL get_param -n \
25889                        osp.$FSNAME-OST0000*MDT0000.maxage)
25890         sleep $((maxage + 1))
25891
25892         #define OBD_FAIL_NET_ERROR_RPC          0x532
25893         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
25894
25895         stack_trap "restore_lustre_params < $p; rm $p"
25896
25897         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
25898                       osp.$FSNAME-OST0000*MDT0000.create_count")
25899         for i in $(seq 1 $count); do
25900                 touch $DIR/$tfile.${i} || error "touch failed"
25901         done
25902 }
25903 run_test 822 "test precreate failure"
25904
25905 #
25906 # tests that do cleanup/setup should be run at the end
25907 #
25908
25909 test_900() {
25910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25911         local ls
25912
25913         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25914         $LCTL set_param fail_loc=0x903
25915
25916         cancel_lru_locks MGC
25917
25918         FAIL_ON_ERROR=true cleanup
25919         FAIL_ON_ERROR=true setup
25920 }
25921 run_test 900 "umount should not race with any mgc requeue thread"
25922
25923 # LUS-6253/LU-11185
25924 test_901() {
25925         local oldc
25926         local newc
25927         local olds
25928         local news
25929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25930
25931         # some get_param have a bug to handle dot in param name
25932         cancel_lru_locks MGC
25933         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25934         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25935         umount_client $MOUNT || error "umount failed"
25936         mount_client $MOUNT || error "mount failed"
25937         cancel_lru_locks MGC
25938         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25939         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25940
25941         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25942         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25943
25944         return 0
25945 }
25946 run_test 901 "don't leak a mgc lock on client umount"
25947
25948 # LU-13377
25949 test_902() {
25950         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25951                 skip "client does not have LU-13377 fix"
25952         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25953         $LCTL set_param fail_loc=0x1415
25954         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25955         cancel_lru_locks osc
25956         rm -f $DIR/$tfile
25957 }
25958 run_test 902 "test short write doesn't hang lustre"
25959
25960 complete $SECONDS
25961 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25962 check_and_cleanup_lustre
25963 if [ "$I_MOUNTED" != "yes" ]; then
25964         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25965 fi
25966 exit_status