Whamcloud - gitweb
LU-13055 mdd: per-user changelog names and mask
[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 60i 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:-$((300000 * $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         mkdir_on_mdt0 $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         mkdir_on_mdt0 $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 ||
2759                 error "pool_add_targets failed"
2760         test_mkdir $DIR/$tdir
2761         $LFS setstripe -p $pool $DIR/$tdir
2762         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2763         $LFS getstripe $DIR/$tdir/$tfile
2764 }
2765 run_test 27I "check that root dir striping does not break parent dir one"
2766
2767 test_27J() {
2768         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2769                 skip "Need MDS version newer than 2.12.51"
2770
2771         test_mkdir $DIR/$tdir
2772         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2773         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2774
2775         # create foreign file (raw way)
2776         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2777                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2778
2779         ! $LFS setstripe --foreign --flags foo \
2780                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2781                         error "creating $tfile with '--flags foo' should fail"
2782
2783         ! $LFS setstripe --foreign --flags 0xffffffff \
2784                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2785                         error "creating $tfile w/ 0xffffffff flags should fail"
2786
2787         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2788                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2789
2790         # verify foreign file (raw way)
2791         parse_foreign_file -f $DIR/$tdir/$tfile |
2792                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2793                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2794         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2795                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2796         parse_foreign_file -f $DIR/$tdir/$tfile |
2797                 grep "lov_foreign_size: 73" ||
2798                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2799         parse_foreign_file -f $DIR/$tdir/$tfile |
2800                 grep "lov_foreign_type: 1" ||
2801                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2802         parse_foreign_file -f $DIR/$tdir/$tfile |
2803                 grep "lov_foreign_flags: 0x0000DA08" ||
2804                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2805         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2806                 grep "lov_foreign_value: 0x" |
2807                 sed -e 's/lov_foreign_value: 0x//')
2808         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2809         [[ $lov = ${lov2// /} ]] ||
2810                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2811
2812         # create foreign file (lfs + API)
2813         $LFS setstripe --foreign=none --flags 0xda08 \
2814                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2815                 error "$DIR/$tdir/${tfile}2: create failed"
2816
2817         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2818                 grep "lfm_magic:.*0x0BD70BD0" ||
2819                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2820         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2821         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2822                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2823         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2824                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2825         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2826                 grep "lfm_flags:.*0x0000DA08" ||
2827                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2828         $LFS getstripe $DIR/$tdir/${tfile}2 |
2829                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2830                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2831
2832         # modify striping should fail
2833         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2834                 error "$DIR/$tdir/$tfile: setstripe should fail"
2835         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2836                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2837
2838         # R/W should fail
2839         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2840         cat $DIR/$tdir/${tfile}2 &&
2841                 error "$DIR/$tdir/${tfile}2: read should fail"
2842         cat /etc/passwd > $DIR/$tdir/$tfile &&
2843                 error "$DIR/$tdir/$tfile: write should fail"
2844         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2845                 error "$DIR/$tdir/${tfile}2: write should fail"
2846
2847         # chmod should work
2848         chmod 222 $DIR/$tdir/$tfile ||
2849                 error "$DIR/$tdir/$tfile: chmod failed"
2850         chmod 222 $DIR/$tdir/${tfile}2 ||
2851                 error "$DIR/$tdir/${tfile}2: chmod failed"
2852
2853         # chown should work
2854         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2855                 error "$DIR/$tdir/$tfile: chown failed"
2856         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2857                 error "$DIR/$tdir/${tfile}2: chown failed"
2858
2859         # rename should work
2860         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2861                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2862         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2863                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2864
2865         #remove foreign file
2866         rm $DIR/$tdir/${tfile}.new ||
2867                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2868         rm $DIR/$tdir/${tfile}2.new ||
2869                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2870 }
2871 run_test 27J "basic ops on file with foreign LOV"
2872
2873 test_27K() {
2874         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2875                 skip "Need MDS version newer than 2.12.49"
2876
2877         test_mkdir $DIR/$tdir
2878         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2879         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2880
2881         # create foreign dir (raw way)
2882         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2883                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2884
2885         ! $LFS setdirstripe --foreign --flags foo \
2886                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2887                         error "creating $tdir with '--flags foo' should fail"
2888
2889         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2890                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2891                         error "creating $tdir w/ 0xffffffff flags should fail"
2892
2893         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2894                 error "create_foreign_dir FAILED"
2895
2896         # verify foreign dir (raw way)
2897         parse_foreign_dir -d $DIR/$tdir/$tdir |
2898                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2899                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2900         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2901                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2902         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2903                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2904         parse_foreign_dir -d $DIR/$tdir/$tdir |
2905                 grep "lmv_foreign_flags: 55813$" ||
2906                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2907         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2908                 grep "lmv_foreign_value: 0x" |
2909                 sed 's/lmv_foreign_value: 0x//')
2910         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2911                 sed 's/ //g')
2912         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2913
2914         # create foreign dir (lfs + API)
2915         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2916                 $DIR/$tdir/${tdir}2 ||
2917                 error "$DIR/$tdir/${tdir}2: create failed"
2918
2919         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2920                 grep "lfm_magic:.*0x0CD50CD0" ||
2921                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2922         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2923         # - sizeof(lfm_type) - sizeof(lfm_flags)
2924         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2925                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2926         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2927                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2928         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2929                 grep "lfm_flags:.*0x0000DA05" ||
2930                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2931         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2932                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2933                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2934
2935         # file create in dir should fail
2936         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2937         touch $DIR/$tdir/${tdir}2/$tfile &&
2938                 "$DIR/${tdir}2: file create should fail"
2939
2940         # chmod should work
2941         chmod 777 $DIR/$tdir/$tdir ||
2942                 error "$DIR/$tdir: chmod failed"
2943         chmod 777 $DIR/$tdir/${tdir}2 ||
2944                 error "$DIR/${tdir}2: chmod failed"
2945
2946         # chown should work
2947         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2948                 error "$DIR/$tdir: chown failed"
2949         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2950                 error "$DIR/${tdir}2: chown failed"
2951
2952         # rename should work
2953         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2954                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2955         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2956                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2957
2958         #remove foreign dir
2959         rmdir $DIR/$tdir/${tdir}.new ||
2960                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2961         rmdir $DIR/$tdir/${tdir}2.new ||
2962                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2963 }
2964 run_test 27K "basic ops on dir with foreign LMV"
2965
2966 test_27L() {
2967         remote_mds_nodsh && skip "remote MDS with nodsh"
2968
2969         local POOL=${POOL:-$TESTNAME}
2970
2971         pool_add $POOL || error "pool_add failed"
2972
2973         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2974                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2975                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2976 }
2977 run_test 27L "lfs pool_list gives correct pool name"
2978
2979 test_27M() {
2980         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2981                 skip "Need MDS version >= than 2.12.57"
2982         remote_mds_nodsh && skip "remote MDS with nodsh"
2983         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2984
2985         test_mkdir $DIR/$tdir
2986
2987         # Set default striping on directory
2988         $LFS setstripe -C 4 $DIR/$tdir
2989
2990         echo 1 > $DIR/$tdir/${tfile}.1
2991         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2992         local setcount=4
2993         [ $count -eq $setcount ] ||
2994                 error "(1) stripe count $count, should be $setcount"
2995
2996         # Capture existing append_stripe_count setting for restore
2997         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2998         local mdts=$(comma_list $(mdts_nodes))
2999         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3000
3001         local appendcount=$orig_count
3002         echo 1 >> $DIR/$tdir/${tfile}.2_append
3003         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3004         [ $count -eq $appendcount ] ||
3005                 error "(2)stripe count $count, should be $appendcount for append"
3006
3007         # Disable O_APPEND striping, verify it works
3008         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3009
3010         # Should now get the default striping, which is 4
3011         setcount=4
3012         echo 1 >> $DIR/$tdir/${tfile}.3_append
3013         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3014         [ $count -eq $setcount ] ||
3015                 error "(3) stripe count $count, should be $setcount"
3016
3017         # Try changing the stripe count for append files
3018         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3019
3020         # Append striping is now 2 (directory default is still 4)
3021         appendcount=2
3022         echo 1 >> $DIR/$tdir/${tfile}.4_append
3023         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3024         [ $count -eq $appendcount ] ||
3025                 error "(4) stripe count $count, should be $appendcount for append"
3026
3027         # Test append stripe count of -1
3028         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3029         appendcount=$OSTCOUNT
3030         echo 1 >> $DIR/$tdir/${tfile}.5
3031         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3032         [ $count -eq $appendcount ] ||
3033                 error "(5) stripe count $count, should be $appendcount for append"
3034
3035         # Set append striping back to default of 1
3036         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3037
3038         # Try a new default striping, PFL + DOM
3039         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3040
3041         # Create normal DOM file, DOM returns stripe count == 0
3042         setcount=0
3043         touch $DIR/$tdir/${tfile}.6
3044         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3045         [ $count -eq $setcount ] ||
3046                 error "(6) stripe count $count, should be $setcount"
3047
3048         # Show
3049         appendcount=1
3050         echo 1 >> $DIR/$tdir/${tfile}.7_append
3051         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3052         [ $count -eq $appendcount ] ||
3053                 error "(7) stripe count $count, should be $appendcount for append"
3054
3055         # Clean up DOM layout
3056         $LFS setstripe -d $DIR/$tdir
3057
3058         # Now test that append striping works when layout is from root
3059         $LFS setstripe -c 2 $MOUNT
3060         # Make a special directory for this
3061         mkdir $DIR/${tdir}/${tdir}.2
3062         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3063
3064         # Verify for normal file
3065         setcount=2
3066         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3067         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3068         [ $count -eq $setcount ] ||
3069                 error "(8) stripe count $count, should be $setcount"
3070
3071         appendcount=1
3072         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3073         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3074         [ $count -eq $appendcount ] ||
3075                 error "(9) stripe count $count, should be $appendcount for append"
3076
3077         # Now test O_APPEND striping with pools
3078         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3079         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3080
3081         # Create the pool
3082         pool_add $TESTNAME || error "pool creation failed"
3083         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3084
3085         echo 1 >> $DIR/$tdir/${tfile}.10_append
3086
3087         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3088         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3089
3090         # Check that count is still correct
3091         appendcount=1
3092         echo 1 >> $DIR/$tdir/${tfile}.11_append
3093         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3094         [ $count -eq $appendcount ] ||
3095                 error "(11) stripe count $count, should be $appendcount for append"
3096
3097         # Disable O_APPEND stripe count, verify pool works separately
3098         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3099
3100         echo 1 >> $DIR/$tdir/${tfile}.12_append
3101
3102         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3103         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3104
3105         # Remove pool setting, verify it's not applied
3106         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3107
3108         echo 1 >> $DIR/$tdir/${tfile}.13_append
3109
3110         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3111         [ "$pool" = "" ] || error "(13) pool found: $pool"
3112 }
3113 run_test 27M "test O_APPEND striping"
3114
3115 test_27N() {
3116         combined_mgs_mds && skip "needs separate MGS/MDT"
3117
3118         pool_add $TESTNAME || error "pool_add failed"
3119         do_facet mgs "$LCTL pool_list $FSNAME" |
3120                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3121                 error "lctl pool_list on MGS failed"
3122 }
3123 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3124
3125 clean_foreign_symlink() {
3126         trap 0
3127         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3128         for i in $DIR/$tdir/* ; do
3129                 $LFS unlink_foreign $i || true
3130         done
3131 }
3132
3133 test_27O() {
3134         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3135                 skip "Need MDS version newer than 2.12.51"
3136
3137         test_mkdir $DIR/$tdir
3138         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3139         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3140
3141         trap clean_foreign_symlink EXIT
3142
3143         # enable foreign_symlink behaviour
3144         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3145
3146         # foreign symlink LOV format is a partial path by default
3147
3148         # create foreign file (lfs + API)
3149         $LFS setstripe --foreign=symlink --flags 0xda05 \
3150                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3151                 error "$DIR/$tdir/${tfile}: create failed"
3152
3153         $LFS getstripe -v $DIR/$tdir/${tfile} |
3154                 grep "lfm_magic:.*0x0BD70BD0" ||
3155                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3156         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3157                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3158         $LFS getstripe -v $DIR/$tdir/${tfile} |
3159                 grep "lfm_flags:.*0x0000DA05" ||
3160                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3161         $LFS getstripe $DIR/$tdir/${tfile} |
3162                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3163                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3164
3165         # modify striping should fail
3166         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3167                 error "$DIR/$tdir/$tfile: setstripe should fail"
3168
3169         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3170         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3171         cat /etc/passwd > $DIR/$tdir/$tfile &&
3172                 error "$DIR/$tdir/$tfile: write should fail"
3173
3174         # rename should succeed
3175         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3176                 error "$DIR/$tdir/$tfile: rename has failed"
3177
3178         #remove foreign_symlink file should fail
3179         rm $DIR/$tdir/${tfile}.new &&
3180                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3181
3182         #test fake symlink
3183         mkdir /tmp/${uuid1} ||
3184                 error "/tmp/${uuid1}: mkdir has failed"
3185         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3186                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3187         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3188         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3189                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3190         #read should succeed now
3191         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3192                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3193         #write should succeed now
3194         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3195                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3196         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3197                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3198         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3199                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3200
3201         #check that getstripe still works
3202         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3203                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3204
3205         # chmod should still succeed
3206         chmod 644 $DIR/$tdir/${tfile}.new ||
3207                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3208
3209         # chown should still succeed
3210         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3211                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3212
3213         # rename should still succeed
3214         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3215                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3216
3217         #remove foreign_symlink file should still fail
3218         rm $DIR/$tdir/${tfile} &&
3219                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3220
3221         #use special ioctl() to unlink foreign_symlink file
3222         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3223                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3224
3225 }
3226 run_test 27O "basic ops on foreign file of symlink type"
3227
3228 test_27P() {
3229         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3230                 skip "Need MDS version newer than 2.12.49"
3231
3232         test_mkdir $DIR/$tdir
3233         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3234         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3235
3236         trap clean_foreign_symlink EXIT
3237
3238         # enable foreign_symlink behaviour
3239         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3240
3241         # foreign symlink LMV format is a partial path by default
3242
3243         # create foreign dir (lfs + API)
3244         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3245                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3246                 error "$DIR/$tdir/${tdir}: create failed"
3247
3248         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3249                 grep "lfm_magic:.*0x0CD50CD0" ||
3250                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3251         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3252                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3253         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3254                 grep "lfm_flags:.*0x0000DA05" ||
3255                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3256         $LFS getdirstripe $DIR/$tdir/${tdir} |
3257                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3258                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3259
3260         # file create in dir should fail
3261         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3262         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3263
3264         # rename should succeed
3265         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3266                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3267
3268         #remove foreign_symlink dir should fail
3269         rmdir $DIR/$tdir/${tdir}.new &&
3270                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3271
3272         #test fake symlink
3273         mkdir -p /tmp/${uuid1}/${uuid2} ||
3274                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3275         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3276                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3277         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3278         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3279                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3280         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3281                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3282
3283         #check that getstripe fails now that foreign_symlink enabled
3284         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3285                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3286
3287         # file create in dir should work now
3288         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3289                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3290         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3291                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3292         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3293                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3294
3295         # chmod should still succeed
3296         chmod 755 $DIR/$tdir/${tdir}.new ||
3297                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3298
3299         # chown should still succeed
3300         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3301                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3302
3303         # rename should still succeed
3304         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3305                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3306
3307         #remove foreign_symlink dir should still fail
3308         rmdir $DIR/$tdir/${tdir} &&
3309                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3310
3311         #use special ioctl() to unlink foreign_symlink file
3312         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3313                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3314
3315         #created file should still exist
3316         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3317                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3318         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3319                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3320 }
3321 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3322
3323 test_27Q() {
3324         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3325         stack_trap "rm -f $TMP/$tfile*"
3326
3327         test_mkdir $DIR/$tdir-1
3328         test_mkdir $DIR/$tdir-2
3329
3330         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3331         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3332
3333         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3334         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3335
3336         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3337         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3338
3339         # Create some bad symlinks and ensure that we don't loop
3340         # forever or something. These should return ELOOP (40) and
3341         # ENOENT (2) but I don't want to test for that because there's
3342         # always some weirdo architecture that needs to ruin
3343         # everything by defining these error numbers differently.
3344
3345         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3346         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3347
3348         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3349         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3350
3351         return 0
3352 }
3353 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3354
3355 # createtest also checks that device nodes are created and
3356 # then visible correctly (#2091)
3357 test_28() { # bug 2091
3358         test_mkdir $DIR/d28
3359         $CREATETEST $DIR/d28/ct || error "createtest failed"
3360 }
3361 run_test 28 "create/mknod/mkdir with bad file types ============"
3362
3363 test_29() {
3364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3365
3366         sync; sleep 1; sync # flush out any dirty pages from previous tests
3367         cancel_lru_locks
3368         test_mkdir $DIR/d29
3369         touch $DIR/d29/foo
3370         log 'first d29'
3371         ls -l $DIR/d29
3372
3373         declare -i LOCKCOUNTORIG=0
3374         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3375                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3376         done
3377         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3378
3379         declare -i LOCKUNUSEDCOUNTORIG=0
3380         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3381                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3382         done
3383
3384         log 'second d29'
3385         ls -l $DIR/d29
3386         log 'done'
3387
3388         declare -i LOCKCOUNTCURRENT=0
3389         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3390                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3391         done
3392
3393         declare -i LOCKUNUSEDCOUNTCURRENT=0
3394         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3395                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3396         done
3397
3398         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3399                 $LCTL set_param -n ldlm.dump_namespaces ""
3400                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3401                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3402                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3403                 return 2
3404         fi
3405         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3406                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3407                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3408                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3409                 return 3
3410         fi
3411 }
3412 run_test 29 "IT_GETATTR regression  ============================"
3413
3414 test_30a() { # was test_30
3415         cp $(which ls) $DIR || cp /bin/ls $DIR
3416         $DIR/ls / || error "Can't execute binary from lustre"
3417         rm $DIR/ls
3418 }
3419 run_test 30a "execute binary from Lustre (execve) =============="
3420
3421 test_30b() {
3422         cp `which ls` $DIR || cp /bin/ls $DIR
3423         chmod go+rx $DIR/ls
3424         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3425         rm $DIR/ls
3426 }
3427 run_test 30b "execute binary from Lustre as non-root ==========="
3428
3429 test_30c() { # b=22376
3430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3431
3432         cp $(which ls) $DIR || cp /bin/ls $DIR
3433         chmod a-rw $DIR/ls
3434         cancel_lru_locks mdc
3435         cancel_lru_locks osc
3436         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3437         rm -f $DIR/ls
3438 }
3439 run_test 30c "execute binary from Lustre without read perms ===="
3440
3441 test_30d() {
3442         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3443
3444         for i in {1..10}; do
3445                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3446                 local PID=$!
3447                 sleep 1
3448                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3449                 wait $PID || error "executing dd from Lustre failed"
3450                 rm -f $DIR/$tfile
3451         done
3452
3453         rm -f $DIR/dd
3454 }
3455 run_test 30d "execute binary from Lustre while clear locks"
3456
3457 test_31a() {
3458         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3459         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3460 }
3461 run_test 31a "open-unlink file =================================="
3462
3463 test_31b() {
3464         touch $DIR/f31 || error "touch $DIR/f31 failed"
3465         ln $DIR/f31 $DIR/f31b || error "ln failed"
3466         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3467         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3468 }
3469 run_test 31b "unlink file with multiple links while open ======="
3470
3471 test_31c() {
3472         touch $DIR/f31 || error "touch $DIR/f31 failed"
3473         ln $DIR/f31 $DIR/f31c || error "ln failed"
3474         multiop_bg_pause $DIR/f31 O_uc ||
3475                 error "multiop_bg_pause for $DIR/f31 failed"
3476         MULTIPID=$!
3477         $MULTIOP $DIR/f31c Ouc
3478         kill -USR1 $MULTIPID
3479         wait $MULTIPID
3480 }
3481 run_test 31c "open-unlink file with multiple links ============="
3482
3483 test_31d() {
3484         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3485         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3486 }
3487 run_test 31d "remove of open directory ========================="
3488
3489 test_31e() { # bug 2904
3490         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3491 }
3492 run_test 31e "remove of open non-empty directory ==============="
3493
3494 test_31f() { # bug 4554
3495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3496
3497         set -vx
3498         test_mkdir $DIR/d31f
3499         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3500         cp /etc/hosts $DIR/d31f
3501         ls -l $DIR/d31f
3502         $LFS getstripe $DIR/d31f/hosts
3503         multiop_bg_pause $DIR/d31f D_c || return 1
3504         MULTIPID=$!
3505
3506         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3507         test_mkdir $DIR/d31f
3508         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3509         cp /etc/hosts $DIR/d31f
3510         ls -l $DIR/d31f
3511         $LFS getstripe $DIR/d31f/hosts
3512         multiop_bg_pause $DIR/d31f D_c || return 1
3513         MULTIPID2=$!
3514
3515         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3516         wait $MULTIPID || error "first opendir $MULTIPID failed"
3517
3518         sleep 6
3519
3520         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3521         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3522         set +vx
3523 }
3524 run_test 31f "remove of open directory with open-unlink file ==="
3525
3526 test_31g() {
3527         echo "-- cross directory link --"
3528         test_mkdir -c1 $DIR/${tdir}ga
3529         test_mkdir -c1 $DIR/${tdir}gb
3530         touch $DIR/${tdir}ga/f
3531         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3532         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3533         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3534         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3535         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3536 }
3537 run_test 31g "cross directory link==============="
3538
3539 test_31h() {
3540         echo "-- cross directory link --"
3541         test_mkdir -c1 $DIR/${tdir}
3542         test_mkdir -c1 $DIR/${tdir}/dir
3543         touch $DIR/${tdir}/f
3544         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3545         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3546         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3547         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3548         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3549 }
3550 run_test 31h "cross directory link under child==============="
3551
3552 test_31i() {
3553         echo "-- cross directory link --"
3554         test_mkdir -c1 $DIR/$tdir
3555         test_mkdir -c1 $DIR/$tdir/dir
3556         touch $DIR/$tdir/dir/f
3557         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3558         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3559         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3560         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3561         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3562 }
3563 run_test 31i "cross directory link under parent==============="
3564
3565 test_31j() {
3566         test_mkdir -c1 -p $DIR/$tdir
3567         test_mkdir -c1 -p $DIR/$tdir/dir1
3568         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3569         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3570         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3571         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3572         return 0
3573 }
3574 run_test 31j "link for directory==============="
3575
3576 test_31k() {
3577         test_mkdir -c1 -p $DIR/$tdir
3578         touch $DIR/$tdir/s
3579         touch $DIR/$tdir/exist
3580         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3581         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3582         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3583         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3584         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3585         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3586         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3587         return 0
3588 }
3589 run_test 31k "link to file: the same, non-existing, dir==============="
3590
3591 test_31m() {
3592         mkdir $DIR/d31m
3593         touch $DIR/d31m/s
3594         mkdir $DIR/d31m2
3595         touch $DIR/d31m2/exist
3596         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3597         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3598         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3599         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3600         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3601         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3602         return 0
3603 }
3604 run_test 31m "link to file: the same, non-existing, dir==============="
3605
3606 test_31n() {
3607         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3608         nlink=$(stat --format=%h $DIR/$tfile)
3609         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3610         local fd=$(free_fd)
3611         local cmd="exec $fd<$DIR/$tfile"
3612         eval $cmd
3613         cmd="exec $fd<&-"
3614         trap "eval $cmd" EXIT
3615         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3616         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3617         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3618         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3619         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3620         eval $cmd
3621 }
3622 run_test 31n "check link count of unlinked file"
3623
3624 link_one() {
3625         local tempfile=$(mktemp $1_XXXXXX)
3626         mlink $tempfile $1 2> /dev/null &&
3627                 echo "$BASHPID: link $tempfile to $1 succeeded"
3628         munlink $tempfile
3629 }
3630
3631 test_31o() { # LU-2901
3632         test_mkdir $DIR/$tdir
3633         for LOOP in $(seq 100); do
3634                 rm -f $DIR/$tdir/$tfile*
3635                 for THREAD in $(seq 8); do
3636                         link_one $DIR/$tdir/$tfile.$LOOP &
3637                 done
3638                 wait
3639                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3640                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3641                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3642                         break || true
3643         done
3644 }
3645 run_test 31o "duplicate hard links with same filename"
3646
3647 test_31p() {
3648         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3649
3650         test_mkdir $DIR/$tdir
3651         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3652         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3653
3654         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3655                 error "open unlink test1 failed"
3656         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3657                 error "open unlink test2 failed"
3658
3659         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3660                 error "test1 still exists"
3661         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3662                 error "test2 still exists"
3663 }
3664 run_test 31p "remove of open striped directory"
3665
3666 test_31q() {
3667         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3668
3669         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3670         index=$($LFS getdirstripe -i $DIR/$tdir)
3671         [ $index -eq 3 ] || error "first stripe index $index != 3"
3672         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3673         [ $index -eq 1 ] || error "second stripe index $index != 1"
3674
3675         # when "-c <stripe_count>" is set, the number of MDTs specified after
3676         # "-i" should equal to the stripe count
3677         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3678 }
3679 run_test 31q "create striped directory on specific MDTs"
3680
3681 cleanup_test32_mount() {
3682         local rc=0
3683         trap 0
3684         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3685         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3686         losetup -d $loopdev || true
3687         rm -rf $DIR/$tdir
3688         return $rc
3689 }
3690
3691 test_32a() {
3692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3693
3694         echo "== more mountpoints and symlinks ================="
3695         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3696         trap cleanup_test32_mount EXIT
3697         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3698         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3699                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3700         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3701                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3702         cleanup_test32_mount
3703 }
3704 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3705
3706 test_32b() {
3707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3708
3709         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3710         trap cleanup_test32_mount EXIT
3711         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3712         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3713                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3714         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3715                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3716         cleanup_test32_mount
3717 }
3718 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3719
3720 test_32c() {
3721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3722
3723         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3724         trap cleanup_test32_mount EXIT
3725         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3726         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3727                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3728         test_mkdir -p $DIR/$tdir/d2/test_dir
3729         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3730                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3731         cleanup_test32_mount
3732 }
3733 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3734
3735 test_32d() {
3736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3737
3738         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3739         trap cleanup_test32_mount EXIT
3740         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3741         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3742                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3743         test_mkdir -p $DIR/$tdir/d2/test_dir
3744         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3745                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3746         cleanup_test32_mount
3747 }
3748 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3749
3750 test_32e() {
3751         rm -fr $DIR/$tdir
3752         test_mkdir -p $DIR/$tdir/tmp
3753         local tmp_dir=$DIR/$tdir/tmp
3754         ln -s $DIR/$tdir $tmp_dir/symlink11
3755         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3756         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3757         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3758 }
3759 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3760
3761 test_32f() {
3762         rm -fr $DIR/$tdir
3763         test_mkdir -p $DIR/$tdir/tmp
3764         local tmp_dir=$DIR/$tdir/tmp
3765         ln -s $DIR/$tdir $tmp_dir/symlink11
3766         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3767         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3768         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3769 }
3770 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3771
3772 test_32g() {
3773         local tmp_dir=$DIR/$tdir/tmp
3774         test_mkdir -p $tmp_dir
3775         test_mkdir $DIR/${tdir}2
3776         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3777         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3778         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3779         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3780         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3781         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3782 }
3783 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3784
3785 test_32h() {
3786         rm -fr $DIR/$tdir $DIR/${tdir}2
3787         tmp_dir=$DIR/$tdir/tmp
3788         test_mkdir -p $tmp_dir
3789         test_mkdir $DIR/${tdir}2
3790         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3791         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3792         ls $tmp_dir/symlink12 || error "listing symlink12"
3793         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3794 }
3795 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3796
3797 test_32i() {
3798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3799
3800         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3801         trap cleanup_test32_mount EXIT
3802         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3803         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3804                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3805         touch $DIR/$tdir/test_file
3806         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3807                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3808         cleanup_test32_mount
3809 }
3810 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3811
3812 test_32j() {
3813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3814
3815         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3816         trap cleanup_test32_mount EXIT
3817         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3818         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3819                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3820         touch $DIR/$tdir/test_file
3821         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3822                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3823         cleanup_test32_mount
3824 }
3825 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3826
3827 test_32k() {
3828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3829
3830         rm -fr $DIR/$tdir
3831         trap cleanup_test32_mount EXIT
3832         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3833         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3834                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3835         test_mkdir -p $DIR/$tdir/d2
3836         touch $DIR/$tdir/d2/test_file || error "touch failed"
3837         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3838                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3839         cleanup_test32_mount
3840 }
3841 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3842
3843 test_32l() {
3844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3845
3846         rm -fr $DIR/$tdir
3847         trap cleanup_test32_mount EXIT
3848         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3849         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3850                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3851         test_mkdir -p $DIR/$tdir/d2
3852         touch $DIR/$tdir/d2/test_file || error "touch failed"
3853         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3854                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3855         cleanup_test32_mount
3856 }
3857 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3858
3859 test_32m() {
3860         rm -fr $DIR/d32m
3861         test_mkdir -p $DIR/d32m/tmp
3862         TMP_DIR=$DIR/d32m/tmp
3863         ln -s $DIR $TMP_DIR/symlink11
3864         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3865         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3866                 error "symlink11 not a link"
3867         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3868                 error "symlink01 not a link"
3869 }
3870 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3871
3872 test_32n() {
3873         rm -fr $DIR/d32n
3874         test_mkdir -p $DIR/d32n/tmp
3875         TMP_DIR=$DIR/d32n/tmp
3876         ln -s $DIR $TMP_DIR/symlink11
3877         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3878         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3879         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3880 }
3881 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3882
3883 test_32o() {
3884         touch $DIR/$tfile
3885         test_mkdir -p $DIR/d32o/tmp
3886         TMP_DIR=$DIR/d32o/tmp
3887         ln -s $DIR/$tfile $TMP_DIR/symlink12
3888         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3889         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3890                 error "symlink12 not a link"
3891         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3892         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3893                 error "$DIR/d32o/tmp/symlink12 not file type"
3894         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3895                 error "$DIR/d32o/symlink02 not file type"
3896 }
3897 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3898
3899 test_32p() {
3900         log 32p_1
3901         rm -fr $DIR/d32p
3902         log 32p_2
3903         rm -f $DIR/$tfile
3904         log 32p_3
3905         touch $DIR/$tfile
3906         log 32p_4
3907         test_mkdir -p $DIR/d32p/tmp
3908         log 32p_5
3909         TMP_DIR=$DIR/d32p/tmp
3910         log 32p_6
3911         ln -s $DIR/$tfile $TMP_DIR/symlink12
3912         log 32p_7
3913         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3914         log 32p_8
3915         cat $DIR/d32p/tmp/symlink12 ||
3916                 error "Can't open $DIR/d32p/tmp/symlink12"
3917         log 32p_9
3918         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3919         log 32p_10
3920 }
3921 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3922
3923 test_32q() {
3924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3925
3926         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3927         trap cleanup_test32_mount EXIT
3928         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3929         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3930         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3931                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3932         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3933         cleanup_test32_mount
3934 }
3935 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3936
3937 test_32r() {
3938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3939
3940         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3941         trap cleanup_test32_mount EXIT
3942         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3943         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3944         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3945                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3946         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3947         cleanup_test32_mount
3948 }
3949 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3950
3951 test_33aa() {
3952         rm -f $DIR/$tfile
3953         touch $DIR/$tfile
3954         chmod 444 $DIR/$tfile
3955         chown $RUNAS_ID $DIR/$tfile
3956         log 33_1
3957         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3958         log 33_2
3959 }
3960 run_test 33aa "write file with mode 444 (should return error)"
3961
3962 test_33a() {
3963         rm -fr $DIR/$tdir
3964         test_mkdir $DIR/$tdir
3965         chown $RUNAS_ID $DIR/$tdir
3966         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3967                 error "$RUNAS create $tdir/$tfile failed"
3968         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3969                 error "open RDWR" || true
3970 }
3971 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3972
3973 test_33b() {
3974         rm -fr $DIR/$tdir
3975         test_mkdir $DIR/$tdir
3976         chown $RUNAS_ID $DIR/$tdir
3977         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3978 }
3979 run_test 33b "test open file with malformed flags (No panic)"
3980
3981 test_33c() {
3982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3983         remote_ost_nodsh && skip "remote OST with nodsh"
3984
3985         local ostnum
3986         local ostname
3987         local write_bytes
3988         local all_zeros
3989
3990         all_zeros=true
3991         test_mkdir $DIR/$tdir
3992         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3993
3994         sync
3995         for ostnum in $(seq $OSTCOUNT); do
3996                 # test-framework's OST numbering is one-based, while Lustre's
3997                 # is zero-based
3998                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3999                 # check if at least some write_bytes stats are counted
4000                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4001                               obdfilter.$ostname.stats |
4002                               awk '/^write_bytes/ {print $7}' )
4003                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4004                 if (( ${write_bytes:-0} > 0 )); then
4005                         all_zeros=false
4006                         break
4007                 fi
4008         done
4009
4010         $all_zeros || return 0
4011
4012         # Write four bytes
4013         echo foo > $DIR/$tdir/bar
4014         # Really write them
4015         sync
4016
4017         # Total up write_bytes after writing.  We'd better find non-zeros.
4018         for ostnum in $(seq $OSTCOUNT); do
4019                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4020                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4021                               obdfilter/$ostname/stats |
4022                               awk '/^write_bytes/ {print $7}' )
4023                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4024                 if (( ${write_bytes:-0} > 0 )); then
4025                         all_zeros=false
4026                         break
4027                 fi
4028         done
4029
4030         if $all_zeros; then
4031                 for ostnum in $(seq $OSTCOUNT); do
4032                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4033                         echo "Check write_bytes is in obdfilter.*.stats:"
4034                         do_facet ost$ostnum lctl get_param -n \
4035                                 obdfilter.$ostname.stats
4036                 done
4037                 error "OST not keeping write_bytes stats (b=22312)"
4038         fi
4039 }
4040 run_test 33c "test write_bytes stats"
4041
4042 test_33d() {
4043         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4045
4046         local MDTIDX=1
4047         local remote_dir=$DIR/$tdir/remote_dir
4048
4049         test_mkdir $DIR/$tdir
4050         $LFS mkdir -i $MDTIDX $remote_dir ||
4051                 error "create remote directory failed"
4052
4053         touch $remote_dir/$tfile
4054         chmod 444 $remote_dir/$tfile
4055         chown $RUNAS_ID $remote_dir/$tfile
4056
4057         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4058
4059         chown $RUNAS_ID $remote_dir
4060         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4061                                         error "create" || true
4062         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4063                                     error "open RDWR" || true
4064         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4065 }
4066 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4067
4068 test_33e() {
4069         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4070
4071         mkdir $DIR/$tdir
4072
4073         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4074         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4075         mkdir $DIR/$tdir/local_dir
4076
4077         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4078         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4079         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4080
4081         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4082                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4083
4084         rmdir $DIR/$tdir/* || error "rmdir failed"
4085
4086         umask 777
4087         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4088         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4089         mkdir $DIR/$tdir/local_dir
4090
4091         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4092         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4093         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4094
4095         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4096                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4097
4098         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4099
4100         umask 000
4101         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4102         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4103         mkdir $DIR/$tdir/local_dir
4104
4105         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4106         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4107         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4108
4109         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4110                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4111 }
4112 run_test 33e "mkdir and striped directory should have same mode"
4113
4114 cleanup_33f() {
4115         trap 0
4116         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4117 }
4118
4119 test_33f() {
4120         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4121         remote_mds_nodsh && skip "remote MDS with nodsh"
4122
4123         mkdir $DIR/$tdir
4124         chmod go+rwx $DIR/$tdir
4125         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4126         trap cleanup_33f EXIT
4127
4128         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4129                 error "cannot create striped directory"
4130
4131         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4132                 error "cannot create files in striped directory"
4133
4134         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4135                 error "cannot remove files in striped directory"
4136
4137         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4138                 error "cannot remove striped directory"
4139
4140         cleanup_33f
4141 }
4142 run_test 33f "nonroot user can create, access, and remove a striped directory"
4143
4144 test_33g() {
4145         mkdir -p $DIR/$tdir/dir2
4146
4147         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4148         echo $err
4149         [[ $err =~ "exists" ]] || error "Not exists error"
4150 }
4151 run_test 33g "nonroot user create already existing root created file"
4152
4153 test_33h() {
4154         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4155         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4156                 skip "Need MDS version at least 2.13.50"
4157
4158         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4159                 error "mkdir $tdir failed"
4160         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4161
4162         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4163         local index2
4164
4165         for fname in $DIR/$tdir/$tfile.bak \
4166                      $DIR/$tdir/$tfile.SAV \
4167                      $DIR/$tdir/$tfile.orig \
4168                      $DIR/$tdir/$tfile~; do
4169                 touch $fname  || error "touch $fname failed"
4170                 index2=$($LFS getstripe -m $fname)
4171                 [ $index -eq $index2 ] ||
4172                         error "$fname MDT index mismatch $index != $index2"
4173         done
4174
4175         local failed=0
4176         for i in {1..250}; do
4177                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4178                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4179                         touch $fname  || error "touch $fname failed"
4180                         index2=$($LFS getstripe -m $fname)
4181                         if [[ $index != $index2 ]]; then
4182                                 failed=$((failed + 1))
4183                                 echo "$fname MDT index mismatch $index != $index2"
4184                         fi
4185                 done
4186         done
4187         echo "$failed MDT index mismatches"
4188         (( failed < 20 )) || error "MDT index mismatch $failed times"
4189
4190 }
4191 run_test 33h "temp file is located on the same MDT as target"
4192
4193 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4194 test_34a() {
4195         rm -f $DIR/f34
4196         $MCREATE $DIR/f34 || error "mcreate failed"
4197         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4198                 error "getstripe failed"
4199         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4200         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4201                 error "getstripe failed"
4202         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4203                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4204 }
4205 run_test 34a "truncate file that has not been opened ==========="
4206
4207 test_34b() {
4208         [ ! -f $DIR/f34 ] && test_34a
4209         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4210                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4211         $OPENFILE -f O_RDONLY $DIR/f34
4212         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4213                 error "getstripe failed"
4214         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4215                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4216 }
4217 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4218
4219 test_34c() {
4220         [ ! -f $DIR/f34 ] && test_34a
4221         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4222                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4223         $OPENFILE -f O_RDWR $DIR/f34
4224         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4225                 error "$LFS getstripe failed"
4226         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4227                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4228 }
4229 run_test 34c "O_RDWR opening file-with-size works =============="
4230
4231 test_34d() {
4232         [ ! -f $DIR/f34 ] && test_34a
4233         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4234                 error "dd failed"
4235         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4236                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4237         rm $DIR/f34
4238 }
4239 run_test 34d "write to sparse file ============================="
4240
4241 test_34e() {
4242         rm -f $DIR/f34e
4243         $MCREATE $DIR/f34e || error "mcreate failed"
4244         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4245         $CHECKSTAT -s 1000 $DIR/f34e ||
4246                 error "Size of $DIR/f34e not equal to 1000 bytes"
4247         $OPENFILE -f O_RDWR $DIR/f34e
4248         $CHECKSTAT -s 1000 $DIR/f34e ||
4249                 error "Size of $DIR/f34e not equal to 1000 bytes"
4250 }
4251 run_test 34e "create objects, some with size and some without =="
4252
4253 test_34f() { # bug 6242, 6243
4254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4255
4256         SIZE34F=48000
4257         rm -f $DIR/f34f
4258         $MCREATE $DIR/f34f || error "mcreate failed"
4259         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4260         dd if=$DIR/f34f of=$TMP/f34f
4261         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4262         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4263         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4264         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4265         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4266 }
4267 run_test 34f "read from a file with no objects until EOF ======="
4268
4269 test_34g() {
4270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4271
4272         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4273                 error "dd failed"
4274         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4275         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4276                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4277         cancel_lru_locks osc
4278         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4279                 error "wrong size after lock cancel"
4280
4281         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4282         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4283                 error "expanding truncate failed"
4284         cancel_lru_locks osc
4285         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4286                 error "wrong expanded size after lock cancel"
4287 }
4288 run_test 34g "truncate long file ==============================="
4289
4290 test_34h() {
4291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4292
4293         local gid=10
4294         local sz=1000
4295
4296         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4297         sync # Flush the cache so that multiop below does not block on cache
4298              # flush when getting the group lock
4299         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4300         MULTIPID=$!
4301
4302         # Since just timed wait is not good enough, let's do a sync write
4303         # that way we are sure enough time for a roundtrip + processing
4304         # passed + 2 seconds of extra margin.
4305         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4306         rm $DIR/${tfile}-1
4307         sleep 2
4308
4309         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4310                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4311                 kill -9 $MULTIPID
4312         fi
4313         wait $MULTIPID
4314         local nsz=`stat -c %s $DIR/$tfile`
4315         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4316 }
4317 run_test 34h "ftruncate file under grouplock should not block"
4318
4319 test_35a() {
4320         cp /bin/sh $DIR/f35a
4321         chmod 444 $DIR/f35a
4322         chown $RUNAS_ID $DIR/f35a
4323         $RUNAS $DIR/f35a && error || true
4324         rm $DIR/f35a
4325 }
4326 run_test 35a "exec file with mode 444 (should return and not leak)"
4327
4328 test_36a() {
4329         rm -f $DIR/f36
4330         utime $DIR/f36 || error "utime failed for MDS"
4331 }
4332 run_test 36a "MDS utime check (mknod, utime)"
4333
4334 test_36b() {
4335         echo "" > $DIR/f36
4336         utime $DIR/f36 || error "utime failed for OST"
4337 }
4338 run_test 36b "OST utime check (open, utime)"
4339
4340 test_36c() {
4341         rm -f $DIR/d36/f36
4342         test_mkdir $DIR/d36
4343         chown $RUNAS_ID $DIR/d36
4344         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4345 }
4346 run_test 36c "non-root MDS utime check (mknod, utime)"
4347
4348 test_36d() {
4349         [ ! -d $DIR/d36 ] && test_36c
4350         echo "" > $DIR/d36/f36
4351         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4352 }
4353 run_test 36d "non-root OST utime check (open, utime)"
4354
4355 test_36e() {
4356         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4357
4358         test_mkdir $DIR/$tdir
4359         touch $DIR/$tdir/$tfile
4360         $RUNAS utime $DIR/$tdir/$tfile &&
4361                 error "utime worked, expected failure" || true
4362 }
4363 run_test 36e "utime on non-owned file (should return error)"
4364
4365 subr_36fh() {
4366         local fl="$1"
4367         local LANG_SAVE=$LANG
4368         local LC_LANG_SAVE=$LC_LANG
4369         export LANG=C LC_LANG=C # for date language
4370
4371         DATESTR="Dec 20  2000"
4372         test_mkdir $DIR/$tdir
4373         lctl set_param fail_loc=$fl
4374         date; date +%s
4375         cp /etc/hosts $DIR/$tdir/$tfile
4376         sync & # write RPC generated with "current" inode timestamp, but delayed
4377         sleep 1
4378         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4379         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4380         cancel_lru_locks $OSC
4381         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4382         date; date +%s
4383         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4384                 echo "BEFORE: $LS_BEFORE" && \
4385                 echo "AFTER : $LS_AFTER" && \
4386                 echo "WANT  : $DATESTR" && \
4387                 error "$DIR/$tdir/$tfile timestamps changed" || true
4388
4389         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4390 }
4391
4392 test_36f() {
4393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4394
4395         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4396         subr_36fh "0x80000214"
4397 }
4398 run_test 36f "utime on file racing with OST BRW write =========="
4399
4400 test_36g() {
4401         remote_ost_nodsh && skip "remote OST with nodsh"
4402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4403         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4404                 skip "Need MDS version at least 2.12.51"
4405
4406         local fmd_max_age
4407         local fmd
4408         local facet="ost1"
4409         local tgt="obdfilter"
4410
4411         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4412
4413         test_mkdir $DIR/$tdir
4414         fmd_max_age=$(do_facet $facet \
4415                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4416                 head -n 1")
4417
4418         echo "FMD max age: ${fmd_max_age}s"
4419         touch $DIR/$tdir/$tfile
4420         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4421                 gawk '{cnt=cnt+$1}  END{print cnt}')
4422         echo "FMD before: $fmd"
4423         [[ $fmd == 0 ]] &&
4424                 error "FMD wasn't create by touch"
4425         sleep $((fmd_max_age + 12))
4426         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4427                 gawk '{cnt=cnt+$1}  END{print cnt}')
4428         echo "FMD after: $fmd"
4429         [[ $fmd == 0 ]] ||
4430                 error "FMD wasn't expired by ping"
4431 }
4432 run_test 36g "FMD cache expiry ====================="
4433
4434 test_36h() {
4435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4436
4437         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4438         subr_36fh "0x80000227"
4439 }
4440 run_test 36h "utime on file racing with OST BRW write =========="
4441
4442 test_36i() {
4443         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4444
4445         test_mkdir $DIR/$tdir
4446         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4447
4448         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4449         local new_mtime=$((mtime + 200))
4450
4451         #change Modify time of striped dir
4452         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4453                         error "change mtime failed"
4454
4455         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4456
4457         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4458 }
4459 run_test 36i "change mtime on striped directory"
4460
4461 # test_37 - duplicate with tests 32q 32r
4462
4463 test_38() {
4464         local file=$DIR/$tfile
4465         touch $file
4466         openfile -f O_DIRECTORY $file
4467         local RC=$?
4468         local ENOTDIR=20
4469         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4470         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4471 }
4472 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4473
4474 test_39a() { # was test_39
4475         touch $DIR/$tfile
4476         touch $DIR/${tfile}2
4477 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4478 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4479 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4480         sleep 2
4481         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4482         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4483                 echo "mtime"
4484                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4485                 echo "atime"
4486                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4487                 echo "ctime"
4488                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4489                 error "O_TRUNC didn't change timestamps"
4490         fi
4491 }
4492 run_test 39a "mtime changed on create"
4493
4494 test_39b() {
4495         test_mkdir -c1 $DIR/$tdir
4496         cp -p /etc/passwd $DIR/$tdir/fopen
4497         cp -p /etc/passwd $DIR/$tdir/flink
4498         cp -p /etc/passwd $DIR/$tdir/funlink
4499         cp -p /etc/passwd $DIR/$tdir/frename
4500         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4501
4502         sleep 1
4503         echo "aaaaaa" >> $DIR/$tdir/fopen
4504         echo "aaaaaa" >> $DIR/$tdir/flink
4505         echo "aaaaaa" >> $DIR/$tdir/funlink
4506         echo "aaaaaa" >> $DIR/$tdir/frename
4507
4508         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4509         local link_new=`stat -c %Y $DIR/$tdir/flink`
4510         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4511         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4512
4513         cat $DIR/$tdir/fopen > /dev/null
4514         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4515         rm -f $DIR/$tdir/funlink2
4516         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4517
4518         for (( i=0; i < 2; i++ )) ; do
4519                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4520                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4521                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4522                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4523
4524                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4525                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4526                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4527                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4528
4529                 cancel_lru_locks $OSC
4530                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4531         done
4532 }
4533 run_test 39b "mtime change on open, link, unlink, rename  ======"
4534
4535 # this should be set to past
4536 TEST_39_MTIME=`date -d "1 year ago" +%s`
4537
4538 # bug 11063
4539 test_39c() {
4540         touch $DIR1/$tfile
4541         sleep 2
4542         local mtime0=`stat -c %Y $DIR1/$tfile`
4543
4544         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4545         local mtime1=`stat -c %Y $DIR1/$tfile`
4546         [ "$mtime1" = $TEST_39_MTIME ] || \
4547                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4548
4549         local d1=`date +%s`
4550         echo hello >> $DIR1/$tfile
4551         local d2=`date +%s`
4552         local mtime2=`stat -c %Y $DIR1/$tfile`
4553         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4554                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4555
4556         mv $DIR1/$tfile $DIR1/$tfile-1
4557
4558         for (( i=0; i < 2; i++ )) ; do
4559                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4560                 [ "$mtime2" = "$mtime3" ] || \
4561                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4562
4563                 cancel_lru_locks $OSC
4564                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4565         done
4566 }
4567 run_test 39c "mtime change on rename ==========================="
4568
4569 # bug 21114
4570 test_39d() {
4571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4572
4573         touch $DIR1/$tfile
4574         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4575
4576         for (( i=0; i < 2; i++ )) ; do
4577                 local mtime=`stat -c %Y $DIR1/$tfile`
4578                 [ $mtime = $TEST_39_MTIME ] || \
4579                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4580
4581                 cancel_lru_locks $OSC
4582                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4583         done
4584 }
4585 run_test 39d "create, utime, stat =============================="
4586
4587 # bug 21114
4588 test_39e() {
4589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4590
4591         touch $DIR1/$tfile
4592         local mtime1=`stat -c %Y $DIR1/$tfile`
4593
4594         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4595
4596         for (( i=0; i < 2; i++ )) ; do
4597                 local mtime2=`stat -c %Y $DIR1/$tfile`
4598                 [ $mtime2 = $TEST_39_MTIME ] || \
4599                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4600
4601                 cancel_lru_locks $OSC
4602                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4603         done
4604 }
4605 run_test 39e "create, stat, utime, stat ========================"
4606
4607 # bug 21114
4608 test_39f() {
4609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4610
4611         touch $DIR1/$tfile
4612         mtime1=`stat -c %Y $DIR1/$tfile`
4613
4614         sleep 2
4615         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4616
4617         for (( i=0; i < 2; i++ )) ; do
4618                 local mtime2=`stat -c %Y $DIR1/$tfile`
4619                 [ $mtime2 = $TEST_39_MTIME ] || \
4620                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4621
4622                 cancel_lru_locks $OSC
4623                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4624         done
4625 }
4626 run_test 39f "create, stat, sleep, utime, stat ================="
4627
4628 # bug 11063
4629 test_39g() {
4630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4631
4632         echo hello >> $DIR1/$tfile
4633         local mtime1=`stat -c %Y $DIR1/$tfile`
4634
4635         sleep 2
4636         chmod o+r $DIR1/$tfile
4637
4638         for (( i=0; i < 2; i++ )) ; do
4639                 local mtime2=`stat -c %Y $DIR1/$tfile`
4640                 [ "$mtime1" = "$mtime2" ] || \
4641                         error "lost mtime: $mtime2, should be $mtime1"
4642
4643                 cancel_lru_locks $OSC
4644                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4645         done
4646 }
4647 run_test 39g "write, chmod, stat ==============================="
4648
4649 # bug 11063
4650 test_39h() {
4651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4652
4653         touch $DIR1/$tfile
4654         sleep 1
4655
4656         local d1=`date`
4657         echo hello >> $DIR1/$tfile
4658         local mtime1=`stat -c %Y $DIR1/$tfile`
4659
4660         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4661         local d2=`date`
4662         if [ "$d1" != "$d2" ]; then
4663                 echo "write and touch not within one second"
4664         else
4665                 for (( i=0; i < 2; i++ )) ; do
4666                         local mtime2=`stat -c %Y $DIR1/$tfile`
4667                         [ "$mtime2" = $TEST_39_MTIME ] || \
4668                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4669
4670                         cancel_lru_locks $OSC
4671                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4672                 done
4673         fi
4674 }
4675 run_test 39h "write, utime within one second, stat ============="
4676
4677 test_39i() {
4678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4679
4680         touch $DIR1/$tfile
4681         sleep 1
4682
4683         echo hello >> $DIR1/$tfile
4684         local mtime1=`stat -c %Y $DIR1/$tfile`
4685
4686         mv $DIR1/$tfile $DIR1/$tfile-1
4687
4688         for (( i=0; i < 2; i++ )) ; do
4689                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4690
4691                 [ "$mtime1" = "$mtime2" ] || \
4692                         error "lost mtime: $mtime2, should be $mtime1"
4693
4694                 cancel_lru_locks $OSC
4695                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4696         done
4697 }
4698 run_test 39i "write, rename, stat =============================="
4699
4700 test_39j() {
4701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4702
4703         start_full_debug_logging
4704         touch $DIR1/$tfile
4705         sleep 1
4706
4707         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4708         lctl set_param fail_loc=0x80000412
4709         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4710                 error "multiop failed"
4711         local multipid=$!
4712         local mtime1=`stat -c %Y $DIR1/$tfile`
4713
4714         mv $DIR1/$tfile $DIR1/$tfile-1
4715
4716         kill -USR1 $multipid
4717         wait $multipid || error "multiop close failed"
4718
4719         for (( i=0; i < 2; i++ )) ; do
4720                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4721                 [ "$mtime1" = "$mtime2" ] ||
4722                         error "mtime is lost on close: $mtime2, " \
4723                               "should be $mtime1"
4724
4725                 cancel_lru_locks
4726                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4727         done
4728         lctl set_param fail_loc=0
4729         stop_full_debug_logging
4730 }
4731 run_test 39j "write, rename, close, stat ======================="
4732
4733 test_39k() {
4734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4735
4736         touch $DIR1/$tfile
4737         sleep 1
4738
4739         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4740         local multipid=$!
4741         local mtime1=`stat -c %Y $DIR1/$tfile`
4742
4743         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4744
4745         kill -USR1 $multipid
4746         wait $multipid || error "multiop close failed"
4747
4748         for (( i=0; i < 2; i++ )) ; do
4749                 local mtime2=`stat -c %Y $DIR1/$tfile`
4750
4751                 [ "$mtime2" = $TEST_39_MTIME ] || \
4752                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4753
4754                 cancel_lru_locks
4755                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4756         done
4757 }
4758 run_test 39k "write, utime, close, stat ========================"
4759
4760 # this should be set to future
4761 TEST_39_ATIME=`date -d "1 year" +%s`
4762
4763 test_39l() {
4764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4765         remote_mds_nodsh && skip "remote MDS with nodsh"
4766
4767         local atime_diff=$(do_facet $SINGLEMDS \
4768                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4769         rm -rf $DIR/$tdir
4770         mkdir_on_mdt0 $DIR/$tdir
4771
4772         # test setting directory atime to future
4773         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4774         local atime=$(stat -c %X $DIR/$tdir)
4775         [ "$atime" = $TEST_39_ATIME ] ||
4776                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4777
4778         # test setting directory atime from future to now
4779         local now=$(date +%s)
4780         touch -a -d @$now $DIR/$tdir
4781
4782         atime=$(stat -c %X $DIR/$tdir)
4783         [ "$atime" -eq "$now"  ] ||
4784                 error "atime is not updated from future: $atime, $now"
4785
4786         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4787         sleep 3
4788
4789         # test setting directory atime when now > dir atime + atime_diff
4790         local d1=$(date +%s)
4791         ls $DIR/$tdir
4792         local d2=$(date +%s)
4793         cancel_lru_locks mdc
4794         atime=$(stat -c %X $DIR/$tdir)
4795         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4796                 error "atime is not updated  : $atime, should be $d2"
4797
4798         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4799         sleep 3
4800
4801         # test not setting directory atime when now < dir atime + atime_diff
4802         ls $DIR/$tdir
4803         cancel_lru_locks mdc
4804         atime=$(stat -c %X $DIR/$tdir)
4805         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4806                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4807
4808         do_facet $SINGLEMDS \
4809                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4810 }
4811 run_test 39l "directory atime update ==========================="
4812
4813 test_39m() {
4814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4815
4816         touch $DIR1/$tfile
4817         sleep 2
4818         local far_past_mtime=$(date -d "May 29 1953" +%s)
4819         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4820
4821         touch -m -d @$far_past_mtime $DIR1/$tfile
4822         touch -a -d @$far_past_atime $DIR1/$tfile
4823
4824         for (( i=0; i < 2; i++ )) ; do
4825                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4826                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4827                         error "atime or mtime set incorrectly"
4828
4829                 cancel_lru_locks $OSC
4830                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4831         done
4832 }
4833 run_test 39m "test atime and mtime before 1970"
4834
4835 test_39n() { # LU-3832
4836         remote_mds_nodsh && skip "remote MDS with nodsh"
4837
4838         local atime_diff=$(do_facet $SINGLEMDS \
4839                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4840         local atime0
4841         local atime1
4842         local atime2
4843
4844         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4845
4846         rm -rf $DIR/$tfile
4847         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4848         atime0=$(stat -c %X $DIR/$tfile)
4849
4850         sleep 5
4851         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4852         atime1=$(stat -c %X $DIR/$tfile)
4853
4854         sleep 5
4855         cancel_lru_locks mdc
4856         cancel_lru_locks osc
4857         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4858         atime2=$(stat -c %X $DIR/$tfile)
4859
4860         do_facet $SINGLEMDS \
4861                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4862
4863         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4864         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4865 }
4866 run_test 39n "check that O_NOATIME is honored"
4867
4868 test_39o() {
4869         TESTDIR=$DIR/$tdir/$tfile
4870         [ -e $TESTDIR ] && rm -rf $TESTDIR
4871         mkdir -p $TESTDIR
4872         cd $TESTDIR
4873         links1=2
4874         ls
4875         mkdir a b
4876         ls
4877         links2=$(stat -c %h .)
4878         [ $(($links1 + 2)) != $links2 ] &&
4879                 error "wrong links count $(($links1 + 2)) != $links2"
4880         rmdir b
4881         links3=$(stat -c %h .)
4882         [ $(($links1 + 1)) != $links3 ] &&
4883                 error "wrong links count $links1 != $links3"
4884         return 0
4885 }
4886 run_test 39o "directory cached attributes updated after create"
4887
4888 test_39p() {
4889         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4890
4891         local MDTIDX=1
4892         TESTDIR=$DIR/$tdir/$tdir
4893         [ -e $TESTDIR ] && rm -rf $TESTDIR
4894         test_mkdir -p $TESTDIR
4895         cd $TESTDIR
4896         links1=2
4897         ls
4898         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4899         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4900         ls
4901         links2=$(stat -c %h .)
4902         [ $(($links1 + 2)) != $links2 ] &&
4903                 error "wrong links count $(($links1 + 2)) != $links2"
4904         rmdir remote_dir2
4905         links3=$(stat -c %h .)
4906         [ $(($links1 + 1)) != $links3 ] &&
4907                 error "wrong links count $links1 != $links3"
4908         return 0
4909 }
4910 run_test 39p "remote directory cached attributes updated after create ========"
4911
4912 test_39r() {
4913         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4914                 skip "no atime update on old OST"
4915         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4916                 skip_env "ldiskfs only test"
4917         fi
4918
4919         local saved_adiff
4920         saved_adiff=$(do_facet ost1 \
4921                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4922         stack_trap "do_facet ost1 \
4923                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4924
4925         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4926
4927         $LFS setstripe -i 0 $DIR/$tfile
4928         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4929                 error "can't write initial file"
4930         cancel_lru_locks osc
4931
4932         # exceed atime_diff and access file
4933         sleep 6
4934         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4935                 error "can't udpate atime"
4936
4937         local atime_cli=$(stat -c %X $DIR/$tfile)
4938         echo "client atime: $atime_cli"
4939         # allow atime update to be written to device
4940         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4941         sleep 5
4942
4943         local ostdev=$(ostdevname 1)
4944         local fid=($(lfs getstripe -y $DIR/$tfile |
4945                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4946         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4947         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4948
4949         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4950         local atime_ost=$(do_facet ost1 "$cmd" |&
4951                           awk -F'[: ]' '/atime:/ { print $4 }')
4952         (( atime_cli == atime_ost )) ||
4953                 error "atime on client $atime_cli != ost $atime_ost"
4954 }
4955 run_test 39r "lazy atime update on OST"
4956
4957 test_39q() { # LU-8041
4958         local testdir=$DIR/$tdir
4959         mkdir -p $testdir
4960         multiop_bg_pause $testdir D_c || error "multiop failed"
4961         local multipid=$!
4962         cancel_lru_locks mdc
4963         kill -USR1 $multipid
4964         local atime=$(stat -c %X $testdir)
4965         [ "$atime" -ne 0 ] || error "atime is zero"
4966 }
4967 run_test 39q "close won't zero out atime"
4968
4969 test_40() {
4970         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4971         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4972                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4973         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4974                 error "$tfile is not 4096 bytes in size"
4975 }
4976 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4977
4978 test_41() {
4979         # bug 1553
4980         small_write $DIR/f41 18
4981 }
4982 run_test 41 "test small file write + fstat ====================="
4983
4984 count_ost_writes() {
4985         lctl get_param -n ${OSC}.*.stats |
4986                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4987                         END { printf("%0.0f", writes) }'
4988 }
4989
4990 # decent default
4991 WRITEBACK_SAVE=500
4992 DIRTY_RATIO_SAVE=40
4993 MAX_DIRTY_RATIO=50
4994 BG_DIRTY_RATIO_SAVE=10
4995 MAX_BG_DIRTY_RATIO=25
4996
4997 start_writeback() {
4998         trap 0
4999         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5000         # dirty_ratio, dirty_background_ratio
5001         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5002                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5003                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5004                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5005         else
5006                 # if file not here, we are a 2.4 kernel
5007                 kill -CONT `pidof kupdated`
5008         fi
5009 }
5010
5011 stop_writeback() {
5012         # setup the trap first, so someone cannot exit the test at the
5013         # exact wrong time and mess up a machine
5014         trap start_writeback EXIT
5015         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5016         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5017                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5018                 sysctl -w vm.dirty_writeback_centisecs=0
5019                 sysctl -w vm.dirty_writeback_centisecs=0
5020                 # save and increase /proc/sys/vm/dirty_ratio
5021                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5022                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5023                 # save and increase /proc/sys/vm/dirty_background_ratio
5024                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5025                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5026         else
5027                 # if file not here, we are a 2.4 kernel
5028                 kill -STOP `pidof kupdated`
5029         fi
5030 }
5031
5032 # ensure that all stripes have some grant before we test client-side cache
5033 setup_test42() {
5034         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5035                 dd if=/dev/zero of=$i bs=4k count=1
5036                 rm $i
5037         done
5038 }
5039
5040 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5041 # file truncation, and file removal.
5042 test_42a() {
5043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5044
5045         setup_test42
5046         cancel_lru_locks $OSC
5047         stop_writeback
5048         sync; sleep 1; sync # just to be safe
5049         BEFOREWRITES=`count_ost_writes`
5050         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5051         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5052         AFTERWRITES=`count_ost_writes`
5053         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5054                 error "$BEFOREWRITES < $AFTERWRITES"
5055         start_writeback
5056 }
5057 run_test 42a "ensure that we don't flush on close"
5058
5059 test_42b() {
5060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5061
5062         setup_test42
5063         cancel_lru_locks $OSC
5064         stop_writeback
5065         sync
5066         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5067         BEFOREWRITES=$(count_ost_writes)
5068         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5069         AFTERWRITES=$(count_ost_writes)
5070         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5071                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5072         fi
5073         BEFOREWRITES=$(count_ost_writes)
5074         sync || error "sync: $?"
5075         AFTERWRITES=$(count_ost_writes)
5076         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5077                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5078         fi
5079         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5080         start_writeback
5081         return 0
5082 }
5083 run_test 42b "test destroy of file with cached dirty data ======"
5084
5085 # if these tests just want to test the effect of truncation,
5086 # they have to be very careful.  consider:
5087 # - the first open gets a {0,EOF}PR lock
5088 # - the first write conflicts and gets a {0, count-1}PW
5089 # - the rest of the writes are under {count,EOF}PW
5090 # - the open for truncate tries to match a {0,EOF}PR
5091 #   for the filesize and cancels the PWs.
5092 # any number of fixes (don't get {0,EOF} on open, match
5093 # composite locks, do smarter file size management) fix
5094 # this, but for now we want these tests to verify that
5095 # the cancellation with truncate intent works, so we
5096 # start the file with a full-file pw lock to match against
5097 # until the truncate.
5098 trunc_test() {
5099         test=$1
5100         file=$DIR/$test
5101         offset=$2
5102         cancel_lru_locks $OSC
5103         stop_writeback
5104         # prime the file with 0,EOF PW to match
5105         touch $file
5106         $TRUNCATE $file 0
5107         sync; sync
5108         # now the real test..
5109         dd if=/dev/zero of=$file bs=1024 count=100
5110         BEFOREWRITES=`count_ost_writes`
5111         $TRUNCATE $file $offset
5112         cancel_lru_locks $OSC
5113         AFTERWRITES=`count_ost_writes`
5114         start_writeback
5115 }
5116
5117 test_42c() {
5118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5119
5120         trunc_test 42c 1024
5121         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5122                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5123         rm $file
5124 }
5125 run_test 42c "test partial truncate of file with cached dirty data"
5126
5127 test_42d() {
5128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5129
5130         trunc_test 42d 0
5131         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5132                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5133         rm $file
5134 }
5135 run_test 42d "test complete truncate of file with cached dirty data"
5136
5137 test_42e() { # bug22074
5138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5139
5140         local TDIR=$DIR/${tdir}e
5141         local pages=16 # hardcoded 16 pages, don't change it.
5142         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5143         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5144         local max_dirty_mb
5145         local warmup_files
5146
5147         test_mkdir $DIR/${tdir}e
5148         $LFS setstripe -c 1 $TDIR
5149         createmany -o $TDIR/f $files
5150
5151         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5152
5153         # we assume that with $OSTCOUNT files, at least one of them will
5154         # be allocated on OST0.
5155         warmup_files=$((OSTCOUNT * max_dirty_mb))
5156         createmany -o $TDIR/w $warmup_files
5157
5158         # write a large amount of data into one file and sync, to get good
5159         # avail_grant number from OST.
5160         for ((i=0; i<$warmup_files; i++)); do
5161                 idx=$($LFS getstripe -i $TDIR/w$i)
5162                 [ $idx -ne 0 ] && continue
5163                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5164                 break
5165         done
5166         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5167         sync
5168         $LCTL get_param $proc_osc0/cur_dirty_bytes
5169         $LCTL get_param $proc_osc0/cur_grant_bytes
5170
5171         # create as much dirty pages as we can while not to trigger the actual
5172         # RPCs directly. but depends on the env, VFS may trigger flush during this
5173         # period, hopefully we are good.
5174         for ((i=0; i<$warmup_files; i++)); do
5175                 idx=$($LFS getstripe -i $TDIR/w$i)
5176                 [ $idx -ne 0 ] && continue
5177                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5178         done
5179         $LCTL get_param $proc_osc0/cur_dirty_bytes
5180         $LCTL get_param $proc_osc0/cur_grant_bytes
5181
5182         # perform the real test
5183         $LCTL set_param $proc_osc0/rpc_stats 0
5184         for ((;i<$files; i++)); do
5185                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5186                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5187         done
5188         sync
5189         $LCTL get_param $proc_osc0/rpc_stats
5190
5191         local percent=0
5192         local have_ppr=false
5193         $LCTL get_param $proc_osc0/rpc_stats |
5194                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5195                         # skip lines until we are at the RPC histogram data
5196                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5197                         $have_ppr || continue
5198
5199                         # we only want the percent stat for < 16 pages
5200                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5201
5202                         percent=$((percent + WPCT))
5203                         if [[ $percent -gt 15 ]]; then
5204                                 error "less than 16-pages write RPCs" \
5205                                       "$percent% > 15%"
5206                                 break
5207                         fi
5208                 done
5209         rm -rf $TDIR
5210 }
5211 run_test 42e "verify sub-RPC writes are not done synchronously"
5212
5213 test_43A() { # was test_43
5214         test_mkdir $DIR/$tdir
5215         cp -p /bin/ls $DIR/$tdir/$tfile
5216         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5217         pid=$!
5218         # give multiop a chance to open
5219         sleep 1
5220
5221         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5222         kill -USR1 $pid
5223         # Wait for multiop to exit
5224         wait $pid
5225 }
5226 run_test 43A "execution of file opened for write should return -ETXTBSY"
5227
5228 test_43a() {
5229         test_mkdir $DIR/$tdir
5230         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5231         $DIR/$tdir/sleep 60 &
5232         SLEEP_PID=$!
5233         # Make sure exec of $tdir/sleep wins race with truncate
5234         sleep 1
5235         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5236         kill $SLEEP_PID
5237 }
5238 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5239
5240 test_43b() {
5241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5242
5243         test_mkdir $DIR/$tdir
5244         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5245         $DIR/$tdir/sleep 60 &
5246         SLEEP_PID=$!
5247         # Make sure exec of $tdir/sleep wins race with truncate
5248         sleep 1
5249         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5250         kill $SLEEP_PID
5251 }
5252 run_test 43b "truncate of file being executed should return -ETXTBSY"
5253
5254 test_43c() {
5255         local testdir="$DIR/$tdir"
5256         test_mkdir $testdir
5257         cp $SHELL $testdir/
5258         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5259                 ( cd $testdir && md5sum -c )
5260 }
5261 run_test 43c "md5sum of copy into lustre"
5262
5263 test_44A() { # was test_44
5264         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5265
5266         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5267         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5268 }
5269 run_test 44A "zero length read from a sparse stripe"
5270
5271 test_44a() {
5272         local nstripe=$($LFS getstripe -c -d $DIR)
5273         [ -z "$nstripe" ] && skip "can't get stripe info"
5274         [[ $nstripe -gt $OSTCOUNT ]] &&
5275                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5276
5277         local stride=$($LFS getstripe -S -d $DIR)
5278         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5279                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5280         fi
5281
5282         OFFSETS="0 $((stride/2)) $((stride-1))"
5283         for offset in $OFFSETS; do
5284                 for i in $(seq 0 $((nstripe-1))); do
5285                         local GLOBALOFFSETS=""
5286                         # size in Bytes
5287                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5288                         local myfn=$DIR/d44a-$size
5289                         echo "--------writing $myfn at $size"
5290                         ll_sparseness_write $myfn $size ||
5291                                 error "ll_sparseness_write"
5292                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5293                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5294                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5295
5296                         for j in $(seq 0 $((nstripe-1))); do
5297                                 # size in Bytes
5298                                 size=$((((j + $nstripe )*$stride + $offset)))
5299                                 ll_sparseness_write $myfn $size ||
5300                                         error "ll_sparseness_write"
5301                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5302                         done
5303                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5304                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5305                         rm -f $myfn
5306                 done
5307         done
5308 }
5309 run_test 44a "test sparse pwrite ==============================="
5310
5311 dirty_osc_total() {
5312         tot=0
5313         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5314                 tot=$(($tot + $d))
5315         done
5316         echo $tot
5317 }
5318 do_dirty_record() {
5319         before=`dirty_osc_total`
5320         echo executing "\"$*\""
5321         eval $*
5322         after=`dirty_osc_total`
5323         echo before $before, after $after
5324 }
5325 test_45() {
5326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5327
5328         f="$DIR/f45"
5329         # Obtain grants from OST if it supports it
5330         echo blah > ${f}_grant
5331         stop_writeback
5332         sync
5333         do_dirty_record "echo blah > $f"
5334         [[ $before -eq $after ]] && error "write wasn't cached"
5335         do_dirty_record "> $f"
5336         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5337         do_dirty_record "echo blah > $f"
5338         [[ $before -eq $after ]] && error "write wasn't cached"
5339         do_dirty_record "sync"
5340         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5341         do_dirty_record "echo blah > $f"
5342         [[ $before -eq $after ]] && error "write wasn't cached"
5343         do_dirty_record "cancel_lru_locks osc"
5344         [[ $before -gt $after ]] ||
5345                 error "lock cancellation didn't lower dirty count"
5346         start_writeback
5347 }
5348 run_test 45 "osc io page accounting ============================"
5349
5350 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5351 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5352 # objects offset and an assert hit when an rpc was built with 1023's mapped
5353 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5354 test_46() {
5355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5356
5357         f="$DIR/f46"
5358         stop_writeback
5359         sync
5360         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5361         sync
5362         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5363         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5364         sync
5365         start_writeback
5366 }
5367 run_test 46 "dirtying a previously written page ================"
5368
5369 # test_47 is removed "Device nodes check" is moved to test_28
5370
5371 test_48a() { # bug 2399
5372         [ "$mds1_FSTYPE" = "zfs" ] &&
5373         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5374                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5375
5376         test_mkdir $DIR/$tdir
5377         cd $DIR/$tdir
5378         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5379         test_mkdir $DIR/$tdir
5380         touch foo || error "'touch foo' failed after recreating cwd"
5381         test_mkdir bar
5382         touch .foo || error "'touch .foo' failed after recreating cwd"
5383         test_mkdir .bar
5384         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5385         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5386         cd . || error "'cd .' failed after recreating cwd"
5387         mkdir . && error "'mkdir .' worked after recreating cwd"
5388         rmdir . && error "'rmdir .' worked after recreating cwd"
5389         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5390         cd .. || error "'cd ..' failed after recreating cwd"
5391 }
5392 run_test 48a "Access renamed working dir (should return errors)="
5393
5394 test_48b() { # bug 2399
5395         rm -rf $DIR/$tdir
5396         test_mkdir $DIR/$tdir
5397         cd $DIR/$tdir
5398         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5399         touch foo && error "'touch foo' worked after removing cwd"
5400         mkdir foo && error "'mkdir foo' worked after removing cwd"
5401         touch .foo && error "'touch .foo' worked after removing cwd"
5402         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5403         ls . > /dev/null && error "'ls .' worked after removing cwd"
5404         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5405         mkdir . && error "'mkdir .' worked after removing cwd"
5406         rmdir . && error "'rmdir .' worked after removing cwd"
5407         ln -s . foo && error "'ln -s .' worked after removing cwd"
5408         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5409 }
5410 run_test 48b "Access removed working dir (should return errors)="
5411
5412 test_48c() { # bug 2350
5413         #lctl set_param debug=-1
5414         #set -vx
5415         rm -rf $DIR/$tdir
5416         test_mkdir -p $DIR/$tdir/dir
5417         cd $DIR/$tdir/dir
5418         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5419         $TRACE touch foo && error "touch foo worked after removing cwd"
5420         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5421         touch .foo && error "touch .foo worked after removing cwd"
5422         mkdir .foo && error "mkdir .foo worked after removing cwd"
5423         $TRACE ls . && error "'ls .' worked after removing cwd"
5424         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5425         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5426         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5427         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5428         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5429 }
5430 run_test 48c "Access removed working subdir (should return errors)"
5431
5432 test_48d() { # bug 2350
5433         #lctl set_param debug=-1
5434         #set -vx
5435         rm -rf $DIR/$tdir
5436         test_mkdir -p $DIR/$tdir/dir
5437         cd $DIR/$tdir/dir
5438         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5439         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5440         $TRACE touch foo && error "'touch foo' worked after removing parent"
5441         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5442         touch .foo && error "'touch .foo' worked after removing parent"
5443         mkdir .foo && error "mkdir .foo worked after removing parent"
5444         $TRACE ls . && error "'ls .' worked after removing parent"
5445         $TRACE ls .. && error "'ls ..' worked after removing parent"
5446         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5447         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5448         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5449         true
5450 }
5451 run_test 48d "Access removed parent subdir (should return errors)"
5452
5453 test_48e() { # bug 4134
5454         #lctl set_param debug=-1
5455         #set -vx
5456         rm -rf $DIR/$tdir
5457         test_mkdir -p $DIR/$tdir/dir
5458         cd $DIR/$tdir/dir
5459         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5460         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5461         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5462         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5463         # On a buggy kernel addition of "touch foo" after cd .. will
5464         # produce kernel oops in lookup_hash_it
5465         touch ../foo && error "'cd ..' worked after recreate parent"
5466         cd $DIR
5467         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5468 }
5469 run_test 48e "Access to recreated parent subdir (should return errors)"
5470
5471 test_48f() {
5472         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5473                 skip "need MDS >= 2.13.55"
5474         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5475         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5476                 skip "needs different host for mdt1 mdt2"
5477         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5478
5479         $LFS mkdir -i0 $DIR/$tdir
5480         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5481
5482         for d in sub1 sub2 sub3; do
5483                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5484                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5485                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5486         done
5487
5488         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5489 }
5490 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5491
5492 test_49() { # LU-1030
5493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5494         remote_ost_nodsh && skip "remote OST with nodsh"
5495
5496         # get ost1 size - $FSNAME-OST0000
5497         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5498                 awk '{ print $4 }')
5499         # write 800M at maximum
5500         [[ $ost1_size -lt 2 ]] && ost1_size=2
5501         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5502
5503         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5504         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5505         local dd_pid=$!
5506
5507         # change max_pages_per_rpc while writing the file
5508         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5509         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5510         # loop until dd process exits
5511         while ps ax -opid | grep -wq $dd_pid; do
5512                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5513                 sleep $((RANDOM % 5 + 1))
5514         done
5515         # restore original max_pages_per_rpc
5516         $LCTL set_param $osc1_mppc=$orig_mppc
5517         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5518 }
5519 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5520
5521 test_50() {
5522         # bug 1485
5523         test_mkdir $DIR/$tdir
5524         cd $DIR/$tdir
5525         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5526 }
5527 run_test 50 "special situations: /proc symlinks  ==============="
5528
5529 test_51a() {    # was test_51
5530         # bug 1516 - create an empty entry right after ".." then split dir
5531         test_mkdir -c1 $DIR/$tdir
5532         touch $DIR/$tdir/foo
5533         $MCREATE $DIR/$tdir/bar
5534         rm $DIR/$tdir/foo
5535         createmany -m $DIR/$tdir/longfile 201
5536         FNUM=202
5537         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5538                 $MCREATE $DIR/$tdir/longfile$FNUM
5539                 FNUM=$(($FNUM + 1))
5540                 echo -n "+"
5541         done
5542         echo
5543         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5544 }
5545 run_test 51a "special situations: split htree with empty entry =="
5546
5547 cleanup_print_lfs_df () {
5548         trap 0
5549         $LFS df
5550         $LFS df -i
5551 }
5552
5553 test_51b() {
5554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5555
5556         local dir=$DIR/$tdir
5557         local nrdirs=$((65536 + 100))
5558
5559         # cleanup the directory
5560         rm -fr $dir
5561
5562         test_mkdir -c1 $dir
5563
5564         $LFS df
5565         $LFS df -i
5566         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5567         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5568         [[ $numfree -lt $nrdirs ]] &&
5569                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5570
5571         # need to check free space for the directories as well
5572         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5573         numfree=$(( blkfree / $(fs_inode_ksize) ))
5574         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5575
5576         trap cleanup_print_lfs_df EXIT
5577
5578         # create files
5579         createmany -d $dir/d $nrdirs || {
5580                 unlinkmany $dir/d $nrdirs
5581                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5582         }
5583
5584         # really created :
5585         nrdirs=$(ls -U $dir | wc -l)
5586
5587         # unlink all but 100 subdirectories, then check it still works
5588         local left=100
5589         local delete=$((nrdirs - left))
5590
5591         $LFS df
5592         $LFS df -i
5593
5594         # for ldiskfs the nlink count should be 1, but this is OSD specific
5595         # and so this is listed for informational purposes only
5596         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5597         unlinkmany -d $dir/d $delete ||
5598                 error "unlink of first $delete subdirs failed"
5599
5600         echo "nlink between: $(stat -c %h $dir)"
5601         local found=$(ls -U $dir | wc -l)
5602         [ $found -ne $left ] &&
5603                 error "can't find subdirs: found only $found, expected $left"
5604
5605         unlinkmany -d $dir/d $delete $left ||
5606                 error "unlink of second $left subdirs failed"
5607         # regardless of whether the backing filesystem tracks nlink accurately
5608         # or not, the nlink count shouldn't be more than "." and ".." here
5609         local after=$(stat -c %h $dir)
5610         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5611                 echo "nlink after: $after"
5612
5613         cleanup_print_lfs_df
5614 }
5615 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5616
5617 test_51d() {
5618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5619         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5620
5621         test_mkdir $DIR/$tdir
5622         createmany -o $DIR/$tdir/t- 1000
5623         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5624         for N in $(seq 0 $((OSTCOUNT - 1))); do
5625                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5626                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5627                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5628                         '($1 == '$N') { objs += 1 } \
5629                         END { printf("%0.0f", objs) }')
5630                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5631         done
5632         unlinkmany $DIR/$tdir/t- 1000
5633
5634         NLAST=0
5635         for N in $(seq 1 $((OSTCOUNT - 1))); do
5636                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5637                         error "OST $N has less objects vs OST $NLAST" \
5638                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5639                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5640                         error "OST $N has less objects vs OST $NLAST" \
5641                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5642
5643                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5644                         error "OST $N has less #0 objects vs OST $NLAST" \
5645                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5646                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5647                         error "OST $N has less #0 objects vs OST $NLAST" \
5648                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5649                 NLAST=$N
5650         done
5651         rm -f $TMP/$tfile
5652 }
5653 run_test 51d "check object distribution"
5654
5655 test_51e() {
5656         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5657                 skip_env "ldiskfs only test"
5658         fi
5659
5660         test_mkdir -c1 $DIR/$tdir
5661         test_mkdir -c1 $DIR/$tdir/d0
5662
5663         touch $DIR/$tdir/d0/foo
5664         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5665                 error "file exceed 65000 nlink limit!"
5666         unlinkmany $DIR/$tdir/d0/f- 65001
5667         return 0
5668 }
5669 run_test 51e "check file nlink limit"
5670
5671 test_51f() {
5672         test_mkdir $DIR/$tdir
5673
5674         local max=100000
5675         local ulimit_old=$(ulimit -n)
5676         local spare=20 # number of spare fd's for scripts/libraries, etc.
5677         local mdt=$($LFS getstripe -m $DIR/$tdir)
5678         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5679
5680         echo "MDT$mdt numfree=$numfree, max=$max"
5681         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5682         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5683                 while ! ulimit -n $((numfree + spare)); do
5684                         numfree=$((numfree * 3 / 4))
5685                 done
5686                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5687         else
5688                 echo "left ulimit at $ulimit_old"
5689         fi
5690
5691         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5692                 unlinkmany $DIR/$tdir/f $numfree
5693                 error "create+open $numfree files in $DIR/$tdir failed"
5694         }
5695         ulimit -n $ulimit_old
5696
5697         # if createmany exits at 120s there will be fewer than $numfree files
5698         unlinkmany $DIR/$tdir/f $numfree || true
5699 }
5700 run_test 51f "check many open files limit"
5701
5702 test_52a() {
5703         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5704         test_mkdir $DIR/$tdir
5705         touch $DIR/$tdir/foo
5706         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5707         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5708         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5709         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5710         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5711                                         error "link worked"
5712         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5713         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5714         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5715                                                      error "lsattr"
5716         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5717         cp -r $DIR/$tdir $TMP/
5718         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5719 }
5720 run_test 52a "append-only flag test (should return errors)"
5721
5722 test_52b() {
5723         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5724         test_mkdir $DIR/$tdir
5725         touch $DIR/$tdir/foo
5726         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5727         cat test > $DIR/$tdir/foo && error "cat test worked"
5728         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5729         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5730         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5731                                         error "link worked"
5732         echo foo >> $DIR/$tdir/foo && error "echo worked"
5733         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5734         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5735         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5736         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5737                                                         error "lsattr"
5738         chattr -i $DIR/$tdir/foo || error "chattr failed"
5739
5740         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5741 }
5742 run_test 52b "immutable flag test (should return errors) ======="
5743
5744 test_53() {
5745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5746         remote_mds_nodsh && skip "remote MDS with nodsh"
5747         remote_ost_nodsh && skip "remote OST with nodsh"
5748
5749         local param
5750         local param_seq
5751         local ostname
5752         local mds_last
5753         local mds_last_seq
5754         local ost_last
5755         local ost_last_seq
5756         local ost_last_id
5757         local ostnum
5758         local node
5759         local found=false
5760         local support_last_seq=true
5761
5762         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5763                 support_last_seq=false
5764
5765         # only test MDT0000
5766         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5767         local value
5768         for value in $(do_facet $SINGLEMDS \
5769                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5770                 param=$(echo ${value[0]} | cut -d "=" -f1)
5771                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5772
5773                 if $support_last_seq; then
5774                         param_seq=$(echo $param |
5775                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5776                         mds_last_seq=$(do_facet $SINGLEMDS \
5777                                        $LCTL get_param -n $param_seq)
5778                 fi
5779                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5780
5781                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5782                 node=$(facet_active_host ost$((ostnum+1)))
5783                 param="obdfilter.$ostname.last_id"
5784                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5785                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5786                         ost_last_id=$ost_last
5787
5788                         if $support_last_seq; then
5789                                 ost_last_id=$(echo $ost_last |
5790                                               awk -F':' '{print $2}' |
5791                                               sed -e "s/^0x//g")
5792                                 ost_last_seq=$(echo $ost_last |
5793                                                awk -F':' '{print $1}')
5794                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5795                         fi
5796
5797                         if [[ $ost_last_id != $mds_last ]]; then
5798                                 error "$ost_last_id != $mds_last"
5799                         else
5800                                 found=true
5801                                 break
5802                         fi
5803                 done
5804         done
5805         $found || error "can not match last_seq/last_id for $mdtosc"
5806         return 0
5807 }
5808 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5809
5810 test_54a() {
5811         perl -MSocket -e ';' || skip "no Socket perl module installed"
5812
5813         $SOCKETSERVER $DIR/socket ||
5814                 error "$SOCKETSERVER $DIR/socket failed: $?"
5815         $SOCKETCLIENT $DIR/socket ||
5816                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5817         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5818 }
5819 run_test 54a "unix domain socket test =========================="
5820
5821 test_54b() {
5822         f="$DIR/f54b"
5823         mknod $f c 1 3
5824         chmod 0666 $f
5825         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5826 }
5827 run_test 54b "char device works in lustre ======================"
5828
5829 find_loop_dev() {
5830         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5831         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5832         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5833
5834         for i in $(seq 3 7); do
5835                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5836                 LOOPDEV=$LOOPBASE$i
5837                 LOOPNUM=$i
5838                 break
5839         done
5840 }
5841
5842 cleanup_54c() {
5843         local rc=0
5844         loopdev="$DIR/loop54c"
5845
5846         trap 0
5847         $UMOUNT $DIR/$tdir || rc=$?
5848         losetup -d $loopdev || true
5849         losetup -d $LOOPDEV || true
5850         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5851         return $rc
5852 }
5853
5854 test_54c() {
5855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5856
5857         loopdev="$DIR/loop54c"
5858
5859         find_loop_dev
5860         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5861         trap cleanup_54c EXIT
5862         mknod $loopdev b 7 $LOOPNUM
5863         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5864         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5865         losetup $loopdev $DIR/$tfile ||
5866                 error "can't set up $loopdev for $DIR/$tfile"
5867         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5868         test_mkdir $DIR/$tdir
5869         mount -t ext2 $loopdev $DIR/$tdir ||
5870                 error "error mounting $loopdev on $DIR/$tdir"
5871         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5872                 error "dd write"
5873         df $DIR/$tdir
5874         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5875                 error "dd read"
5876         cleanup_54c
5877 }
5878 run_test 54c "block device works in lustre ====================="
5879
5880 test_54d() {
5881         f="$DIR/f54d"
5882         string="aaaaaa"
5883         mknod $f p
5884         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5885 }
5886 run_test 54d "fifo device works in lustre ======================"
5887
5888 test_54e() {
5889         f="$DIR/f54e"
5890         string="aaaaaa"
5891         cp -aL /dev/console $f
5892         echo $string > $f || error "echo $string to $f failed"
5893 }
5894 run_test 54e "console/tty device works in lustre ======================"
5895
5896 test_56a() {
5897         local numfiles=3
5898         local numdirs=2
5899         local dir=$DIR/$tdir
5900
5901         rm -rf $dir
5902         test_mkdir -p $dir/dir
5903         for i in $(seq $numfiles); do
5904                 touch $dir/file$i
5905                 touch $dir/dir/file$i
5906         done
5907
5908         local numcomp=$($LFS getstripe --component-count $dir)
5909
5910         [[ $numcomp == 0 ]] && numcomp=1
5911
5912         # test lfs getstripe with --recursive
5913         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5914
5915         [[ $filenum -eq $((numfiles * 2)) ]] ||
5916                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5917         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5918         [[ $filenum -eq $numfiles ]] ||
5919                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5920         echo "$LFS getstripe showed obdidx or l_ost_idx"
5921
5922         # test lfs getstripe with file instead of dir
5923         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5924         [[ $filenum -eq 1 ]] ||
5925                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5926         echo "$LFS getstripe file1 passed"
5927
5928         #test lfs getstripe with --verbose
5929         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5930         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5931                 error "$LFS getstripe --verbose $dir: "\
5932                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5933         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5934                 error "$LFS getstripe $dir: showed lmm_magic"
5935
5936         #test lfs getstripe with -v prints lmm_fid
5937         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5938         local countfids=$((numdirs + numfiles * numcomp))
5939         [[ $filenum -eq $countfids ]] ||
5940                 error "$LFS getstripe -v $dir: "\
5941                       "got $filenum want $countfids lmm_fid"
5942         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5943                 error "$LFS getstripe $dir: showed lmm_fid by default"
5944         echo "$LFS getstripe --verbose passed"
5945
5946         #check for FID information
5947         local fid1=$($LFS getstripe --fid $dir/file1)
5948         local fid2=$($LFS getstripe --verbose $dir/file1 |
5949                      awk '/lmm_fid: / { print $2; exit; }')
5950         local fid3=$($LFS path2fid $dir/file1)
5951
5952         [ "$fid1" != "$fid2" ] &&
5953                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5954         [ "$fid1" != "$fid3" ] &&
5955                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5956         echo "$LFS getstripe --fid passed"
5957
5958         #test lfs getstripe with --obd
5959         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5960                 error "$LFS getstripe --obd wrong_uuid: should return error"
5961
5962         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5963
5964         local ostidx=1
5965         local obduuid=$(ostuuid_from_index $ostidx)
5966         local found=$($LFS getstripe -r --obd $obduuid $dir |
5967                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5968
5969         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5970         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5971                 ((filenum--))
5972         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5973                 ((filenum--))
5974
5975         [[ $found -eq $filenum ]] ||
5976                 error "$LFS getstripe --obd: found $found expect $filenum"
5977         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5978                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5979                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5980                 error "$LFS getstripe --obd: should not show file on other obd"
5981         echo "$LFS getstripe --obd passed"
5982 }
5983 run_test 56a "check $LFS getstripe"
5984
5985 test_56b() {
5986         local dir=$DIR/$tdir
5987         local numdirs=3
5988
5989         test_mkdir $dir
5990         for i in $(seq $numdirs); do
5991                 test_mkdir $dir/dir$i
5992         done
5993
5994         # test lfs getdirstripe default mode is non-recursion, which is
5995         # different from lfs getstripe
5996         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5997
5998         [[ $dircnt -eq 1 ]] ||
5999                 error "$LFS getdirstripe: found $dircnt, not 1"
6000         dircnt=$($LFS getdirstripe --recursive $dir |
6001                 grep -c lmv_stripe_count)
6002         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6003                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6004 }
6005 run_test 56b "check $LFS getdirstripe"
6006
6007 test_56c() {
6008         remote_ost_nodsh && skip "remote OST with nodsh"
6009
6010         local ost_idx=0
6011         local ost_name=$(ostname_from_index $ost_idx)
6012         local old_status=$(ost_dev_status $ost_idx)
6013         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6014
6015         [[ -z "$old_status" ]] ||
6016                 skip_env "OST $ost_name is in $old_status status"
6017
6018         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6019         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6020                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6021         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6022                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6023                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6024         fi
6025
6026         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6027                 error "$LFS df -v showing inactive devices"
6028         sleep_maxage
6029
6030         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6031
6032         [[ "$new_status" =~ "D" ]] ||
6033                 error "$ost_name status is '$new_status', missing 'D'"
6034         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6035                 [[ "$new_status" =~ "N" ]] ||
6036                         error "$ost_name status is '$new_status', missing 'N'"
6037         fi
6038         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6039                 [[ "$new_status" =~ "f" ]] ||
6040                         error "$ost_name status is '$new_status', missing 'f'"
6041         fi
6042
6043         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6044         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6045                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6046         [[ -z "$p" ]] && restore_lustre_params < $p || true
6047         sleep_maxage
6048
6049         new_status=$(ost_dev_status $ost_idx)
6050         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6051                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6052         # can't check 'f' as devices may actually be on flash
6053 }
6054 run_test 56c "check 'lfs df' showing device status"
6055
6056 test_56d() {
6057         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6058         local osts=$($LFS df -v $MOUNT | grep -c OST)
6059
6060         $LFS df $MOUNT
6061
6062         (( mdts == MDSCOUNT )) ||
6063                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6064         (( osts == OSTCOUNT )) ||
6065                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6066 }
6067 run_test 56d "'lfs df -v' prints only configured devices"
6068
6069 NUMFILES=3
6070 NUMDIRS=3
6071 setup_56() {
6072         local local_tdir="$1"
6073         local local_numfiles="$2"
6074         local local_numdirs="$3"
6075         local dir_params="$4"
6076         local dir_stripe_params="$5"
6077
6078         if [ ! -d "$local_tdir" ] ; then
6079                 test_mkdir -p $dir_stripe_params $local_tdir
6080                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6081                 for i in $(seq $local_numfiles) ; do
6082                         touch $local_tdir/file$i
6083                 done
6084                 for i in $(seq $local_numdirs) ; do
6085                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6086                         for j in $(seq $local_numfiles) ; do
6087                                 touch $local_tdir/dir$i/file$j
6088                         done
6089                 done
6090         fi
6091 }
6092
6093 setup_56_special() {
6094         local local_tdir=$1
6095         local local_numfiles=$2
6096         local local_numdirs=$3
6097
6098         setup_56 $local_tdir $local_numfiles $local_numdirs
6099
6100         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6101                 for i in $(seq $local_numfiles) ; do
6102                         mknod $local_tdir/loop${i}b b 7 $i
6103                         mknod $local_tdir/null${i}c c 1 3
6104                         ln -s $local_tdir/file1 $local_tdir/link${i}
6105                 done
6106                 for i in $(seq $local_numdirs) ; do
6107                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6108                         mknod $local_tdir/dir$i/null${i}c c 1 3
6109                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6110                 done
6111         fi
6112 }
6113
6114 test_56g() {
6115         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6116         local expected=$(($NUMDIRS + 2))
6117
6118         setup_56 $dir $NUMFILES $NUMDIRS
6119
6120         # test lfs find with -name
6121         for i in $(seq $NUMFILES) ; do
6122                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6123
6124                 [ $nums -eq $expected ] ||
6125                         error "lfs find -name '*$i' $dir wrong: "\
6126                               "found $nums, expected $expected"
6127         done
6128 }
6129 run_test 56g "check lfs find -name"
6130
6131 test_56h() {
6132         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6133         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6134
6135         setup_56 $dir $NUMFILES $NUMDIRS
6136
6137         # test lfs find with ! -name
6138         for i in $(seq $NUMFILES) ; do
6139                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6140
6141                 [ $nums -eq $expected ] ||
6142                         error "lfs find ! -name '*$i' $dir wrong: "\
6143                               "found $nums, expected $expected"
6144         done
6145 }
6146 run_test 56h "check lfs find ! -name"
6147
6148 test_56i() {
6149         local dir=$DIR/$tdir
6150
6151         test_mkdir $dir
6152
6153         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6154         local out=$($cmd)
6155
6156         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6157 }
6158 run_test 56i "check 'lfs find -ost UUID' skips directories"
6159
6160 test_56j() {
6161         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6162
6163         setup_56_special $dir $NUMFILES $NUMDIRS
6164
6165         local expected=$((NUMDIRS + 1))
6166         local cmd="$LFS find -type d $dir"
6167         local nums=$($cmd | wc -l)
6168
6169         [ $nums -eq $expected ] ||
6170                 error "'$cmd' wrong: found $nums, expected $expected"
6171 }
6172 run_test 56j "check lfs find -type d"
6173
6174 test_56k() {
6175         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6176
6177         setup_56_special $dir $NUMFILES $NUMDIRS
6178
6179         local expected=$(((NUMDIRS + 1) * NUMFILES))
6180         local cmd="$LFS find -type f $dir"
6181         local nums=$($cmd | wc -l)
6182
6183         [ $nums -eq $expected ] ||
6184                 error "'$cmd' wrong: found $nums, expected $expected"
6185 }
6186 run_test 56k "check lfs find -type f"
6187
6188 test_56l() {
6189         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6190
6191         setup_56_special $dir $NUMFILES $NUMDIRS
6192
6193         local expected=$((NUMDIRS + NUMFILES))
6194         local cmd="$LFS find -type b $dir"
6195         local nums=$($cmd | wc -l)
6196
6197         [ $nums -eq $expected ] ||
6198                 error "'$cmd' wrong: found $nums, expected $expected"
6199 }
6200 run_test 56l "check lfs find -type b"
6201
6202 test_56m() {
6203         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6204
6205         setup_56_special $dir $NUMFILES $NUMDIRS
6206
6207         local expected=$((NUMDIRS + NUMFILES))
6208         local cmd="$LFS find -type c $dir"
6209         local nums=$($cmd | wc -l)
6210         [ $nums -eq $expected ] ||
6211                 error "'$cmd' wrong: found $nums, expected $expected"
6212 }
6213 run_test 56m "check lfs find -type c"
6214
6215 test_56n() {
6216         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6217         setup_56_special $dir $NUMFILES $NUMDIRS
6218
6219         local expected=$((NUMDIRS + NUMFILES))
6220         local cmd="$LFS find -type l $dir"
6221         local nums=$($cmd | wc -l)
6222
6223         [ $nums -eq $expected ] ||
6224                 error "'$cmd' wrong: found $nums, expected $expected"
6225 }
6226 run_test 56n "check lfs find -type l"
6227
6228 test_56o() {
6229         local dir=$DIR/$tdir
6230
6231         setup_56 $dir $NUMFILES $NUMDIRS
6232         utime $dir/file1 > /dev/null || error "utime (1)"
6233         utime $dir/file2 > /dev/null || error "utime (2)"
6234         utime $dir/dir1 > /dev/null || error "utime (3)"
6235         utime $dir/dir2 > /dev/null || error "utime (4)"
6236         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6237         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6238
6239         local expected=4
6240         local nums=$($LFS find -mtime +0 $dir | wc -l)
6241
6242         [ $nums -eq $expected ] ||
6243                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6244
6245         expected=12
6246         cmd="$LFS find -mtime 0 $dir"
6247         nums=$($cmd | wc -l)
6248         [ $nums -eq $expected ] ||
6249                 error "'$cmd' wrong: found $nums, expected $expected"
6250 }
6251 run_test 56o "check lfs find -mtime for old files"
6252
6253 test_56ob() {
6254         local dir=$DIR/$tdir
6255         local expected=1
6256         local count=0
6257
6258         # just to make sure there is something that won't be found
6259         test_mkdir $dir
6260         touch $dir/$tfile.now
6261
6262         for age in year week day hour min; do
6263                 count=$((count + 1))
6264
6265                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6266                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6267                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6268
6269                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6270                 local nums=$($cmd | wc -l)
6271                 [ $nums -eq $expected ] ||
6272                         error "'$cmd' wrong: found $nums, expected $expected"
6273
6274                 cmd="$LFS find $dir -atime $count${age:0:1}"
6275                 nums=$($cmd | wc -l)
6276                 [ $nums -eq $expected ] ||
6277                         error "'$cmd' wrong: found $nums, expected $expected"
6278         done
6279
6280         sleep 2
6281         cmd="$LFS find $dir -ctime +1s -type f"
6282         nums=$($cmd | wc -l)
6283         (( $nums == $count * 2 + 1)) ||
6284                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6285 }
6286 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6287
6288 test_newerXY_base() {
6289         local x=$1
6290         local y=$2
6291         local dir=$DIR/$tdir
6292         local ref
6293         local negref
6294
6295         if [ $y == "t" ]; then
6296                 if [ $x == "b" ]; then
6297                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6298                 else
6299                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6300                 fi
6301         else
6302                 ref=$DIR/$tfile.newer.$x$y
6303                 touch $ref || error "touch $ref failed"
6304         fi
6305
6306         echo "before = $ref"
6307         sleep 2
6308         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6309         sleep 2
6310         if [ $y == "t" ]; then
6311                 if [ $x == "b" ]; then
6312                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6313                 else
6314                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6315                 fi
6316         else
6317                 negref=$DIR/$tfile.negnewer.$x$y
6318                 touch $negref || error "touch $negref failed"
6319         fi
6320
6321         echo "after = $negref"
6322         local cmd="$LFS find $dir -newer$x$y $ref"
6323         local nums=$(eval $cmd | wc -l)
6324         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6325
6326         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6327                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6328
6329         cmd="$LFS find $dir ! -newer$x$y $negref"
6330         nums=$(eval $cmd | wc -l)
6331         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6332                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6333
6334         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6335         nums=$(eval $cmd | wc -l)
6336         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6337                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6338
6339         rm -rf $DIR/*
6340 }
6341
6342 test_56oc() {
6343         test_newerXY_base "a" "a"
6344         test_newerXY_base "a" "m"
6345         test_newerXY_base "a" "c"
6346         test_newerXY_base "m" "a"
6347         test_newerXY_base "m" "m"
6348         test_newerXY_base "m" "c"
6349         test_newerXY_base "c" "a"
6350         test_newerXY_base "c" "m"
6351         test_newerXY_base "c" "c"
6352
6353         [[ -n "$sles_version" ]] &&
6354                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6355
6356         test_newerXY_base "a" "t"
6357         test_newerXY_base "m" "t"
6358         test_newerXY_base "c" "t"
6359
6360         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6361            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6362                 ! btime_supported && echo "btime unsupported" && return 0
6363
6364         test_newerXY_base "b" "b"
6365         test_newerXY_base "b" "t"
6366 }
6367 run_test 56oc "check lfs find -newerXY work"
6368
6369 btime_supported() {
6370         local dir=$DIR/$tdir
6371         local rc
6372
6373         mkdir -p $dir
6374         touch $dir/$tfile
6375         $LFS find $dir -btime -1d -type f
6376         rc=$?
6377         rm -rf $dir
6378         return $rc
6379 }
6380
6381 test_56od() {
6382         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6383                 ! btime_supported && skip "btime unsupported on MDS"
6384
6385         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6386                 ! btime_supported && skip "btime unsupported on clients"
6387
6388         local dir=$DIR/$tdir
6389         local ref=$DIR/$tfile.ref
6390         local negref=$DIR/$tfile.negref
6391
6392         mkdir $dir || error "mkdir $dir failed"
6393         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6394         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6395         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6396         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6397         touch $ref || error "touch $ref failed"
6398         # sleep 3 seconds at least
6399         sleep 3
6400
6401         local before=$(do_facet mds1 date +%s)
6402         local skew=$(($(date +%s) - before + 1))
6403
6404         if (( skew < 0 && skew > -5 )); then
6405                 sleep $((0 - skew + 1))
6406                 skew=0
6407         fi
6408
6409         # Set the dir stripe params to limit files all on MDT0,
6410         # otherwise we need to calc the max clock skew between
6411         # the client and MDTs.
6412         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6413         sleep 2
6414         touch $negref || error "touch $negref failed"
6415
6416         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6417         local nums=$($cmd | wc -l)
6418         local expected=$(((NUMFILES + 1) * NUMDIRS))
6419
6420         [ $nums -eq $expected ] ||
6421                 error "'$cmd' wrong: found $nums, expected $expected"
6422
6423         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6424         nums=$($cmd | wc -l)
6425         expected=$((NUMFILES + 1))
6426         [ $nums -eq $expected ] ||
6427                 error "'$cmd' wrong: found $nums, expected $expected"
6428
6429         [ $skew -lt 0 ] && return
6430
6431         local after=$(do_facet mds1 date +%s)
6432         local age=$((after - before + 1 + skew))
6433
6434         cmd="$LFS find $dir -btime -${age}s -type f"
6435         nums=$($cmd | wc -l)
6436         expected=$(((NUMFILES + 1) * NUMDIRS))
6437
6438         echo "Clock skew between client and server: $skew, age:$age"
6439         [ $nums -eq $expected ] ||
6440                 error "'$cmd' wrong: found $nums, expected $expected"
6441
6442         expected=$(($NUMDIRS + 1))
6443         cmd="$LFS find $dir -btime -${age}s -type d"
6444         nums=$($cmd | wc -l)
6445         [ $nums -eq $expected ] ||
6446                 error "'$cmd' wrong: found $nums, expected $expected"
6447         rm -f $ref $negref || error "Failed to remove $ref $negref"
6448 }
6449 run_test 56od "check lfs find -btime with units"
6450
6451 test_56p() {
6452         [ $RUNAS_ID -eq $UID ] &&
6453                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6454
6455         local dir=$DIR/$tdir
6456
6457         setup_56 $dir $NUMFILES $NUMDIRS
6458         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6459
6460         local expected=$NUMFILES
6461         local cmd="$LFS find -uid $RUNAS_ID $dir"
6462         local nums=$($cmd | wc -l)
6463
6464         [ $nums -eq $expected ] ||
6465                 error "'$cmd' wrong: found $nums, expected $expected"
6466
6467         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6468         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6469         nums=$($cmd | wc -l)
6470         [ $nums -eq $expected ] ||
6471                 error "'$cmd' wrong: found $nums, expected $expected"
6472 }
6473 run_test 56p "check lfs find -uid and ! -uid"
6474
6475 test_56q() {
6476         [ $RUNAS_ID -eq $UID ] &&
6477                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6478
6479         local dir=$DIR/$tdir
6480
6481         setup_56 $dir $NUMFILES $NUMDIRS
6482         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6483
6484         local expected=$NUMFILES
6485         local cmd="$LFS find -gid $RUNAS_GID $dir"
6486         local nums=$($cmd | wc -l)
6487
6488         [ $nums -eq $expected ] ||
6489                 error "'$cmd' wrong: found $nums, expected $expected"
6490
6491         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6492         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6493         nums=$($cmd | wc -l)
6494         [ $nums -eq $expected ] ||
6495                 error "'$cmd' wrong: found $nums, expected $expected"
6496 }
6497 run_test 56q "check lfs find -gid and ! -gid"
6498
6499 test_56r() {
6500         local dir=$DIR/$tdir
6501
6502         setup_56 $dir $NUMFILES $NUMDIRS
6503
6504         local expected=12
6505         local cmd="$LFS find -size 0 -type f -lazy $dir"
6506         local nums=$($cmd | wc -l)
6507
6508         [ $nums -eq $expected ] ||
6509                 error "'$cmd' wrong: found $nums, expected $expected"
6510         cmd="$LFS find -size 0 -type f $dir"
6511         nums=$($cmd | wc -l)
6512         [ $nums -eq $expected ] ||
6513                 error "'$cmd' wrong: found $nums, expected $expected"
6514
6515         expected=0
6516         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6517         nums=$($cmd | wc -l)
6518         [ $nums -eq $expected ] ||
6519                 error "'$cmd' wrong: found $nums, expected $expected"
6520         cmd="$LFS find ! -size 0 -type f $dir"
6521         nums=$($cmd | wc -l)
6522         [ $nums -eq $expected ] ||
6523                 error "'$cmd' wrong: found $nums, expected $expected"
6524
6525         echo "test" > $dir/$tfile
6526         echo "test2" > $dir/$tfile.2 && sync
6527         expected=1
6528         cmd="$LFS find -size 5 -type f -lazy $dir"
6529         nums=$($cmd | wc -l)
6530         [ $nums -eq $expected ] ||
6531                 error "'$cmd' wrong: found $nums, expected $expected"
6532         cmd="$LFS find -size 5 -type f $dir"
6533         nums=$($cmd | wc -l)
6534         [ $nums -eq $expected ] ||
6535                 error "'$cmd' wrong: found $nums, expected $expected"
6536
6537         expected=1
6538         cmd="$LFS find -size +5 -type f -lazy $dir"
6539         nums=$($cmd | wc -l)
6540         [ $nums -eq $expected ] ||
6541                 error "'$cmd' wrong: found $nums, expected $expected"
6542         cmd="$LFS find -size +5 -type f $dir"
6543         nums=$($cmd | wc -l)
6544         [ $nums -eq $expected ] ||
6545                 error "'$cmd' wrong: found $nums, expected $expected"
6546
6547         expected=2
6548         cmd="$LFS find -size +0 -type f -lazy $dir"
6549         nums=$($cmd | wc -l)
6550         [ $nums -eq $expected ] ||
6551                 error "'$cmd' wrong: found $nums, expected $expected"
6552         cmd="$LFS find -size +0 -type f $dir"
6553         nums=$($cmd | wc -l)
6554         [ $nums -eq $expected ] ||
6555                 error "'$cmd' wrong: found $nums, expected $expected"
6556
6557         expected=2
6558         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6559         nums=$($cmd | wc -l)
6560         [ $nums -eq $expected ] ||
6561                 error "'$cmd' wrong: found $nums, expected $expected"
6562         cmd="$LFS find ! -size -5 -type f $dir"
6563         nums=$($cmd | wc -l)
6564         [ $nums -eq $expected ] ||
6565                 error "'$cmd' wrong: found $nums, expected $expected"
6566
6567         expected=12
6568         cmd="$LFS find -size -5 -type f -lazy $dir"
6569         nums=$($cmd | wc -l)
6570         [ $nums -eq $expected ] ||
6571                 error "'$cmd' wrong: found $nums, expected $expected"
6572         cmd="$LFS find -size -5 -type f $dir"
6573         nums=$($cmd | wc -l)
6574         [ $nums -eq $expected ] ||
6575                 error "'$cmd' wrong: found $nums, expected $expected"
6576 }
6577 run_test 56r "check lfs find -size works"
6578
6579 test_56ra_sub() {
6580         local expected=$1
6581         local glimpses=$2
6582         local cmd="$3"
6583
6584         cancel_lru_locks $OSC
6585
6586         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6587         local nums=$($cmd | wc -l)
6588
6589         [ $nums -eq $expected ] ||
6590                 error "'$cmd' wrong: found $nums, expected $expected"
6591
6592         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6593
6594         if (( rpcs_before + glimpses != rpcs_after )); then
6595                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6596                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6597
6598                 if [[ $glimpses == 0 ]]; then
6599                         error "'$cmd' should not send glimpse RPCs to OST"
6600                 else
6601                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6602                 fi
6603         fi
6604 }
6605
6606 test_56ra() {
6607         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6608                 skip "MDS < 2.12.58 doesn't return LSOM data"
6609         local dir=$DIR/$tdir
6610         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6611
6612         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6613
6614         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6615         $LCTL set_param -n llite.*.statahead_agl=0
6616         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6617
6618         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6619         # open and close all files to ensure LSOM is updated
6620         cancel_lru_locks $OSC
6621         find $dir -type f | xargs cat > /dev/null
6622
6623         #   expect_found  glimpse_rpcs  command_to_run
6624         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6625         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6626         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6627         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6628
6629         echo "test" > $dir/$tfile
6630         echo "test2" > $dir/$tfile.2 && sync
6631         cancel_lru_locks $OSC
6632         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6633
6634         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6635         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6636         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6637         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6638
6639         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6640         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6641         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6642         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6643         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6644         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6645 }
6646 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6647
6648 test_56rb() {
6649         local dir=$DIR/$tdir
6650         local tmp=$TMP/$tfile.log
6651         local mdt_idx;
6652
6653         test_mkdir -p $dir || error "failed to mkdir $dir"
6654         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6655                 error "failed to setstripe $dir/$tfile"
6656         mdt_idx=$($LFS getdirstripe -i $dir)
6657         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6658
6659         stack_trap "rm -f $tmp" EXIT
6660         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6661         ! grep -q obd_uuid $tmp ||
6662                 error "failed to find --size +100K --ost 0 $dir"
6663         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6664         ! grep -q obd_uuid $tmp ||
6665                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6666 }
6667 run_test 56rb "check lfs find --size --ost/--mdt works"
6668
6669 test_56rc() {
6670         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6671         local dir=$DIR/$tdir
6672         local found
6673
6674         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6675         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6676         (( $MDSCOUNT > 2 )) &&
6677                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6678         mkdir $dir/$tdir-{1..10}
6679         touch $dir/$tfile-{1..10}
6680
6681         found=$($LFS find $dir --mdt-count 2 | wc -l)
6682         expect=11
6683         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6684
6685         found=$($LFS find $dir -T +1 | wc -l)
6686         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6687         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6688
6689         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6690         expect=11
6691         (( $found == $expect )) || error "found $found all_char, expect $expect"
6692
6693         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6694         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6695         (( $found == $expect )) || error "found $found all_char, expect $expect"
6696 }
6697 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6698
6699 test_56s() { # LU-611 #LU-9369
6700         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6701
6702         local dir=$DIR/$tdir
6703         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6704
6705         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6706         for i in $(seq $NUMDIRS); do
6707                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6708         done
6709
6710         local expected=$NUMDIRS
6711         local cmd="$LFS find -c $OSTCOUNT $dir"
6712         local nums=$($cmd | wc -l)
6713
6714         [ $nums -eq $expected ] || {
6715                 $LFS getstripe -R $dir
6716                 error "'$cmd' wrong: found $nums, expected $expected"
6717         }
6718
6719         expected=$((NUMDIRS + onestripe))
6720         cmd="$LFS find -stripe-count +0 -type f $dir"
6721         nums=$($cmd | wc -l)
6722         [ $nums -eq $expected ] || {
6723                 $LFS getstripe -R $dir
6724                 error "'$cmd' wrong: found $nums, expected $expected"
6725         }
6726
6727         expected=$onestripe
6728         cmd="$LFS find -stripe-count 1 -type f $dir"
6729         nums=$($cmd | wc -l)
6730         [ $nums -eq $expected ] || {
6731                 $LFS getstripe -R $dir
6732                 error "'$cmd' wrong: found $nums, expected $expected"
6733         }
6734
6735         cmd="$LFS find -stripe-count -2 -type f $dir"
6736         nums=$($cmd | wc -l)
6737         [ $nums -eq $expected ] || {
6738                 $LFS getstripe -R $dir
6739                 error "'$cmd' wrong: found $nums, expected $expected"
6740         }
6741
6742         expected=0
6743         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6744         nums=$($cmd | wc -l)
6745         [ $nums -eq $expected ] || {
6746                 $LFS getstripe -R $dir
6747                 error "'$cmd' wrong: found $nums, expected $expected"
6748         }
6749 }
6750 run_test 56s "check lfs find -stripe-count works"
6751
6752 test_56t() { # LU-611 #LU-9369
6753         local dir=$DIR/$tdir
6754
6755         setup_56 $dir 0 $NUMDIRS
6756         for i in $(seq $NUMDIRS); do
6757                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6758         done
6759
6760         local expected=$NUMDIRS
6761         local cmd="$LFS find -S 8M $dir"
6762         local nums=$($cmd | wc -l)
6763
6764         [ $nums -eq $expected ] || {
6765                 $LFS getstripe -R $dir
6766                 error "'$cmd' wrong: found $nums, expected $expected"
6767         }
6768         rm -rf $dir
6769
6770         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6771
6772         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6773
6774         expected=$(((NUMDIRS + 1) * NUMFILES))
6775         cmd="$LFS find -stripe-size 512k -type f $dir"
6776         nums=$($cmd | wc -l)
6777         [ $nums -eq $expected ] ||
6778                 error "'$cmd' wrong: found $nums, expected $expected"
6779
6780         cmd="$LFS find -stripe-size +320k -type f $dir"
6781         nums=$($cmd | wc -l)
6782         [ $nums -eq $expected ] ||
6783                 error "'$cmd' wrong: found $nums, expected $expected"
6784
6785         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6786         cmd="$LFS find -stripe-size +200k -type f $dir"
6787         nums=$($cmd | wc -l)
6788         [ $nums -eq $expected ] ||
6789                 error "'$cmd' wrong: found $nums, expected $expected"
6790
6791         cmd="$LFS find -stripe-size -640k -type f $dir"
6792         nums=$($cmd | wc -l)
6793         [ $nums -eq $expected ] ||
6794                 error "'$cmd' wrong: found $nums, expected $expected"
6795
6796         expected=4
6797         cmd="$LFS find -stripe-size 256k -type f $dir"
6798         nums=$($cmd | wc -l)
6799         [ $nums -eq $expected ] ||
6800                 error "'$cmd' wrong: found $nums, expected $expected"
6801
6802         cmd="$LFS find -stripe-size -320k -type f $dir"
6803         nums=$($cmd | wc -l)
6804         [ $nums -eq $expected ] ||
6805                 error "'$cmd' wrong: found $nums, expected $expected"
6806
6807         expected=0
6808         cmd="$LFS find -stripe-size 1024k -type f $dir"
6809         nums=$($cmd | wc -l)
6810         [ $nums -eq $expected ] ||
6811                 error "'$cmd' wrong: found $nums, expected $expected"
6812 }
6813 run_test 56t "check lfs find -stripe-size works"
6814
6815 test_56u() { # LU-611
6816         local dir=$DIR/$tdir
6817
6818         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6819
6820         if [[ $OSTCOUNT -gt 1 ]]; then
6821                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6822                 onestripe=4
6823         else
6824                 onestripe=0
6825         fi
6826
6827         local expected=$(((NUMDIRS + 1) * NUMFILES))
6828         local cmd="$LFS find -stripe-index 0 -type f $dir"
6829         local nums=$($cmd | wc -l)
6830
6831         [ $nums -eq $expected ] ||
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833
6834         expected=$onestripe
6835         cmd="$LFS find -stripe-index 1 -type f $dir"
6836         nums=$($cmd | wc -l)
6837         [ $nums -eq $expected ] ||
6838                 error "'$cmd' wrong: found $nums, expected $expected"
6839
6840         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6841         nums=$($cmd | wc -l)
6842         [ $nums -eq $expected ] ||
6843                 error "'$cmd' wrong: found $nums, expected $expected"
6844
6845         expected=0
6846         # This should produce an error and not return any files
6847         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6848         nums=$($cmd 2>/dev/null | wc -l)
6849         [ $nums -eq $expected ] ||
6850                 error "'$cmd' wrong: found $nums, expected $expected"
6851
6852         if [[ $OSTCOUNT -gt 1 ]]; then
6853                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6854                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6855                 nums=$($cmd | wc -l)
6856                 [ $nums -eq $expected ] ||
6857                         error "'$cmd' wrong: found $nums, expected $expected"
6858         fi
6859 }
6860 run_test 56u "check lfs find -stripe-index works"
6861
6862 test_56v() {
6863         local mdt_idx=0
6864         local dir=$DIR/$tdir
6865
6866         setup_56 $dir $NUMFILES $NUMDIRS
6867
6868         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6869         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6870
6871         for file in $($LFS find -m $UUID $dir); do
6872                 file_midx=$($LFS getstripe -m $file)
6873                 [ $file_midx -eq $mdt_idx ] ||
6874                         error "lfs find -m $UUID != getstripe -m $file_midx"
6875         done
6876 }
6877 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6878
6879 test_56w() {
6880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6882
6883         local dir=$DIR/$tdir
6884
6885         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6886
6887         local stripe_size=$($LFS getstripe -S -d $dir) ||
6888                 error "$LFS getstripe -S -d $dir failed"
6889         stripe_size=${stripe_size%% *}
6890
6891         local file_size=$((stripe_size * OSTCOUNT))
6892         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6893         local required_space=$((file_num * file_size))
6894         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6895                            head -n1)
6896         [[ $free_space -le $((required_space / 1024)) ]] &&
6897                 skip_env "need $required_space, have $free_space kbytes"
6898
6899         local dd_bs=65536
6900         local dd_count=$((file_size / dd_bs))
6901
6902         # write data into the files
6903         local i
6904         local j
6905         local file
6906
6907         for i in $(seq $NUMFILES); do
6908                 file=$dir/file$i
6909                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6910                         error "write data into $file failed"
6911         done
6912         for i in $(seq $NUMDIRS); do
6913                 for j in $(seq $NUMFILES); do
6914                         file=$dir/dir$i/file$j
6915                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6916                                 error "write data into $file failed"
6917                 done
6918         done
6919
6920         # $LFS_MIGRATE will fail if hard link migration is unsupported
6921         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6922                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6923                         error "creating links to $dir/dir1/file1 failed"
6924         fi
6925
6926         local expected=-1
6927
6928         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6929
6930         # lfs_migrate file
6931         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6932
6933         echo "$cmd"
6934         eval $cmd || error "$cmd failed"
6935
6936         check_stripe_count $dir/file1 $expected
6937
6938         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6939         then
6940                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6941                 # OST 1 if it is on OST 0. This file is small enough to
6942                 # be on only one stripe.
6943                 file=$dir/migr_1_ost
6944                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6945                         error "write data into $file failed"
6946                 local obdidx=$($LFS getstripe -i $file)
6947                 local oldmd5=$(md5sum $file)
6948                 local newobdidx=0
6949
6950                 [[ $obdidx -eq 0 ]] && newobdidx=1
6951                 cmd="$LFS migrate -i $newobdidx $file"
6952                 echo $cmd
6953                 eval $cmd || error "$cmd failed"
6954
6955                 local realobdix=$($LFS getstripe -i $file)
6956                 local newmd5=$(md5sum $file)
6957
6958                 [[ $newobdidx -ne $realobdix ]] &&
6959                         error "new OST is different (was=$obdidx, "\
6960                               "wanted=$newobdidx, got=$realobdix)"
6961                 [[ "$oldmd5" != "$newmd5" ]] &&
6962                         error "md5sum differ: $oldmd5, $newmd5"
6963         fi
6964
6965         # lfs_migrate dir
6966         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6967         echo "$cmd"
6968         eval $cmd || error "$cmd failed"
6969
6970         for j in $(seq $NUMFILES); do
6971                 check_stripe_count $dir/dir1/file$j $expected
6972         done
6973
6974         # lfs_migrate works with lfs find
6975         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6976              $LFS_MIGRATE -y -c $expected"
6977         echo "$cmd"
6978         eval $cmd || error "$cmd failed"
6979
6980         for i in $(seq 2 $NUMFILES); do
6981                 check_stripe_count $dir/file$i $expected
6982         done
6983         for i in $(seq 2 $NUMDIRS); do
6984                 for j in $(seq $NUMFILES); do
6985                 check_stripe_count $dir/dir$i/file$j $expected
6986                 done
6987         done
6988 }
6989 run_test 56w "check lfs_migrate -c stripe_count works"
6990
6991 test_56wb() {
6992         local file1=$DIR/$tdir/file1
6993         local create_pool=false
6994         local initial_pool=$($LFS getstripe -p $DIR)
6995         local pool_list=()
6996         local pool=""
6997
6998         echo -n "Creating test dir..."
6999         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7000         echo "done."
7001
7002         echo -n "Creating test file..."
7003         touch $file1 || error "cannot create file"
7004         echo "done."
7005
7006         echo -n "Detecting existing pools..."
7007         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7008
7009         if [ ${#pool_list[@]} -gt 0 ]; then
7010                 echo "${pool_list[@]}"
7011                 for thispool in "${pool_list[@]}"; do
7012                         if [[ -z "$initial_pool" ||
7013                               "$initial_pool" != "$thispool" ]]; then
7014                                 pool="$thispool"
7015                                 echo "Using existing pool '$pool'"
7016                                 break
7017                         fi
7018                 done
7019         else
7020                 echo "none detected."
7021         fi
7022         if [ -z "$pool" ]; then
7023                 pool=${POOL:-testpool}
7024                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7025                 echo -n "Creating pool '$pool'..."
7026                 create_pool=true
7027                 pool_add $pool &> /dev/null ||
7028                         error "pool_add failed"
7029                 echo "done."
7030
7031                 echo -n "Adding target to pool..."
7032                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7033                         error "pool_add_targets failed"
7034                 echo "done."
7035         fi
7036
7037         echo -n "Setting pool using -p option..."
7038         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7039                 error "migrate failed rc = $?"
7040         echo "done."
7041
7042         echo -n "Verifying test file is in pool after migrating..."
7043         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7044                 error "file was not migrated to pool $pool"
7045         echo "done."
7046
7047         echo -n "Removing test file from pool '$pool'..."
7048         # "lfs migrate $file" won't remove the file from the pool
7049         # until some striping information is changed.
7050         $LFS migrate -c 1 $file1 &> /dev/null ||
7051                 error "cannot remove from pool"
7052         [ "$($LFS getstripe -p $file1)" ] &&
7053                 error "pool still set"
7054         echo "done."
7055
7056         echo -n "Setting pool using --pool option..."
7057         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7058                 error "migrate failed rc = $?"
7059         echo "done."
7060
7061         # Clean up
7062         rm -f $file1
7063         if $create_pool; then
7064                 destroy_test_pools 2> /dev/null ||
7065                         error "destroy test pools failed"
7066         fi
7067 }
7068 run_test 56wb "check lfs_migrate pool support"
7069
7070 test_56wc() {
7071         local file1="$DIR/$tdir/file1"
7072         local parent_ssize
7073         local parent_scount
7074         local cur_ssize
7075         local cur_scount
7076         local orig_ssize
7077
7078         echo -n "Creating test dir..."
7079         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7080         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7081                 error "cannot set stripe by '-S 1M -c 1'"
7082         echo "done"
7083
7084         echo -n "Setting initial stripe for test file..."
7085         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7086                 error "cannot set stripe"
7087         cur_ssize=$($LFS getstripe -S "$file1")
7088         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7089         echo "done."
7090
7091         # File currently set to -S 512K -c 1
7092
7093         # Ensure -c and -S options are rejected when -R is set
7094         echo -n "Verifying incompatible options are detected..."
7095         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7096                 error "incompatible -c and -R options not detected"
7097         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7098                 error "incompatible -S and -R options not detected"
7099         echo "done."
7100
7101         # Ensure unrecognized options are passed through to 'lfs migrate'
7102         echo -n "Verifying -S option is passed through to lfs migrate..."
7103         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7104                 error "migration failed"
7105         cur_ssize=$($LFS getstripe -S "$file1")
7106         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7107         echo "done."
7108
7109         # File currently set to -S 1M -c 1
7110
7111         # Ensure long options are supported
7112         echo -n "Verifying long options supported..."
7113         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7114                 error "long option without argument not supported"
7115         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7116                 error "long option with argument not supported"
7117         cur_ssize=$($LFS getstripe -S "$file1")
7118         [ $cur_ssize -eq 524288 ] ||
7119                 error "migrate --stripe-size $cur_ssize != 524288"
7120         echo "done."
7121
7122         # File currently set to -S 512K -c 1
7123
7124         if [ "$OSTCOUNT" -gt 1 ]; then
7125                 echo -n "Verifying explicit stripe count can be set..."
7126                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7127                         error "migrate failed"
7128                 cur_scount=$($LFS getstripe -c "$file1")
7129                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7130                 echo "done."
7131         fi
7132
7133         # File currently set to -S 512K -c 1 or -S 512K -c 2
7134
7135         # Ensure parent striping is used if -R is set, and no stripe
7136         # count or size is specified
7137         echo -n "Setting stripe for parent directory..."
7138         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7139                 error "cannot set stripe '-S 2M -c 1'"
7140         echo "done."
7141
7142         echo -n "Verifying restripe option uses parent stripe settings..."
7143         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7144         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7145         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7146                 error "migrate failed"
7147         cur_ssize=$($LFS getstripe -S "$file1")
7148         [ $cur_ssize -eq $parent_ssize ] ||
7149                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7150         cur_scount=$($LFS getstripe -c "$file1")
7151         [ $cur_scount -eq $parent_scount ] ||
7152                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7153         echo "done."
7154
7155         # File currently set to -S 1M -c 1
7156
7157         # Ensure striping is preserved if -R is not set, and no stripe
7158         # count or size is specified
7159         echo -n "Verifying striping size preserved when not specified..."
7160         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7161         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7162                 error "cannot set stripe on parent directory"
7163         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7164                 error "migrate failed"
7165         cur_ssize=$($LFS getstripe -S "$file1")
7166         [ $cur_ssize -eq $orig_ssize ] ||
7167                 error "migrate by default $cur_ssize != $orig_ssize"
7168         echo "done."
7169
7170         # Ensure file name properly detected when final option has no argument
7171         echo -n "Verifying file name properly detected..."
7172         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7173                 error "file name interpreted as option argument"
7174         echo "done."
7175
7176         # Clean up
7177         rm -f "$file1"
7178 }
7179 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7180
7181 test_56wd() {
7182         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7183
7184         local file1=$DIR/$tdir/file1
7185
7186         echo -n "Creating test dir..."
7187         test_mkdir $DIR/$tdir || error "cannot create dir"
7188         echo "done."
7189
7190         echo -n "Creating test file..."
7191         touch $file1
7192         echo "done."
7193
7194         # Ensure 'lfs migrate' will fail by using a non-existent option,
7195         # and make sure rsync is not called to recover
7196         echo -n "Make sure --no-rsync option works..."
7197         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7198                 grep -q 'refusing to fall back to rsync' ||
7199                 error "rsync was called with --no-rsync set"
7200         echo "done."
7201
7202         # Ensure rsync is called without trying 'lfs migrate' first
7203         echo -n "Make sure --rsync option works..."
7204         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7205                 grep -q 'falling back to rsync' &&
7206                 error "lfs migrate was called with --rsync set"
7207         echo "done."
7208
7209         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7210         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7211                 grep -q 'at the same time' ||
7212                 error "--rsync and --no-rsync accepted concurrently"
7213         echo "done."
7214
7215         # Clean up
7216         rm -f $file1
7217 }
7218 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7219
7220 test_56we() {
7221         local td=$DIR/$tdir
7222         local tf=$td/$tfile
7223
7224         test_mkdir $td || error "cannot create $td"
7225         touch $tf || error "cannot touch $tf"
7226
7227         echo -n "Make sure --non-direct|-D works..."
7228         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7229                 grep -q "lfs migrate --non-direct" ||
7230                 error "--non-direct option cannot work correctly"
7231         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7232                 grep -q "lfs migrate -D" ||
7233                 error "-D option cannot work correctly"
7234         echo "done."
7235 }
7236 run_test 56we "check lfs_migrate --non-direct|-D support"
7237
7238 test_56x() {
7239         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7240         check_swap_layouts_support
7241
7242         local dir=$DIR/$tdir
7243         local ref1=/etc/passwd
7244         local file1=$dir/file1
7245
7246         test_mkdir $dir || error "creating dir $dir"
7247         $LFS setstripe -c 2 $file1
7248         cp $ref1 $file1
7249         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7250         stripe=$($LFS getstripe -c $file1)
7251         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7252         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7253
7254         # clean up
7255         rm -f $file1
7256 }
7257 run_test 56x "lfs migration support"
7258
7259 test_56xa() {
7260         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7261         check_swap_layouts_support
7262
7263         local dir=$DIR/$tdir/$testnum
7264
7265         test_mkdir -p $dir
7266
7267         local ref1=/etc/passwd
7268         local file1=$dir/file1
7269
7270         $LFS setstripe -c 2 $file1
7271         cp $ref1 $file1
7272         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7273
7274         local stripe=$($LFS getstripe -c $file1)
7275
7276         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7277         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7278
7279         # clean up
7280         rm -f $file1
7281 }
7282 run_test 56xa "lfs migration --block support"
7283
7284 check_migrate_links() {
7285         local dir="$1"
7286         local file1="$dir/file1"
7287         local begin="$2"
7288         local count="$3"
7289         local runas="$4"
7290         local total_count=$(($begin + $count - 1))
7291         local symlink_count=10
7292         local uniq_count=10
7293
7294         if [ ! -f "$file1" ]; then
7295                 echo -n "creating initial file..."
7296                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7297                         error "cannot setstripe initial file"
7298                 echo "done"
7299
7300                 echo -n "creating symlinks..."
7301                 for s in $(seq 1 $symlink_count); do
7302                         ln -s "$file1" "$dir/slink$s" ||
7303                                 error "cannot create symlinks"
7304                 done
7305                 echo "done"
7306
7307                 echo -n "creating nonlinked files..."
7308                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7309                         error "cannot create nonlinked files"
7310                 echo "done"
7311         fi
7312
7313         # create hard links
7314         if [ ! -f "$dir/file$total_count" ]; then
7315                 echo -n "creating hard links $begin:$total_count..."
7316                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7317                         /dev/null || error "cannot create hard links"
7318                 echo "done"
7319         fi
7320
7321         echo -n "checking number of hard links listed in xattrs..."
7322         local fid=$($LFS getstripe -F "$file1")
7323         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7324
7325         echo "${#paths[*]}"
7326         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7327                         skip "hard link list has unexpected size, skipping test"
7328         fi
7329         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7330                         error "link names should exceed xattrs size"
7331         fi
7332
7333         echo -n "migrating files..."
7334         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7335         local rc=$?
7336         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7337         echo "done"
7338
7339         # make sure all links have been properly migrated
7340         echo -n "verifying files..."
7341         fid=$($LFS getstripe -F "$file1") ||
7342                 error "cannot get fid for file $file1"
7343         for i in $(seq 2 $total_count); do
7344                 local fid2=$($LFS getstripe -F $dir/file$i)
7345
7346                 [ "$fid2" == "$fid" ] ||
7347                         error "migrated hard link has mismatched FID"
7348         done
7349
7350         # make sure hard links were properly detected, and migration was
7351         # performed only once for the entire link set; nonlinked files should
7352         # also be migrated
7353         local actual=$(grep -c 'done' <<< "$migrate_out")
7354         local expected=$(($uniq_count + 1))
7355
7356         [ "$actual" -eq  "$expected" ] ||
7357                 error "hard links individually migrated ($actual != $expected)"
7358
7359         # make sure the correct number of hard links are present
7360         local hardlinks=$(stat -c '%h' "$file1")
7361
7362         [ $hardlinks -eq $total_count ] ||
7363                 error "num hard links $hardlinks != $total_count"
7364         echo "done"
7365
7366         return 0
7367 }
7368
7369 test_56xb() {
7370         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7371                 skip "Need MDS version at least 2.10.55"
7372
7373         local dir="$DIR/$tdir"
7374
7375         test_mkdir "$dir" || error "cannot create dir $dir"
7376
7377         echo "testing lfs migrate mode when all links fit within xattrs"
7378         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7379
7380         echo "testing rsync mode when all links fit within xattrs"
7381         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7382
7383         echo "testing lfs migrate mode when all links do not fit within xattrs"
7384         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7385
7386         echo "testing rsync mode when all links do not fit within xattrs"
7387         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7388
7389         chown -R $RUNAS_ID $dir
7390         echo "testing non-root lfs migrate mode when not all links are in xattr"
7391         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7392
7393         # clean up
7394         rm -rf $dir
7395 }
7396 run_test 56xb "lfs migration hard link support"
7397
7398 test_56xc() {
7399         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7400
7401         local dir="$DIR/$tdir"
7402
7403         test_mkdir "$dir" || error "cannot create dir $dir"
7404
7405         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7406         echo -n "Setting initial stripe for 20MB test file..."
7407         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7408                 error "cannot setstripe 20MB file"
7409         echo "done"
7410         echo -n "Sizing 20MB test file..."
7411         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7412         echo "done"
7413         echo -n "Verifying small file autostripe count is 1..."
7414         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7415                 error "cannot migrate 20MB file"
7416         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7417                 error "cannot get stripe for $dir/20mb"
7418         [ $stripe_count -eq 1 ] ||
7419                 error "unexpected stripe count $stripe_count for 20MB file"
7420         rm -f "$dir/20mb"
7421         echo "done"
7422
7423         # Test 2: File is small enough to fit within the available space on
7424         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7425         # have at least an additional 1KB for each desired stripe for test 3
7426         echo -n "Setting stripe for 1GB test file..."
7427         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7428         echo "done"
7429         echo -n "Sizing 1GB test file..."
7430         # File size is 1GB + 3KB
7431         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7432         echo "done"
7433
7434         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7435         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7436         if (( avail > 524288 * OSTCOUNT )); then
7437                 echo -n "Migrating 1GB file..."
7438                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7439                         error "cannot migrate 1GB file"
7440                 echo "done"
7441                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7442                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7443                         error "cannot getstripe for 1GB file"
7444                 [ $stripe_count -eq 2 ] ||
7445                         error "unexpected stripe count $stripe_count != 2"
7446                 echo "done"
7447         fi
7448
7449         # Test 3: File is too large to fit within the available space on
7450         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7451         if [ $OSTCOUNT -ge 3 ]; then
7452                 # The required available space is calculated as
7453                 # file size (1GB + 3KB) / OST count (3).
7454                 local kb_per_ost=349526
7455
7456                 echo -n "Migrating 1GB file with limit..."
7457                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7458                         error "cannot migrate 1GB file with limit"
7459                 echo "done"
7460
7461                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7462                 echo -n "Verifying 1GB autostripe count with limited space..."
7463                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7464                         error "unexpected stripe count $stripe_count (min 3)"
7465                 echo "done"
7466         fi
7467
7468         # clean up
7469         rm -rf $dir
7470 }
7471 run_test 56xc "lfs migration autostripe"
7472
7473 test_56xd() {
7474         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7475
7476         local dir=$DIR/$tdir
7477         local f_mgrt=$dir/$tfile.mgrt
7478         local f_yaml=$dir/$tfile.yaml
7479         local f_copy=$dir/$tfile.copy
7480         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7481         local layout_copy="-c 2 -S 2M -i 1"
7482         local yamlfile=$dir/yamlfile
7483         local layout_before;
7484         local layout_after;
7485
7486         test_mkdir "$dir" || error "cannot create dir $dir"
7487         $LFS setstripe $layout_yaml $f_yaml ||
7488                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7489         $LFS getstripe --yaml $f_yaml > $yamlfile
7490         $LFS setstripe $layout_copy $f_copy ||
7491                 error "cannot setstripe $f_copy with layout $layout_copy"
7492         touch $f_mgrt
7493         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7494
7495         # 1. test option --yaml
7496         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7497                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7498         layout_before=$(get_layout_param $f_yaml)
7499         layout_after=$(get_layout_param $f_mgrt)
7500         [ "$layout_after" == "$layout_before" ] ||
7501                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7502
7503         # 2. test option --copy
7504         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7505                 error "cannot migrate $f_mgrt with --copy $f_copy"
7506         layout_before=$(get_layout_param $f_copy)
7507         layout_after=$(get_layout_param $f_mgrt)
7508         [ "$layout_after" == "$layout_before" ] ||
7509                 error "lfs_migrate --copy: $layout_after != $layout_before"
7510 }
7511 run_test 56xd "check lfs_migrate --yaml and --copy support"
7512
7513 test_56xe() {
7514         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7515
7516         local dir=$DIR/$tdir
7517         local f_comp=$dir/$tfile
7518         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7519         local layout_before=""
7520         local layout_after=""
7521
7522         test_mkdir "$dir" || error "cannot create dir $dir"
7523         $LFS setstripe $layout $f_comp ||
7524                 error "cannot setstripe $f_comp with layout $layout"
7525         layout_before=$(get_layout_param $f_comp)
7526         dd if=/dev/zero of=$f_comp bs=1M count=4
7527
7528         # 1. migrate a comp layout file by lfs_migrate
7529         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7530         layout_after=$(get_layout_param $f_comp)
7531         [ "$layout_before" == "$layout_after" ] ||
7532                 error "lfs_migrate: $layout_before != $layout_after"
7533
7534         # 2. migrate a comp layout file by lfs migrate
7535         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7536         layout_after=$(get_layout_param $f_comp)
7537         [ "$layout_before" == "$layout_after" ] ||
7538                 error "lfs migrate: $layout_before != $layout_after"
7539 }
7540 run_test 56xe "migrate a composite layout file"
7541
7542 test_56xf() {
7543         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7544
7545         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7546                 skip "Need server version at least 2.13.53"
7547
7548         local dir=$DIR/$tdir
7549         local f_comp=$dir/$tfile
7550         local layout="-E 1M -c1 -E -1 -c2"
7551         local fid_before=""
7552         local fid_after=""
7553
7554         test_mkdir "$dir" || error "cannot create dir $dir"
7555         $LFS setstripe $layout $f_comp ||
7556                 error "cannot setstripe $f_comp with layout $layout"
7557         fid_before=$($LFS getstripe --fid $f_comp)
7558         dd if=/dev/zero of=$f_comp bs=1M count=4
7559
7560         # 1. migrate a comp layout file to a comp layout
7561         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7562         fid_after=$($LFS getstripe --fid $f_comp)
7563         [ "$fid_before" == "$fid_after" ] ||
7564                 error "comp-to-comp migrate: $fid_before != $fid_after"
7565
7566         # 2. migrate a comp layout file to a plain layout
7567         $LFS migrate -c2 $f_comp ||
7568                 error "cannot migrate $f_comp by lfs migrate"
7569         fid_after=$($LFS getstripe --fid $f_comp)
7570         [ "$fid_before" == "$fid_after" ] ||
7571                 error "comp-to-plain migrate: $fid_before != $fid_after"
7572
7573         # 3. migrate a plain layout file to a comp layout
7574         $LFS migrate $layout $f_comp ||
7575                 error "cannot migrate $f_comp by lfs migrate"
7576         fid_after=$($LFS getstripe --fid $f_comp)
7577         [ "$fid_before" == "$fid_after" ] ||
7578                 error "plain-to-comp migrate: $fid_before != $fid_after"
7579 }
7580 run_test 56xf "FID is not lost during migration of a composite layout file"
7581
7582 test_56y() {
7583         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7584                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7585
7586         local res=""
7587         local dir=$DIR/$tdir
7588         local f1=$dir/file1
7589         local f2=$dir/file2
7590
7591         test_mkdir -p $dir || error "creating dir $dir"
7592         touch $f1 || error "creating std file $f1"
7593         $MULTIOP $f2 H2c || error "creating released file $f2"
7594
7595         # a directory can be raid0, so ask only for files
7596         res=$($LFS find $dir -L raid0 -type f | wc -l)
7597         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7598
7599         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7600         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7601
7602         # only files can be released, so no need to force file search
7603         res=$($LFS find $dir -L released)
7604         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7605
7606         res=$($LFS find $dir -type f \! -L released)
7607         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7608 }
7609 run_test 56y "lfs find -L raid0|released"
7610
7611 test_56z() { # LU-4824
7612         # This checks to make sure 'lfs find' continues after errors
7613         # There are two classes of errors that should be caught:
7614         # - If multiple paths are provided, all should be searched even if one
7615         #   errors out
7616         # - If errors are encountered during the search, it should not terminate
7617         #   early
7618         local dir=$DIR/$tdir
7619         local i
7620
7621         test_mkdir $dir
7622         for i in d{0..9}; do
7623                 test_mkdir $dir/$i
7624                 touch $dir/$i/$tfile
7625         done
7626         $LFS find $DIR/non_existent_dir $dir &&
7627                 error "$LFS find did not return an error"
7628         # Make a directory unsearchable. This should NOT be the last entry in
7629         # directory order.  Arbitrarily pick the 6th entry
7630         chmod 700 $($LFS find $dir -type d | sed '6!d')
7631
7632         $RUNAS $LFS find $DIR/non_existent $dir
7633         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7634
7635         # The user should be able to see 10 directories and 9 files
7636         (( count == 19 )) ||
7637                 error "$LFS find found $count != 19 entries after error"
7638 }
7639 run_test 56z "lfs find should continue after an error"
7640
7641 test_56aa() { # LU-5937
7642         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7643
7644         local dir=$DIR/$tdir
7645
7646         mkdir $dir
7647         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7648
7649         createmany -o $dir/striped_dir/${tfile}- 1024
7650         local dirs=$($LFS find --size +8k $dir/)
7651
7652         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7653 }
7654 run_test 56aa "lfs find --size under striped dir"
7655
7656 test_56ab() { # LU-10705
7657         test_mkdir $DIR/$tdir
7658         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7659         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7660         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7661         # Flush writes to ensure valid blocks.  Need to be more thorough for
7662         # ZFS, since blocks are not allocated/returned to client immediately.
7663         sync_all_data
7664         wait_zfs_commit ost1 2
7665         cancel_lru_locks osc
7666         ls -ls $DIR/$tdir
7667
7668         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7669
7670         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7671
7672         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7673         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7674
7675         rm -f $DIR/$tdir/$tfile.[123]
7676 }
7677 run_test 56ab "lfs find --blocks"
7678
7679 # LU-11188
7680 test_56aca() {
7681         local dir="$DIR/$tdir"
7682         local perms=(001 002 003 004 005 006 007
7683                      010 020 030 040 050 060 070
7684                      100 200 300 400 500 600 700
7685                      111 222 333 444 555 666 777)
7686         local perm_minus=(8 8 4 8 4 4 2
7687                           8 8 4 8 4 4 2
7688                           8 8 4 8 4 4 2
7689                           4 4 2 4 2 2 1)
7690         local perm_slash=(8  8 12  8 12 12 14
7691                           8  8 12  8 12 12 14
7692                           8  8 12  8 12 12 14
7693                          16 16 24 16 24 24 28)
7694
7695         test_mkdir "$dir"
7696         for perm in ${perms[*]}; do
7697                 touch "$dir/$tfile.$perm"
7698                 chmod $perm "$dir/$tfile.$perm"
7699         done
7700
7701         for ((i = 0; i < ${#perms[*]}; i++)); do
7702                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7703                 (( $num == 1 )) ||
7704                         error "lfs find -perm ${perms[i]}:"\
7705                               "$num != 1"
7706
7707                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7708                 (( $num == ${perm_minus[i]} )) ||
7709                         error "lfs find -perm -${perms[i]}:"\
7710                               "$num != ${perm_minus[i]}"
7711
7712                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7713                 (( $num == ${perm_slash[i]} )) ||
7714                         error "lfs find -perm /${perms[i]}:"\
7715                               "$num != ${perm_slash[i]}"
7716         done
7717 }
7718 run_test 56aca "check lfs find -perm with octal representation"
7719
7720 test_56acb() {
7721         local dir=$DIR/$tdir
7722         # p is the permission of write and execute for user, group and other
7723         # without the umask. It is used to test +wx.
7724         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7725         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7726         local symbolic=(+t  a+t u+t g+t o+t
7727                         g+s u+s o+s +s o+sr
7728                         o=r,ug+o,u+w
7729                         u+ g+ o+ a+ ugo+
7730                         u- g- o- a- ugo-
7731                         u= g= o= a= ugo=
7732                         o=r,ug+o,u+w u=r,a+u,u+w
7733                         g=r,ugo=g,u+w u+x,+X +X
7734                         u+x,u+X u+X u+x,g+X o+r,+X
7735                         u+x,go+X +wx +rwx)
7736
7737         test_mkdir $dir
7738         for perm in ${perms[*]}; do
7739                 touch "$dir/$tfile.$perm"
7740                 chmod $perm "$dir/$tfile.$perm"
7741         done
7742
7743         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7744                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7745
7746                 (( $num == 1 )) ||
7747                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7748         done
7749 }
7750 run_test 56acb "check lfs find -perm with symbolic representation"
7751
7752 test_56acc() {
7753         local dir=$DIR/$tdir
7754         local tests="17777 787 789 abcd
7755                 ug=uu ug=a ug=gu uo=ou urw
7756                 u+xg+x a=r,u+x,"
7757
7758         test_mkdir $dir
7759         for err in $tests; do
7760                 if $LFS find $dir -perm $err 2>/dev/null; then
7761                         error "lfs find -perm $err: parsing should have failed"
7762                 fi
7763         done
7764 }
7765 run_test 56acc "check parsing error for lfs find -perm"
7766
7767 test_56ba() {
7768         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7769                 skip "Need MDS version at least 2.10.50"
7770
7771         # Create composite files with one component
7772         local dir=$DIR/$tdir
7773
7774         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7775         # Create composite files with three components
7776         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7777         # Create non-composite files
7778         createmany -o $dir/${tfile}- 10
7779
7780         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7781
7782         [[ $nfiles == 10 ]] ||
7783                 error "lfs find -E 1M found $nfiles != 10 files"
7784
7785         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7786         [[ $nfiles == 25 ]] ||
7787                 error "lfs find ! -E 1M found $nfiles != 25 files"
7788
7789         # All files have a component that starts at 0
7790         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7791         [[ $nfiles == 35 ]] ||
7792                 error "lfs find --component-start 0 - $nfiles != 35 files"
7793
7794         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7795         [[ $nfiles == 15 ]] ||
7796                 error "lfs find --component-start 2M - $nfiles != 15 files"
7797
7798         # All files created here have a componenet that does not starts at 2M
7799         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7800         [[ $nfiles == 35 ]] ||
7801                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7802
7803         # Find files with a specified number of components
7804         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7805         [[ $nfiles == 15 ]] ||
7806                 error "lfs find --component-count 3 - $nfiles != 15 files"
7807
7808         # Remember non-composite files have a component count of zero
7809         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7810         [[ $nfiles == 10 ]] ||
7811                 error "lfs find --component-count 0 - $nfiles != 10 files"
7812
7813         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7814         [[ $nfiles == 20 ]] ||
7815                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7816
7817         # All files have a flag called "init"
7818         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7819         [[ $nfiles == 35 ]] ||
7820                 error "lfs find --component-flags init - $nfiles != 35 files"
7821
7822         # Multi-component files will have a component not initialized
7823         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7824         [[ $nfiles == 15 ]] ||
7825                 error "lfs find !--component-flags init - $nfiles != 15 files"
7826
7827         rm -rf $dir
7828
7829 }
7830 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7831
7832 test_56ca() {
7833         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7834                 skip "Need MDS version at least 2.10.57"
7835
7836         local td=$DIR/$tdir
7837         local tf=$td/$tfile
7838         local dir
7839         local nfiles
7840         local cmd
7841         local i
7842         local j
7843
7844         # create mirrored directories and mirrored files
7845         mkdir $td || error "mkdir $td failed"
7846         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7847         createmany -o $tf- 10 || error "create $tf- failed"
7848
7849         for i in $(seq 2); do
7850                 dir=$td/dir$i
7851                 mkdir $dir || error "mkdir $dir failed"
7852                 $LFS mirror create -N$((3 + i)) $dir ||
7853                         error "create mirrored dir $dir failed"
7854                 createmany -o $dir/$tfile- 10 ||
7855                         error "create $dir/$tfile- failed"
7856         done
7857
7858         # change the states of some mirrored files
7859         echo foo > $tf-6
7860         for i in $(seq 2); do
7861                 dir=$td/dir$i
7862                 for j in $(seq 4 9); do
7863                         echo foo > $dir/$tfile-$j
7864                 done
7865         done
7866
7867         # find mirrored files with specific mirror count
7868         cmd="$LFS find --mirror-count 3 --type f $td"
7869         nfiles=$($cmd | wc -l)
7870         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7871
7872         cmd="$LFS find ! --mirror-count 3 --type f $td"
7873         nfiles=$($cmd | wc -l)
7874         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7875
7876         cmd="$LFS find --mirror-count +2 --type f $td"
7877         nfiles=$($cmd | wc -l)
7878         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7879
7880         cmd="$LFS find --mirror-count -6 --type f $td"
7881         nfiles=$($cmd | wc -l)
7882         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7883
7884         # find mirrored files with specific file state
7885         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7886         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7887
7888         cmd="$LFS find --mirror-state=ro --type f $td"
7889         nfiles=$($cmd | wc -l)
7890         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7891
7892         cmd="$LFS find ! --mirror-state=ro --type f $td"
7893         nfiles=$($cmd | wc -l)
7894         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7895
7896         cmd="$LFS find --mirror-state=wp --type f $td"
7897         nfiles=$($cmd | wc -l)
7898         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7899
7900         cmd="$LFS find ! --mirror-state=sp --type f $td"
7901         nfiles=$($cmd | wc -l)
7902         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7903 }
7904 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7905
7906 test_56da() { # LU-14179
7907         local path=$DIR/$tdir
7908
7909         test_mkdir $path
7910         cd $path
7911
7912         local longdir=$(str_repeat 'a' 255)
7913
7914         for i in {1..15}; do
7915                 path=$path/$longdir
7916                 test_mkdir $longdir
7917                 cd $longdir
7918         done
7919
7920         local len=${#path}
7921         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7922
7923         test_mkdir $lastdir
7924         cd $lastdir
7925         # PATH_MAX-1
7926         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7927
7928         # NAME_MAX
7929         touch $(str_repeat 'f' 255)
7930
7931         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7932                 error "lfs find reported an error"
7933
7934         rm -rf $DIR/$tdir
7935 }
7936 run_test 56da "test lfs find with long paths"
7937
7938 test_57a() {
7939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7940         # note test will not do anything if MDS is not local
7941         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7942                 skip_env "ldiskfs only test"
7943         fi
7944         remote_mds_nodsh && skip "remote MDS with nodsh"
7945
7946         local MNTDEV="osd*.*MDT*.mntdev"
7947         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7948         [ -z "$DEV" ] && error "can't access $MNTDEV"
7949         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7950                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7951                         error "can't access $DEV"
7952                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7953                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7954                 rm $TMP/t57a.dump
7955         done
7956 }
7957 run_test 57a "verify MDS filesystem created with large inodes =="
7958
7959 test_57b() {
7960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7961         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7962                 skip_env "ldiskfs only test"
7963         fi
7964         remote_mds_nodsh && skip "remote MDS with nodsh"
7965
7966         local dir=$DIR/$tdir
7967         local filecount=100
7968         local file1=$dir/f1
7969         local fileN=$dir/f$filecount
7970
7971         rm -rf $dir || error "removing $dir"
7972         test_mkdir -c1 $dir
7973         local mdtidx=$($LFS getstripe -m $dir)
7974         local mdtname=MDT$(printf %04x $mdtidx)
7975         local facet=mds$((mdtidx + 1))
7976
7977         echo "mcreating $filecount files"
7978         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7979
7980         # verify that files do not have EAs yet
7981         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7982                 error "$file1 has an EA"
7983         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7984                 error "$fileN has an EA"
7985
7986         sync
7987         sleep 1
7988         df $dir  #make sure we get new statfs data
7989         local mdsfree=$(do_facet $facet \
7990                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7991         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7992         local file
7993
7994         echo "opening files to create objects/EAs"
7995         for file in $(seq -f $dir/f%g 1 $filecount); do
7996                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7997                         error "opening $file"
7998         done
7999
8000         # verify that files have EAs now
8001         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8002         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8003
8004         sleep 1  #make sure we get new statfs data
8005         df $dir
8006         local mdsfree2=$(do_facet $facet \
8007                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8008         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8009
8010         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8011                 if [ "$mdsfree" != "$mdsfree2" ]; then
8012                         error "MDC before $mdcfree != after $mdcfree2"
8013                 else
8014                         echo "MDC before $mdcfree != after $mdcfree2"
8015                         echo "unable to confirm if MDS has large inodes"
8016                 fi
8017         fi
8018         rm -rf $dir
8019 }
8020 run_test 57b "default LOV EAs are stored inside large inodes ==="
8021
8022 test_58() {
8023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8024         [ -z "$(which wiretest 2>/dev/null)" ] &&
8025                         skip_env "could not find wiretest"
8026
8027         wiretest
8028 }
8029 run_test 58 "verify cross-platform wire constants =============="
8030
8031 test_59() {
8032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8033
8034         echo "touch 130 files"
8035         createmany -o $DIR/f59- 130
8036         echo "rm 130 files"
8037         unlinkmany $DIR/f59- 130
8038         sync
8039         # wait for commitment of removal
8040         wait_delete_completed
8041 }
8042 run_test 59 "verify cancellation of llog records async ========="
8043
8044 TEST60_HEAD="test_60 run $RANDOM"
8045 test_60a() {
8046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8047         remote_mgs_nodsh && skip "remote MGS with nodsh"
8048         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8049                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8050                         skip_env "missing subtest run-llog.sh"
8051
8052         log "$TEST60_HEAD - from kernel mode"
8053         do_facet mgs "$LCTL dk > /dev/null"
8054         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8055         do_facet mgs $LCTL dk > $TMP/$tfile
8056
8057         # LU-6388: test llog_reader
8058         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8059         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8060         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8061                         skip_env "missing llog_reader"
8062         local fstype=$(facet_fstype mgs)
8063         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8064                 skip_env "Only for ldiskfs or zfs type mgs"
8065
8066         local mntpt=$(facet_mntpt mgs)
8067         local mgsdev=$(mgsdevname 1)
8068         local fid_list
8069         local fid
8070         local rec_list
8071         local rec
8072         local rec_type
8073         local obj_file
8074         local path
8075         local seq
8076         local oid
8077         local pass=true
8078
8079         #get fid and record list
8080         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8081                 tail -n 4))
8082         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8083                 tail -n 4))
8084         #remount mgs as ldiskfs or zfs type
8085         stop mgs || error "stop mgs failed"
8086         mount_fstype mgs || error "remount mgs failed"
8087         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8088                 fid=${fid_list[i]}
8089                 rec=${rec_list[i]}
8090                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8091                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8092                 oid=$((16#$oid))
8093
8094                 case $fstype in
8095                         ldiskfs )
8096                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8097                         zfs )
8098                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8099                 esac
8100                 echo "obj_file is $obj_file"
8101                 do_facet mgs $llog_reader $obj_file
8102
8103                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8104                         awk '{ print $3 }' | sed -e "s/^type=//g")
8105                 if [ $rec_type != $rec ]; then
8106                         echo "FAILED test_60a wrong record type $rec_type," \
8107                               "should be $rec"
8108                         pass=false
8109                         break
8110                 fi
8111
8112                 #check obj path if record type is LLOG_LOGID_MAGIC
8113                 if [ "$rec" == "1064553b" ]; then
8114                         path=$(do_facet mgs $llog_reader $obj_file |
8115                                 grep "path=" | awk '{ print $NF }' |
8116                                 sed -e "s/^path=//g")
8117                         if [ $obj_file != $mntpt/$path ]; then
8118                                 echo "FAILED test_60a wrong obj path" \
8119                                       "$montpt/$path, should be $obj_file"
8120                                 pass=false
8121                                 break
8122                         fi
8123                 fi
8124         done
8125         rm -f $TMP/$tfile
8126         #restart mgs before "error", otherwise it will block the next test
8127         stop mgs || error "stop mgs failed"
8128         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8129         $pass || error "test failed, see FAILED test_60a messages for specifics"
8130 }
8131 run_test 60a "llog_test run from kernel module and test llog_reader"
8132
8133 test_60b() { # bug 6411
8134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8135
8136         dmesg > $DIR/$tfile
8137         LLOG_COUNT=$(do_facet mgs dmesg |
8138                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8139                           /llog_[a-z]*.c:[0-9]/ {
8140                                 if (marker)
8141                                         from_marker++
8142                                 from_begin++
8143                           }
8144                           END {
8145                                 if (marker)
8146                                         print from_marker
8147                                 else
8148                                         print from_begin
8149                           }")
8150
8151         [[ $LLOG_COUNT -gt 120 ]] &&
8152                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8153 }
8154 run_test 60b "limit repeated messages from CERROR/CWARN"
8155
8156 test_60c() {
8157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8158
8159         echo "create 5000 files"
8160         createmany -o $DIR/f60c- 5000
8161 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8162         lctl set_param fail_loc=0x80000137
8163         unlinkmany $DIR/f60c- 5000
8164         lctl set_param fail_loc=0
8165 }
8166 run_test 60c "unlink file when mds full"
8167
8168 test_60d() {
8169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8170
8171         SAVEPRINTK=$(lctl get_param -n printk)
8172         # verify "lctl mark" is even working"
8173         MESSAGE="test message ID $RANDOM $$"
8174         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8175         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8176
8177         lctl set_param printk=0 || error "set lnet.printk failed"
8178         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8179         MESSAGE="new test message ID $RANDOM $$"
8180         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8181         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8182         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8183
8184         lctl set_param -n printk="$SAVEPRINTK"
8185 }
8186 run_test 60d "test printk console message masking"
8187
8188 test_60e() {
8189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8190         remote_mds_nodsh && skip "remote MDS with nodsh"
8191
8192         touch $DIR/$tfile
8193 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8194         do_facet mds1 lctl set_param fail_loc=0x15b
8195         rm $DIR/$tfile
8196 }
8197 run_test 60e "no space while new llog is being created"
8198
8199 test_60f() {
8200         local old_path=$($LCTL get_param -n debug_path)
8201
8202         stack_trap "$LCTL set_param debug_path=$old_path"
8203         stack_trap "rm -f $TMP/$tfile*"
8204         rm -f $TMP/$tfile* 2> /dev/null
8205         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8206         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8207         test_mkdir $DIR/$tdir
8208         # retry in case the open is cached and not released
8209         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8210                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8211                 sleep 0.1
8212         done
8213         ls $TMP/$tfile*
8214         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8215 }
8216 run_test 60f "change debug_path works"
8217
8218 test_60g() {
8219         local pid
8220         local i
8221
8222         test_mkdir -c $MDSCOUNT $DIR/$tdir
8223
8224         (
8225                 local index=0
8226                 while true; do
8227                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8228                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8229                                 2>/dev/null
8230                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8231                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8232                         index=$((index + 1))
8233                 done
8234         ) &
8235
8236         pid=$!
8237
8238         for i in {0..100}; do
8239                 # define OBD_FAIL_OSD_TXN_START    0x19a
8240                 local index=$((i % MDSCOUNT + 1))
8241
8242                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8243                         > /dev/null
8244                 sleep 0.01
8245         done
8246
8247         kill -9 $pid
8248
8249         for i in $(seq $MDSCOUNT); do
8250                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8251         done
8252
8253         mkdir $DIR/$tdir/new || error "mkdir failed"
8254         rmdir $DIR/$tdir/new || error "rmdir failed"
8255
8256         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8257                 -t namespace
8258         for i in $(seq $MDSCOUNT); do
8259                 wait_update_facet mds$i "$LCTL get_param -n \
8260                         mdd.$(facet_svc mds$i).lfsck_namespace |
8261                         awk '/^status/ { print \\\$2 }'" "completed"
8262         done
8263
8264         ls -R $DIR/$tdir || error "ls failed"
8265         rm -rf $DIR/$tdir || error "rmdir failed"
8266 }
8267 run_test 60g "transaction abort won't cause MDT hung"
8268
8269 test_60h() {
8270         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8271                 skip "Need MDS version at least 2.12.52"
8272         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8273
8274         local f
8275
8276         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8277         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8278         for fail_loc in 0x80000188 0x80000189; do
8279                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8280                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8281                         error "mkdir $dir-$fail_loc failed"
8282                 for i in {0..10}; do
8283                         # create may fail on missing stripe
8284                         echo $i > $DIR/$tdir-$fail_loc/$i
8285                 done
8286                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8287                         error "getdirstripe $tdir-$fail_loc failed"
8288                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8289                         error "migrate $tdir-$fail_loc failed"
8290                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8291                         error "getdirstripe $tdir-$fail_loc failed"
8292                 pushd $DIR/$tdir-$fail_loc
8293                 for f in *; do
8294                         echo $f | cmp $f - || error "$f data mismatch"
8295                 done
8296                 popd
8297                 rm -rf $DIR/$tdir-$fail_loc
8298         done
8299 }
8300 run_test 60h "striped directory with missing stripes can be accessed"
8301
8302 function t60i_load() {
8303         mkdir $DIR/$tdir
8304         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8305         $LCTL set_param fail_loc=0x131c fail_val=1
8306         for ((i=0; i<5000; i++)); do
8307                 touch $DIR/$tdir/f$i
8308         done
8309 }
8310
8311 test_60i() {
8312         changelog_register || error "changelog_register failed"
8313         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8314         changelog_users $SINGLEMDS | grep -q $cl_user ||
8315                 error "User $cl_user not found in changelog_users"
8316         changelog_chmask "ALL"
8317         t60i_load &
8318         local PID=$!
8319         for((i=0; i<100; i++)); do
8320                 changelog_dump >/dev/null ||
8321                         error "can't read changelog"
8322         done
8323         kill $PID
8324         wait $PID
8325         changelog_deregister || error "changelog_deregister failed"
8326         $LCTL set_param fail_loc=0
8327 }
8328 run_test 60i "llog: new record vs reader race"
8329
8330 test_61a() {
8331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8332
8333         f="$DIR/f61"
8334         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8335         cancel_lru_locks osc
8336         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8337         sync
8338 }
8339 run_test 61a "mmap() writes don't make sync hang ================"
8340
8341 test_61b() {
8342         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8343 }
8344 run_test 61b "mmap() of unstriped file is successful"
8345
8346 # bug 2330 - insufficient obd_match error checking causes LBUG
8347 test_62() {
8348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8349
8350         f="$DIR/f62"
8351         echo foo > $f
8352         cancel_lru_locks osc
8353         lctl set_param fail_loc=0x405
8354         cat $f && error "cat succeeded, expect -EIO"
8355         lctl set_param fail_loc=0
8356 }
8357 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8358 # match every page all of the time.
8359 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8360
8361 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8362 # Though this test is irrelevant anymore, it helped to reveal some
8363 # other grant bugs (LU-4482), let's keep it.
8364 test_63a() {   # was test_63
8365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8366
8367         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8368
8369         for i in `seq 10` ; do
8370                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8371                 sleep 5
8372                 kill $!
8373                 sleep 1
8374         done
8375
8376         rm -f $DIR/f63 || true
8377 }
8378 run_test 63a "Verify oig_wait interruption does not crash ======="
8379
8380 # bug 2248 - async write errors didn't return to application on sync
8381 # bug 3677 - async write errors left page locked
8382 test_63b() {
8383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8384
8385         debugsave
8386         lctl set_param debug=-1
8387
8388         # ensure we have a grant to do async writes
8389         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8390         rm $DIR/$tfile
8391
8392         sync    # sync lest earlier test intercept the fail_loc
8393
8394         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8395         lctl set_param fail_loc=0x80000406
8396         $MULTIOP $DIR/$tfile Owy && \
8397                 error "sync didn't return ENOMEM"
8398         sync; sleep 2; sync     # do a real sync this time to flush page
8399         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8400                 error "locked page left in cache after async error" || true
8401         debugrestore
8402 }
8403 run_test 63b "async write errors should be returned to fsync ==="
8404
8405 test_64a () {
8406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8407
8408         lfs df $DIR
8409         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8410 }
8411 run_test 64a "verify filter grant calculations (in kernel) ====="
8412
8413 test_64b () {
8414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8415
8416         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8417 }
8418 run_test 64b "check out-of-space detection on client"
8419
8420 test_64c() {
8421         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8422 }
8423 run_test 64c "verify grant shrink"
8424
8425 import_param() {
8426         local tgt=$1
8427         local param=$2
8428
8429         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8430 }
8431
8432 # this does exactly what osc_request.c:osc_announce_cached() does in
8433 # order to calculate max amount of grants to ask from server
8434 want_grant() {
8435         local tgt=$1
8436
8437         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8438         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8439
8440         ((rpc_in_flight++));
8441         nrpages=$((nrpages * rpc_in_flight))
8442
8443         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8444
8445         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8446
8447         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8448         local undirty=$((nrpages * PAGE_SIZE))
8449
8450         local max_extent_pages
8451         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8452         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8453         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8454         local grant_extent_tax
8455         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8456
8457         undirty=$((undirty + nrextents * grant_extent_tax))
8458
8459         echo $undirty
8460 }
8461
8462 # this is size of unit for grant allocation. It should be equal to
8463 # what tgt_grant.c:tgt_grant_chunk() calculates
8464 grant_chunk() {
8465         local tgt=$1
8466         local max_brw_size
8467         local grant_extent_tax
8468
8469         max_brw_size=$(import_param $tgt max_brw_size)
8470
8471         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8472
8473         echo $(((max_brw_size + grant_extent_tax) * 2))
8474 }
8475
8476 test_64d() {
8477         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8478                 skip "OST < 2.10.55 doesn't limit grants enough"
8479
8480         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8481
8482         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8483                 skip "no grant_param connect flag"
8484
8485         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8486
8487         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8488         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8489
8490
8491         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8492         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8493
8494         $LFS setstripe $DIR/$tfile -i 0 -c 1
8495         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8496         ddpid=$!
8497
8498         while kill -0 $ddpid; do
8499                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8500
8501                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8502                         kill $ddpid
8503                         error "cur_grant $cur_grant > $max_cur_granted"
8504                 fi
8505
8506                 sleep 1
8507         done
8508 }
8509 run_test 64d "check grant limit exceed"
8510
8511 check_grants() {
8512         local tgt=$1
8513         local expected=$2
8514         local msg=$3
8515         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8516
8517         ((cur_grants == expected)) ||
8518                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8519 }
8520
8521 round_up_p2() {
8522         echo $((($1 + $2 - 1) & ~($2 - 1)))
8523 }
8524
8525 test_64e() {
8526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8527         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8528                 skip "Need OSS version at least 2.11.56"
8529
8530         # Remount client to reset grant
8531         remount_client $MOUNT || error "failed to remount client"
8532         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8533
8534         local init_grants=$(import_param $osc_tgt initial_grant)
8535
8536         check_grants $osc_tgt $init_grants "init grants"
8537
8538         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8539         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8540         local gbs=$(import_param $osc_tgt grant_block_size)
8541
8542         # write random number of bytes from max_brw_size / 4 to max_brw_size
8543         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8544         # align for direct io
8545         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8546         # round to grant consumption unit
8547         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8548
8549         local grants=$((wb_round_up + extent_tax))
8550
8551         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8552
8553         # define OBD_FAIL_TGT_NO_GRANT 0x725
8554         # make the server not grant more back
8555         do_facet ost1 $LCTL set_param fail_loc=0x725
8556         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8557
8558         do_facet ost1 $LCTL set_param fail_loc=0
8559
8560         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8561
8562         rm -f $DIR/$tfile || error "rm failed"
8563
8564         # Remount client to reset grant
8565         remount_client $MOUNT || error "failed to remount client"
8566         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8567
8568         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8569
8570         # define OBD_FAIL_TGT_NO_GRANT 0x725
8571         # make the server not grant more back
8572         do_facet ost1 $LCTL set_param fail_loc=0x725
8573         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8574         do_facet ost1 $LCTL set_param fail_loc=0
8575
8576         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8577 }
8578 run_test 64e "check grant consumption (no grant allocation)"
8579
8580 test_64f() {
8581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8582
8583         # Remount client to reset grant
8584         remount_client $MOUNT || error "failed to remount client"
8585         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8586
8587         local init_grants=$(import_param $osc_tgt initial_grant)
8588         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8589         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8590         local gbs=$(import_param $osc_tgt grant_block_size)
8591         local chunk=$(grant_chunk $osc_tgt)
8592
8593         # write random number of bytes from max_brw_size / 4 to max_brw_size
8594         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8595         # align for direct io
8596         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8597         # round to grant consumption unit
8598         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8599
8600         local grants=$((wb_round_up + extent_tax))
8601
8602         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8603         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8604                 error "error writing to $DIR/$tfile"
8605
8606         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8607                 "direct io with grant allocation"
8608
8609         rm -f $DIR/$tfile || error "rm failed"
8610
8611         # Remount client to reset grant
8612         remount_client $MOUNT || error "failed to remount client"
8613         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8614
8615         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8616
8617         local cmd="oO_WRONLY:w${write_bytes}_yc"
8618
8619         $MULTIOP $DIR/$tfile $cmd &
8620         MULTIPID=$!
8621         sleep 1
8622
8623         check_grants $osc_tgt $((init_grants - grants)) \
8624                 "buffered io, not write rpc"
8625
8626         kill -USR1 $MULTIPID
8627         wait
8628
8629         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8630                 "buffered io, one RPC"
8631 }
8632 run_test 64f "check grant consumption (with grant allocation)"
8633
8634 # bug 1414 - set/get directories' stripe info
8635 test_65a() {
8636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8637
8638         test_mkdir $DIR/$tdir
8639         touch $DIR/$tdir/f1
8640         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8641 }
8642 run_test 65a "directory with no stripe info"
8643
8644 test_65b() {
8645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8646
8647         test_mkdir $DIR/$tdir
8648         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8649
8650         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8651                                                 error "setstripe"
8652         touch $DIR/$tdir/f2
8653         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8654 }
8655 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8656
8657 test_65c() {
8658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8659         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8660
8661         test_mkdir $DIR/$tdir
8662         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8663
8664         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8665                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8666         touch $DIR/$tdir/f3
8667         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8668 }
8669 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8670
8671 test_65d() {
8672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8673
8674         test_mkdir $DIR/$tdir
8675         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8676         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8677
8678         if [[ $STRIPECOUNT -le 0 ]]; then
8679                 sc=1
8680         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8681                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8682                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8683         else
8684                 sc=$(($STRIPECOUNT - 1))
8685         fi
8686         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8687         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8688         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8689                 error "lverify failed"
8690 }
8691 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8692
8693 test_65e() {
8694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8695
8696         test_mkdir $DIR/$tdir
8697
8698         $LFS setstripe $DIR/$tdir || error "setstripe"
8699         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8700                                         error "no stripe info failed"
8701         touch $DIR/$tdir/f6
8702         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8703 }
8704 run_test 65e "directory setstripe defaults"
8705
8706 test_65f() {
8707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8708
8709         test_mkdir $DIR/${tdir}f
8710         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8711                 error "setstripe succeeded" || true
8712 }
8713 run_test 65f "dir setstripe permission (should return error) ==="
8714
8715 test_65g() {
8716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8717
8718         test_mkdir $DIR/$tdir
8719         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8720
8721         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8722                 error "setstripe -S failed"
8723         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8724         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8725                 error "delete default stripe failed"
8726 }
8727 run_test 65g "directory setstripe -d"
8728
8729 test_65h() {
8730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8731
8732         test_mkdir $DIR/$tdir
8733         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8734
8735         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8736                 error "setstripe -S failed"
8737         test_mkdir $DIR/$tdir/dd1
8738         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8739                 error "stripe info inherit failed"
8740 }
8741 run_test 65h "directory stripe info inherit ===================="
8742
8743 test_65i() {
8744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8745
8746         save_layout_restore_at_exit $MOUNT
8747
8748         # bug6367: set non-default striping on root directory
8749         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8750
8751         # bug12836: getstripe on -1 default directory striping
8752         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8753
8754         # bug12836: getstripe -v on -1 default directory striping
8755         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8756
8757         # bug12836: new find on -1 default directory striping
8758         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8759 }
8760 run_test 65i "various tests to set root directory striping"
8761
8762 test_65j() { # bug6367
8763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8764
8765         sync; sleep 1
8766
8767         # if we aren't already remounting for each test, do so for this test
8768         if [ "$I_MOUNTED" = "yes" ]; then
8769                 cleanup || error "failed to unmount"
8770                 setup
8771         fi
8772
8773         save_layout_restore_at_exit $MOUNT
8774
8775         $LFS setstripe -d $MOUNT || error "setstripe failed"
8776 }
8777 run_test 65j "set default striping on root directory (bug 6367)="
8778
8779 cleanup_65k() {
8780         rm -rf $DIR/$tdir
8781         wait_delete_completed
8782         do_facet $SINGLEMDS "lctl set_param -n \
8783                 osp.$ost*MDT0000.max_create_count=$max_count"
8784         do_facet $SINGLEMDS "lctl set_param -n \
8785                 osp.$ost*MDT0000.create_count=$count"
8786         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8787         echo $INACTIVE_OSC "is Activate"
8788
8789         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8790 }
8791
8792 test_65k() { # bug11679
8793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8794         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8795         remote_mds_nodsh && skip "remote MDS with nodsh"
8796
8797         local disable_precreate=true
8798         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8799                 disable_precreate=false
8800
8801         echo "Check OST status: "
8802         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8803                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8804
8805         for OSC in $MDS_OSCS; do
8806                 echo $OSC "is active"
8807                 do_facet $SINGLEMDS lctl --device %$OSC activate
8808         done
8809
8810         for INACTIVE_OSC in $MDS_OSCS; do
8811                 local ost=$(osc_to_ost $INACTIVE_OSC)
8812                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8813                                lov.*md*.target_obd |
8814                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8815
8816                 mkdir -p $DIR/$tdir
8817                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8818                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8819
8820                 echo "Deactivate: " $INACTIVE_OSC
8821                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8822
8823                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8824                               osp.$ost*MDT0000.create_count")
8825                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8826                                   osp.$ost*MDT0000.max_create_count")
8827                 $disable_precreate &&
8828                         do_facet $SINGLEMDS "lctl set_param -n \
8829                                 osp.$ost*MDT0000.max_create_count=0"
8830
8831                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8832                         [ -f $DIR/$tdir/$idx ] && continue
8833                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8834                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8835                                 { cleanup_65k;
8836                                   error "setstripe $idx should succeed"; }
8837                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8838                 done
8839                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8840                 rmdir $DIR/$tdir
8841
8842                 do_facet $SINGLEMDS "lctl set_param -n \
8843                         osp.$ost*MDT0000.max_create_count=$max_count"
8844                 do_facet $SINGLEMDS "lctl set_param -n \
8845                         osp.$ost*MDT0000.create_count=$count"
8846                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8847                 echo $INACTIVE_OSC "is Activate"
8848
8849                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8850         done
8851 }
8852 run_test 65k "validate manual striping works properly with deactivated OSCs"
8853
8854 test_65l() { # bug 12836
8855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8856
8857         test_mkdir -p $DIR/$tdir/test_dir
8858         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8859         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8860 }
8861 run_test 65l "lfs find on -1 stripe dir ========================"
8862
8863 test_65m() {
8864         local layout=$(save_layout $MOUNT)
8865         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8866                 restore_layout $MOUNT $layout
8867                 error "setstripe should fail by non-root users"
8868         }
8869         true
8870 }
8871 run_test 65m "normal user can't set filesystem default stripe"
8872
8873 test_65n() {
8874         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8875         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8876                 skip "Need MDS version at least 2.12.50"
8877         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8878
8879         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8880         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8881         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8882
8883         save_layout_restore_at_exit $MOUNT
8884
8885         # new subdirectory under root directory should not inherit
8886         # the default layout from root
8887         local dir1=$MOUNT/$tdir-1
8888         mkdir $dir1 || error "mkdir $dir1 failed"
8889         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8890                 error "$dir1 shouldn't have LOV EA"
8891
8892         # delete the default layout on root directory
8893         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8894
8895         local dir2=$MOUNT/$tdir-2
8896         mkdir $dir2 || error "mkdir $dir2 failed"
8897         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8898                 error "$dir2 shouldn't have LOV EA"
8899
8900         # set a new striping pattern on root directory
8901         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8902         local new_def_stripe_size=$((def_stripe_size * 2))
8903         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8904                 error "set stripe size on $MOUNT failed"
8905
8906         # new file created in $dir2 should inherit the new stripe size from
8907         # the filesystem default
8908         local file2=$dir2/$tfile-2
8909         touch $file2 || error "touch $file2 failed"
8910
8911         local file2_stripe_size=$($LFS getstripe -S $file2)
8912         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8913         {
8914                 echo "file2_stripe_size: '$file2_stripe_size'"
8915                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8916                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8917         }
8918
8919         local dir3=$MOUNT/$tdir-3
8920         mkdir $dir3 || error "mkdir $dir3 failed"
8921         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8922         # the root layout, which is the actual default layout that will be used
8923         # when new files are created in $dir3.
8924         local dir3_layout=$(get_layout_param $dir3)
8925         local root_dir_layout=$(get_layout_param $MOUNT)
8926         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8927         {
8928                 echo "dir3_layout: '$dir3_layout'"
8929                 echo "root_dir_layout: '$root_dir_layout'"
8930                 error "$dir3 should show the default layout from $MOUNT"
8931         }
8932
8933         # set OST pool on root directory
8934         local pool=$TESTNAME
8935         pool_add $pool || error "add $pool failed"
8936         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8937                 error "add targets to $pool failed"
8938
8939         $LFS setstripe -p $pool $MOUNT ||
8940                 error "set OST pool on $MOUNT failed"
8941
8942         # new file created in $dir3 should inherit the pool from
8943         # the filesystem default
8944         local file3=$dir3/$tfile-3
8945         touch $file3 || error "touch $file3 failed"
8946
8947         local file3_pool=$($LFS getstripe -p $file3)
8948         [[ "$file3_pool" = "$pool" ]] ||
8949                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8950
8951         local dir4=$MOUNT/$tdir-4
8952         mkdir $dir4 || error "mkdir $dir4 failed"
8953         local dir4_layout=$(get_layout_param $dir4)
8954         root_dir_layout=$(get_layout_param $MOUNT)
8955         echo "$LFS getstripe -d $dir4"
8956         $LFS getstripe -d $dir4
8957         echo "$LFS getstripe -d $MOUNT"
8958         $LFS getstripe -d $MOUNT
8959         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8960         {
8961                 echo "dir4_layout: '$dir4_layout'"
8962                 echo "root_dir_layout: '$root_dir_layout'"
8963                 error "$dir4 should show the default layout from $MOUNT"
8964         }
8965
8966         # new file created in $dir4 should inherit the pool from
8967         # the filesystem default
8968         local file4=$dir4/$tfile-4
8969         touch $file4 || error "touch $file4 failed"
8970
8971         local file4_pool=$($LFS getstripe -p $file4)
8972         [[ "$file4_pool" = "$pool" ]] ||
8973                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8974
8975         # new subdirectory under non-root directory should inherit
8976         # the default layout from its parent directory
8977         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8978                 error "set directory layout on $dir4 failed"
8979
8980         local dir5=$dir4/$tdir-5
8981         mkdir $dir5 || error "mkdir $dir5 failed"
8982
8983         dir4_layout=$(get_layout_param $dir4)
8984         local dir5_layout=$(get_layout_param $dir5)
8985         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8986         {
8987                 echo "dir4_layout: '$dir4_layout'"
8988                 echo "dir5_layout: '$dir5_layout'"
8989                 error "$dir5 should inherit the default layout from $dir4"
8990         }
8991
8992         # though subdir under ROOT doesn't inherit default layout, but
8993         # its sub dir/file should be created with default layout.
8994         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8995         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8996                 skip "Need MDS version at least 2.12.59"
8997
8998         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8999         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9000         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9001
9002         if [ $default_lmv_hash == "none" ]; then
9003                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9004         else
9005                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9006                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9007         fi
9008
9009         $LFS setdirstripe -D -c 2 $MOUNT ||
9010                 error "setdirstripe -D -c 2 failed"
9011         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9012         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9013         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9014 }
9015 run_test 65n "don't inherit default layout from root for new subdirectories"
9016
9017 # bug 2543 - update blocks count on client
9018 test_66() {
9019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9020
9021         COUNT=${COUNT:-8}
9022         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9023         sync; sync_all_data; sync; sync_all_data
9024         cancel_lru_locks osc
9025         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9026         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9027 }
9028 run_test 66 "update inode blocks count on client ==============="
9029
9030 meminfo() {
9031         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9032 }
9033
9034 swap_used() {
9035         swapon -s | awk '($1 == "'$1'") { print $4 }'
9036 }
9037
9038 # bug5265, obdfilter oa2dentry return -ENOENT
9039 # #define OBD_FAIL_SRV_ENOENT 0x217
9040 test_69() {
9041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9042         remote_ost_nodsh && skip "remote OST with nodsh"
9043
9044         f="$DIR/$tfile"
9045         $LFS setstripe -c 1 -i 0 $f
9046
9047         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9048
9049         do_facet ost1 lctl set_param fail_loc=0x217
9050         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9051         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9052
9053         do_facet ost1 lctl set_param fail_loc=0
9054         $DIRECTIO write $f 0 2 || error "write error"
9055
9056         cancel_lru_locks osc
9057         $DIRECTIO read $f 0 1 || error "read error"
9058
9059         do_facet ost1 lctl set_param fail_loc=0x217
9060         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9061
9062         do_facet ost1 lctl set_param fail_loc=0
9063         rm -f $f
9064 }
9065 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9066
9067 test_71() {
9068         test_mkdir $DIR/$tdir
9069         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9070         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9071 }
9072 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9073
9074 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9076         [ "$RUNAS_ID" = "$UID" ] &&
9077                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9078         # Check that testing environment is properly set up. Skip if not
9079         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9080                 skip_env "User $RUNAS_ID does not exist - skipping"
9081
9082         touch $DIR/$tfile
9083         chmod 777 $DIR/$tfile
9084         chmod ug+s $DIR/$tfile
9085         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9086                 error "$RUNAS dd $DIR/$tfile failed"
9087         # See if we are still setuid/sgid
9088         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9089                 error "S/gid is not dropped on write"
9090         # Now test that MDS is updated too
9091         cancel_lru_locks mdc
9092         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9093                 error "S/gid is not dropped on MDS"
9094         rm -f $DIR/$tfile
9095 }
9096 run_test 72a "Test that remove suid works properly (bug5695) ===="
9097
9098 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9099         local perm
9100
9101         [ "$RUNAS_ID" = "$UID" ] &&
9102                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9103         [ "$RUNAS_ID" -eq 0 ] &&
9104                 skip_env "RUNAS_ID = 0 -- skipping"
9105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9106         # Check that testing environment is properly set up. Skip if not
9107         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9108                 skip_env "User $RUNAS_ID does not exist - skipping"
9109
9110         touch $DIR/${tfile}-f{g,u}
9111         test_mkdir $DIR/${tfile}-dg
9112         test_mkdir $DIR/${tfile}-du
9113         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9114         chmod g+s $DIR/${tfile}-{f,d}g
9115         chmod u+s $DIR/${tfile}-{f,d}u
9116         for perm in 777 2777 4777; do
9117                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9118                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9119                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9120                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9121         done
9122         true
9123 }
9124 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9125
9126 # bug 3462 - multiple simultaneous MDC requests
9127 test_73() {
9128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9129
9130         test_mkdir $DIR/d73-1
9131         test_mkdir $DIR/d73-2
9132         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9133         pid1=$!
9134
9135         lctl set_param fail_loc=0x80000129
9136         $MULTIOP $DIR/d73-1/f73-2 Oc &
9137         sleep 1
9138         lctl set_param fail_loc=0
9139
9140         $MULTIOP $DIR/d73-2/f73-3 Oc &
9141         pid3=$!
9142
9143         kill -USR1 $pid1
9144         wait $pid1 || return 1
9145
9146         sleep 25
9147
9148         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9149         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9150         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9151
9152         rm -rf $DIR/d73-*
9153 }
9154 run_test 73 "multiple MDC requests (should not deadlock)"
9155
9156 test_74a() { # bug 6149, 6184
9157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9158
9159         touch $DIR/f74a
9160         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9161         #
9162         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9163         # will spin in a tight reconnection loop
9164         $LCTL set_param fail_loc=0x8000030e
9165         # get any lock that won't be difficult - lookup works.
9166         ls $DIR/f74a
9167         $LCTL set_param fail_loc=0
9168         rm -f $DIR/f74a
9169         true
9170 }
9171 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9172
9173 test_74b() { # bug 13310
9174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9175
9176         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9177         #
9178         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9179         # will spin in a tight reconnection loop
9180         $LCTL set_param fail_loc=0x8000030e
9181         # get a "difficult" lock
9182         touch $DIR/f74b
9183         $LCTL set_param fail_loc=0
9184         rm -f $DIR/f74b
9185         true
9186 }
9187 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9188
9189 test_74c() {
9190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9191
9192         #define OBD_FAIL_LDLM_NEW_LOCK
9193         $LCTL set_param fail_loc=0x319
9194         touch $DIR/$tfile && error "touch successful"
9195         $LCTL set_param fail_loc=0
9196         true
9197 }
9198 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9199
9200 slab_lic=/sys/kernel/slab/lustre_inode_cache
9201 num_objects() {
9202         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9203         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9204                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9205 }
9206
9207 test_76a() { # Now for b=20433, added originally in b=1443
9208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9209
9210         cancel_lru_locks osc
9211         # there may be some slab objects cached per core
9212         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9213         local before=$(num_objects)
9214         local count=$((512 * cpus))
9215         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9216         local margin=$((count / 10))
9217         if [[ -f $slab_lic/aliases ]]; then
9218                 local aliases=$(cat $slab_lic/aliases)
9219                 (( aliases > 0 )) && margin=$((margin * aliases))
9220         fi
9221
9222         echo "before slab objects: $before"
9223         for i in $(seq $count); do
9224                 touch $DIR/$tfile
9225                 rm -f $DIR/$tfile
9226         done
9227         cancel_lru_locks osc
9228         local after=$(num_objects)
9229         echo "created: $count, after slab objects: $after"
9230         # shared slab counts are not very accurate, allow significant margin
9231         # the main goal is that the cache growth is not permanently > $count
9232         while (( after > before + margin )); do
9233                 sleep 1
9234                 after=$(num_objects)
9235                 wait=$((wait + 1))
9236                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9237                 if (( wait > 60 )); then
9238                         error "inode slab grew from $before+$margin to $after"
9239                 fi
9240         done
9241 }
9242 run_test 76a "confirm clients recycle inodes properly ===="
9243
9244 test_76b() {
9245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9246         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9247
9248         local count=512
9249         local before=$(num_objects)
9250
9251         for i in $(seq $count); do
9252                 mkdir $DIR/$tdir
9253                 rmdir $DIR/$tdir
9254         done
9255
9256         local after=$(num_objects)
9257         local wait=0
9258
9259         while (( after > before )); do
9260                 sleep 1
9261                 after=$(num_objects)
9262                 wait=$((wait + 1))
9263                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9264                 if (( wait > 60 )); then
9265                         error "inode slab grew from $before to $after"
9266                 fi
9267         done
9268
9269         echo "slab objects before: $before, after: $after"
9270 }
9271 run_test 76b "confirm clients recycle directory inodes properly ===="
9272
9273 export ORIG_CSUM=""
9274 set_checksums()
9275 {
9276         # Note: in sptlrpc modes which enable its own bulk checksum, the
9277         # original crc32_le bulk checksum will be automatically disabled,
9278         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9279         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9280         # In this case set_checksums() will not be no-op, because sptlrpc
9281         # bulk checksum will be enabled all through the test.
9282
9283         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9284         lctl set_param -n osc.*.checksums $1
9285         return 0
9286 }
9287
9288 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9289                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9290 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9291                              tr -d [] | head -n1)}
9292 set_checksum_type()
9293 {
9294         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9295         rc=$?
9296         log "set checksum type to $1, rc = $rc"
9297         return $rc
9298 }
9299
9300 get_osc_checksum_type()
9301 {
9302         # arugment 1: OST name, like OST0000
9303         ost=$1
9304         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9305                         sed 's/.*\[\(.*\)\].*/\1/g')
9306         rc=$?
9307         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9308         echo $checksum_type
9309 }
9310
9311 F77_TMP=$TMP/f77-temp
9312 F77SZ=8
9313 setup_f77() {
9314         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9315                 error "error writing to $F77_TMP"
9316 }
9317
9318 test_77a() { # bug 10889
9319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9320         $GSS && skip_env "could not run with gss"
9321
9322         [ ! -f $F77_TMP ] && setup_f77
9323         set_checksums 1
9324         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9325         set_checksums 0
9326         rm -f $DIR/$tfile
9327 }
9328 run_test 77a "normal checksum read/write operation"
9329
9330 test_77b() { # bug 10889
9331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9332         $GSS && skip_env "could not run with gss"
9333
9334         [ ! -f $F77_TMP ] && setup_f77
9335         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9336         $LCTL set_param fail_loc=0x80000409
9337         set_checksums 1
9338
9339         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9340                 error "dd error: $?"
9341         $LCTL set_param fail_loc=0
9342
9343         for algo in $CKSUM_TYPES; do
9344                 cancel_lru_locks osc
9345                 set_checksum_type $algo
9346                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9347                 $LCTL set_param fail_loc=0x80000408
9348                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9349                 $LCTL set_param fail_loc=0
9350         done
9351         set_checksums 0
9352         set_checksum_type $ORIG_CSUM_TYPE
9353         rm -f $DIR/$tfile
9354 }
9355 run_test 77b "checksum error on client write, read"
9356
9357 cleanup_77c() {
9358         trap 0
9359         set_checksums 0
9360         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9361         $check_ost &&
9362                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9363         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9364         $check_ost && [ -n "$ost_file_prefix" ] &&
9365                 do_facet ost1 rm -f ${ost_file_prefix}\*
9366 }
9367
9368 test_77c() {
9369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9370         $GSS && skip_env "could not run with gss"
9371         remote_ost_nodsh && skip "remote OST with nodsh"
9372
9373         local bad1
9374         local osc_file_prefix
9375         local osc_file
9376         local check_ost=false
9377         local ost_file_prefix
9378         local ost_file
9379         local orig_cksum
9380         local dump_cksum
9381         local fid
9382
9383         # ensure corruption will occur on first OSS/OST
9384         $LFS setstripe -i 0 $DIR/$tfile
9385
9386         [ ! -f $F77_TMP ] && setup_f77
9387         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9388                 error "dd write error: $?"
9389         fid=$($LFS path2fid $DIR/$tfile)
9390
9391         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9392         then
9393                 check_ost=true
9394                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9395                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9396         else
9397                 echo "OSS do not support bulk pages dump upon error"
9398         fi
9399
9400         osc_file_prefix=$($LCTL get_param -n debug_path)
9401         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9402
9403         trap cleanup_77c EXIT
9404
9405         set_checksums 1
9406         # enable bulk pages dump upon error on Client
9407         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9408         # enable bulk pages dump upon error on OSS
9409         $check_ost &&
9410                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9411
9412         # flush Client cache to allow next read to reach OSS
9413         cancel_lru_locks osc
9414
9415         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9416         $LCTL set_param fail_loc=0x80000408
9417         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9418         $LCTL set_param fail_loc=0
9419
9420         rm -f $DIR/$tfile
9421
9422         # check cksum dump on Client
9423         osc_file=$(ls ${osc_file_prefix}*)
9424         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9425         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9426         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9427         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9428         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9429                      cksum)
9430         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9431         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9432                 error "dump content does not match on Client"
9433
9434         $check_ost || skip "No need to check cksum dump on OSS"
9435
9436         # check cksum dump on OSS
9437         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9438         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9439         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9440         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9441         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9442                 error "dump content does not match on OSS"
9443
9444         cleanup_77c
9445 }
9446 run_test 77c "checksum error on client read with debug"
9447
9448 test_77d() { # bug 10889
9449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9450         $GSS && skip_env "could not run with gss"
9451
9452         stack_trap "rm -f $DIR/$tfile"
9453         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9454         $LCTL set_param fail_loc=0x80000409
9455         set_checksums 1
9456         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9457                 error "direct write: rc=$?"
9458         $LCTL set_param fail_loc=0
9459         set_checksums 0
9460
9461         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9462         $LCTL set_param fail_loc=0x80000408
9463         set_checksums 1
9464         cancel_lru_locks osc
9465         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9466                 error "direct read: rc=$?"
9467         $LCTL set_param fail_loc=0
9468         set_checksums 0
9469 }
9470 run_test 77d "checksum error on OST direct write, read"
9471
9472 test_77f() { # bug 10889
9473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9474         $GSS && skip_env "could not run with gss"
9475
9476         set_checksums 1
9477         stack_trap "rm -f $DIR/$tfile"
9478         for algo in $CKSUM_TYPES; do
9479                 cancel_lru_locks osc
9480                 set_checksum_type $algo
9481                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9482                 $LCTL set_param fail_loc=0x409
9483                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9484                         error "direct write succeeded"
9485                 $LCTL set_param fail_loc=0
9486         done
9487         set_checksum_type $ORIG_CSUM_TYPE
9488         set_checksums 0
9489 }
9490 run_test 77f "repeat checksum error on write (expect error)"
9491
9492 test_77g() { # bug 10889
9493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9494         $GSS && skip_env "could not run with gss"
9495         remote_ost_nodsh && skip "remote OST with nodsh"
9496
9497         [ ! -f $F77_TMP ] && setup_f77
9498
9499         local file=$DIR/$tfile
9500         stack_trap "rm -f $file" EXIT
9501
9502         $LFS setstripe -c 1 -i 0 $file
9503         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9504         do_facet ost1 lctl set_param fail_loc=0x8000021a
9505         set_checksums 1
9506         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9507                 error "write error: rc=$?"
9508         do_facet ost1 lctl set_param fail_loc=0
9509         set_checksums 0
9510
9511         cancel_lru_locks osc
9512         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9513         do_facet ost1 lctl set_param fail_loc=0x8000021b
9514         set_checksums 1
9515         cmp $F77_TMP $file || error "file compare failed"
9516         do_facet ost1 lctl set_param fail_loc=0
9517         set_checksums 0
9518 }
9519 run_test 77g "checksum error on OST write, read"
9520
9521 test_77k() { # LU-10906
9522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9523         $GSS && skip_env "could not run with gss"
9524
9525         local cksum_param="osc.$FSNAME*.checksums"
9526         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9527         local checksum
9528         local i
9529
9530         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9531         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9532         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9533
9534         for i in 0 1; do
9535                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9536                         error "failed to set checksum=$i on MGS"
9537                 wait_update $HOSTNAME "$get_checksum" $i
9538                 #remount
9539                 echo "remount client, checksum should be $i"
9540                 remount_client $MOUNT || error "failed to remount client"
9541                 checksum=$(eval $get_checksum)
9542                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9543         done
9544         # remove persistent param to avoid races with checksum mountopt below
9545         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9546                 error "failed to delete checksum on MGS"
9547
9548         for opt in "checksum" "nochecksum"; do
9549                 #remount with mount option
9550                 echo "remount client with option $opt, checksum should be $i"
9551                 umount_client $MOUNT || error "failed to umount client"
9552                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9553                         error "failed to mount client with option '$opt'"
9554                 checksum=$(eval $get_checksum)
9555                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9556                 i=$((i - 1))
9557         done
9558
9559         remount_client $MOUNT || error "failed to remount client"
9560 }
9561 run_test 77k "enable/disable checksum correctly"
9562
9563 test_77l() {
9564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9565         $GSS && skip_env "could not run with gss"
9566
9567         set_checksums 1
9568         stack_trap "set_checksums $ORIG_CSUM" EXIT
9569         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9570
9571         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9572
9573         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9574         for algo in $CKSUM_TYPES; do
9575                 set_checksum_type $algo || error "fail to set checksum type $algo"
9576                 osc_algo=$(get_osc_checksum_type OST0000)
9577                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9578
9579                 # no locks, no reqs to let the connection idle
9580                 cancel_lru_locks osc
9581                 lru_resize_disable osc
9582                 wait_osc_import_state client ost1 IDLE
9583
9584                 # ensure ost1 is connected
9585                 stat $DIR/$tfile >/dev/null || error "can't stat"
9586                 wait_osc_import_state client ost1 FULL
9587
9588                 osc_algo=$(get_osc_checksum_type OST0000)
9589                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9590         done
9591         return 0
9592 }
9593 run_test 77l "preferred checksum type is remembered after reconnected"
9594
9595 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9596 rm -f $F77_TMP
9597 unset F77_TMP
9598
9599 cleanup_test_78() {
9600         trap 0
9601         rm -f $DIR/$tfile
9602 }
9603
9604 test_78() { # bug 10901
9605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9606         remote_ost || skip_env "local OST"
9607
9608         NSEQ=5
9609         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9610         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9611         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9612         echo "MemTotal: $MEMTOTAL"
9613
9614         # reserve 256MB of memory for the kernel and other running processes,
9615         # and then take 1/2 of the remaining memory for the read/write buffers.
9616         if [ $MEMTOTAL -gt 512 ] ;then
9617                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9618         else
9619                 # for those poor memory-starved high-end clusters...
9620                 MEMTOTAL=$((MEMTOTAL / 2))
9621         fi
9622         echo "Mem to use for directio: $MEMTOTAL"
9623
9624         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9625         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9626         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9627         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9628                 head -n1)
9629         echo "Smallest OST: $SMALLESTOST"
9630         [[ $SMALLESTOST -lt 10240 ]] &&
9631                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9632
9633         trap cleanup_test_78 EXIT
9634
9635         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9636                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9637
9638         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9639         echo "File size: $F78SIZE"
9640         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9641         for i in $(seq 1 $NSEQ); do
9642                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9643                 echo directIO rdwr round $i of $NSEQ
9644                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9645         done
9646
9647         cleanup_test_78
9648 }
9649 run_test 78 "handle large O_DIRECT writes correctly ============"
9650
9651 test_79() { # bug 12743
9652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9653
9654         wait_delete_completed
9655
9656         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9657         BKFREE=$(calc_osc_kbytes kbytesfree)
9658         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9659
9660         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9661         DFTOTAL=`echo $STRING | cut -d, -f1`
9662         DFUSED=`echo $STRING  | cut -d, -f2`
9663         DFAVAIL=`echo $STRING | cut -d, -f3`
9664         DFFREE=$(($DFTOTAL - $DFUSED))
9665
9666         ALLOWANCE=$((64 * $OSTCOUNT))
9667
9668         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9669            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9670                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9671         fi
9672         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9673            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9674                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9675         fi
9676         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9677            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9678                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9679         fi
9680 }
9681 run_test 79 "df report consistency check ======================="
9682
9683 test_80() { # bug 10718
9684         remote_ost_nodsh && skip "remote OST with nodsh"
9685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9686
9687         # relax strong synchronous semantics for slow backends like ZFS
9688         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9689                 local soc="obdfilter.*.sync_lock_cancel"
9690                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9691
9692                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9693                 if [ -z "$save" ]; then
9694                         soc="obdfilter.*.sync_on_lock_cancel"
9695                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9696                 fi
9697
9698                 if [ "$save" != "never" ]; then
9699                         local hosts=$(comma_list $(osts_nodes))
9700
9701                         do_nodes $hosts $LCTL set_param $soc=never
9702                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9703                 fi
9704         fi
9705
9706         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9707         sync; sleep 1; sync
9708         local before=$(date +%s)
9709         cancel_lru_locks osc
9710         local after=$(date +%s)
9711         local diff=$((after - before))
9712         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9713
9714         rm -f $DIR/$tfile
9715 }
9716 run_test 80 "Page eviction is equally fast at high offsets too"
9717
9718 test_81a() { # LU-456
9719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9720         remote_ost_nodsh && skip "remote OST with nodsh"
9721
9722         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9723         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9724         do_facet ost1 lctl set_param fail_loc=0x80000228
9725
9726         # write should trigger a retry and success
9727         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9728         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9729         RC=$?
9730         if [ $RC -ne 0 ] ; then
9731                 error "write should success, but failed for $RC"
9732         fi
9733 }
9734 run_test 81a "OST should retry write when get -ENOSPC ==============="
9735
9736 test_81b() { # LU-456
9737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9738         remote_ost_nodsh && skip "remote OST with nodsh"
9739
9740         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9741         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9742         do_facet ost1 lctl set_param fail_loc=0x228
9743
9744         # write should retry several times and return -ENOSPC finally
9745         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9746         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9747         RC=$?
9748         ENOSPC=28
9749         if [ $RC -ne $ENOSPC ] ; then
9750                 error "dd should fail for -ENOSPC, but succeed."
9751         fi
9752 }
9753 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9754
9755 test_99() {
9756         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9757
9758         test_mkdir $DIR/$tdir.cvsroot
9759         chown $RUNAS_ID $DIR/$tdir.cvsroot
9760
9761         cd $TMP
9762         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9763
9764         cd /etc/init.d
9765         # some versions of cvs import exit(1) when asked to import links or
9766         # files they can't read.  ignore those files.
9767         local toignore=$(find . -type l -printf '-I %f\n' -o \
9768                          ! -perm /4 -printf '-I %f\n')
9769         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9770                 $tdir.reposname vtag rtag
9771
9772         cd $DIR
9773         test_mkdir $DIR/$tdir.reposname
9774         chown $RUNAS_ID $DIR/$tdir.reposname
9775         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9776
9777         cd $DIR/$tdir.reposname
9778         $RUNAS touch foo99
9779         $RUNAS cvs add -m 'addmsg' foo99
9780         $RUNAS cvs update
9781         $RUNAS cvs commit -m 'nomsg' foo99
9782         rm -fr $DIR/$tdir.cvsroot
9783 }
9784 run_test 99 "cvs strange file/directory operations"
9785
9786 test_100() {
9787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9788         [[ "$NETTYPE" =~ tcp ]] ||
9789                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9790         remote_ost_nodsh && skip "remote OST with nodsh"
9791         remote_mds_nodsh && skip "remote MDS with nodsh"
9792         remote_servers ||
9793                 skip "useless for local single node setup"
9794
9795         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9796                 [ "$PROT" != "tcp" ] && continue
9797                 RPORT=$(echo $REMOTE | cut -d: -f2)
9798                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9799
9800                 rc=0
9801                 LPORT=`echo $LOCAL | cut -d: -f2`
9802                 if [ $LPORT -ge 1024 ]; then
9803                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9804                         netstat -tna
9805                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9806                 fi
9807         done
9808         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9809 }
9810 run_test 100 "check local port using privileged port ==========="
9811
9812 function get_named_value()
9813 {
9814     local tag=$1
9815
9816     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9817 }
9818
9819 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9820                    awk '/^max_cached_mb/ { print $2 }')
9821
9822 cleanup_101a() {
9823         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9824         trap 0
9825 }
9826
9827 test_101a() {
9828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9829
9830         local s
9831         local discard
9832         local nreads=10000
9833         local cache_limit=32
9834
9835         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9836         trap cleanup_101a EXIT
9837         $LCTL set_param -n llite.*.read_ahead_stats=0
9838         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9839
9840         #
9841         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9842         #
9843         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9844         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9845
9846         discard=0
9847         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9848                    get_named_value 'read.but.discarded'); do
9849                         discard=$(($discard + $s))
9850         done
9851         cleanup_101a
9852
9853         $LCTL get_param osc.*-osc*.rpc_stats
9854         $LCTL get_param llite.*.read_ahead_stats
9855
9856         # Discard is generally zero, but sometimes a few random reads line up
9857         # and trigger larger readahead, which is wasted & leads to discards.
9858         if [[ $(($discard)) -gt $nreads ]]; then
9859                 error "too many ($discard) discarded pages"
9860         fi
9861         rm -f $DIR/$tfile || true
9862 }
9863 run_test 101a "check read-ahead for random reads"
9864
9865 setup_test101bc() {
9866         test_mkdir $DIR/$tdir
9867         local ssize=$1
9868         local FILE_LENGTH=$2
9869         STRIPE_OFFSET=0
9870
9871         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9872
9873         local list=$(comma_list $(osts_nodes))
9874         set_osd_param $list '' read_cache_enable 0
9875         set_osd_param $list '' writethrough_cache_enable 0
9876
9877         trap cleanup_test101bc EXIT
9878         # prepare the read-ahead file
9879         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9880
9881         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9882                                 count=$FILE_SIZE_MB 2> /dev/null
9883
9884 }
9885
9886 cleanup_test101bc() {
9887         trap 0
9888         rm -rf $DIR/$tdir
9889         rm -f $DIR/$tfile
9890
9891         local list=$(comma_list $(osts_nodes))
9892         set_osd_param $list '' read_cache_enable 1
9893         set_osd_param $list '' writethrough_cache_enable 1
9894 }
9895
9896 calc_total() {
9897         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9898 }
9899
9900 ra_check_101() {
9901         local READ_SIZE=$1
9902         local STRIPE_SIZE=$2
9903         local FILE_LENGTH=$3
9904         local RA_INC=1048576
9905         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9906         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9907                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9908         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9909                   get_named_value 'read.but.discarded' | calc_total)
9910         if [[ $DISCARD -gt $discard_limit ]]; then
9911                 $LCTL get_param llite.*.read_ahead_stats
9912                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9913         else
9914                 echo "Read-ahead success for size ${READ_SIZE}"
9915         fi
9916 }
9917
9918 test_101b() {
9919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9920         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9921
9922         local STRIPE_SIZE=1048576
9923         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9924
9925         if [ $SLOW == "yes" ]; then
9926                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9927         else
9928                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9929         fi
9930
9931         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9932
9933         # prepare the read-ahead file
9934         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9935         cancel_lru_locks osc
9936         for BIDX in 2 4 8 16 32 64 128 256
9937         do
9938                 local BSIZE=$((BIDX*4096))
9939                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9940                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9941                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9942                 $LCTL set_param -n llite.*.read_ahead_stats=0
9943                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9944                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9945                 cancel_lru_locks osc
9946                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9947         done
9948         cleanup_test101bc
9949         true
9950 }
9951 run_test 101b "check stride-io mode read-ahead ================="
9952
9953 test_101c() {
9954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9955
9956         local STRIPE_SIZE=1048576
9957         local FILE_LENGTH=$((STRIPE_SIZE*100))
9958         local nreads=10000
9959         local rsize=65536
9960         local osc_rpc_stats
9961
9962         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9963
9964         cancel_lru_locks osc
9965         $LCTL set_param osc.*.rpc_stats=0
9966         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9967         $LCTL get_param osc.*.rpc_stats
9968         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9969                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9970                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9971                 local size
9972
9973                 if [ $lines -le 20 ]; then
9974                         echo "continue debug"
9975                         continue
9976                 fi
9977                 for size in 1 2 4 8; do
9978                         local rpc=$(echo "$stats" |
9979                                     awk '($1 == "'$size':") {print $2; exit; }')
9980                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9981                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9982                 done
9983                 echo "$osc_rpc_stats check passed!"
9984         done
9985         cleanup_test101bc
9986         true
9987 }
9988 run_test 101c "check stripe_size aligned read-ahead"
9989
9990 test_101d() {
9991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9992
9993         local file=$DIR/$tfile
9994         local sz_MB=${FILESIZE_101d:-80}
9995         local ra_MB=${READAHEAD_MB:-40}
9996
9997         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9998         [ $free_MB -lt $sz_MB ] &&
9999                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10000
10001         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10002         $LFS setstripe -c -1 $file || error "setstripe failed"
10003
10004         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10005         echo Cancel LRU locks on lustre client to flush the client cache
10006         cancel_lru_locks osc
10007
10008         echo Disable read-ahead
10009         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10010         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10011         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10012         $LCTL get_param -n llite.*.max_read_ahead_mb
10013
10014         echo "Reading the test file $file with read-ahead disabled"
10015         local sz_KB=$((sz_MB * 1024 / 4))
10016         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10017         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10018         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10019                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10020
10021         echo "Cancel LRU locks on lustre client to flush the client cache"
10022         cancel_lru_locks osc
10023         echo Enable read-ahead with ${ra_MB}MB
10024         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10025
10026         echo "Reading the test file $file with read-ahead enabled"
10027         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10028                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10029
10030         echo "read-ahead disabled time read $raOFF"
10031         echo "read-ahead enabled time read $raON"
10032
10033         rm -f $file
10034         wait_delete_completed
10035
10036         # use awk for this check instead of bash because it handles decimals
10037         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10038                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10039 }
10040 run_test 101d "file read with and without read-ahead enabled"
10041
10042 test_101e() {
10043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10044
10045         local file=$DIR/$tfile
10046         local size_KB=500  #KB
10047         local count=100
10048         local bsize=1024
10049
10050         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10051         local need_KB=$((count * size_KB))
10052         [[ $free_KB -le $need_KB ]] &&
10053                 skip_env "Need free space $need_KB, have $free_KB"
10054
10055         echo "Creating $count ${size_KB}K test files"
10056         for ((i = 0; i < $count; i++)); do
10057                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10058         done
10059
10060         echo "Cancel LRU locks on lustre client to flush the client cache"
10061         cancel_lru_locks $OSC
10062
10063         echo "Reset readahead stats"
10064         $LCTL set_param -n llite.*.read_ahead_stats=0
10065
10066         for ((i = 0; i < $count; i++)); do
10067                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10068         done
10069
10070         $LCTL get_param llite.*.max_cached_mb
10071         $LCTL get_param llite.*.read_ahead_stats
10072         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10073                      get_named_value 'misses' | calc_total)
10074
10075         for ((i = 0; i < $count; i++)); do
10076                 rm -rf $file.$i 2>/dev/null
10077         done
10078
10079         #10000 means 20% reads are missing in readahead
10080         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10081 }
10082 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10083
10084 test_101f() {
10085         which iozone || skip_env "no iozone installed"
10086
10087         local old_debug=$($LCTL get_param debug)
10088         old_debug=${old_debug#*=}
10089         $LCTL set_param debug="reada mmap"
10090
10091         # create a test file
10092         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10093
10094         echo Cancel LRU locks on lustre client to flush the client cache
10095         cancel_lru_locks osc
10096
10097         echo Reset readahead stats
10098         $LCTL set_param -n llite.*.read_ahead_stats=0
10099
10100         echo mmap read the file with small block size
10101         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10102                 > /dev/null 2>&1
10103
10104         echo checking missing pages
10105         $LCTL get_param llite.*.read_ahead_stats
10106         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10107                         get_named_value 'misses' | calc_total)
10108
10109         $LCTL set_param debug="$old_debug"
10110         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10111         rm -f $DIR/$tfile
10112 }
10113 run_test 101f "check mmap read performance"
10114
10115 test_101g_brw_size_test() {
10116         local mb=$1
10117         local pages=$((mb * 1048576 / PAGE_SIZE))
10118         local file=$DIR/$tfile
10119
10120         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10121                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10122         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10123                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10124                         return 2
10125         done
10126
10127         stack_trap "rm -f $file" EXIT
10128         $LCTL set_param -n osc.*.rpc_stats=0
10129
10130         # 10 RPCs should be enough for the test
10131         local count=10
10132         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10133                 { error "dd write ${mb} MB blocks failed"; return 3; }
10134         cancel_lru_locks osc
10135         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10136                 { error "dd write ${mb} MB blocks failed"; return 4; }
10137
10138         # calculate number of full-sized read and write RPCs
10139         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10140                 sed -n '/pages per rpc/,/^$/p' |
10141                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10142                 END { print reads,writes }'))
10143         # allow one extra full-sized read RPC for async readahead
10144         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10145                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10146         [[ ${rpcs[1]} == $count ]] ||
10147                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10148 }
10149
10150 test_101g() {
10151         remote_ost_nodsh && skip "remote OST with nodsh"
10152
10153         local rpcs
10154         local osts=$(get_facets OST)
10155         local list=$(comma_list $(osts_nodes))
10156         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10157         local brw_size="obdfilter.*.brw_size"
10158
10159         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10160
10161         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10162
10163         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10164                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10165                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10166            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10167                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10168                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10169
10170                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10171                         suffix="M"
10172
10173                 if [[ $orig_mb -lt 16 ]]; then
10174                         save_lustre_params $osts "$brw_size" > $p
10175                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10176                                 error "set 16MB RPC size failed"
10177
10178                         echo "remount client to enable new RPC size"
10179                         remount_client $MOUNT || error "remount_client failed"
10180                 fi
10181
10182                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10183                 # should be able to set brw_size=12, but no rpc_stats for that
10184                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10185         fi
10186
10187         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10188
10189         if [[ $orig_mb -lt 16 ]]; then
10190                 restore_lustre_params < $p
10191                 remount_client $MOUNT || error "remount_client restore failed"
10192         fi
10193
10194         rm -f $p $DIR/$tfile
10195 }
10196 run_test 101g "Big bulk(4/16 MiB) readahead"
10197
10198 test_101h() {
10199         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10200
10201         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10202                 error "dd 70M file failed"
10203         echo Cancel LRU locks on lustre client to flush the client cache
10204         cancel_lru_locks osc
10205
10206         echo "Reset readahead stats"
10207         $LCTL set_param -n llite.*.read_ahead_stats 0
10208
10209         echo "Read 10M of data but cross 64M bundary"
10210         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10211         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10212                      get_named_value 'misses' | calc_total)
10213         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10214         rm -f $p $DIR/$tfile
10215 }
10216 run_test 101h "Readahead should cover current read window"
10217
10218 test_101i() {
10219         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10220                 error "dd 10M file failed"
10221
10222         local max_per_file_mb=$($LCTL get_param -n \
10223                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10224         cancel_lru_locks osc
10225         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10226         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10227                 error "set max_read_ahead_per_file_mb to 1 failed"
10228
10229         echo "Reset readahead stats"
10230         $LCTL set_param llite.*.read_ahead_stats=0
10231
10232         dd if=$DIR/$tfile of=/dev/null bs=2M
10233
10234         $LCTL get_param llite.*.read_ahead_stats
10235         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10236                      awk '/misses/ { print $2 }')
10237         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10238         rm -f $DIR/$tfile
10239 }
10240 run_test 101i "allow current readahead to exceed reservation"
10241
10242 test_101j() {
10243         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10244                 error "setstripe $DIR/$tfile failed"
10245         local file_size=$((1048576 * 16))
10246         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10247         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10248
10249         echo Disable read-ahead
10250         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10251
10252         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10253         for blk in $PAGE_SIZE 1048576 $file_size; do
10254                 cancel_lru_locks osc
10255                 echo "Reset readahead stats"
10256                 $LCTL set_param -n llite.*.read_ahead_stats=0
10257                 local count=$(($file_size / $blk))
10258                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10259                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10260                              get_named_value 'failed.to.fast.read' | calc_total)
10261                 $LCTL get_param -n llite.*.read_ahead_stats
10262                 [ $miss -eq $count ] || error "expected $count got $miss"
10263         done
10264
10265         rm -f $p $DIR/$tfile
10266 }
10267 run_test 101j "A complete read block should be submitted when no RA"
10268
10269 setup_test102() {
10270         test_mkdir $DIR/$tdir
10271         chown $RUNAS_ID $DIR/$tdir
10272         STRIPE_SIZE=65536
10273         STRIPE_OFFSET=1
10274         STRIPE_COUNT=$OSTCOUNT
10275         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10276
10277         trap cleanup_test102 EXIT
10278         cd $DIR
10279         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10280         cd $DIR/$tdir
10281         for num in 1 2 3 4; do
10282                 for count in $(seq 1 $STRIPE_COUNT); do
10283                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10284                                 local size=`expr $STRIPE_SIZE \* $num`
10285                                 local file=file"$num-$idx-$count"
10286                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10287                         done
10288                 done
10289         done
10290
10291         cd $DIR
10292         $1 tar cf $TMP/f102.tar $tdir --xattrs
10293 }
10294
10295 cleanup_test102() {
10296         trap 0
10297         rm -f $TMP/f102.tar
10298         rm -rf $DIR/d0.sanity/d102
10299 }
10300
10301 test_102a() {
10302         [ "$UID" != 0 ] && skip "must run as root"
10303         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10304                 skip_env "must have user_xattr"
10305
10306         [ -z "$(which setfattr 2>/dev/null)" ] &&
10307                 skip_env "could not find setfattr"
10308
10309         local testfile=$DIR/$tfile
10310
10311         touch $testfile
10312         echo "set/get xattr..."
10313         setfattr -n trusted.name1 -v value1 $testfile ||
10314                 error "setfattr -n trusted.name1=value1 $testfile failed"
10315         getfattr -n trusted.name1 $testfile 2> /dev/null |
10316           grep "trusted.name1=.value1" ||
10317                 error "$testfile missing trusted.name1=value1"
10318
10319         setfattr -n user.author1 -v author1 $testfile ||
10320                 error "setfattr -n user.author1=author1 $testfile failed"
10321         getfattr -n user.author1 $testfile 2> /dev/null |
10322           grep "user.author1=.author1" ||
10323                 error "$testfile missing trusted.author1=author1"
10324
10325         echo "listxattr..."
10326         setfattr -n trusted.name2 -v value2 $testfile ||
10327                 error "$testfile unable to set trusted.name2"
10328         setfattr -n trusted.name3 -v value3 $testfile ||
10329                 error "$testfile unable to set trusted.name3"
10330         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10331             grep "trusted.name" | wc -l) -eq 3 ] ||
10332                 error "$testfile missing 3 trusted.name xattrs"
10333
10334         setfattr -n user.author2 -v author2 $testfile ||
10335                 error "$testfile unable to set user.author2"
10336         setfattr -n user.author3 -v author3 $testfile ||
10337                 error "$testfile unable to set user.author3"
10338         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10339             grep "user.author" | wc -l) -eq 3 ] ||
10340                 error "$testfile missing 3 user.author xattrs"
10341
10342         echo "remove xattr..."
10343         setfattr -x trusted.name1 $testfile ||
10344                 error "$testfile error deleting trusted.name1"
10345         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10346                 error "$testfile did not delete trusted.name1 xattr"
10347
10348         setfattr -x user.author1 $testfile ||
10349                 error "$testfile error deleting user.author1"
10350         echo "set lustre special xattr ..."
10351         $LFS setstripe -c1 $testfile
10352         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10353                 awk -F "=" '/trusted.lov/ { print $2 }' )
10354         setfattr -n "trusted.lov" -v $lovea $testfile ||
10355                 error "$testfile doesn't ignore setting trusted.lov again"
10356         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10357                 error "$testfile allow setting invalid trusted.lov"
10358         rm -f $testfile
10359 }
10360 run_test 102a "user xattr test =================================="
10361
10362 check_102b_layout() {
10363         local layout="$*"
10364         local testfile=$DIR/$tfile
10365
10366         echo "test layout '$layout'"
10367         $LFS setstripe $layout $testfile || error "setstripe failed"
10368         $LFS getstripe -y $testfile
10369
10370         echo "get/set/list trusted.lov xattr ..." # b=10930
10371         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10372         [[ "$value" =~ "trusted.lov" ]] ||
10373                 error "can't get trusted.lov from $testfile"
10374         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10375                 error "getstripe failed"
10376
10377         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10378
10379         value=$(cut -d= -f2 <<<$value)
10380         # LU-13168: truncated xattr should fail if short lov_user_md header
10381         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10382                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10383         for len in $lens; do
10384                 echo "setfattr $len $testfile.2"
10385                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10386                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10387         done
10388         local stripe_size=$($LFS getstripe -S $testfile.2)
10389         local stripe_count=$($LFS getstripe -c $testfile.2)
10390         [[ $stripe_size -eq 65536 ]] ||
10391                 error "stripe size $stripe_size != 65536"
10392         [[ $stripe_count -eq $stripe_count_orig ]] ||
10393                 error "stripe count $stripe_count != $stripe_count_orig"
10394         rm $testfile $testfile.2
10395 }
10396
10397 test_102b() {
10398         [ -z "$(which setfattr 2>/dev/null)" ] &&
10399                 skip_env "could not find setfattr"
10400         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10401
10402         # check plain layout
10403         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10404
10405         # and also check composite layout
10406         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10407
10408 }
10409 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10410
10411 test_102c() {
10412         [ -z "$(which setfattr 2>/dev/null)" ] &&
10413                 skip_env "could not find setfattr"
10414         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10415
10416         # b10930: get/set/list lustre.lov xattr
10417         echo "get/set/list lustre.lov xattr ..."
10418         test_mkdir $DIR/$tdir
10419         chown $RUNAS_ID $DIR/$tdir
10420         local testfile=$DIR/$tdir/$tfile
10421         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10422                 error "setstripe failed"
10423         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10424                 error "getstripe failed"
10425         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10426         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10427
10428         local testfile2=${testfile}2
10429         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10430                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10431
10432         $RUNAS $MCREATE $testfile2
10433         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10434         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10435         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10436         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10437         [ $stripe_count -eq $STRIPECOUNT ] ||
10438                 error "stripe count $stripe_count != $STRIPECOUNT"
10439 }
10440 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10441
10442 compare_stripe_info1() {
10443         local stripe_index_all_zero=true
10444
10445         for num in 1 2 3 4; do
10446                 for count in $(seq 1 $STRIPE_COUNT); do
10447                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10448                                 local size=$((STRIPE_SIZE * num))
10449                                 local file=file"$num-$offset-$count"
10450                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10451                                 [[ $stripe_size -ne $size ]] &&
10452                                     error "$file: size $stripe_size != $size"
10453                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10454                                 # allow fewer stripes to be created, ORI-601
10455                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10456                                     error "$file: count $stripe_count != $count"
10457                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10458                                 [[ $stripe_index -ne 0 ]] &&
10459                                         stripe_index_all_zero=false
10460                         done
10461                 done
10462         done
10463         $stripe_index_all_zero &&
10464                 error "all files are being extracted starting from OST index 0"
10465         return 0
10466 }
10467
10468 have_xattrs_include() {
10469         tar --help | grep -q xattrs-include &&
10470                 echo --xattrs-include="lustre.*"
10471 }
10472
10473 test_102d() {
10474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10475         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10476
10477         XINC=$(have_xattrs_include)
10478         setup_test102
10479         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10480         cd $DIR/$tdir/$tdir
10481         compare_stripe_info1
10482 }
10483 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10484
10485 test_102f() {
10486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10487         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10488
10489         XINC=$(have_xattrs_include)
10490         setup_test102
10491         test_mkdir $DIR/$tdir.restore
10492         cd $DIR
10493         tar cf - --xattrs $tdir | tar xf - \
10494                 -C $DIR/$tdir.restore --xattrs $XINC
10495         cd $DIR/$tdir.restore/$tdir
10496         compare_stripe_info1
10497 }
10498 run_test 102f "tar copy files, not keep osts"
10499
10500 grow_xattr() {
10501         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10502                 skip "must have user_xattr"
10503         [ -z "$(which setfattr 2>/dev/null)" ] &&
10504                 skip_env "could not find setfattr"
10505         [ -z "$(which getfattr 2>/dev/null)" ] &&
10506                 skip_env "could not find getfattr"
10507
10508         local xsize=${1:-1024}  # in bytes
10509         local file=$DIR/$tfile
10510         local value="$(generate_string $xsize)"
10511         local xbig=trusted.big
10512         local toobig=$2
10513
10514         touch $file
10515         log "save $xbig on $file"
10516         if [ -z "$toobig" ]
10517         then
10518                 setfattr -n $xbig -v $value $file ||
10519                         error "saving $xbig on $file failed"
10520         else
10521                 setfattr -n $xbig -v $value $file &&
10522                         error "saving $xbig on $file succeeded"
10523                 return 0
10524         fi
10525
10526         local orig=$(get_xattr_value $xbig $file)
10527         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10528
10529         local xsml=trusted.sml
10530         log "save $xsml on $file"
10531         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10532
10533         local new=$(get_xattr_value $xbig $file)
10534         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10535
10536         log "grow $xsml on $file"
10537         setfattr -n $xsml -v "$value" $file ||
10538                 error "growing $xsml on $file failed"
10539
10540         new=$(get_xattr_value $xbig $file)
10541         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10542         log "$xbig still valid after growing $xsml"
10543
10544         rm -f $file
10545 }
10546
10547 test_102h() { # bug 15777
10548         grow_xattr 1024
10549 }
10550 run_test 102h "grow xattr from inside inode to external block"
10551
10552 test_102ha() {
10553         large_xattr_enabled || skip_env "ea_inode feature disabled"
10554
10555         echo "setting xattr of max xattr size: $(max_xattr_size)"
10556         grow_xattr $(max_xattr_size)
10557
10558         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10559         echo "This should fail:"
10560         grow_xattr $(($(max_xattr_size) + 10)) 1
10561 }
10562 run_test 102ha "grow xattr from inside inode to external inode"
10563
10564 test_102i() { # bug 17038
10565         [ -z "$(which getfattr 2>/dev/null)" ] &&
10566                 skip "could not find getfattr"
10567
10568         touch $DIR/$tfile
10569         ln -s $DIR/$tfile $DIR/${tfile}link
10570         getfattr -n trusted.lov $DIR/$tfile ||
10571                 error "lgetxattr on $DIR/$tfile failed"
10572         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10573                 grep -i "no such attr" ||
10574                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10575         rm -f $DIR/$tfile $DIR/${tfile}link
10576 }
10577 run_test 102i "lgetxattr test on symbolic link ============"
10578
10579 test_102j() {
10580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10581         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10582
10583         XINC=$(have_xattrs_include)
10584         setup_test102 "$RUNAS"
10585         chown $RUNAS_ID $DIR/$tdir
10586         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10587         cd $DIR/$tdir/$tdir
10588         compare_stripe_info1 "$RUNAS"
10589 }
10590 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10591
10592 test_102k() {
10593         [ -z "$(which setfattr 2>/dev/null)" ] &&
10594                 skip "could not find setfattr"
10595
10596         touch $DIR/$tfile
10597         # b22187 just check that does not crash for regular file.
10598         setfattr -n trusted.lov $DIR/$tfile
10599         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10600         local test_kdir=$DIR/$tdir
10601         test_mkdir $test_kdir
10602         local default_size=$($LFS getstripe -S $test_kdir)
10603         local default_count=$($LFS getstripe -c $test_kdir)
10604         local default_offset=$($LFS getstripe -i $test_kdir)
10605         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10606                 error 'dir setstripe failed'
10607         setfattr -n trusted.lov $test_kdir
10608         local stripe_size=$($LFS getstripe -S $test_kdir)
10609         local stripe_count=$($LFS getstripe -c $test_kdir)
10610         local stripe_offset=$($LFS getstripe -i $test_kdir)
10611         [ $stripe_size -eq $default_size ] ||
10612                 error "stripe size $stripe_size != $default_size"
10613         [ $stripe_count -eq $default_count ] ||
10614                 error "stripe count $stripe_count != $default_count"
10615         [ $stripe_offset -eq $default_offset ] ||
10616                 error "stripe offset $stripe_offset != $default_offset"
10617         rm -rf $DIR/$tfile $test_kdir
10618 }
10619 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10620
10621 test_102l() {
10622         [ -z "$(which getfattr 2>/dev/null)" ] &&
10623                 skip "could not find getfattr"
10624
10625         # LU-532 trusted. xattr is invisible to non-root
10626         local testfile=$DIR/$tfile
10627
10628         touch $testfile
10629
10630         echo "listxattr as user..."
10631         chown $RUNAS_ID $testfile
10632         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10633             grep -q "trusted" &&
10634                 error "$testfile trusted xattrs are user visible"
10635
10636         return 0;
10637 }
10638 run_test 102l "listxattr size test =================================="
10639
10640 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10641         local path=$DIR/$tfile
10642         touch $path
10643
10644         listxattr_size_check $path || error "listattr_size_check $path failed"
10645 }
10646 run_test 102m "Ensure listxattr fails on small bufffer ========"
10647
10648 cleanup_test102
10649
10650 getxattr() { # getxattr path name
10651         # Return the base64 encoding of the value of xattr name on path.
10652         local path=$1
10653         local name=$2
10654
10655         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10656         # file: $path
10657         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10658         #
10659         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10660
10661         getfattr --absolute-names --encoding=base64 --name=$name $path |
10662                 awk -F= -v name=$name '$1 == name {
10663                         print substr($0, index($0, "=") + 1);
10664         }'
10665 }
10666
10667 test_102n() { # LU-4101 mdt: protect internal xattrs
10668         [ -z "$(which setfattr 2>/dev/null)" ] &&
10669                 skip "could not find setfattr"
10670         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10671         then
10672                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10673         fi
10674
10675         local file0=$DIR/$tfile.0
10676         local file1=$DIR/$tfile.1
10677         local xattr0=$TMP/$tfile.0
10678         local xattr1=$TMP/$tfile.1
10679         local namelist="lov lma lmv link fid version som hsm"
10680         local name
10681         local value
10682
10683         rm -rf $file0 $file1 $xattr0 $xattr1
10684         touch $file0 $file1
10685
10686         # Get 'before' xattrs of $file1.
10687         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10688
10689         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10690                 namelist+=" lfsck_namespace"
10691         for name in $namelist; do
10692                 # Try to copy xattr from $file0 to $file1.
10693                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10694
10695                 setfattr --name=trusted.$name --value="$value" $file1 ||
10696                         error "setxattr 'trusted.$name' failed"
10697
10698                 # Try to set a garbage xattr.
10699                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10700
10701                 if [[ x$name == "xlov" ]]; then
10702                         setfattr --name=trusted.lov --value="$value" $file1 &&
10703                         error "setxattr invalid 'trusted.lov' success"
10704                 else
10705                         setfattr --name=trusted.$name --value="$value" $file1 ||
10706                                 error "setxattr invalid 'trusted.$name' failed"
10707                 fi
10708
10709                 # Try to remove the xattr from $file1. We don't care if this
10710                 # appears to succeed or fail, we just don't want there to be
10711                 # any changes or crashes.
10712                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10713         done
10714
10715         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10716         then
10717                 name="lfsck_ns"
10718                 # Try to copy xattr from $file0 to $file1.
10719                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10720
10721                 setfattr --name=trusted.$name --value="$value" $file1 ||
10722                         error "setxattr 'trusted.$name' failed"
10723
10724                 # Try to set a garbage xattr.
10725                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10726
10727                 setfattr --name=trusted.$name --value="$value" $file1 ||
10728                         error "setxattr 'trusted.$name' failed"
10729
10730                 # Try to remove the xattr from $file1. We don't care if this
10731                 # appears to succeed or fail, we just don't want there to be
10732                 # any changes or crashes.
10733                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10734         fi
10735
10736         # Get 'after' xattrs of file1.
10737         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10738
10739         if ! diff $xattr0 $xattr1; then
10740                 error "before and after xattrs of '$file1' differ"
10741         fi
10742
10743         rm -rf $file0 $file1 $xattr0 $xattr1
10744
10745         return 0
10746 }
10747 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10748
10749 test_102p() { # LU-4703 setxattr did not check ownership
10750         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10751                 skip "MDS needs to be at least 2.5.56"
10752
10753         local testfile=$DIR/$tfile
10754
10755         touch $testfile
10756
10757         echo "setfacl as user..."
10758         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10759         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10760
10761         echo "setfattr as user..."
10762         setfacl -m "u:$RUNAS_ID:---" $testfile
10763         $RUNAS setfattr -x system.posix_acl_access $testfile
10764         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10765 }
10766 run_test 102p "check setxattr(2) correctly fails without permission"
10767
10768 test_102q() {
10769         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10770                 skip "MDS needs to be at least 2.6.92"
10771
10772         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10773 }
10774 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10775
10776 test_102r() {
10777         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10778                 skip "MDS needs to be at least 2.6.93"
10779
10780         touch $DIR/$tfile || error "touch"
10781         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10782         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10783         rm $DIR/$tfile || error "rm"
10784
10785         #normal directory
10786         mkdir -p $DIR/$tdir || error "mkdir"
10787         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10788         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10789         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10790                 error "$testfile error deleting user.author1"
10791         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10792                 grep "user.$(basename $tdir)" &&
10793                 error "$tdir did not delete user.$(basename $tdir)"
10794         rmdir $DIR/$tdir || error "rmdir"
10795
10796         #striped directory
10797         test_mkdir $DIR/$tdir
10798         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10799         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10800         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10801                 error "$testfile error deleting user.author1"
10802         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10803                 grep "user.$(basename $tdir)" &&
10804                 error "$tdir did not delete user.$(basename $tdir)"
10805         rmdir $DIR/$tdir || error "rm striped dir"
10806 }
10807 run_test 102r "set EAs with empty values"
10808
10809 test_102s() {
10810         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10811                 skip "MDS needs to be at least 2.11.52"
10812
10813         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10814
10815         save_lustre_params client "llite.*.xattr_cache" > $save
10816
10817         for cache in 0 1; do
10818                 lctl set_param llite.*.xattr_cache=$cache
10819
10820                 rm -f $DIR/$tfile
10821                 touch $DIR/$tfile || error "touch"
10822                 for prefix in lustre security system trusted user; do
10823                         # Note getxattr() may fail with 'Operation not
10824                         # supported' or 'No such attribute' depending
10825                         # on prefix and cache.
10826                         getfattr -n $prefix.n102s $DIR/$tfile &&
10827                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10828                 done
10829         done
10830
10831         restore_lustre_params < $save
10832 }
10833 run_test 102s "getting nonexistent xattrs should fail"
10834
10835 test_102t() {
10836         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10837                 skip "MDS needs to be at least 2.11.52"
10838
10839         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10840
10841         save_lustre_params client "llite.*.xattr_cache" > $save
10842
10843         for cache in 0 1; do
10844                 lctl set_param llite.*.xattr_cache=$cache
10845
10846                 for buf_size in 0 256; do
10847                         rm -f $DIR/$tfile
10848                         touch $DIR/$tfile || error "touch"
10849                         setfattr -n user.multiop $DIR/$tfile
10850                         $MULTIOP $DIR/$tfile oa$buf_size ||
10851                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10852                 done
10853         done
10854
10855         restore_lustre_params < $save
10856 }
10857 run_test 102t "zero length xattr values handled correctly"
10858
10859 run_acl_subtest()
10860 {
10861     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10862     return $?
10863 }
10864
10865 test_103a() {
10866         [ "$UID" != 0 ] && skip "must run as root"
10867         $GSS && skip_env "could not run under gss"
10868         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10869                 skip_env "must have acl enabled"
10870         [ -z "$(which setfacl 2>/dev/null)" ] &&
10871                 skip_env "could not find setfacl"
10872         remote_mds_nodsh && skip "remote MDS with nodsh"
10873
10874         gpasswd -a daemon bin                           # LU-5641
10875         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10876
10877         declare -a identity_old
10878
10879         for num in $(seq $MDSCOUNT); do
10880                 switch_identity $num true || identity_old[$num]=$?
10881         done
10882
10883         SAVE_UMASK=$(umask)
10884         umask 0022
10885         mkdir -p $DIR/$tdir
10886         cd $DIR/$tdir
10887
10888         echo "performing cp ..."
10889         run_acl_subtest cp || error "run_acl_subtest cp failed"
10890         echo "performing getfacl-noacl..."
10891         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10892         echo "performing misc..."
10893         run_acl_subtest misc || error  "misc test failed"
10894         echo "performing permissions..."
10895         run_acl_subtest permissions || error "permissions failed"
10896         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10897         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10898                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10899                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10900         then
10901                 echo "performing permissions xattr..."
10902                 run_acl_subtest permissions_xattr ||
10903                         error "permissions_xattr failed"
10904         fi
10905         echo "performing setfacl..."
10906         run_acl_subtest setfacl || error  "setfacl test failed"
10907
10908         # inheritance test got from HP
10909         echo "performing inheritance..."
10910         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10911         chmod +x make-tree || error "chmod +x failed"
10912         run_acl_subtest inheritance || error "inheritance test failed"
10913         rm -f make-tree
10914
10915         echo "LU-974 ignore umask when acl is enabled..."
10916         run_acl_subtest 974 || error "LU-974 umask test failed"
10917         if [ $MDSCOUNT -ge 2 ]; then
10918                 run_acl_subtest 974_remote ||
10919                         error "LU-974 umask test failed under remote dir"
10920         fi
10921
10922         echo "LU-2561 newly created file is same size as directory..."
10923         if [ "$mds1_FSTYPE" != "zfs" ]; then
10924                 run_acl_subtest 2561 || error "LU-2561 test failed"
10925         else
10926                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10927         fi
10928
10929         run_acl_subtest 4924 || error "LU-4924 test failed"
10930
10931         cd $SAVE_PWD
10932         umask $SAVE_UMASK
10933
10934         for num in $(seq $MDSCOUNT); do
10935                 if [ "${identity_old[$num]}" = 1 ]; then
10936                         switch_identity $num false || identity_old[$num]=$?
10937                 fi
10938         done
10939 }
10940 run_test 103a "acl test"
10941
10942 test_103b() {
10943         declare -a pids
10944         local U
10945
10946         for U in {0..511}; do
10947                 {
10948                 local O=$(printf "%04o" $U)
10949
10950                 umask $(printf "%04o" $((511 ^ $O)))
10951                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10952                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10953
10954                 (( $S == ($O & 0666) )) ||
10955                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10956
10957                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10958                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10959                 (( $S == ($O & 0666) )) ||
10960                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10961
10962                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10963                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10964                 (( $S == ($O & 0666) )) ||
10965                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10966                 rm -f $DIR/$tfile.[smp]$0
10967                 } &
10968                 local pid=$!
10969
10970                 # limit the concurrently running threads to 64. LU-11878
10971                 local idx=$((U % 64))
10972                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10973                 pids[idx]=$pid
10974         done
10975         wait
10976 }
10977 run_test 103b "umask lfs setstripe"
10978
10979 test_103c() {
10980         mkdir -p $DIR/$tdir
10981         cp -rp $DIR/$tdir $DIR/$tdir.bak
10982
10983         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10984                 error "$DIR/$tdir shouldn't contain default ACL"
10985         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10986                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10987         true
10988 }
10989 run_test 103c "'cp -rp' won't set empty acl"
10990
10991 test_103e() {
10992         local numacl
10993         local fileacl
10994         local saved_debug=$($LCTL get_param -n debug)
10995
10996         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
10997                 skip "MDS needs to be at least 2.14.0"
10998
10999         large_xattr_enabled || skip_env "ea_inode feature disabled"
11000
11001         mkdir -p $DIR/$tdir
11002         # add big LOV EA to cause reply buffer overflow earlier
11003         $LFS setstripe -C 1000 $DIR/$tdir
11004         lctl set_param mdc.*-mdc*.stats=clear
11005
11006         $LCTL set_param debug=0
11007         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11008         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11009
11010         # add a large number of default ACLs (expect 8000+ for 2.13+)
11011         for U in {2..7000}; do
11012                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11013                         error "Able to add just $U default ACLs"
11014         done
11015         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11016         echo "$numacl default ACLs created"
11017
11018         stat $DIR/$tdir || error "Cannot stat directory"
11019         # check file creation
11020         touch $DIR/$tdir/$tfile ||
11021                 error "failed to create $tfile with $numacl default ACLs"
11022         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11023         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11024         echo "$fileacl ACLs were inherited"
11025         (( $fileacl == $numacl )) ||
11026                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11027         # check that new ACLs creation adds new ACLs to inherited ACLs
11028         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11029                 error "Cannot set new ACL"
11030         numacl=$((numacl + 1))
11031         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11032         (( $fileacl == $numacl )) ||
11033                 error "failed to add new ACL: $fileacl != $numacl as expected"
11034         # adds more ACLs to a file to reach their maximum at 8000+
11035         numacl=0
11036         for U in {20000..25000}; do
11037                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11038                 numacl=$((numacl + 1))
11039         done
11040         echo "Added $numacl more ACLs to the file"
11041         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11042         echo "Total $fileacl ACLs in file"
11043         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11044         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11045         rmdir $DIR/$tdir || error "Cannot remove directory"
11046 }
11047 run_test 103e "inheritance of big amount of default ACLs"
11048
11049 test_103f() {
11050         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11051                 skip "MDS needs to be at least 2.14.51"
11052
11053         large_xattr_enabled || skip_env "ea_inode feature disabled"
11054
11055         # enable changelog to consume more internal MDD buffers
11056         changelog_register
11057
11058         mkdir -p $DIR/$tdir
11059         # add big LOV EA
11060         $LFS setstripe -C 1000 $DIR/$tdir
11061         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11062         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11063         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11064         rmdir $DIR/$tdir || error "Cannot remove directory"
11065 }
11066 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11067
11068 test_104a() {
11069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11070
11071         touch $DIR/$tfile
11072         lfs df || error "lfs df failed"
11073         lfs df -ih || error "lfs df -ih failed"
11074         lfs df -h $DIR || error "lfs df -h $DIR failed"
11075         lfs df -i $DIR || error "lfs df -i $DIR failed"
11076         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11077         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11078
11079         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11080         lctl --device %$OSC deactivate
11081         lfs df || error "lfs df with deactivated OSC failed"
11082         lctl --device %$OSC activate
11083         # wait the osc back to normal
11084         wait_osc_import_ready client ost
11085
11086         lfs df || error "lfs df with reactivated OSC failed"
11087         rm -f $DIR/$tfile
11088 }
11089 run_test 104a "lfs df [-ih] [path] test ========================="
11090
11091 test_104b() {
11092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11093         [ $RUNAS_ID -eq $UID ] &&
11094                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11095
11096         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11097                         grep "Permission denied" | wc -l)))
11098         if [ $denied_cnt -ne 0 ]; then
11099                 error "lfs check servers test failed"
11100         fi
11101 }
11102 run_test 104b "$RUNAS lfs check servers test ===================="
11103
11104 #
11105 # Verify $1 is within range of $2.
11106 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11107 # $1 is <= 2% of $2. Else Fail.
11108 #
11109 value_in_range() {
11110         # Strip all units (M, G, T)
11111         actual=$(echo $1 | tr -d A-Z)
11112         expect=$(echo $2 | tr -d A-Z)
11113
11114         expect_lo=$(($expect * 98 / 100)) # 2% below
11115         expect_hi=$(($expect * 102 / 100)) # 2% above
11116
11117         # permit 2% drift above and below
11118         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11119 }
11120
11121 test_104c() {
11122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11123         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11124
11125         local ost_param="osd-zfs.$FSNAME-OST0000."
11126         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11127         local ofacets=$(get_facets OST)
11128         local mfacets=$(get_facets MDS)
11129         local saved_ost_blocks=
11130         local saved_mdt_blocks=
11131
11132         echo "Before recordsize change"
11133         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11134         df=($(df -h | grep "/mnt/lustre"$))
11135
11136         # For checking.
11137         echo "lfs output : ${lfs_df[*]}"
11138         echo "df  output : ${df[*]}"
11139
11140         for facet in ${ofacets//,/ }; do
11141                 if [ -z $saved_ost_blocks ]; then
11142                         saved_ost_blocks=$(do_facet $facet \
11143                                 lctl get_param -n $ost_param.blocksize)
11144                         echo "OST Blocksize: $saved_ost_blocks"
11145                 fi
11146                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11147                 do_facet $facet zfs set recordsize=32768 $ost
11148         done
11149
11150         # BS too small. Sufficient for functional testing.
11151         for facet in ${mfacets//,/ }; do
11152                 if [ -z $saved_mdt_blocks ]; then
11153                         saved_mdt_blocks=$(do_facet $facet \
11154                                 lctl get_param -n $mdt_param.blocksize)
11155                         echo "MDT Blocksize: $saved_mdt_blocks"
11156                 fi
11157                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11158                 do_facet $facet zfs set recordsize=32768 $mdt
11159         done
11160
11161         # Give new values chance to reflect change
11162         sleep 2
11163
11164         echo "After recordsize change"
11165         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11166         df_after=($(df -h | grep "/mnt/lustre"$))
11167
11168         # For checking.
11169         echo "lfs output : ${lfs_df_after[*]}"
11170         echo "df  output : ${df_after[*]}"
11171
11172         # Verify lfs df
11173         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11174                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11175         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11176                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11177         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11178                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11179
11180         # Verify df
11181         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11182                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11183         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11184                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11185         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11186                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11187
11188         # Restore MDT recordize back to original
11189         for facet in ${mfacets//,/ }; do
11190                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11191                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11192         done
11193
11194         # Restore OST recordize back to original
11195         for facet in ${ofacets//,/ }; do
11196                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11197                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11198         done
11199
11200         return 0
11201 }
11202 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11203
11204 test_105a() {
11205         # doesn't work on 2.4 kernels
11206         touch $DIR/$tfile
11207         if $(flock_is_enabled); then
11208                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11209         else
11210                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11211         fi
11212         rm -f $DIR/$tfile
11213 }
11214 run_test 105a "flock when mounted without -o flock test ========"
11215
11216 test_105b() {
11217         touch $DIR/$tfile
11218         if $(flock_is_enabled); then
11219                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11220         else
11221                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11222         fi
11223         rm -f $DIR/$tfile
11224 }
11225 run_test 105b "fcntl when mounted without -o flock test ========"
11226
11227 test_105c() {
11228         touch $DIR/$tfile
11229         if $(flock_is_enabled); then
11230                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11231         else
11232                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11233         fi
11234         rm -f $DIR/$tfile
11235 }
11236 run_test 105c "lockf when mounted without -o flock test"
11237
11238 test_105d() { # bug 15924
11239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11240
11241         test_mkdir $DIR/$tdir
11242         flock_is_enabled || skip_env "mount w/o flock enabled"
11243         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11244         $LCTL set_param fail_loc=0x80000315
11245         flocks_test 2 $DIR/$tdir
11246 }
11247 run_test 105d "flock race (should not freeze) ========"
11248
11249 test_105e() { # bug 22660 && 22040
11250         flock_is_enabled || skip_env "mount w/o flock enabled"
11251
11252         touch $DIR/$tfile
11253         flocks_test 3 $DIR/$tfile
11254 }
11255 run_test 105e "Two conflicting flocks from same process"
11256
11257 test_106() { #bug 10921
11258         test_mkdir $DIR/$tdir
11259         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11260         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11261 }
11262 run_test 106 "attempt exec of dir followed by chown of that dir"
11263
11264 test_107() {
11265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11266
11267         CDIR=`pwd`
11268         local file=core
11269
11270         cd $DIR
11271         rm -f $file
11272
11273         local save_pattern=$(sysctl -n kernel.core_pattern)
11274         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11275         sysctl -w kernel.core_pattern=$file
11276         sysctl -w kernel.core_uses_pid=0
11277
11278         ulimit -c unlimited
11279         sleep 60 &
11280         SLEEPPID=$!
11281
11282         sleep 1
11283
11284         kill -s 11 $SLEEPPID
11285         wait $SLEEPPID
11286         if [ -e $file ]; then
11287                 size=`stat -c%s $file`
11288                 [ $size -eq 0 ] && error "Fail to create core file $file"
11289         else
11290                 error "Fail to create core file $file"
11291         fi
11292         rm -f $file
11293         sysctl -w kernel.core_pattern=$save_pattern
11294         sysctl -w kernel.core_uses_pid=$save_uses_pid
11295         cd $CDIR
11296 }
11297 run_test 107 "Coredump on SIG"
11298
11299 test_110() {
11300         test_mkdir $DIR/$tdir
11301         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11302         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11303                 error "mkdir with 256 char should fail, but did not"
11304         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11305                 error "create with 255 char failed"
11306         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11307                 error "create with 256 char should fail, but did not"
11308
11309         ls -l $DIR/$tdir
11310         rm -rf $DIR/$tdir
11311 }
11312 run_test 110 "filename length checking"
11313
11314 #
11315 # Purpose: To verify dynamic thread (OSS) creation.
11316 #
11317 test_115() {
11318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11319         remote_ost_nodsh && skip "remote OST with nodsh"
11320
11321         # Lustre does not stop service threads once they are started.
11322         # Reset number of running threads to default.
11323         stopall
11324         setupall
11325
11326         local OSTIO_pre
11327         local save_params="$TMP/sanity-$TESTNAME.parameters"
11328
11329         # Get ll_ost_io count before I/O
11330         OSTIO_pre=$(do_facet ost1 \
11331                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11332         # Exit if lustre is not running (ll_ost_io not running).
11333         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11334
11335         echo "Starting with $OSTIO_pre threads"
11336         local thread_max=$((OSTIO_pre * 2))
11337         local rpc_in_flight=$((thread_max * 2))
11338         # Number of I/O Process proposed to be started.
11339         local nfiles
11340         local facets=$(get_facets OST)
11341
11342         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11343         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11344
11345         # Set in_flight to $rpc_in_flight
11346         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11347                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11348         nfiles=${rpc_in_flight}
11349         # Set ost thread_max to $thread_max
11350         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11351
11352         # 5 Minutes should be sufficient for max number of OSS
11353         # threads(thread_max) to be created.
11354         local timeout=300
11355
11356         # Start I/O.
11357         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11358         test_mkdir $DIR/$tdir
11359         for i in $(seq $nfiles); do
11360                 local file=$DIR/$tdir/${tfile}-$i
11361                 $LFS setstripe -c -1 -i 0 $file
11362                 ($WTL $file $timeout)&
11363         done
11364
11365         # I/O Started - Wait for thread_started to reach thread_max or report
11366         # error if thread_started is more than thread_max.
11367         echo "Waiting for thread_started to reach thread_max"
11368         local thread_started=0
11369         local end_time=$((SECONDS + timeout))
11370
11371         while [ $SECONDS -le $end_time ] ; do
11372                 echo -n "."
11373                 # Get ost i/o thread_started count.
11374                 thread_started=$(do_facet ost1 \
11375                         "$LCTL get_param \
11376                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11377                 # Break out if thread_started is equal/greater than thread_max
11378                 if [[ $thread_started -ge $thread_max ]]; then
11379                         echo ll_ost_io thread_started $thread_started, \
11380                                 equal/greater than thread_max $thread_max
11381                         break
11382                 fi
11383                 sleep 1
11384         done
11385
11386         # Cleanup - We have the numbers, Kill i/o jobs if running.
11387         jobcount=($(jobs -p))
11388         for i in $(seq 0 $((${#jobcount[@]}-1)))
11389         do
11390                 kill -9 ${jobcount[$i]}
11391                 if [ $? -ne 0 ] ; then
11392                         echo Warning: \
11393                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11394                 fi
11395         done
11396
11397         # Cleanup files left by WTL binary.
11398         for i in $(seq $nfiles); do
11399                 local file=$DIR/$tdir/${tfile}-$i
11400                 rm -rf $file
11401                 if [ $? -ne 0 ] ; then
11402                         echo "Warning: Failed to delete file $file"
11403                 fi
11404         done
11405
11406         restore_lustre_params <$save_params
11407         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11408
11409         # Error out if no new thread has started or Thread started is greater
11410         # than thread max.
11411         if [[ $thread_started -le $OSTIO_pre ||
11412                         $thread_started -gt $thread_max ]]; then
11413                 error "ll_ost_io: thread_started $thread_started" \
11414                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11415                       "No new thread started or thread started greater " \
11416                       "than thread_max."
11417         fi
11418 }
11419 run_test 115 "verify dynamic thread creation===================="
11420
11421 free_min_max () {
11422         wait_delete_completed
11423         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11424         echo "OST kbytes available: ${AVAIL[@]}"
11425         MAXV=${AVAIL[0]}
11426         MAXI=0
11427         MINV=${AVAIL[0]}
11428         MINI=0
11429         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11430                 #echo OST $i: ${AVAIL[i]}kb
11431                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11432                         MAXV=${AVAIL[i]}
11433                         MAXI=$i
11434                 fi
11435                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11436                         MINV=${AVAIL[i]}
11437                         MINI=$i
11438                 fi
11439         done
11440         echo "Min free space: OST $MINI: $MINV"
11441         echo "Max free space: OST $MAXI: $MAXV"
11442 }
11443
11444 test_116a() { # was previously test_116()
11445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11446         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11447         remote_mds_nodsh && skip "remote MDS with nodsh"
11448
11449         echo -n "Free space priority "
11450         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11451                 head -n1
11452         declare -a AVAIL
11453         free_min_max
11454
11455         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11456         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11457         trap simple_cleanup_common EXIT
11458
11459         # Check if we need to generate uneven OSTs
11460         test_mkdir -p $DIR/$tdir/OST${MINI}
11461         local FILL=$((MINV / 4))
11462         local DIFF=$((MAXV - MINV))
11463         local DIFF2=$((DIFF * 100 / MINV))
11464
11465         local threshold=$(do_facet $SINGLEMDS \
11466                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11467         threshold=${threshold%%%}
11468         echo -n "Check for uneven OSTs: "
11469         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11470
11471         if [[ $DIFF2 -gt $threshold ]]; then
11472                 echo "ok"
11473                 echo "Don't need to fill OST$MINI"
11474         else
11475                 # generate uneven OSTs. Write 2% over the QOS threshold value
11476                 echo "no"
11477                 DIFF=$((threshold - DIFF2 + 2))
11478                 DIFF2=$((MINV * DIFF / 100))
11479                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11480                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11481                         error "setstripe failed"
11482                 DIFF=$((DIFF2 / 2048))
11483                 i=0
11484                 while [ $i -lt $DIFF ]; do
11485                         i=$((i + 1))
11486                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11487                                 bs=2M count=1 2>/dev/null
11488                         echo -n .
11489                 done
11490                 echo .
11491                 sync
11492                 sleep_maxage
11493                 free_min_max
11494         fi
11495
11496         DIFF=$((MAXV - MINV))
11497         DIFF2=$((DIFF * 100 / MINV))
11498         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11499         if [ $DIFF2 -gt $threshold ]; then
11500                 echo "ok"
11501         else
11502                 echo "failed - QOS mode won't be used"
11503                 simple_cleanup_common
11504                 skip "QOS imbalance criteria not met"
11505         fi
11506
11507         MINI1=$MINI
11508         MINV1=$MINV
11509         MAXI1=$MAXI
11510         MAXV1=$MAXV
11511
11512         # now fill using QOS
11513         $LFS setstripe -c 1 $DIR/$tdir
11514         FILL=$((FILL / 200))
11515         if [ $FILL -gt 600 ]; then
11516                 FILL=600
11517         fi
11518         echo "writing $FILL files to QOS-assigned OSTs"
11519         i=0
11520         while [ $i -lt $FILL ]; do
11521                 i=$((i + 1))
11522                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11523                         count=1 2>/dev/null
11524                 echo -n .
11525         done
11526         echo "wrote $i 200k files"
11527         sync
11528         sleep_maxage
11529
11530         echo "Note: free space may not be updated, so measurements might be off"
11531         free_min_max
11532         DIFF2=$((MAXV - MINV))
11533         echo "free space delta: orig $DIFF final $DIFF2"
11534         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11535         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11536         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11537         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11538         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11539         if [[ $DIFF -gt 0 ]]; then
11540                 FILL=$((DIFF2 * 100 / DIFF - 100))
11541                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11542         fi
11543
11544         # Figure out which files were written where
11545         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11546                awk '/'$MINI1': / {print $2; exit}')
11547         echo $UUID
11548         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11549         echo "$MINC files created on smaller OST $MINI1"
11550         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11551                awk '/'$MAXI1': / {print $2; exit}')
11552         echo $UUID
11553         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11554         echo "$MAXC files created on larger OST $MAXI1"
11555         if [[ $MINC -gt 0 ]]; then
11556                 FILL=$((MAXC * 100 / MINC - 100))
11557                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11558         fi
11559         [[ $MAXC -gt $MINC ]] ||
11560                 error_ignore LU-9 "stripe QOS didn't balance free space"
11561         simple_cleanup_common
11562 }
11563 run_test 116a "stripe QOS: free space balance ==================="
11564
11565 test_116b() { # LU-2093
11566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11567         remote_mds_nodsh && skip "remote MDS with nodsh"
11568
11569 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11570         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11571                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11572         [ -z "$old_rr" ] && skip "no QOS"
11573         do_facet $SINGLEMDS lctl set_param \
11574                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11575         mkdir -p $DIR/$tdir
11576         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11577         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11578         do_facet $SINGLEMDS lctl set_param fail_loc=0
11579         rm -rf $DIR/$tdir
11580         do_facet $SINGLEMDS lctl set_param \
11581                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11582 }
11583 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11584
11585 test_117() # bug 10891
11586 {
11587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11588
11589         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11590         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11591         lctl set_param fail_loc=0x21e
11592         > $DIR/$tfile || error "truncate failed"
11593         lctl set_param fail_loc=0
11594         echo "Truncate succeeded."
11595         rm -f $DIR/$tfile
11596 }
11597 run_test 117 "verify osd extend =========="
11598
11599 NO_SLOW_RESENDCOUNT=4
11600 export OLD_RESENDCOUNT=""
11601 set_resend_count () {
11602         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11603         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11604         lctl set_param -n $PROC_RESENDCOUNT $1
11605         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11606 }
11607
11608 # for reduce test_118* time (b=14842)
11609 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11610
11611 # Reset async IO behavior after error case
11612 reset_async() {
11613         FILE=$DIR/reset_async
11614
11615         # Ensure all OSCs are cleared
11616         $LFS setstripe -c -1 $FILE
11617         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11618         sync
11619         rm $FILE
11620 }
11621
11622 test_118a() #bug 11710
11623 {
11624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11625
11626         reset_async
11627
11628         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11629         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11630         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11631
11632         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11633                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11634                 return 1;
11635         fi
11636         rm -f $DIR/$tfile
11637 }
11638 run_test 118a "verify O_SYNC works =========="
11639
11640 test_118b()
11641 {
11642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11643         remote_ost_nodsh && skip "remote OST with nodsh"
11644
11645         reset_async
11646
11647         #define OBD_FAIL_SRV_ENOENT 0x217
11648         set_nodes_failloc "$(osts_nodes)" 0x217
11649         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11650         RC=$?
11651         set_nodes_failloc "$(osts_nodes)" 0
11652         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11653         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11654                     grep -c writeback)
11655
11656         if [[ $RC -eq 0 ]]; then
11657                 error "Must return error due to dropped pages, rc=$RC"
11658                 return 1;
11659         fi
11660
11661         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11662                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11663                 return 1;
11664         fi
11665
11666         echo "Dirty pages not leaked on ENOENT"
11667
11668         # Due to the above error the OSC will issue all RPCs syncronously
11669         # until a subsequent RPC completes successfully without error.
11670         $MULTIOP $DIR/$tfile Ow4096yc
11671         rm -f $DIR/$tfile
11672
11673         return 0
11674 }
11675 run_test 118b "Reclaim dirty pages on fatal error =========="
11676
11677 test_118c()
11678 {
11679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11680
11681         # for 118c, restore the original resend count, LU-1940
11682         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11683                                 set_resend_count $OLD_RESENDCOUNT
11684         remote_ost_nodsh && skip "remote OST with nodsh"
11685
11686         reset_async
11687
11688         #define OBD_FAIL_OST_EROFS               0x216
11689         set_nodes_failloc "$(osts_nodes)" 0x216
11690
11691         # multiop should block due to fsync until pages are written
11692         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11693         MULTIPID=$!
11694         sleep 1
11695
11696         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11697                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11698         fi
11699
11700         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11701                     grep -c writeback)
11702         if [[ $WRITEBACK -eq 0 ]]; then
11703                 error "No page in writeback, writeback=$WRITEBACK"
11704         fi
11705
11706         set_nodes_failloc "$(osts_nodes)" 0
11707         wait $MULTIPID
11708         RC=$?
11709         if [[ $RC -ne 0 ]]; then
11710                 error "Multiop fsync failed, rc=$RC"
11711         fi
11712
11713         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11714         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11715                     grep -c writeback)
11716         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11717                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11718         fi
11719
11720         rm -f $DIR/$tfile
11721         echo "Dirty pages flushed via fsync on EROFS"
11722         return 0
11723 }
11724 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11725
11726 # continue to use small resend count to reduce test_118* time (b=14842)
11727 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11728
11729 test_118d()
11730 {
11731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11732         remote_ost_nodsh && skip "remote OST with nodsh"
11733
11734         reset_async
11735
11736         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11737         set_nodes_failloc "$(osts_nodes)" 0x214
11738         # multiop should block due to fsync until pages are written
11739         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11740         MULTIPID=$!
11741         sleep 1
11742
11743         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11744                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11745         fi
11746
11747         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11748                     grep -c writeback)
11749         if [[ $WRITEBACK -eq 0 ]]; then
11750                 error "No page in writeback, writeback=$WRITEBACK"
11751         fi
11752
11753         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11754         set_nodes_failloc "$(osts_nodes)" 0
11755
11756         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11757         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11758                     grep -c writeback)
11759         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11760                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11761         fi
11762
11763         rm -f $DIR/$tfile
11764         echo "Dirty pages gaurenteed flushed via fsync"
11765         return 0
11766 }
11767 run_test 118d "Fsync validation inject a delay of the bulk =========="
11768
11769 test_118f() {
11770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11771
11772         reset_async
11773
11774         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11775         lctl set_param fail_loc=0x8000040a
11776
11777         # Should simulate EINVAL error which is fatal
11778         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11779         RC=$?
11780         if [[ $RC -eq 0 ]]; then
11781                 error "Must return error due to dropped pages, rc=$RC"
11782         fi
11783
11784         lctl set_param fail_loc=0x0
11785
11786         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11787         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11788         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11789                     grep -c writeback)
11790         if [[ $LOCKED -ne 0 ]]; then
11791                 error "Locked pages remain in cache, locked=$LOCKED"
11792         fi
11793
11794         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11795                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11796         fi
11797
11798         rm -f $DIR/$tfile
11799         echo "No pages locked after fsync"
11800
11801         reset_async
11802         return 0
11803 }
11804 run_test 118f "Simulate unrecoverable OSC side error =========="
11805
11806 test_118g() {
11807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11808
11809         reset_async
11810
11811         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11812         lctl set_param fail_loc=0x406
11813
11814         # simulate local -ENOMEM
11815         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11816         RC=$?
11817
11818         lctl set_param fail_loc=0
11819         if [[ $RC -eq 0 ]]; then
11820                 error "Must return error due to dropped pages, rc=$RC"
11821         fi
11822
11823         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11824         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11825         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11826                         grep -c writeback)
11827         if [[ $LOCKED -ne 0 ]]; then
11828                 error "Locked pages remain in cache, locked=$LOCKED"
11829         fi
11830
11831         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11832                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11833         fi
11834
11835         rm -f $DIR/$tfile
11836         echo "No pages locked after fsync"
11837
11838         reset_async
11839         return 0
11840 }
11841 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11842
11843 test_118h() {
11844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11845         remote_ost_nodsh && skip "remote OST with nodsh"
11846
11847         reset_async
11848
11849         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11850         set_nodes_failloc "$(osts_nodes)" 0x20e
11851         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11852         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11853         RC=$?
11854
11855         set_nodes_failloc "$(osts_nodes)" 0
11856         if [[ $RC -eq 0 ]]; then
11857                 error "Must return error due to dropped pages, rc=$RC"
11858         fi
11859
11860         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11861         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11862         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11863                     grep -c writeback)
11864         if [[ $LOCKED -ne 0 ]]; then
11865                 error "Locked pages remain in cache, locked=$LOCKED"
11866         fi
11867
11868         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11869                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11870         fi
11871
11872         rm -f $DIR/$tfile
11873         echo "No pages locked after fsync"
11874
11875         return 0
11876 }
11877 run_test 118h "Verify timeout in handling recoverables errors  =========="
11878
11879 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11880
11881 test_118i() {
11882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11883         remote_ost_nodsh && skip "remote OST with nodsh"
11884
11885         reset_async
11886
11887         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11888         set_nodes_failloc "$(osts_nodes)" 0x20e
11889
11890         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11891         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11892         PID=$!
11893         sleep 5
11894         set_nodes_failloc "$(osts_nodes)" 0
11895
11896         wait $PID
11897         RC=$?
11898         if [[ $RC -ne 0 ]]; then
11899                 error "got error, but should be not, rc=$RC"
11900         fi
11901
11902         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11903         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11904         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11905         if [[ $LOCKED -ne 0 ]]; then
11906                 error "Locked pages remain in cache, locked=$LOCKED"
11907         fi
11908
11909         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11910                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11911         fi
11912
11913         rm -f $DIR/$tfile
11914         echo "No pages locked after fsync"
11915
11916         return 0
11917 }
11918 run_test 118i "Fix error before timeout in recoverable error  =========="
11919
11920 [ "$SLOW" = "no" ] && set_resend_count 4
11921
11922 test_118j() {
11923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11924         remote_ost_nodsh && skip "remote OST with nodsh"
11925
11926         reset_async
11927
11928         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11929         set_nodes_failloc "$(osts_nodes)" 0x220
11930
11931         # return -EIO from OST
11932         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11933         RC=$?
11934         set_nodes_failloc "$(osts_nodes)" 0x0
11935         if [[ $RC -eq 0 ]]; then
11936                 error "Must return error due to dropped pages, rc=$RC"
11937         fi
11938
11939         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11940         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11941         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11942         if [[ $LOCKED -ne 0 ]]; then
11943                 error "Locked pages remain in cache, locked=$LOCKED"
11944         fi
11945
11946         # in recoverable error on OST we want resend and stay until it finished
11947         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11948                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11949         fi
11950
11951         rm -f $DIR/$tfile
11952         echo "No pages locked after fsync"
11953
11954         return 0
11955 }
11956 run_test 118j "Simulate unrecoverable OST side error =========="
11957
11958 test_118k()
11959 {
11960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11961         remote_ost_nodsh && skip "remote OSTs with nodsh"
11962
11963         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11964         set_nodes_failloc "$(osts_nodes)" 0x20e
11965         test_mkdir $DIR/$tdir
11966
11967         for ((i=0;i<10;i++)); do
11968                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11969                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11970                 SLEEPPID=$!
11971                 sleep 0.500s
11972                 kill $SLEEPPID
11973                 wait $SLEEPPID
11974         done
11975
11976         set_nodes_failloc "$(osts_nodes)" 0
11977         rm -rf $DIR/$tdir
11978 }
11979 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11980
11981 test_118l() # LU-646
11982 {
11983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11984
11985         test_mkdir $DIR/$tdir
11986         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11987         rm -rf $DIR/$tdir
11988 }
11989 run_test 118l "fsync dir"
11990
11991 test_118m() # LU-3066
11992 {
11993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11994
11995         test_mkdir $DIR/$tdir
11996         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11997         rm -rf $DIR/$tdir
11998 }
11999 run_test 118m "fdatasync dir ========="
12000
12001 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12002
12003 test_118n()
12004 {
12005         local begin
12006         local end
12007
12008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12009         remote_ost_nodsh && skip "remote OSTs with nodsh"
12010
12011         # Sleep to avoid a cached response.
12012         #define OBD_STATFS_CACHE_SECONDS 1
12013         sleep 2
12014
12015         # Inject a 10 second delay in the OST_STATFS handler.
12016         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12017         set_nodes_failloc "$(osts_nodes)" 0x242
12018
12019         begin=$SECONDS
12020         stat --file-system $MOUNT > /dev/null
12021         end=$SECONDS
12022
12023         set_nodes_failloc "$(osts_nodes)" 0
12024
12025         if ((end - begin > 20)); then
12026             error "statfs took $((end - begin)) seconds, expected 10"
12027         fi
12028 }
12029 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12030
12031 test_119a() # bug 11737
12032 {
12033         BSIZE=$((512 * 1024))
12034         directio write $DIR/$tfile 0 1 $BSIZE
12035         # We ask to read two blocks, which is more than a file size.
12036         # directio will indicate an error when requested and actual
12037         # sizes aren't equeal (a normal situation in this case) and
12038         # print actual read amount.
12039         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12040         if [ "$NOB" != "$BSIZE" ]; then
12041                 error "read $NOB bytes instead of $BSIZE"
12042         fi
12043         rm -f $DIR/$tfile
12044 }
12045 run_test 119a "Short directIO read must return actual read amount"
12046
12047 test_119b() # bug 11737
12048 {
12049         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12050
12051         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12052         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12053         sync
12054         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12055                 error "direct read failed"
12056         rm -f $DIR/$tfile
12057 }
12058 run_test 119b "Sparse directIO read must return actual read amount"
12059
12060 test_119c() # bug 13099
12061 {
12062         BSIZE=1048576
12063         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12064         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12065         rm -f $DIR/$tfile
12066 }
12067 run_test 119c "Testing for direct read hitting hole"
12068
12069 test_119d() # bug 15950
12070 {
12071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12072
12073         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12074         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12075         BSIZE=1048576
12076         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12077         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12078         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12079         lctl set_param fail_loc=0x40d
12080         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12081         pid_dio=$!
12082         sleep 1
12083         cat $DIR/$tfile > /dev/null &
12084         lctl set_param fail_loc=0
12085         pid_reads=$!
12086         wait $pid_dio
12087         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12088         sleep 2
12089         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12090         error "the read rpcs have not completed in 2s"
12091         rm -f $DIR/$tfile
12092         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12093 }
12094 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12095
12096 test_120a() {
12097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12098         remote_mds_nodsh && skip "remote MDS with nodsh"
12099         test_mkdir -i0 -c1 $DIR/$tdir
12100         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12101                 skip_env "no early lock cancel on server"
12102
12103         lru_resize_disable mdc
12104         lru_resize_disable osc
12105         cancel_lru_locks mdc
12106         # asynchronous object destroy at MDT could cause bl ast to client
12107         cancel_lru_locks osc
12108
12109         stat $DIR/$tdir > /dev/null
12110         can1=$(do_facet mds1 \
12111                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12112                awk '/ldlm_cancel/ {print $2}')
12113         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12114                awk '/ldlm_bl_callback/ {print $2}')
12115         test_mkdir -i0 -c1 $DIR/$tdir/d1
12116         can2=$(do_facet mds1 \
12117                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12118                awk '/ldlm_cancel/ {print $2}')
12119         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12120                awk '/ldlm_bl_callback/ {print $2}')
12121         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12122         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12123         lru_resize_enable mdc
12124         lru_resize_enable osc
12125 }
12126 run_test 120a "Early Lock Cancel: mkdir test"
12127
12128 test_120b() {
12129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12130         remote_mds_nodsh && skip "remote MDS with nodsh"
12131         test_mkdir $DIR/$tdir
12132         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12133                 skip_env "no early lock cancel on server"
12134
12135         lru_resize_disable mdc
12136         lru_resize_disable osc
12137         cancel_lru_locks mdc
12138         stat $DIR/$tdir > /dev/null
12139         can1=$(do_facet $SINGLEMDS \
12140                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12141                awk '/ldlm_cancel/ {print $2}')
12142         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12143                awk '/ldlm_bl_callback/ {print $2}')
12144         touch $DIR/$tdir/f1
12145         can2=$(do_facet $SINGLEMDS \
12146                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12147                awk '/ldlm_cancel/ {print $2}')
12148         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12149                awk '/ldlm_bl_callback/ {print $2}')
12150         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12151         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12152         lru_resize_enable mdc
12153         lru_resize_enable osc
12154 }
12155 run_test 120b "Early Lock Cancel: create test"
12156
12157 test_120c() {
12158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12159         remote_mds_nodsh && skip "remote MDS with nodsh"
12160         test_mkdir -i0 -c1 $DIR/$tdir
12161         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12162                 skip "no early lock cancel on server"
12163
12164         lru_resize_disable mdc
12165         lru_resize_disable osc
12166         test_mkdir -i0 -c1 $DIR/$tdir/d1
12167         test_mkdir -i0 -c1 $DIR/$tdir/d2
12168         touch $DIR/$tdir/d1/f1
12169         cancel_lru_locks mdc
12170         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12171         can1=$(do_facet mds1 \
12172                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12173                awk '/ldlm_cancel/ {print $2}')
12174         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12175                awk '/ldlm_bl_callback/ {print $2}')
12176         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12177         can2=$(do_facet mds1 \
12178                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12179                awk '/ldlm_cancel/ {print $2}')
12180         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12181                awk '/ldlm_bl_callback/ {print $2}')
12182         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12183         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12184         lru_resize_enable mdc
12185         lru_resize_enable osc
12186 }
12187 run_test 120c "Early Lock Cancel: link test"
12188
12189 test_120d() {
12190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12191         remote_mds_nodsh && skip "remote MDS with nodsh"
12192         test_mkdir -i0 -c1 $DIR/$tdir
12193         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12194                 skip_env "no early lock cancel on server"
12195
12196         lru_resize_disable mdc
12197         lru_resize_disable osc
12198         touch $DIR/$tdir
12199         cancel_lru_locks mdc
12200         stat $DIR/$tdir > /dev/null
12201         can1=$(do_facet mds1 \
12202                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12203                awk '/ldlm_cancel/ {print $2}')
12204         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12205                awk '/ldlm_bl_callback/ {print $2}')
12206         chmod a+x $DIR/$tdir
12207         can2=$(do_facet mds1 \
12208                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12209                awk '/ldlm_cancel/ {print $2}')
12210         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12211                awk '/ldlm_bl_callback/ {print $2}')
12212         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12213         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12214         lru_resize_enable mdc
12215         lru_resize_enable osc
12216 }
12217 run_test 120d "Early Lock Cancel: setattr test"
12218
12219 test_120e() {
12220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12221         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12222                 skip_env "no early lock cancel on server"
12223         remote_mds_nodsh && skip "remote MDS with nodsh"
12224
12225         local dlmtrace_set=false
12226
12227         test_mkdir -i0 -c1 $DIR/$tdir
12228         lru_resize_disable mdc
12229         lru_resize_disable osc
12230         ! $LCTL get_param debug | grep -q dlmtrace &&
12231                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12232         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12233         cancel_lru_locks mdc
12234         cancel_lru_locks osc
12235         dd if=$DIR/$tdir/f1 of=/dev/null
12236         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12237         # XXX client can not do early lock cancel of OST lock
12238         # during unlink (LU-4206), so cancel osc lock now.
12239         sleep 2
12240         cancel_lru_locks osc
12241         can1=$(do_facet mds1 \
12242                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12243                awk '/ldlm_cancel/ {print $2}')
12244         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12245                awk '/ldlm_bl_callback/ {print $2}')
12246         unlink $DIR/$tdir/f1
12247         sleep 5
12248         can2=$(do_facet mds1 \
12249                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12250                awk '/ldlm_cancel/ {print $2}')
12251         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12252                awk '/ldlm_bl_callback/ {print $2}')
12253         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12254                 $LCTL dk $TMP/cancel.debug.txt
12255         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12256                 $LCTL dk $TMP/blocking.debug.txt
12257         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12258         lru_resize_enable mdc
12259         lru_resize_enable osc
12260 }
12261 run_test 120e "Early Lock Cancel: unlink test"
12262
12263 test_120f() {
12264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12265         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12266                 skip_env "no early lock cancel on server"
12267         remote_mds_nodsh && skip "remote MDS with nodsh"
12268
12269         test_mkdir -i0 -c1 $DIR/$tdir
12270         lru_resize_disable mdc
12271         lru_resize_disable osc
12272         test_mkdir -i0 -c1 $DIR/$tdir/d1
12273         test_mkdir -i0 -c1 $DIR/$tdir/d2
12274         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12275         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12276         cancel_lru_locks mdc
12277         cancel_lru_locks osc
12278         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12279         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12280         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12281         # XXX client can not do early lock cancel of OST lock
12282         # during rename (LU-4206), so cancel osc lock now.
12283         sleep 2
12284         cancel_lru_locks osc
12285         can1=$(do_facet mds1 \
12286                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12287                awk '/ldlm_cancel/ {print $2}')
12288         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12289                awk '/ldlm_bl_callback/ {print $2}')
12290         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12291         sleep 5
12292         can2=$(do_facet mds1 \
12293                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12294                awk '/ldlm_cancel/ {print $2}')
12295         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12296                awk '/ldlm_bl_callback/ {print $2}')
12297         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12298         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12299         lru_resize_enable mdc
12300         lru_resize_enable osc
12301 }
12302 run_test 120f "Early Lock Cancel: rename test"
12303
12304 test_120g() {
12305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12306         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12307                 skip_env "no early lock cancel on server"
12308         remote_mds_nodsh && skip "remote MDS with nodsh"
12309
12310         lru_resize_disable mdc
12311         lru_resize_disable osc
12312         count=10000
12313         echo create $count files
12314         test_mkdir $DIR/$tdir
12315         cancel_lru_locks mdc
12316         cancel_lru_locks osc
12317         t0=$(date +%s)
12318
12319         can0=$(do_facet $SINGLEMDS \
12320                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12321                awk '/ldlm_cancel/ {print $2}')
12322         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12323                awk '/ldlm_bl_callback/ {print $2}')
12324         createmany -o $DIR/$tdir/f $count
12325         sync
12326         can1=$(do_facet $SINGLEMDS \
12327                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12328                awk '/ldlm_cancel/ {print $2}')
12329         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12330                awk '/ldlm_bl_callback/ {print $2}')
12331         t1=$(date +%s)
12332         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12333         echo rm $count files
12334         rm -r $DIR/$tdir
12335         sync
12336         can2=$(do_facet $SINGLEMDS \
12337                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12338                awk '/ldlm_cancel/ {print $2}')
12339         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12340                awk '/ldlm_bl_callback/ {print $2}')
12341         t2=$(date +%s)
12342         echo total: $count removes in $((t2-t1))
12343         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12344         sleep 2
12345         # wait for commitment of removal
12346         lru_resize_enable mdc
12347         lru_resize_enable osc
12348 }
12349 run_test 120g "Early Lock Cancel: performance test"
12350
12351 test_121() { #bug #10589
12352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12353
12354         rm -rf $DIR/$tfile
12355         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12356 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12357         lctl set_param fail_loc=0x310
12358         cancel_lru_locks osc > /dev/null
12359         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12360         lctl set_param fail_loc=0
12361         [[ $reads -eq $writes ]] ||
12362                 error "read $reads blocks, must be $writes blocks"
12363 }
12364 run_test 121 "read cancel race ========="
12365
12366 test_123a_base() { # was test 123, statahead(bug 11401)
12367         local lsx="$1"
12368
12369         SLOWOK=0
12370         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12371                 log "testing UP system. Performance may be lower than expected."
12372                 SLOWOK=1
12373         fi
12374
12375         rm -rf $DIR/$tdir
12376         test_mkdir $DIR/$tdir
12377         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12378         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12379         MULT=10
12380         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12381                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12382
12383                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12384                 lctl set_param -n llite.*.statahead_max 0
12385                 lctl get_param llite.*.statahead_max
12386                 cancel_lru_locks mdc
12387                 cancel_lru_locks osc
12388                 stime=$(date +%s)
12389                 time $lsx $DIR/$tdir | wc -l
12390                 etime=$(date +%s)
12391                 delta=$((etime - stime))
12392                 log "$lsx $i files without statahead: $delta sec"
12393                 lctl set_param llite.*.statahead_max=$max
12394
12395                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12396                         grep "statahead wrong:" | awk '{print $3}')
12397                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12398                 cancel_lru_locks mdc
12399                 cancel_lru_locks osc
12400                 stime=$(date +%s)
12401                 time $lsx $DIR/$tdir | wc -l
12402                 etime=$(date +%s)
12403                 delta_sa=$((etime - stime))
12404                 log "$lsx $i files with statahead: $delta_sa sec"
12405                 lctl get_param -n llite.*.statahead_stats
12406                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12407                         grep "statahead wrong:" | awk '{print $3}')
12408
12409                 [[ $swrong -lt $ewrong ]] &&
12410                         log "statahead was stopped, maybe too many locks held!"
12411                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12412
12413                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12414                         max=$(lctl get_param -n llite.*.statahead_max |
12415                                 head -n 1)
12416                         lctl set_param -n llite.*.statahead_max 0
12417                         lctl get_param llite.*.statahead_max
12418                         cancel_lru_locks mdc
12419                         cancel_lru_locks osc
12420                         stime=$(date +%s)
12421                         time $lsx $DIR/$tdir | wc -l
12422                         etime=$(date +%s)
12423                         delta=$((etime - stime))
12424                         log "$lsx $i files again without statahead: $delta sec"
12425                         lctl set_param llite.*.statahead_max=$max
12426                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12427                                 if [  $SLOWOK -eq 0 ]; then
12428                                         error "$lsx $i files is slower with statahead!"
12429                                 else
12430                                         log "$lsx $i files is slower with statahead!"
12431                                 fi
12432                                 break
12433                         fi
12434                 fi
12435
12436                 [ $delta -gt 20 ] && break
12437                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12438                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12439         done
12440         log "$lsx done"
12441
12442         stime=$(date +%s)
12443         rm -r $DIR/$tdir
12444         sync
12445         etime=$(date +%s)
12446         delta=$((etime - stime))
12447         log "rm -r $DIR/$tdir/: $delta seconds"
12448         log "rm done"
12449         lctl get_param -n llite.*.statahead_stats
12450 }
12451
12452 test_123aa() {
12453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12454
12455         test_123a_base "ls -l"
12456 }
12457 run_test 123aa "verify statahead work"
12458
12459 test_123ab() {
12460         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12461
12462         statx_supported || skip_env "Test must be statx() syscall supported"
12463
12464         test_123a_base "$STATX -l"
12465 }
12466 run_test 123ab "verify statahead work by using statx"
12467
12468 test_123ac() {
12469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12470
12471         statx_supported || skip_env "Test must be statx() syscall supported"
12472
12473         local rpcs_before
12474         local rpcs_after
12475         local agl_before
12476         local agl_after
12477
12478         cancel_lru_locks $OSC
12479         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12480         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12481                 awk '/agl.total:/ {print $3}')
12482         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12483         test_123a_base "$STATX --cached=always -D"
12484         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12485                 awk '/agl.total:/ {print $3}')
12486         [ $agl_before -eq $agl_after ] ||
12487                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12488         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12489         [ $rpcs_after -eq $rpcs_before ] ||
12490                 error "$STATX should not send glimpse RPCs to $OSC"
12491 }
12492 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12493
12494 test_123b () { # statahead(bug 15027)
12495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12496
12497         test_mkdir $DIR/$tdir
12498         createmany -o $DIR/$tdir/$tfile-%d 1000
12499
12500         cancel_lru_locks mdc
12501         cancel_lru_locks osc
12502
12503 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12504         lctl set_param fail_loc=0x80000803
12505         ls -lR $DIR/$tdir > /dev/null
12506         log "ls done"
12507         lctl set_param fail_loc=0x0
12508         lctl get_param -n llite.*.statahead_stats
12509         rm -r $DIR/$tdir
12510         sync
12511
12512 }
12513 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12514
12515 test_123c() {
12516         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12517
12518         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12519         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12520         touch $DIR/$tdir.1/{1..3}
12521         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12522
12523         remount_client $MOUNT
12524
12525         $MULTIOP $DIR/$tdir.0 Q
12526
12527         # let statahead to complete
12528         ls -l $DIR/$tdir.0 > /dev/null
12529
12530         testid=$(echo $TESTNAME | tr '_' ' ')
12531         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12532                 error "statahead warning" || true
12533 }
12534 run_test 123c "Can not initialize inode warning on DNE statahead"
12535
12536 test_124a() {
12537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12538         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12539                 skip_env "no lru resize on server"
12540
12541         local NR=2000
12542
12543         test_mkdir $DIR/$tdir
12544
12545         log "create $NR files at $DIR/$tdir"
12546         createmany -o $DIR/$tdir/f $NR ||
12547                 error "failed to create $NR files in $DIR/$tdir"
12548
12549         cancel_lru_locks mdc
12550         ls -l $DIR/$tdir > /dev/null
12551
12552         local NSDIR=""
12553         local LRU_SIZE=0
12554         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12555                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12556                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12557                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12558                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12559                         log "NSDIR=$NSDIR"
12560                         log "NS=$(basename $NSDIR)"
12561                         break
12562                 fi
12563         done
12564
12565         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12566                 skip "Not enough cached locks created!"
12567         fi
12568         log "LRU=$LRU_SIZE"
12569
12570         local SLEEP=30
12571
12572         # We know that lru resize allows one client to hold $LIMIT locks
12573         # for 10h. After that locks begin to be killed by client.
12574         local MAX_HRS=10
12575         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12576         log "LIMIT=$LIMIT"
12577         if [ $LIMIT -lt $LRU_SIZE ]; then
12578                 skip "Limit is too small $LIMIT"
12579         fi
12580
12581         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12582         # killing locks. Some time was spent for creating locks. This means
12583         # that up to the moment of sleep finish we must have killed some of
12584         # them (10-100 locks). This depends on how fast ther were created.
12585         # Many of them were touched in almost the same moment and thus will
12586         # be killed in groups.
12587         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12588
12589         # Use $LRU_SIZE_B here to take into account real number of locks
12590         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12591         local LRU_SIZE_B=$LRU_SIZE
12592         log "LVF=$LVF"
12593         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12594         log "OLD_LVF=$OLD_LVF"
12595         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12596
12597         # Let's make sure that we really have some margin. Client checks
12598         # cached locks every 10 sec.
12599         SLEEP=$((SLEEP+20))
12600         log "Sleep ${SLEEP} sec"
12601         local SEC=0
12602         while ((SEC<$SLEEP)); do
12603                 echo -n "..."
12604                 sleep 5
12605                 SEC=$((SEC+5))
12606                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12607                 echo -n "$LRU_SIZE"
12608         done
12609         echo ""
12610         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12611         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12612
12613         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12614                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12615                 unlinkmany $DIR/$tdir/f $NR
12616                 return
12617         }
12618
12619         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12620         log "unlink $NR files at $DIR/$tdir"
12621         unlinkmany $DIR/$tdir/f $NR
12622 }
12623 run_test 124a "lru resize ======================================="
12624
12625 get_max_pool_limit()
12626 {
12627         local limit=$($LCTL get_param \
12628                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12629         local max=0
12630         for l in $limit; do
12631                 if [[ $l -gt $max ]]; then
12632                         max=$l
12633                 fi
12634         done
12635         echo $max
12636 }
12637
12638 test_124b() {
12639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12640         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12641                 skip_env "no lru resize on server"
12642
12643         LIMIT=$(get_max_pool_limit)
12644
12645         NR=$(($(default_lru_size)*20))
12646         if [[ $NR -gt $LIMIT ]]; then
12647                 log "Limit lock number by $LIMIT locks"
12648                 NR=$LIMIT
12649         fi
12650
12651         IFree=$(mdsrate_inodes_available)
12652         if [ $IFree -lt $NR ]; then
12653                 log "Limit lock number by $IFree inodes"
12654                 NR=$IFree
12655         fi
12656
12657         lru_resize_disable mdc
12658         test_mkdir -p $DIR/$tdir/disable_lru_resize
12659
12660         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12661         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12662         cancel_lru_locks mdc
12663         stime=`date +%s`
12664         PID=""
12665         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12666         PID="$PID $!"
12667         sleep 2
12668         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12669         PID="$PID $!"
12670         sleep 2
12671         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12672         PID="$PID $!"
12673         wait $PID
12674         etime=`date +%s`
12675         nolruresize_delta=$((etime-stime))
12676         log "ls -la time: $nolruresize_delta seconds"
12677         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12678         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12679
12680         lru_resize_enable mdc
12681         test_mkdir -p $DIR/$tdir/enable_lru_resize
12682
12683         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12684         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12685         cancel_lru_locks mdc
12686         stime=`date +%s`
12687         PID=""
12688         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12689         PID="$PID $!"
12690         sleep 2
12691         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12692         PID="$PID $!"
12693         sleep 2
12694         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12695         PID="$PID $!"
12696         wait $PID
12697         etime=`date +%s`
12698         lruresize_delta=$((etime-stime))
12699         log "ls -la time: $lruresize_delta seconds"
12700         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12701
12702         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12703                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12704         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12705                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12706         else
12707                 log "lru resize performs the same with no lru resize"
12708         fi
12709         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12710 }
12711 run_test 124b "lru resize (performance test) ======================="
12712
12713 test_124c() {
12714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12715         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12716                 skip_env "no lru resize on server"
12717
12718         # cache ununsed locks on client
12719         local nr=100
12720         cancel_lru_locks mdc
12721         test_mkdir $DIR/$tdir
12722         createmany -o $DIR/$tdir/f $nr ||
12723                 error "failed to create $nr files in $DIR/$tdir"
12724         ls -l $DIR/$tdir > /dev/null
12725
12726         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12727         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12728         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12729         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12730         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12731
12732         # set lru_max_age to 1 sec
12733         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12734         echo "sleep $((recalc_p * 2)) seconds..."
12735         sleep $((recalc_p * 2))
12736
12737         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12738         # restore lru_max_age
12739         $LCTL set_param -n $nsdir.lru_max_age $max_age
12740         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12741         unlinkmany $DIR/$tdir/f $nr
12742 }
12743 run_test 124c "LRUR cancel very aged locks"
12744
12745 test_124d() {
12746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12747         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12748                 skip_env "no lru resize on server"
12749
12750         # cache ununsed locks on client
12751         local nr=100
12752
12753         lru_resize_disable mdc
12754         stack_trap "lru_resize_enable mdc" EXIT
12755
12756         cancel_lru_locks mdc
12757
12758         # asynchronous object destroy at MDT could cause bl ast to client
12759         test_mkdir $DIR/$tdir
12760         createmany -o $DIR/$tdir/f $nr ||
12761                 error "failed to create $nr files in $DIR/$tdir"
12762         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12763
12764         ls -l $DIR/$tdir > /dev/null
12765
12766         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12767         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12768         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12769         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12770
12771         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12772
12773         # set lru_max_age to 1 sec
12774         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12775         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12776
12777         echo "sleep $((recalc_p * 2)) seconds..."
12778         sleep $((recalc_p * 2))
12779
12780         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12781
12782         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12783 }
12784 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12785
12786 test_125() { # 13358
12787         $LCTL get_param -n llite.*.client_type | grep -q local ||
12788                 skip "must run as local client"
12789         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12790                 skip_env "must have acl enabled"
12791         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12792
12793         test_mkdir $DIR/$tdir
12794         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12795         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12796         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12797 }
12798 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12799
12800 test_126() { # bug 12829/13455
12801         $GSS && skip_env "must run as gss disabled"
12802         $LCTL get_param -n llite.*.client_type | grep -q local ||
12803                 skip "must run as local client"
12804         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12805
12806         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12807         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12808         rm -f $DIR/$tfile
12809         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12810 }
12811 run_test 126 "check that the fsgid provided by the client is taken into account"
12812
12813 test_127a() { # bug 15521
12814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12815         local name count samp unit min max sum sumsq
12816
12817         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12818         echo "stats before reset"
12819         $LCTL get_param osc.*.stats
12820         $LCTL set_param osc.*.stats=0
12821         local fsize=$((2048 * 1024))
12822
12823         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12824         cancel_lru_locks osc
12825         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12826
12827         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12828         stack_trap "rm -f $TMP/$tfile.tmp"
12829         while read name count samp unit min max sum sumsq; do
12830                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12831                 [ ! $min ] && error "Missing min value for $name proc entry"
12832                 eval $name=$count || error "Wrong proc format"
12833
12834                 case $name in
12835                 read_bytes|write_bytes)
12836                         [[ "$unit" =~ "bytes" ]] ||
12837                                 error "unit is not 'bytes': $unit"
12838                         (( $min >= 4096 )) || error "min is too small: $min"
12839                         (( $min <= $fsize )) || error "min is too big: $min"
12840                         (( $max >= 4096 )) || error "max is too small: $max"
12841                         (( $max <= $fsize )) || error "max is too big: $max"
12842                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12843                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12844                                 error "sumsquare is too small: $sumsq"
12845                         (( $sumsq <= $fsize * $fsize )) ||
12846                                 error "sumsquare is too big: $sumsq"
12847                         ;;
12848                 ost_read|ost_write)
12849                         [[ "$unit" =~ "usec" ]] ||
12850                                 error "unit is not 'usec': $unit"
12851                         ;;
12852                 *)      ;;
12853                 esac
12854         done < $DIR/$tfile.tmp
12855
12856         #check that we actually got some stats
12857         [ "$read_bytes" ] || error "Missing read_bytes stats"
12858         [ "$write_bytes" ] || error "Missing write_bytes stats"
12859         [ "$read_bytes" != 0 ] || error "no read done"
12860         [ "$write_bytes" != 0 ] || error "no write done"
12861 }
12862 run_test 127a "verify the client stats are sane"
12863
12864 test_127b() { # bug LU-333
12865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12866         local name count samp unit min max sum sumsq
12867
12868         echo "stats before reset"
12869         $LCTL get_param llite.*.stats
12870         $LCTL set_param llite.*.stats=0
12871
12872         # perform 2 reads and writes so MAX is different from SUM.
12873         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12874         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12875         cancel_lru_locks osc
12876         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12877         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12878
12879         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12880         stack_trap "rm -f $TMP/$tfile.tmp"
12881         while read name count samp unit min max sum sumsq; do
12882                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12883                 eval $name=$count || error "Wrong proc format"
12884
12885                 case $name in
12886                 read_bytes|write_bytes)
12887                         [[ "$unit" =~ "bytes" ]] ||
12888                                 error "unit is not 'bytes': $unit"
12889                         (( $count == 2 )) || error "count is not 2: $count"
12890                         (( $min == $PAGE_SIZE )) ||
12891                                 error "min is not $PAGE_SIZE: $min"
12892                         (( $max == $PAGE_SIZE )) ||
12893                                 error "max is not $PAGE_SIZE: $max"
12894                         (( $sum == $PAGE_SIZE * 2 )) ||
12895                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12896                         ;;
12897                 read|write)
12898                         [[ "$unit" =~ "usec" ]] ||
12899                                 error "unit is not 'usec': $unit"
12900                         ;;
12901                 *)      ;;
12902                 esac
12903         done < $TMP/$tfile.tmp
12904
12905         #check that we actually got some stats
12906         [ "$read_bytes" ] || error "Missing read_bytes stats"
12907         [ "$write_bytes" ] || error "Missing write_bytes stats"
12908         [ "$read_bytes" != 0 ] || error "no read done"
12909         [ "$write_bytes" != 0 ] || error "no write done"
12910 }
12911 run_test 127b "verify the llite client stats are sane"
12912
12913 test_127c() { # LU-12394
12914         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12915         local size
12916         local bsize
12917         local reads
12918         local writes
12919         local count
12920
12921         $LCTL set_param llite.*.extents_stats=1
12922         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12923
12924         # Use two stripes so there is enough space in default config
12925         $LFS setstripe -c 2 $DIR/$tfile
12926
12927         # Extent stats start at 0-4K and go in power of two buckets
12928         # LL_HIST_START = 12 --> 2^12 = 4K
12929         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12930         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12931         # small configs
12932         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12933                 do
12934                 # Write and read, 2x each, second time at a non-zero offset
12935                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12936                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12937                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12938                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12939                 rm -f $DIR/$tfile
12940         done
12941
12942         $LCTL get_param llite.*.extents_stats
12943
12944         count=2
12945         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12946                 do
12947                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12948                                 grep -m 1 $bsize)
12949                 reads=$(echo $bucket | awk '{print $5}')
12950                 writes=$(echo $bucket | awk '{print $9}')
12951                 [ "$reads" -eq $count ] ||
12952                         error "$reads reads in < $bsize bucket, expect $count"
12953                 [ "$writes" -eq $count ] ||
12954                         error "$writes writes in < $bsize bucket, expect $count"
12955         done
12956
12957         # Test mmap write and read
12958         $LCTL set_param llite.*.extents_stats=c
12959         size=512
12960         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12961         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12962         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12963
12964         $LCTL get_param llite.*.extents_stats
12965
12966         count=$(((size*1024) / PAGE_SIZE))
12967
12968         bsize=$((2 * PAGE_SIZE / 1024))K
12969
12970         bucket=$($LCTL get_param -n llite.*.extents_stats |
12971                         grep -m 1 $bsize)
12972         reads=$(echo $bucket | awk '{print $5}')
12973         writes=$(echo $bucket | awk '{print $9}')
12974         # mmap writes fault in the page first, creating an additonal read
12975         [ "$reads" -eq $((2 * count)) ] ||
12976                 error "$reads reads in < $bsize bucket, expect $count"
12977         [ "$writes" -eq $count ] ||
12978                 error "$writes writes in < $bsize bucket, expect $count"
12979 }
12980 run_test 127c "test llite extent stats with regular & mmap i/o"
12981
12982 test_128() { # bug 15212
12983         touch $DIR/$tfile
12984         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12985                 find $DIR/$tfile
12986                 find $DIR/$tfile
12987         EOF
12988
12989         result=$(grep error $TMP/$tfile.log)
12990         rm -f $DIR/$tfile $TMP/$tfile.log
12991         [ -z "$result" ] ||
12992                 error "consecutive find's under interactive lfs failed"
12993 }
12994 run_test 128 "interactive lfs for 2 consecutive find's"
12995
12996 set_dir_limits () {
12997         local mntdev
12998         local canondev
12999         local node
13000
13001         local ldproc=/proc/fs/ldiskfs
13002         local facets=$(get_facets MDS)
13003
13004         for facet in ${facets//,/ }; do
13005                 canondev=$(ldiskfs_canon \
13006                            *.$(convert_facet2label $facet).mntdev $facet)
13007                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13008                         ldproc=/sys/fs/ldiskfs
13009                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13010                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13011         done
13012 }
13013
13014 check_mds_dmesg() {
13015         local facets=$(get_facets MDS)
13016         for facet in ${facets//,/ }; do
13017                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13018         done
13019         return 1
13020 }
13021
13022 test_129() {
13023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13024         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13025                 skip "Need MDS version with at least 2.5.56"
13026         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13027                 skip_env "ldiskfs only test"
13028         fi
13029         remote_mds_nodsh && skip "remote MDS with nodsh"
13030
13031         local ENOSPC=28
13032         local has_warning=false
13033
13034         rm -rf $DIR/$tdir
13035         mkdir -p $DIR/$tdir
13036
13037         # block size of mds1
13038         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13039         set_dir_limits $maxsize $((maxsize * 6 / 8))
13040         stack_trap "set_dir_limits 0 0"
13041         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13042         local dirsize=$(stat -c%s "$DIR/$tdir")
13043         local nfiles=0
13044         while (( $dirsize <= $maxsize )); do
13045                 $MCREATE $DIR/$tdir/file_base_$nfiles
13046                 rc=$?
13047                 # check two errors:
13048                 # ENOSPC for ext4 max_dir_size, which has been used since
13049                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13050                 if (( rc == ENOSPC )); then
13051                         set_dir_limits 0 0
13052                         echo "rc=$rc returned as expected after $nfiles files"
13053
13054                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13055                                 error "create failed w/o dir size limit"
13056
13057                         # messages may be rate limited if test is run repeatedly
13058                         check_mds_dmesg '"is approaching max"' ||
13059                                 echo "warning message should be output"
13060                         check_mds_dmesg '"has reached max"' ||
13061                                 echo "reached message should be output"
13062
13063                         dirsize=$(stat -c%s "$DIR/$tdir")
13064
13065                         [[ $dirsize -ge $maxsize ]] && return 0
13066                         error "dirsize $dirsize < $maxsize after $nfiles files"
13067                 elif (( rc != 0 )); then
13068                         break
13069                 fi
13070                 nfiles=$((nfiles + 1))
13071                 dirsize=$(stat -c%s "$DIR/$tdir")
13072         done
13073
13074         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13075 }
13076 run_test 129 "test directory size limit ========================"
13077
13078 OLDIFS="$IFS"
13079 cleanup_130() {
13080         trap 0
13081         IFS="$OLDIFS"
13082 }
13083
13084 test_130a() {
13085         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13086         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13087
13088         trap cleanup_130 EXIT RETURN
13089
13090         local fm_file=$DIR/$tfile
13091         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13092         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13093                 error "dd failed for $fm_file"
13094
13095         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13096         filefrag -ves $fm_file
13097         RC=$?
13098         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13099                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13100         [ $RC != 0 ] && error "filefrag $fm_file failed"
13101
13102         filefrag_op=$(filefrag -ve -k $fm_file |
13103                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13104         lun=$($LFS getstripe -i $fm_file)
13105
13106         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13107         IFS=$'\n'
13108         tot_len=0
13109         for line in $filefrag_op
13110         do
13111                 frag_lun=`echo $line | cut -d: -f5`
13112                 ext_len=`echo $line | cut -d: -f4`
13113                 if (( $frag_lun != $lun )); then
13114                         cleanup_130
13115                         error "FIEMAP on 1-stripe file($fm_file) failed"
13116                         return
13117                 fi
13118                 (( tot_len += ext_len ))
13119         done
13120
13121         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13122                 cleanup_130
13123                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13124                 return
13125         fi
13126
13127         cleanup_130
13128
13129         echo "FIEMAP on single striped file succeeded"
13130 }
13131 run_test 130a "FIEMAP (1-stripe file)"
13132
13133 test_130b() {
13134         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13135
13136         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13137         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13138
13139         trap cleanup_130 EXIT RETURN
13140
13141         local fm_file=$DIR/$tfile
13142         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13143                         error "setstripe on $fm_file"
13144         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13145                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13146
13147         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13148                 error "dd failed on $fm_file"
13149
13150         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13151         filefrag_op=$(filefrag -ve -k $fm_file |
13152                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13153
13154         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13155                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13156
13157         IFS=$'\n'
13158         tot_len=0
13159         num_luns=1
13160         for line in $filefrag_op
13161         do
13162                 frag_lun=$(echo $line | cut -d: -f5 |
13163                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13164                 ext_len=$(echo $line | cut -d: -f4)
13165                 if (( $frag_lun != $last_lun )); then
13166                         if (( tot_len != 1024 )); then
13167                                 cleanup_130
13168                                 error "FIEMAP on $fm_file failed; returned " \
13169                                 "len $tot_len for OST $last_lun instead of 1024"
13170                                 return
13171                         else
13172                                 (( num_luns += 1 ))
13173                                 tot_len=0
13174                         fi
13175                 fi
13176                 (( tot_len += ext_len ))
13177                 last_lun=$frag_lun
13178         done
13179         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13180                 cleanup_130
13181                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13182                         "luns or wrong len for OST $last_lun"
13183                 return
13184         fi
13185
13186         cleanup_130
13187
13188         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13189 }
13190 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13191
13192 test_130c() {
13193         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13194
13195         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13196         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13197
13198         trap cleanup_130 EXIT RETURN
13199
13200         local fm_file=$DIR/$tfile
13201         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13202         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13203                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13204
13205         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13206                         error "dd failed on $fm_file"
13207
13208         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13209         filefrag_op=$(filefrag -ve -k $fm_file |
13210                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13211
13212         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13213                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13214
13215         IFS=$'\n'
13216         tot_len=0
13217         num_luns=1
13218         for line in $filefrag_op
13219         do
13220                 frag_lun=$(echo $line | cut -d: -f5 |
13221                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13222                 ext_len=$(echo $line | cut -d: -f4)
13223                 if (( $frag_lun != $last_lun )); then
13224                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13225                         if (( logical != 512 )); then
13226                                 cleanup_130
13227                                 error "FIEMAP on $fm_file failed; returned " \
13228                                 "logical start for lun $logical instead of 512"
13229                                 return
13230                         fi
13231                         if (( tot_len != 512 )); then
13232                                 cleanup_130
13233                                 error "FIEMAP on $fm_file failed; returned " \
13234                                 "len $tot_len for OST $last_lun instead of 1024"
13235                                 return
13236                         else
13237                                 (( num_luns += 1 ))
13238                                 tot_len=0
13239                         fi
13240                 fi
13241                 (( tot_len += ext_len ))
13242                 last_lun=$frag_lun
13243         done
13244         if (( num_luns != 2 || tot_len != 512 )); then
13245                 cleanup_130
13246                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13247                         "luns or wrong len for OST $last_lun"
13248                 return
13249         fi
13250
13251         cleanup_130
13252
13253         echo "FIEMAP on 2-stripe file with hole succeeded"
13254 }
13255 run_test 130c "FIEMAP (2-stripe file with hole)"
13256
13257 test_130d() {
13258         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13259
13260         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13261         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13262
13263         trap cleanup_130 EXIT RETURN
13264
13265         local fm_file=$DIR/$tfile
13266         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13267                         error "setstripe on $fm_file"
13268         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13269                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13270
13271         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13272         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13273                 error "dd failed on $fm_file"
13274
13275         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13276         filefrag_op=$(filefrag -ve -k $fm_file |
13277                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13278
13279         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13280                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13281
13282         IFS=$'\n'
13283         tot_len=0
13284         num_luns=1
13285         for line in $filefrag_op
13286         do
13287                 frag_lun=$(echo $line | cut -d: -f5 |
13288                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13289                 ext_len=$(echo $line | cut -d: -f4)
13290                 if (( $frag_lun != $last_lun )); then
13291                         if (( tot_len != 1024 )); then
13292                                 cleanup_130
13293                                 error "FIEMAP on $fm_file failed; returned " \
13294                                 "len $tot_len for OST $last_lun instead of 1024"
13295                                 return
13296                         else
13297                                 (( num_luns += 1 ))
13298                                 tot_len=0
13299                         fi
13300                 fi
13301                 (( tot_len += ext_len ))
13302                 last_lun=$frag_lun
13303         done
13304         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13305                 cleanup_130
13306                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13307                         "luns or wrong len for OST $last_lun"
13308                 return
13309         fi
13310
13311         cleanup_130
13312
13313         echo "FIEMAP on N-stripe file succeeded"
13314 }
13315 run_test 130d "FIEMAP (N-stripe file)"
13316
13317 test_130e() {
13318         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13319
13320         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13321         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13322
13323         trap cleanup_130 EXIT RETURN
13324
13325         local fm_file=$DIR/$tfile
13326         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13327
13328         NUM_BLKS=512
13329         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13330         for ((i = 0; i < $NUM_BLKS; i++)); do
13331                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13332                         conv=notrunc > /dev/null 2>&1
13333         done
13334
13335         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13336         filefrag_op=$(filefrag -ve -k $fm_file |
13337                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13338
13339         last_lun=$(echo $filefrag_op | cut -d: -f5)
13340
13341         IFS=$'\n'
13342         tot_len=0
13343         num_luns=1
13344         for line in $filefrag_op; do
13345                 frag_lun=$(echo $line | cut -d: -f5)
13346                 ext_len=$(echo $line | cut -d: -f4)
13347                 if [[ "$frag_lun" != "$last_lun" ]]; then
13348                         if (( tot_len != $EXPECTED_LEN )); then
13349                                 cleanup_130
13350                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13351                         else
13352                                 (( num_luns += 1 ))
13353                                 tot_len=0
13354                         fi
13355                 fi
13356                 (( tot_len += ext_len ))
13357                 last_lun=$frag_lun
13358         done
13359         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13360                 cleanup_130
13361                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13362         fi
13363
13364         echo "FIEMAP with continuation calls succeeded"
13365 }
13366 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13367
13368 test_130f() {
13369         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13370         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13371
13372         local fm_file=$DIR/$tfile
13373         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13374                 error "multiop create with lov_delay_create on $fm_file"
13375
13376         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13377         filefrag_extents=$(filefrag -vek $fm_file |
13378                            awk '/extents? found/ { print $2 }')
13379         if [[ "$filefrag_extents" != "0" ]]; then
13380                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13381         fi
13382
13383         rm -f $fm_file
13384 }
13385 run_test 130f "FIEMAP (unstriped file)"
13386
13387 test_130g() {
13388         local file=$DIR/$tfile
13389         local nr=$((OSTCOUNT * 100))
13390
13391         $LFS setstripe -C $nr $file ||
13392                 error "failed to setstripe -C $nr $file"
13393
13394         dd if=/dev/zero of=$file count=$nr bs=1M
13395         sync
13396         nr=$($LFS getstripe -c $file)
13397
13398         local extents=$(filefrag -v $file |
13399                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13400
13401         echo "filefrag list $extents extents in file with stripecount $nr"
13402         if (( extents < nr )); then
13403                 $LFS getstripe $file
13404                 filefrag -v $file
13405                 error "filefrag printed $extents < $nr extents"
13406         fi
13407
13408         rm -f $file
13409 }
13410 run_test 130g "FIEMAP (overstripe file)"
13411
13412 # Test for writev/readv
13413 test_131a() {
13414         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13415                 error "writev test failed"
13416         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13417                 error "readv failed"
13418         rm -f $DIR/$tfile
13419 }
13420 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13421
13422 test_131b() {
13423         local fsize=$((524288 + 1048576 + 1572864))
13424         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13425                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13426                         error "append writev test failed"
13427
13428         ((fsize += 1572864 + 1048576))
13429         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13430                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13431                         error "append writev test failed"
13432         rm -f $DIR/$tfile
13433 }
13434 run_test 131b "test append writev"
13435
13436 test_131c() {
13437         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13438         error "NOT PASS"
13439 }
13440 run_test 131c "test read/write on file w/o objects"
13441
13442 test_131d() {
13443         rwv -f $DIR/$tfile -w -n 1 1572864
13444         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13445         if [ "$NOB" != 1572864 ]; then
13446                 error "Short read filed: read $NOB bytes instead of 1572864"
13447         fi
13448         rm -f $DIR/$tfile
13449 }
13450 run_test 131d "test short read"
13451
13452 test_131e() {
13453         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13454         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13455         error "read hitting hole failed"
13456         rm -f $DIR/$tfile
13457 }
13458 run_test 131e "test read hitting hole"
13459
13460 check_stats() {
13461         local facet=$1
13462         local op=$2
13463         local want=${3:-0}
13464         local res
13465
13466         case $facet in
13467         mds*) res=$(do_facet $facet \
13468                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13469                  ;;
13470         ost*) res=$(do_facet $facet \
13471                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13472                  ;;
13473         *) error "Wrong facet '$facet'" ;;
13474         esac
13475         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13476         # if the argument $3 is zero, it means any stat increment is ok.
13477         if [[ $want -gt 0 ]]; then
13478                 local count=$(echo $res | awk '{ print $2 }')
13479                 [[ $count -ne $want ]] &&
13480                         error "The $op counter on $facet is $count, not $want"
13481         fi
13482 }
13483
13484 test_133a() {
13485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13486         remote_ost_nodsh && skip "remote OST with nodsh"
13487         remote_mds_nodsh && skip "remote MDS with nodsh"
13488         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13489                 skip_env "MDS doesn't support rename stats"
13490
13491         local testdir=$DIR/${tdir}/stats_testdir
13492
13493         mkdir -p $DIR/${tdir}
13494
13495         # clear stats.
13496         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13497         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13498
13499         # verify mdt stats first.
13500         mkdir ${testdir} || error "mkdir failed"
13501         check_stats $SINGLEMDS "mkdir" 1
13502         touch ${testdir}/${tfile} || error "touch failed"
13503         check_stats $SINGLEMDS "open" 1
13504         check_stats $SINGLEMDS "close" 1
13505         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13506                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13507                 check_stats $SINGLEMDS "mknod" 2
13508         }
13509         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13510         check_stats $SINGLEMDS "unlink" 1
13511         rm -f ${testdir}/${tfile} || error "file remove failed"
13512         check_stats $SINGLEMDS "unlink" 2
13513
13514         # remove working dir and check mdt stats again.
13515         rmdir ${testdir} || error "rmdir failed"
13516         check_stats $SINGLEMDS "rmdir" 1
13517
13518         local testdir1=$DIR/${tdir}/stats_testdir1
13519         mkdir -p ${testdir}
13520         mkdir -p ${testdir1}
13521         touch ${testdir1}/test1
13522         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13523         check_stats $SINGLEMDS "crossdir_rename" 1
13524
13525         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13526         check_stats $SINGLEMDS "samedir_rename" 1
13527
13528         rm -rf $DIR/${tdir}
13529 }
13530 run_test 133a "Verifying MDT stats ========================================"
13531
13532 test_133b() {
13533         local res
13534
13535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13536         remote_ost_nodsh && skip "remote OST with nodsh"
13537         remote_mds_nodsh && skip "remote MDS with nodsh"
13538
13539         local testdir=$DIR/${tdir}/stats_testdir
13540
13541         mkdir -p ${testdir} || error "mkdir failed"
13542         touch ${testdir}/${tfile} || error "touch failed"
13543         cancel_lru_locks mdc
13544
13545         # clear stats.
13546         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13547         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13548
13549         # extra mdt stats verification.
13550         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13551         check_stats $SINGLEMDS "setattr" 1
13552         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13553         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13554         then            # LU-1740
13555                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13556                 check_stats $SINGLEMDS "getattr" 1
13557         fi
13558         rm -rf $DIR/${tdir}
13559
13560         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13561         # so the check below is not reliable
13562         [ $MDSCOUNT -eq 1 ] || return 0
13563
13564         # Sleep to avoid a cached response.
13565         #define OBD_STATFS_CACHE_SECONDS 1
13566         sleep 2
13567         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13568         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13569         $LFS df || error "lfs failed"
13570         check_stats $SINGLEMDS "statfs" 1
13571
13572         # check aggregated statfs (LU-10018)
13573         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13574                 return 0
13575         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13576                 return 0
13577         sleep 2
13578         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13579         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13580         df $DIR
13581         check_stats $SINGLEMDS "statfs" 1
13582
13583         # We want to check that the client didn't send OST_STATFS to
13584         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13585         # extra care is needed here.
13586         if remote_mds; then
13587                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13588                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13589
13590                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13591                 [ "$res" ] && error "OST got STATFS"
13592         fi
13593
13594         return 0
13595 }
13596 run_test 133b "Verifying extra MDT stats =================================="
13597
13598 test_133c() {
13599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13600         remote_ost_nodsh && skip "remote OST with nodsh"
13601         remote_mds_nodsh && skip "remote MDS with nodsh"
13602
13603         local testdir=$DIR/$tdir/stats_testdir
13604
13605         test_mkdir -p $testdir
13606
13607         # verify obdfilter stats.
13608         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13609         sync
13610         cancel_lru_locks osc
13611         wait_delete_completed
13612
13613         # clear stats.
13614         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13615         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13616
13617         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13618                 error "dd failed"
13619         sync
13620         cancel_lru_locks osc
13621         check_stats ost1 "write" 1
13622
13623         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13624         check_stats ost1 "read" 1
13625
13626         > $testdir/$tfile || error "truncate failed"
13627         check_stats ost1 "punch" 1
13628
13629         rm -f $testdir/$tfile || error "file remove failed"
13630         wait_delete_completed
13631         check_stats ost1 "destroy" 1
13632
13633         rm -rf $DIR/$tdir
13634 }
13635 run_test 133c "Verifying OST stats ========================================"
13636
13637 order_2() {
13638         local value=$1
13639         local orig=$value
13640         local order=1
13641
13642         while [ $value -ge 2 ]; do
13643                 order=$((order*2))
13644                 value=$((value/2))
13645         done
13646
13647         if [ $orig -gt $order ]; then
13648                 order=$((order*2))
13649         fi
13650         echo $order
13651 }
13652
13653 size_in_KMGT() {
13654     local value=$1
13655     local size=('K' 'M' 'G' 'T');
13656     local i=0
13657     local size_string=$value
13658
13659     while [ $value -ge 1024 ]; do
13660         if [ $i -gt 3 ]; then
13661             #T is the biggest unit we get here, if that is bigger,
13662             #just return XXXT
13663             size_string=${value}T
13664             break
13665         fi
13666         value=$((value >> 10))
13667         if [ $value -lt 1024 ]; then
13668             size_string=${value}${size[$i]}
13669             break
13670         fi
13671         i=$((i + 1))
13672     done
13673
13674     echo $size_string
13675 }
13676
13677 get_rename_size() {
13678         local size=$1
13679         local context=${2:-.}
13680         local sample=$(do_facet $SINGLEMDS $LCTL \
13681                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13682                 grep -A1 $context |
13683                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13684         echo $sample
13685 }
13686
13687 test_133d() {
13688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13689         remote_ost_nodsh && skip "remote OST with nodsh"
13690         remote_mds_nodsh && skip "remote MDS with nodsh"
13691         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13692                 skip_env "MDS doesn't support rename stats"
13693
13694         local testdir1=$DIR/${tdir}/stats_testdir1
13695         local testdir2=$DIR/${tdir}/stats_testdir2
13696         mkdir -p $DIR/${tdir}
13697
13698         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13699
13700         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13701         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13702
13703         createmany -o $testdir1/test 512 || error "createmany failed"
13704
13705         # check samedir rename size
13706         mv ${testdir1}/test0 ${testdir1}/test_0
13707
13708         local testdir1_size=$(ls -l $DIR/${tdir} |
13709                 awk '/stats_testdir1/ {print $5}')
13710         local testdir2_size=$(ls -l $DIR/${tdir} |
13711                 awk '/stats_testdir2/ {print $5}')
13712
13713         testdir1_size=$(order_2 $testdir1_size)
13714         testdir2_size=$(order_2 $testdir2_size)
13715
13716         testdir1_size=$(size_in_KMGT $testdir1_size)
13717         testdir2_size=$(size_in_KMGT $testdir2_size)
13718
13719         echo "source rename dir size: ${testdir1_size}"
13720         echo "target rename dir size: ${testdir2_size}"
13721
13722         local cmd="do_facet $SINGLEMDS $LCTL "
13723         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13724
13725         eval $cmd || error "$cmd failed"
13726         local samedir=$($cmd | grep 'same_dir')
13727         local same_sample=$(get_rename_size $testdir1_size)
13728         [ -z "$samedir" ] && error "samedir_rename_size count error"
13729         [[ $same_sample -eq 1 ]] ||
13730                 error "samedir_rename_size error $same_sample"
13731         echo "Check same dir rename stats success"
13732
13733         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13734
13735         # check crossdir rename size
13736         mv ${testdir1}/test_0 ${testdir2}/test_0
13737
13738         testdir1_size=$(ls -l $DIR/${tdir} |
13739                 awk '/stats_testdir1/ {print $5}')
13740         testdir2_size=$(ls -l $DIR/${tdir} |
13741                 awk '/stats_testdir2/ {print $5}')
13742
13743         testdir1_size=$(order_2 $testdir1_size)
13744         testdir2_size=$(order_2 $testdir2_size)
13745
13746         testdir1_size=$(size_in_KMGT $testdir1_size)
13747         testdir2_size=$(size_in_KMGT $testdir2_size)
13748
13749         echo "source rename dir size: ${testdir1_size}"
13750         echo "target rename dir size: ${testdir2_size}"
13751
13752         eval $cmd || error "$cmd failed"
13753         local crossdir=$($cmd | grep 'crossdir')
13754         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13755         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13756         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13757         [[ $src_sample -eq 1 ]] ||
13758                 error "crossdir_rename_size error $src_sample"
13759         [[ $tgt_sample -eq 1 ]] ||
13760                 error "crossdir_rename_size error $tgt_sample"
13761         echo "Check cross dir rename stats success"
13762         rm -rf $DIR/${tdir}
13763 }
13764 run_test 133d "Verifying rename_stats ========================================"
13765
13766 test_133e() {
13767         remote_mds_nodsh && skip "remote MDS with nodsh"
13768         remote_ost_nodsh && skip "remote OST with nodsh"
13769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13770
13771         local testdir=$DIR/${tdir}/stats_testdir
13772         local ctr f0 f1 bs=32768 count=42 sum
13773
13774         mkdir -p ${testdir} || error "mkdir failed"
13775
13776         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13777
13778         for ctr in {write,read}_bytes; do
13779                 sync
13780                 cancel_lru_locks osc
13781
13782                 do_facet ost1 $LCTL set_param -n \
13783                         "obdfilter.*.exports.clear=clear"
13784
13785                 if [ $ctr = write_bytes ]; then
13786                         f0=/dev/zero
13787                         f1=${testdir}/${tfile}
13788                 else
13789                         f0=${testdir}/${tfile}
13790                         f1=/dev/null
13791                 fi
13792
13793                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13794                         error "dd failed"
13795                 sync
13796                 cancel_lru_locks osc
13797
13798                 sum=$(do_facet ost1 $LCTL get_param \
13799                         "obdfilter.*.exports.*.stats" |
13800                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13801                                 $1 == ctr { sum += $7 }
13802                                 END { printf("%0.0f", sum) }')
13803
13804                 if ((sum != bs * count)); then
13805                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13806                 fi
13807         done
13808
13809         rm -rf $DIR/${tdir}
13810 }
13811 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13812
13813 test_133f() {
13814         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13815                 skip "too old lustre for get_param -R ($facet_ver)"
13816
13817         # verifying readability.
13818         $LCTL get_param -R '*' &> /dev/null
13819
13820         # Verifing writability with badarea_io.
13821         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13822                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13823                 error "client badarea_io failed"
13824
13825         # remount the FS in case writes/reads /proc break the FS
13826         cleanup || error "failed to unmount"
13827         setup || error "failed to setup"
13828 }
13829 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13830
13831 test_133g() {
13832         remote_mds_nodsh && skip "remote MDS with nodsh"
13833         remote_ost_nodsh && skip "remote OST with nodsh"
13834
13835         local facet
13836         for facet in mds1 ost1; do
13837                 local facet_ver=$(lustre_version_code $facet)
13838                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13839                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13840                 else
13841                         log "$facet: too old lustre for get_param -R"
13842                 fi
13843                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13844                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13845                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13846                                 xargs badarea_io" ||
13847                                         error "$facet badarea_io failed"
13848                 else
13849                         skip_noexit "$facet: too old lustre for get_param -R"
13850                 fi
13851         done
13852
13853         # remount the FS in case writes/reads /proc break the FS
13854         cleanup || error "failed to unmount"
13855         setup || error "failed to setup"
13856 }
13857 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13858
13859 test_133h() {
13860         remote_mds_nodsh && skip "remote MDS with nodsh"
13861         remote_ost_nodsh && skip "remote OST with nodsh"
13862         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13863                 skip "Need MDS version at least 2.9.54"
13864
13865         local facet
13866         for facet in client mds1 ost1; do
13867                 # Get the list of files that are missing the terminating newline
13868                 local plist=$(do_facet $facet
13869                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13870                 local ent
13871                 for ent in $plist; do
13872                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13873                                 awk -v FS='\v' -v RS='\v\v' \
13874                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13875                                         print FILENAME}'" 2>/dev/null)
13876                         [ -z $missing ] || {
13877                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13878                                 error "file does not end with newline: $facet-$ent"
13879                         }
13880                 done
13881         done
13882 }
13883 run_test 133h "Proc files should end with newlines"
13884
13885 test_134a() {
13886         remote_mds_nodsh && skip "remote MDS with nodsh"
13887         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13888                 skip "Need MDS version at least 2.7.54"
13889
13890         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
13891         cancel_lru_locks mdc
13892
13893         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13894         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13895         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13896
13897         local nr=1000
13898         createmany -o $DIR/$tdir/f $nr ||
13899                 error "failed to create $nr files in $DIR/$tdir"
13900         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13901
13902         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13903         do_facet mds1 $LCTL set_param fail_loc=0x327
13904         do_facet mds1 $LCTL set_param fail_val=500
13905         touch $DIR/$tdir/m
13906
13907         echo "sleep 10 seconds ..."
13908         sleep 10
13909         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13910
13911         do_facet mds1 $LCTL set_param fail_loc=0
13912         do_facet mds1 $LCTL set_param fail_val=0
13913         [ $lck_cnt -lt $unused ] ||
13914                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13915
13916         rm $DIR/$tdir/m
13917         unlinkmany $DIR/$tdir/f $nr
13918 }
13919 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13920
13921 test_134b() {
13922         remote_mds_nodsh && skip "remote MDS with nodsh"
13923         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13924                 skip "Need MDS version at least 2.7.54"
13925
13926         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
13927         cancel_lru_locks mdc
13928
13929         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13930                         ldlm.lock_reclaim_threshold_mb)
13931         # disable reclaim temporarily
13932         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13933
13934         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13935         do_facet mds1 $LCTL set_param fail_loc=0x328
13936         do_facet mds1 $LCTL set_param fail_val=500
13937
13938         $LCTL set_param debug=+trace
13939
13940         local nr=600
13941         createmany -o $DIR/$tdir/f $nr &
13942         local create_pid=$!
13943
13944         echo "Sleep $TIMEOUT seconds ..."
13945         sleep $TIMEOUT
13946         if ! ps -p $create_pid  > /dev/null 2>&1; then
13947                 do_facet mds1 $LCTL set_param fail_loc=0
13948                 do_facet mds1 $LCTL set_param fail_val=0
13949                 do_facet mds1 $LCTL set_param \
13950                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13951                 error "createmany finished incorrectly!"
13952         fi
13953         do_facet mds1 $LCTL set_param fail_loc=0
13954         do_facet mds1 $LCTL set_param fail_val=0
13955         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13956         wait $create_pid || return 1
13957
13958         unlinkmany $DIR/$tdir/f $nr
13959 }
13960 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13961
13962 test_135() {
13963         remote_mds_nodsh && skip "remote MDS with nodsh"
13964         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13965                 skip "Need MDS version at least 2.13.50"
13966         local fname
13967
13968         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13969
13970 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13971         #set only one record at plain llog
13972         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13973
13974         #fill already existed plain llog each 64767
13975         #wrapping whole catalog
13976         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13977
13978         createmany -o $DIR/$tdir/$tfile_ 64700
13979         for (( i = 0; i < 64700; i = i + 2 ))
13980         do
13981                 rm $DIR/$tdir/$tfile_$i &
13982                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13983                 local pid=$!
13984                 wait $pid
13985         done
13986
13987         #waiting osp synchronization
13988         wait_delete_completed
13989 }
13990 run_test 135 "Race catalog processing"
13991
13992 test_136() {
13993         remote_mds_nodsh && skip "remote MDS with nodsh"
13994         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13995                 skip "Need MDS version at least 2.13.50"
13996         local fname
13997
13998         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13999         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14000         #set only one record at plain llog
14001 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14002         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14003
14004         #fill already existed 2 plain llogs each 64767
14005         #wrapping whole catalog
14006         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14007         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14008         wait_delete_completed
14009
14010         createmany -o $DIR/$tdir/$tfile_ 10
14011         sleep 25
14012
14013         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14014         for (( i = 0; i < 10; i = i + 3 ))
14015         do
14016                 rm $DIR/$tdir/$tfile_$i &
14017                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14018                 local pid=$!
14019                 wait $pid
14020                 sleep 7
14021                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14022         done
14023
14024         #waiting osp synchronization
14025         wait_delete_completed
14026 }
14027 run_test 136 "Race catalog processing 2"
14028
14029 test_140() { #bug-17379
14030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14031
14032         test_mkdir $DIR/$tdir
14033         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14034         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14035
14036         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14037         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14038         local i=0
14039         while i=$((i + 1)); do
14040                 test_mkdir $i
14041                 cd $i || error "Changing to $i"
14042                 ln -s ../stat stat || error "Creating stat symlink"
14043                 # Read the symlink until ELOOP present,
14044                 # not LBUGing the system is considered success,
14045                 # we didn't overrun the stack.
14046                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14047                 if [ $ret -ne 0 ]; then
14048                         if [ $ret -eq 40 ]; then
14049                                 break  # -ELOOP
14050                         else
14051                                 error "Open stat symlink"
14052                                         return
14053                         fi
14054                 fi
14055         done
14056         i=$((i - 1))
14057         echo "The symlink depth = $i"
14058         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14059                 error "Invalid symlink depth"
14060
14061         # Test recursive symlink
14062         ln -s symlink_self symlink_self
14063         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14064         echo "open symlink_self returns $ret"
14065         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14066 }
14067 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14068
14069 test_150a() {
14070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14071
14072         local TF="$TMP/$tfile"
14073
14074         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14075         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14076         cp $TF $DIR/$tfile
14077         cancel_lru_locks $OSC
14078         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14079         remount_client $MOUNT
14080         df -P $MOUNT
14081         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14082
14083         $TRUNCATE $TF 6000
14084         $TRUNCATE $DIR/$tfile 6000
14085         cancel_lru_locks $OSC
14086         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14087
14088         echo "12345" >>$TF
14089         echo "12345" >>$DIR/$tfile
14090         cancel_lru_locks $OSC
14091         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14092
14093         echo "12345" >>$TF
14094         echo "12345" >>$DIR/$tfile
14095         cancel_lru_locks $OSC
14096         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14097 }
14098 run_test 150a "truncate/append tests"
14099
14100 test_150b() {
14101         check_set_fallocate_or_skip
14102
14103         touch $DIR/$tfile
14104         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14105         check_fallocate $DIR/$tfile || error "fallocate failed"
14106 }
14107 run_test 150b "Verify fallocate (prealloc) functionality"
14108
14109 test_150bb() {
14110         check_set_fallocate_or_skip
14111
14112         touch $DIR/$tfile
14113         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14114         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14115         > $DIR/$tfile
14116         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14117         # precomputed md5sum for 20MB of zeroes
14118         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14119         local sum=($(md5sum $DIR/$tfile))
14120
14121         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14122
14123         check_set_fallocate 1
14124
14125         > $DIR/$tfile
14126         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14127         sum=($(md5sum $DIR/$tfile))
14128
14129         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14130 }
14131 run_test 150bb "Verify fallocate modes both zero space"
14132
14133 test_150c() {
14134         check_set_fallocate_or_skip
14135
14136         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14137         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14138         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14139         sync; sync_all_data
14140         cancel_lru_locks $OSC
14141         sleep 5
14142         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14143         want=$((OSTCOUNT * 1048576))
14144
14145         # Must allocate all requested space, not more than 5% extra
14146         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14147                 error "bytes $bytes is not $want"
14148
14149         rm -f $DIR/$tfile
14150         # verify fallocate on PFL file
14151         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14152                 error "Create $DIR/$tfile failed"
14153         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
14154                         error "fallocate failed"
14155         sync; sync_all_data
14156         cancel_lru_locks $OSC
14157         sleep 5
14158         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14159         local want=$((1024 * 1048576))
14160
14161         # Must allocate all requested space, not more than 5% extra
14162         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14163                 error "bytes $bytes is not $want"
14164 }
14165 run_test 150c "Verify fallocate Size and Blocks"
14166
14167 test_150d() {
14168         check_set_fallocate_or_skip
14169
14170         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14171         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
14172         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14173         sync; sync_all_data
14174         cancel_lru_locks $OSC
14175         sleep 5
14176         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14177         local want=$((OSTCOUNT * 1048576))
14178
14179         # Must allocate all requested space, not more than 5% extra
14180         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14181                 error "bytes $bytes is not $want"
14182 }
14183 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14184
14185 test_150e() {
14186         check_set_fallocate_or_skip
14187
14188         echo "df before:"
14189         $LFS df
14190         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14191         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14192                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14193
14194         # Find OST with Minimum Size
14195         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14196                        sort -un | head -1)
14197
14198         # Get 100MB per OST of the available space to reduce run time
14199         # else 60% of the available space if we are running SLOW tests
14200         if [ $SLOW == "no" ]; then
14201                 local space=$((1024 * 100 * OSTCOUNT))
14202         else
14203                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14204         fi
14205
14206         fallocate -l${space}k $DIR/$tfile ||
14207                 error "fallocate ${space}k $DIR/$tfile failed"
14208         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14209
14210         # get size immediately after fallocate. This should be correctly
14211         # updated
14212         local size=$(stat -c '%s' $DIR/$tfile)
14213         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14214
14215         # Sleep for a while for statfs to get updated. And not pull from cache.
14216         sleep 2
14217
14218         echo "df after fallocate:"
14219         $LFS df
14220
14221         (( size / 1024 == space )) || error "size $size != requested $space"
14222         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14223                 error "used $used < space $space"
14224
14225         rm $DIR/$tfile || error "rm failed"
14226         sync
14227         wait_delete_completed
14228
14229         echo "df after unlink:"
14230         $LFS df
14231 }
14232 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14233
14234 test_150f() {
14235         local size
14236         local blocks
14237         local want_size_before=20480 # in bytes
14238         local want_blocks_before=40 # 512 sized blocks
14239         local want_blocks_after=24  # 512 sized blocks
14240         local length=$(((want_blocks_before - want_blocks_after) * 512))
14241
14242         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14243                 skip "need at least 2.14.0 for fallocate punch"
14244
14245         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14246                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14247         fi
14248
14249         check_set_fallocate_or_skip
14250         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14251
14252         echo "Verify fallocate punch: Range within the file range"
14253         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14254                 error "dd failed for bs 4096 and count 5"
14255
14256         # Call fallocate with punch range which is within the file range
14257         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14258                 error "fallocate failed: offset 4096 and length $length"
14259         # client must see changes immediately after fallocate
14260         size=$(stat -c '%s' $DIR/$tfile)
14261         blocks=$(stat -c '%b' $DIR/$tfile)
14262
14263         # Verify punch worked.
14264         (( blocks == want_blocks_after )) ||
14265                 error "punch failed: blocks $blocks != $want_blocks_after"
14266
14267         (( size == want_size_before )) ||
14268                 error "punch failed: size $size != $want_size_before"
14269
14270         # Verify there is hole in file
14271         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14272         # precomputed md5sum
14273         local expect="4a9a834a2db02452929c0a348273b4aa"
14274
14275         cksum=($(md5sum $DIR/$tfile))
14276         [[ "${cksum[0]}" == "$expect" ]] ||
14277                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14278
14279         # Start second sub-case for fallocate punch.
14280         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14281         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14282                 error "dd failed for bs 4096 and count 5"
14283
14284         # Punch range less than block size will have no change in block count
14285         want_blocks_after=40  # 512 sized blocks
14286
14287         # Punch overlaps two blocks and less than blocksize
14288         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14289                 error "fallocate failed: offset 4000 length 3000"
14290         size=$(stat -c '%s' $DIR/$tfile)
14291         blocks=$(stat -c '%b' $DIR/$tfile)
14292
14293         # Verify punch worked.
14294         (( blocks == want_blocks_after )) ||
14295                 error "punch failed: blocks $blocks != $want_blocks_after"
14296
14297         (( size == want_size_before )) ||
14298                 error "punch failed: size $size != $want_size_before"
14299
14300         # Verify if range is really zero'ed out. We expect Zeros.
14301         # precomputed md5sum
14302         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14303         cksum=($(md5sum $DIR/$tfile))
14304         [[ "${cksum[0]}" == "$expect" ]] ||
14305                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14306 }
14307 run_test 150f "Verify fallocate punch functionality"
14308
14309 test_150g() {
14310         local space
14311         local size
14312         local blocks
14313         local blocks_after
14314         local size_after
14315         local BS=4096 # Block size in bytes
14316
14317         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14318                 skip "need at least 2.14.0 for fallocate punch"
14319
14320         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14321                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14322         fi
14323
14324         check_set_fallocate_or_skip
14325         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14326
14327         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14328                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14329
14330         # Get 100MB per OST of the available space to reduce run time
14331         # else 60% of the available space if we are running SLOW tests
14332         if [ $SLOW == "no" ]; then
14333                 space=$((1024 * 100 * OSTCOUNT))
14334         else
14335                 # Find OST with Minimum Size
14336                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14337                         sort -un | head -1)
14338                 echo "min size OST: $space"
14339                 space=$(((space * 60)/100 * OSTCOUNT))
14340         fi
14341         # space in 1k units, round to 4k blocks
14342         local blkcount=$((space * 1024 / $BS))
14343
14344         echo "Verify fallocate punch: Very large Range"
14345         fallocate -l${space}k $DIR/$tfile ||
14346                 error "fallocate ${space}k $DIR/$tfile failed"
14347         # write 1M at the end, start and in the middle
14348         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14349                 error "dd failed: bs $BS count 256"
14350         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14351                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14352         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14353                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14354
14355         # Gather stats.
14356         size=$(stat -c '%s' $DIR/$tfile)
14357
14358         # gather punch length.
14359         local punch_size=$((size - (BS * 2)))
14360
14361         echo "punch_size = $punch_size"
14362         echo "size - punch_size: $((size - punch_size))"
14363         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14364
14365         # Call fallocate to punch all except 2 blocks. We leave the
14366         # first and the last block
14367         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14368         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14369                 error "fallocate failed: offset $BS length $punch_size"
14370
14371         size_after=$(stat -c '%s' $DIR/$tfile)
14372         blocks_after=$(stat -c '%b' $DIR/$tfile)
14373
14374         # Verify punch worked.
14375         # Size should be kept
14376         (( size == size_after )) ||
14377                 error "punch failed: size $size != $size_after"
14378
14379         # two 4k data blocks to remain plus possible 1 extra extent block
14380         (( blocks_after <= ((BS / 512) * 3) )) ||
14381                 error "too many blocks remains: $blocks_after"
14382
14383         # Verify that file has hole between the first and the last blocks
14384         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14385         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14386
14387         echo "Hole at [$hole_start, $hole_end)"
14388         (( hole_start == BS )) ||
14389                 error "no hole at offset $BS after punch"
14390
14391         (( hole_end == BS + punch_size )) ||
14392                 error "data at offset $hole_end < $((BS + punch_size))"
14393 }
14394 run_test 150g "Verify fallocate punch on large range"
14395
14396 #LU-2902 roc_hit was not able to read all values from lproc
14397 function roc_hit_init() {
14398         local list=$(comma_list $(osts_nodes))
14399         local dir=$DIR/$tdir-check
14400         local file=$dir/$tfile
14401         local BEFORE
14402         local AFTER
14403         local idx
14404
14405         test_mkdir $dir
14406         #use setstripe to do a write to every ost
14407         for i in $(seq 0 $((OSTCOUNT-1))); do
14408                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14409                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14410                 idx=$(printf %04x $i)
14411                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14412                         awk '$1 == "cache_access" {sum += $7}
14413                                 END { printf("%0.0f", sum) }')
14414
14415                 cancel_lru_locks osc
14416                 cat $file >/dev/null
14417
14418                 AFTER=$(get_osd_param $list *OST*$idx stats |
14419                         awk '$1 == "cache_access" {sum += $7}
14420                                 END { printf("%0.0f", sum) }')
14421
14422                 echo BEFORE:$BEFORE AFTER:$AFTER
14423                 if ! let "AFTER - BEFORE == 4"; then
14424                         rm -rf $dir
14425                         error "roc_hit is not safe to use"
14426                 fi
14427                 rm $file
14428         done
14429
14430         rm -rf $dir
14431 }
14432
14433 function roc_hit() {
14434         local list=$(comma_list $(osts_nodes))
14435         echo $(get_osd_param $list '' stats |
14436                 awk '$1 == "cache_hit" {sum += $7}
14437                         END { printf("%0.0f", sum) }')
14438 }
14439
14440 function set_cache() {
14441         local on=1
14442
14443         if [ "$2" == "off" ]; then
14444                 on=0;
14445         fi
14446         local list=$(comma_list $(osts_nodes))
14447         set_osd_param $list '' $1_cache_enable $on
14448
14449         cancel_lru_locks osc
14450 }
14451
14452 test_151() {
14453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14454         remote_ost_nodsh && skip "remote OST with nodsh"
14455
14456         local CPAGES=3
14457         local list=$(comma_list $(osts_nodes))
14458
14459         # check whether obdfilter is cache capable at all
14460         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14461                 skip "not cache-capable obdfilter"
14462         fi
14463
14464         # check cache is enabled on all obdfilters
14465         if get_osd_param $list '' read_cache_enable | grep 0; then
14466                 skip "oss cache is disabled"
14467         fi
14468
14469         set_osd_param $list '' writethrough_cache_enable 1
14470
14471         # check write cache is enabled on all obdfilters
14472         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14473                 skip "oss write cache is NOT enabled"
14474         fi
14475
14476         roc_hit_init
14477
14478         #define OBD_FAIL_OBD_NO_LRU  0x609
14479         do_nodes $list $LCTL set_param fail_loc=0x609
14480
14481         # pages should be in the case right after write
14482         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14483                 error "dd failed"
14484
14485         local BEFORE=$(roc_hit)
14486         cancel_lru_locks osc
14487         cat $DIR/$tfile >/dev/null
14488         local AFTER=$(roc_hit)
14489
14490         do_nodes $list $LCTL set_param fail_loc=0
14491
14492         if ! let "AFTER - BEFORE == CPAGES"; then
14493                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14494         fi
14495
14496         cancel_lru_locks osc
14497         # invalidates OST cache
14498         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14499         set_osd_param $list '' read_cache_enable 0
14500         cat $DIR/$tfile >/dev/null
14501
14502         # now data shouldn't be found in the cache
14503         BEFORE=$(roc_hit)
14504         cancel_lru_locks osc
14505         cat $DIR/$tfile >/dev/null
14506         AFTER=$(roc_hit)
14507         if let "AFTER - BEFORE != 0"; then
14508                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14509         fi
14510
14511         set_osd_param $list '' read_cache_enable 1
14512         rm -f $DIR/$tfile
14513 }
14514 run_test 151 "test cache on oss and controls ==============================="
14515
14516 test_152() {
14517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14518
14519         local TF="$TMP/$tfile"
14520
14521         # simulate ENOMEM during write
14522 #define OBD_FAIL_OST_NOMEM      0x226
14523         lctl set_param fail_loc=0x80000226
14524         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14525         cp $TF $DIR/$tfile
14526         sync || error "sync failed"
14527         lctl set_param fail_loc=0
14528
14529         # discard client's cache
14530         cancel_lru_locks osc
14531
14532         # simulate ENOMEM during read
14533         lctl set_param fail_loc=0x80000226
14534         cmp $TF $DIR/$tfile || error "cmp failed"
14535         lctl set_param fail_loc=0
14536
14537         rm -f $TF
14538 }
14539 run_test 152 "test read/write with enomem ============================"
14540
14541 test_153() {
14542         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14543 }
14544 run_test 153 "test if fdatasync does not crash ======================="
14545
14546 dot_lustre_fid_permission_check() {
14547         local fid=$1
14548         local ffid=$MOUNT/.lustre/fid/$fid
14549         local test_dir=$2
14550
14551         echo "stat fid $fid"
14552         stat $ffid > /dev/null || error "stat $ffid failed."
14553         echo "touch fid $fid"
14554         touch $ffid || error "touch $ffid failed."
14555         echo "write to fid $fid"
14556         cat /etc/hosts > $ffid || error "write $ffid failed."
14557         echo "read fid $fid"
14558         diff /etc/hosts $ffid || error "read $ffid failed."
14559         echo "append write to fid $fid"
14560         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14561         echo "rename fid $fid"
14562         mv $ffid $test_dir/$tfile.1 &&
14563                 error "rename $ffid to $tfile.1 should fail."
14564         touch $test_dir/$tfile.1
14565         mv $test_dir/$tfile.1 $ffid &&
14566                 error "rename $tfile.1 to $ffid should fail."
14567         rm -f $test_dir/$tfile.1
14568         echo "truncate fid $fid"
14569         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14570         echo "link fid $fid"
14571         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14572         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14573                 echo "setfacl fid $fid"
14574                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14575                 echo "getfacl fid $fid"
14576                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14577         fi
14578         echo "unlink fid $fid"
14579         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14580         echo "mknod fid $fid"
14581         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14582
14583         fid=[0xf00000400:0x1:0x0]
14584         ffid=$MOUNT/.lustre/fid/$fid
14585
14586         echo "stat non-exist fid $fid"
14587         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14588         echo "write to non-exist fid $fid"
14589         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14590         echo "link new fid $fid"
14591         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14592
14593         mkdir -p $test_dir/$tdir
14594         touch $test_dir/$tdir/$tfile
14595         fid=$($LFS path2fid $test_dir/$tdir)
14596         rc=$?
14597         [ $rc -ne 0 ] &&
14598                 error "error: could not get fid for $test_dir/$dir/$tfile."
14599
14600         ffid=$MOUNT/.lustre/fid/$fid
14601
14602         echo "ls $fid"
14603         ls $ffid > /dev/null || error "ls $ffid failed."
14604         echo "touch $fid/$tfile.1"
14605         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14606
14607         echo "touch $MOUNT/.lustre/fid/$tfile"
14608         touch $MOUNT/.lustre/fid/$tfile && \
14609                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14610
14611         echo "setxattr to $MOUNT/.lustre/fid"
14612         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14613
14614         echo "listxattr for $MOUNT/.lustre/fid"
14615         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14616
14617         echo "delxattr from $MOUNT/.lustre/fid"
14618         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14619
14620         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14621         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14622                 error "touch invalid fid should fail."
14623
14624         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14625         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14626                 error "touch non-normal fid should fail."
14627
14628         echo "rename $tdir to $MOUNT/.lustre/fid"
14629         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14630                 error "rename to $MOUNT/.lustre/fid should fail."
14631
14632         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14633         then            # LU-3547
14634                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14635                 local new_obf_mode=777
14636
14637                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14638                 chmod $new_obf_mode $DIR/.lustre/fid ||
14639                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14640
14641                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14642                 [ $obf_mode -eq $new_obf_mode ] ||
14643                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14644
14645                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14646                 chmod $old_obf_mode $DIR/.lustre/fid ||
14647                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14648         fi
14649
14650         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14651         fid=$($LFS path2fid $test_dir/$tfile-2)
14652
14653         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14654         then # LU-5424
14655                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14656                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14657                         error "create lov data thru .lustre failed"
14658         fi
14659         echo "cp /etc/passwd $test_dir/$tfile-2"
14660         cp /etc/passwd $test_dir/$tfile-2 ||
14661                 error "copy to $test_dir/$tfile-2 failed."
14662         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14663         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14664                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14665
14666         rm -rf $test_dir/tfile.lnk
14667         rm -rf $test_dir/$tfile-2
14668 }
14669
14670 test_154A() {
14671         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14672                 skip "Need MDS version at least 2.4.1"
14673
14674         local tf=$DIR/$tfile
14675         touch $tf
14676
14677         local fid=$($LFS path2fid $tf)
14678         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14679
14680         # check that we get the same pathname back
14681         local rootpath
14682         local found
14683         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14684                 echo "$rootpath $fid"
14685                 found=$($LFS fid2path $rootpath "$fid")
14686                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14687                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14688         done
14689
14690         # check wrong root path format
14691         rootpath=$MOUNT"_wrong"
14692         found=$($LFS fid2path $rootpath "$fid")
14693         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14694 }
14695 run_test 154A "lfs path2fid and fid2path basic checks"
14696
14697 test_154B() {
14698         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14699                 skip "Need MDS version at least 2.4.1"
14700
14701         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14702         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14703         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14704         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14705
14706         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14707         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14708
14709         # check that we get the same pathname
14710         echo "PFID: $PFID, name: $name"
14711         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14712         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14713         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14714                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14715
14716         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14717 }
14718 run_test 154B "verify the ll_decode_linkea tool"
14719
14720 test_154a() {
14721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14722         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14723         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14724                 skip "Need MDS version at least 2.2.51"
14725         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14726
14727         cp /etc/hosts $DIR/$tfile
14728
14729         fid=$($LFS path2fid $DIR/$tfile)
14730         rc=$?
14731         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14732
14733         dot_lustre_fid_permission_check "$fid" $DIR ||
14734                 error "dot lustre permission check $fid failed"
14735
14736         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14737
14738         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14739
14740         touch $MOUNT/.lustre/file &&
14741                 error "creation is not allowed under .lustre"
14742
14743         mkdir $MOUNT/.lustre/dir &&
14744                 error "mkdir is not allowed under .lustre"
14745
14746         rm -rf $DIR/$tfile
14747 }
14748 run_test 154a "Open-by-FID"
14749
14750 test_154b() {
14751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14752         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14754         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14755                 skip "Need MDS version at least 2.2.51"
14756
14757         local remote_dir=$DIR/$tdir/remote_dir
14758         local MDTIDX=1
14759         local rc=0
14760
14761         mkdir -p $DIR/$tdir
14762         $LFS mkdir -i $MDTIDX $remote_dir ||
14763                 error "create remote directory failed"
14764
14765         cp /etc/hosts $remote_dir/$tfile
14766
14767         fid=$($LFS path2fid $remote_dir/$tfile)
14768         rc=$?
14769         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14770
14771         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14772                 error "dot lustre permission check $fid failed"
14773         rm -rf $DIR/$tdir
14774 }
14775 run_test 154b "Open-by-FID for remote directory"
14776
14777 test_154c() {
14778         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14779                 skip "Need MDS version at least 2.4.1"
14780
14781         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14782         local FID1=$($LFS path2fid $DIR/$tfile.1)
14783         local FID2=$($LFS path2fid $DIR/$tfile.2)
14784         local FID3=$($LFS path2fid $DIR/$tfile.3)
14785
14786         local N=1
14787         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14788                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14789                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14790                 local want=FID$N
14791                 [ "$FID" = "${!want}" ] ||
14792                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14793                 N=$((N + 1))
14794         done
14795
14796         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14797         do
14798                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14799                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14800                 N=$((N + 1))
14801         done
14802 }
14803 run_test 154c "lfs path2fid and fid2path multiple arguments"
14804
14805 test_154d() {
14806         remote_mds_nodsh && skip "remote MDS with nodsh"
14807         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14808                 skip "Need MDS version at least 2.5.53"
14809
14810         if remote_mds; then
14811                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14812         else
14813                 nid="0@lo"
14814         fi
14815         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14816         local fd
14817         local cmd
14818
14819         rm -f $DIR/$tfile
14820         touch $DIR/$tfile
14821
14822         local fid=$($LFS path2fid $DIR/$tfile)
14823         # Open the file
14824         fd=$(free_fd)
14825         cmd="exec $fd<$DIR/$tfile"
14826         eval $cmd
14827         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14828         echo "$fid_list" | grep "$fid"
14829         rc=$?
14830
14831         cmd="exec $fd>/dev/null"
14832         eval $cmd
14833         if [ $rc -ne 0 ]; then
14834                 error "FID $fid not found in open files list $fid_list"
14835         fi
14836 }
14837 run_test 154d "Verify open file fid"
14838
14839 test_154e()
14840 {
14841         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14842                 skip "Need MDS version at least 2.6.50"
14843
14844         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14845                 error ".lustre returned by readdir"
14846         fi
14847 }
14848 run_test 154e ".lustre is not returned by readdir"
14849
14850 test_154f() {
14851         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14852
14853         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14854         test_mkdir -p -c1 $DIR/$tdir/d
14855         # test dirs inherit from its stripe
14856         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14857         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14858         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14859         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14860         touch $DIR/f
14861
14862         # get fid of parents
14863         local FID0=$($LFS path2fid $DIR/$tdir/d)
14864         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14865         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14866         local FID3=$($LFS path2fid $DIR)
14867
14868         # check that path2fid --parents returns expected <parent_fid>/name
14869         # 1) test for a directory (single parent)
14870         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14871         [ "$parent" == "$FID0/foo1" ] ||
14872                 error "expected parent: $FID0/foo1, got: $parent"
14873
14874         # 2) test for a file with nlink > 1 (multiple parents)
14875         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14876         echo "$parent" | grep -F "$FID1/$tfile" ||
14877                 error "$FID1/$tfile not returned in parent list"
14878         echo "$parent" | grep -F "$FID2/link" ||
14879                 error "$FID2/link not returned in parent list"
14880
14881         # 3) get parent by fid
14882         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14883         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14884         echo "$parent" | grep -F "$FID1/$tfile" ||
14885                 error "$FID1/$tfile not returned in parent list (by fid)"
14886         echo "$parent" | grep -F "$FID2/link" ||
14887                 error "$FID2/link not returned in parent list (by fid)"
14888
14889         # 4) test for entry in root directory
14890         parent=$($LFS path2fid --parents $DIR/f)
14891         echo "$parent" | grep -F "$FID3/f" ||
14892                 error "$FID3/f not returned in parent list"
14893
14894         # 5) test it on root directory
14895         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14896                 error "$MOUNT should not have parents"
14897
14898         # enable xattr caching and check that linkea is correctly updated
14899         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14900         save_lustre_params client "llite.*.xattr_cache" > $save
14901         lctl set_param llite.*.xattr_cache 1
14902
14903         # 6.1) linkea update on rename
14904         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14905
14906         # get parents by fid
14907         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14908         # foo1 should no longer be returned in parent list
14909         echo "$parent" | grep -F "$FID1" &&
14910                 error "$FID1 should no longer be in parent list"
14911         # the new path should appear
14912         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14913                 error "$FID2/$tfile.moved is not in parent list"
14914
14915         # 6.2) linkea update on unlink
14916         rm -f $DIR/$tdir/d/foo2/link
14917         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14918         # foo2/link should no longer be returned in parent list
14919         echo "$parent" | grep -F "$FID2/link" &&
14920                 error "$FID2/link should no longer be in parent list"
14921         true
14922
14923         rm -f $DIR/f
14924         restore_lustre_params < $save
14925         rm -f $save
14926 }
14927 run_test 154f "get parent fids by reading link ea"
14928
14929 test_154g()
14930 {
14931         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14932         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14933            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14934                 skip "Need MDS version at least 2.6.92"
14935
14936         mkdir -p $DIR/$tdir
14937         llapi_fid_test -d $DIR/$tdir
14938 }
14939 run_test 154g "various llapi FID tests"
14940
14941 test_155_small_load() {
14942     local temp=$TMP/$tfile
14943     local file=$DIR/$tfile
14944
14945     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14946         error "dd of=$temp bs=6096 count=1 failed"
14947     cp $temp $file
14948     cancel_lru_locks $OSC
14949     cmp $temp $file || error "$temp $file differ"
14950
14951     $TRUNCATE $temp 6000
14952     $TRUNCATE $file 6000
14953     cmp $temp $file || error "$temp $file differ (truncate1)"
14954
14955     echo "12345" >>$temp
14956     echo "12345" >>$file
14957     cmp $temp $file || error "$temp $file differ (append1)"
14958
14959     echo "12345" >>$temp
14960     echo "12345" >>$file
14961     cmp $temp $file || error "$temp $file differ (append2)"
14962
14963     rm -f $temp $file
14964     true
14965 }
14966
14967 test_155_big_load() {
14968         remote_ost_nodsh && skip "remote OST with nodsh"
14969
14970         local temp=$TMP/$tfile
14971         local file=$DIR/$tfile
14972
14973         free_min_max
14974         local cache_size=$(do_facet ost$((MAXI+1)) \
14975                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14976         local large_file_size=$((cache_size * 2))
14977
14978         echo "OSS cache size: $cache_size KB"
14979         echo "Large file size: $large_file_size KB"
14980
14981         [ $MAXV -le $large_file_size ] &&
14982                 skip_env "max available OST size needs > $large_file_size KB"
14983
14984         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14985
14986         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14987                 error "dd of=$temp bs=$large_file_size count=1k failed"
14988         cp $temp $file
14989         ls -lh $temp $file
14990         cancel_lru_locks osc
14991         cmp $temp $file || error "$temp $file differ"
14992
14993         rm -f $temp $file
14994         true
14995 }
14996
14997 save_writethrough() {
14998         local facets=$(get_facets OST)
14999
15000         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15001 }
15002
15003 test_155a() {
15004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15005
15006         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15007
15008         save_writethrough $p
15009
15010         set_cache read on
15011         set_cache writethrough on
15012         test_155_small_load
15013         restore_lustre_params < $p
15014         rm -f $p
15015 }
15016 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15017
15018 test_155b() {
15019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15020
15021         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15022
15023         save_writethrough $p
15024
15025         set_cache read on
15026         set_cache writethrough off
15027         test_155_small_load
15028         restore_lustre_params < $p
15029         rm -f $p
15030 }
15031 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15032
15033 test_155c() {
15034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15035
15036         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15037
15038         save_writethrough $p
15039
15040         set_cache read off
15041         set_cache writethrough on
15042         test_155_small_load
15043         restore_lustre_params < $p
15044         rm -f $p
15045 }
15046 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15047
15048 test_155d() {
15049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15050
15051         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15052
15053         save_writethrough $p
15054
15055         set_cache read off
15056         set_cache writethrough off
15057         test_155_small_load
15058         restore_lustre_params < $p
15059         rm -f $p
15060 }
15061 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15062
15063 test_155e() {
15064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15065
15066         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15067
15068         save_writethrough $p
15069
15070         set_cache read on
15071         set_cache writethrough on
15072         test_155_big_load
15073         restore_lustre_params < $p
15074         rm -f $p
15075 }
15076 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15077
15078 test_155f() {
15079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15080
15081         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15082
15083         save_writethrough $p
15084
15085         set_cache read on
15086         set_cache writethrough off
15087         test_155_big_load
15088         restore_lustre_params < $p
15089         rm -f $p
15090 }
15091 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15092
15093 test_155g() {
15094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15095
15096         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15097
15098         save_writethrough $p
15099
15100         set_cache read off
15101         set_cache writethrough on
15102         test_155_big_load
15103         restore_lustre_params < $p
15104         rm -f $p
15105 }
15106 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15107
15108 test_155h() {
15109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15110
15111         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15112
15113         save_writethrough $p
15114
15115         set_cache read off
15116         set_cache writethrough off
15117         test_155_big_load
15118         restore_lustre_params < $p
15119         rm -f $p
15120 }
15121 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15122
15123 test_156() {
15124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15125         remote_ost_nodsh && skip "remote OST with nodsh"
15126         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15127                 skip "stats not implemented on old servers"
15128         [ "$ost1_FSTYPE" = "zfs" ] &&
15129                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15130
15131         local CPAGES=3
15132         local BEFORE
15133         local AFTER
15134         local file="$DIR/$tfile"
15135         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15136
15137         save_writethrough $p
15138         roc_hit_init
15139
15140         log "Turn on read and write cache"
15141         set_cache read on
15142         set_cache writethrough on
15143
15144         log "Write data and read it back."
15145         log "Read should be satisfied from the cache."
15146         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15147         BEFORE=$(roc_hit)
15148         cancel_lru_locks osc
15149         cat $file >/dev/null
15150         AFTER=$(roc_hit)
15151         if ! let "AFTER - BEFORE == CPAGES"; then
15152                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15153         else
15154                 log "cache hits: before: $BEFORE, after: $AFTER"
15155         fi
15156
15157         log "Read again; it should be satisfied from the cache."
15158         BEFORE=$AFTER
15159         cancel_lru_locks osc
15160         cat $file >/dev/null
15161         AFTER=$(roc_hit)
15162         if ! let "AFTER - BEFORE == CPAGES"; then
15163                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15164         else
15165                 log "cache hits:: before: $BEFORE, after: $AFTER"
15166         fi
15167
15168         log "Turn off the read cache and turn on the write cache"
15169         set_cache read off
15170         set_cache writethrough on
15171
15172         log "Read again; it should be satisfied from the cache."
15173         BEFORE=$(roc_hit)
15174         cancel_lru_locks osc
15175         cat $file >/dev/null
15176         AFTER=$(roc_hit)
15177         if ! let "AFTER - BEFORE == CPAGES"; then
15178                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15179         else
15180                 log "cache hits:: before: $BEFORE, after: $AFTER"
15181         fi
15182
15183         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15184                 # > 2.12.56 uses pagecache if cached
15185                 log "Read again; it should not be satisfied from the cache."
15186                 BEFORE=$AFTER
15187                 cancel_lru_locks osc
15188                 cat $file >/dev/null
15189                 AFTER=$(roc_hit)
15190                 if ! let "AFTER - BEFORE == 0"; then
15191                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15192                 else
15193                         log "cache hits:: before: $BEFORE, after: $AFTER"
15194                 fi
15195         fi
15196
15197         log "Write data and read it back."
15198         log "Read should be satisfied from the cache."
15199         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15200         BEFORE=$(roc_hit)
15201         cancel_lru_locks osc
15202         cat $file >/dev/null
15203         AFTER=$(roc_hit)
15204         if ! let "AFTER - BEFORE == CPAGES"; then
15205                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15206         else
15207                 log "cache hits:: before: $BEFORE, after: $AFTER"
15208         fi
15209
15210         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15211                 # > 2.12.56 uses pagecache if cached
15212                 log "Read again; it should not be satisfied from the cache."
15213                 BEFORE=$AFTER
15214                 cancel_lru_locks osc
15215                 cat $file >/dev/null
15216                 AFTER=$(roc_hit)
15217                 if ! let "AFTER - BEFORE == 0"; then
15218                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15219                 else
15220                         log "cache hits:: before: $BEFORE, after: $AFTER"
15221                 fi
15222         fi
15223
15224         log "Turn off read and write cache"
15225         set_cache read off
15226         set_cache writethrough off
15227
15228         log "Write data and read it back"
15229         log "It should not be satisfied from the cache."
15230         rm -f $file
15231         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15232         cancel_lru_locks osc
15233         BEFORE=$(roc_hit)
15234         cat $file >/dev/null
15235         AFTER=$(roc_hit)
15236         if ! let "AFTER - BEFORE == 0"; then
15237                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15238         else
15239                 log "cache hits:: before: $BEFORE, after: $AFTER"
15240         fi
15241
15242         log "Turn on the read cache and turn off the write cache"
15243         set_cache read on
15244         set_cache writethrough off
15245
15246         log "Write data and read it back"
15247         log "It should not be satisfied from the cache."
15248         rm -f $file
15249         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15250         BEFORE=$(roc_hit)
15251         cancel_lru_locks osc
15252         cat $file >/dev/null
15253         AFTER=$(roc_hit)
15254         if ! let "AFTER - BEFORE == 0"; then
15255                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15256         else
15257                 log "cache hits:: before: $BEFORE, after: $AFTER"
15258         fi
15259
15260         log "Read again; it should be satisfied from the cache."
15261         BEFORE=$(roc_hit)
15262         cancel_lru_locks osc
15263         cat $file >/dev/null
15264         AFTER=$(roc_hit)
15265         if ! let "AFTER - BEFORE == CPAGES"; then
15266                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15267         else
15268                 log "cache hits:: before: $BEFORE, after: $AFTER"
15269         fi
15270
15271         restore_lustre_params < $p
15272         rm -f $p $file
15273 }
15274 run_test 156 "Verification of tunables"
15275
15276 test_160a() {
15277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15278         remote_mds_nodsh && skip "remote MDS with nodsh"
15279         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15280                 skip "Need MDS version at least 2.2.0"
15281
15282         changelog_register || error "changelog_register failed"
15283         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15284         changelog_users $SINGLEMDS | grep -q $cl_user ||
15285                 error "User $cl_user not found in changelog_users"
15286
15287         mkdir_on_mdt0 $DIR/$tdir
15288
15289         # change something
15290         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15291         changelog_clear 0 || error "changelog_clear failed"
15292         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15293         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15294         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15295         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15296         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15297         rm $DIR/$tdir/pics/desktop.jpg
15298
15299         echo "verifying changelog mask"
15300         changelog_chmask "-MKDIR"
15301         changelog_chmask "-CLOSE"
15302
15303         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15304         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15305
15306         changelog_chmask "+MKDIR"
15307         changelog_chmask "+CLOSE"
15308
15309         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15310         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15311
15312         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15313         CLOSES=$(changelog_dump | grep -c "CLOSE")
15314         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15315         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15316
15317         # verify contents
15318         echo "verifying target fid"
15319         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15320         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15321         [ "$fidc" == "$fidf" ] ||
15322                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15323         echo "verifying parent fid"
15324         # The FID returned from the Changelog may be the directory shard on
15325         # a different MDT, and not the FID returned by path2fid on the parent.
15326         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15327         # since this is what will matter when recreating this file in the tree.
15328         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15329         local pathp=$($LFS fid2path $MOUNT "$fidp")
15330         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15331                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15332
15333         echo "getting records for $cl_user"
15334         changelog_users $SINGLEMDS
15335         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15336         local nclr=3
15337         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15338                 error "changelog_clear failed"
15339         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15340         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15341         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15342                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15343
15344         local min0_rec=$(changelog_users $SINGLEMDS |
15345                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15346         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15347                           awk '{ print $1; exit; }')
15348
15349         changelog_dump | tail -n 5
15350         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15351         [ $first_rec == $((min0_rec + 1)) ] ||
15352                 error "first index should be $min0_rec + 1 not $first_rec"
15353
15354         # LU-3446 changelog index reset on MDT restart
15355         local cur_rec1=$(changelog_users $SINGLEMDS |
15356                          awk '/^current.index:/ { print $NF }')
15357         changelog_clear 0 ||
15358                 error "clear all changelog records for $cl_user failed"
15359         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15360         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15361                 error "Fail to start $SINGLEMDS"
15362         local cur_rec2=$(changelog_users $SINGLEMDS |
15363                          awk '/^current.index:/ { print $NF }')
15364         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15365         [ $cur_rec1 == $cur_rec2 ] ||
15366                 error "current index should be $cur_rec1 not $cur_rec2"
15367
15368         echo "verifying users from this test are deregistered"
15369         changelog_deregister || error "changelog_deregister failed"
15370         changelog_users $SINGLEMDS | grep -q $cl_user &&
15371                 error "User '$cl_user' still in changelog_users"
15372
15373         # lctl get_param -n mdd.*.changelog_users
15374         # current_index: 144
15375         # ID    index (idle seconds)
15376         # cl3   144   (2) mask=<list>
15377         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15378                 # this is the normal case where all users were deregistered
15379                 # make sure no new records are added when no users are present
15380                 local last_rec1=$(changelog_users $SINGLEMDS |
15381                                   awk '/^current.index:/ { print $NF }')
15382                 touch $DIR/$tdir/chloe
15383                 local last_rec2=$(changelog_users $SINGLEMDS |
15384                                   awk '/^current.index:/ { print $NF }')
15385                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15386                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15387         else
15388                 # any changelog users must be leftovers from a previous test
15389                 changelog_users $SINGLEMDS
15390                 echo "other changelog users; can't verify off"
15391         fi
15392 }
15393 run_test 160a "changelog sanity"
15394
15395 test_160b() { # LU-3587
15396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15397         remote_mds_nodsh && skip "remote MDS with nodsh"
15398         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15399                 skip "Need MDS version at least 2.2.0"
15400
15401         changelog_register || error "changelog_register failed"
15402         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15403         changelog_users $SINGLEMDS | grep -q $cl_user ||
15404                 error "User '$cl_user' not found in changelog_users"
15405
15406         local longname1=$(str_repeat a 255)
15407         local longname2=$(str_repeat b 255)
15408
15409         cd $DIR
15410         echo "creating very long named file"
15411         touch $longname1 || error "create of '$longname1' failed"
15412         echo "renaming very long named file"
15413         mv $longname1 $longname2
15414
15415         changelog_dump | grep RENME | tail -n 5
15416         rm -f $longname2
15417 }
15418 run_test 160b "Verify that very long rename doesn't crash in changelog"
15419
15420 test_160c() {
15421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15422         remote_mds_nodsh && skip "remote MDS with nodsh"
15423
15424         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15425                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15426                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15427                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15428
15429         local rc=0
15430
15431         # Registration step
15432         changelog_register || error "changelog_register failed"
15433
15434         rm -rf $DIR/$tdir
15435         mkdir -p $DIR/$tdir
15436         $MCREATE $DIR/$tdir/foo_160c
15437         changelog_chmask "-TRUNC"
15438         $TRUNCATE $DIR/$tdir/foo_160c 200
15439         changelog_chmask "+TRUNC"
15440         $TRUNCATE $DIR/$tdir/foo_160c 199
15441         changelog_dump | tail -n 5
15442         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15443         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15444 }
15445 run_test 160c "verify that changelog log catch the truncate event"
15446
15447 test_160d() {
15448         remote_mds_nodsh && skip "remote MDS with nodsh"
15449         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15451         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15452                 skip "Need MDS version at least 2.7.60"
15453
15454         # Registration step
15455         changelog_register || error "changelog_register failed"
15456
15457         mkdir -p $DIR/$tdir/migrate_dir
15458         changelog_clear 0 || error "changelog_clear failed"
15459
15460         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15461         changelog_dump | tail -n 5
15462         local migrates=$(changelog_dump | grep -c "MIGRT")
15463         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15464 }
15465 run_test 160d "verify that changelog log catch the migrate event"
15466
15467 test_160e() {
15468         remote_mds_nodsh && skip "remote MDS with nodsh"
15469
15470         # Create a user
15471         changelog_register || error "changelog_register failed"
15472
15473         # Delete a future user (expect fail)
15474         local MDT0=$(facet_svc $SINGLEMDS)
15475         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15476         local rc=$?
15477
15478         if [ $rc -eq 0 ]; then
15479                 error "Deleted non-existant user cl77"
15480         elif [ $rc -ne 2 ]; then
15481                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15482         fi
15483
15484         # Clear to a bad index (1 billion should be safe)
15485         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15486         rc=$?
15487
15488         if [ $rc -eq 0 ]; then
15489                 error "Successfully cleared to invalid CL index"
15490         elif [ $rc -ne 22 ]; then
15491                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15492         fi
15493 }
15494 run_test 160e "changelog negative testing (should return errors)"
15495
15496 test_160f() {
15497         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15498         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15499                 skip "Need MDS version at least 2.10.56"
15500
15501         local mdts=$(comma_list $(mdts_nodes))
15502
15503         # Create a user
15504         changelog_register || error "first changelog_register failed"
15505         changelog_register || error "second changelog_register failed"
15506         local cl_users
15507         declare -A cl_user1
15508         declare -A cl_user2
15509         local user_rec1
15510         local user_rec2
15511         local i
15512
15513         # generate some changelog records to accumulate on each MDT
15514         # use all_char because created files should be evenly distributed
15515         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15516                 error "test_mkdir $tdir failed"
15517         log "$(date +%s): creating first files"
15518         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15519                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15520                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15521         done
15522
15523         # check changelogs have been generated
15524         local start=$SECONDS
15525         local idle_time=$((MDSCOUNT * 5 + 5))
15526         local nbcl=$(changelog_dump | wc -l)
15527         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15528
15529         for param in "changelog_max_idle_time=$idle_time" \
15530                      "changelog_gc=1" \
15531                      "changelog_min_gc_interval=2" \
15532                      "changelog_min_free_cat_entries=3"; do
15533                 local MDT0=$(facet_svc $SINGLEMDS)
15534                 local var="${param%=*}"
15535                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15536
15537                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15538                 do_nodes $mdts $LCTL set_param mdd.*.$param
15539         done
15540
15541         # force cl_user2 to be idle (1st part), but also cancel the
15542         # cl_user1 records so that it is not evicted later in the test.
15543         local sleep1=$((idle_time / 2))
15544         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15545         sleep $sleep1
15546
15547         # simulate changelog catalog almost full
15548         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15549         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15550
15551         for i in $(seq $MDSCOUNT); do
15552                 cl_users=(${CL_USERS[mds$i]})
15553                 cl_user1[mds$i]="${cl_users[0]}"
15554                 cl_user2[mds$i]="${cl_users[1]}"
15555
15556                 [ -n "${cl_user1[mds$i]}" ] ||
15557                         error "mds$i: no user registered"
15558                 [ -n "${cl_user2[mds$i]}" ] ||
15559                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15560
15561                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15562                 [ -n "$user_rec1" ] ||
15563                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15564                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15565                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15566                 [ -n "$user_rec2" ] ||
15567                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15568                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15569                      "$user_rec1 + 2 == $user_rec2"
15570                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15571                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15572                               "$user_rec1 + 2, but is $user_rec2"
15573                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15574                 [ -n "$user_rec2" ] ||
15575                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15576                 [ $user_rec1 == $user_rec2 ] ||
15577                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15578                               "$user_rec1, but is $user_rec2"
15579         done
15580
15581         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15582         local sleep2=$((idle_time - (SECONDS - start) + 1))
15583         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15584         sleep $sleep2
15585
15586         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15587         # cl_user1 should be OK because it recently processed records.
15588         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15589         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15590                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15591                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15592         done
15593
15594         # ensure gc thread is done
15595         for i in $(mdts_nodes); do
15596                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15597                         error "$i: GC-thread not done"
15598         done
15599
15600         local first_rec
15601         for (( i = 1; i <= MDSCOUNT; i++ )); do
15602                 # check cl_user1 still registered
15603                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15604                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15605                 # check cl_user2 unregistered
15606                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15607                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15608
15609                 # check changelogs are present and starting at $user_rec1 + 1
15610                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15611                 [ -n "$user_rec1" ] ||
15612                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15613                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15614                             awk '{ print $1; exit; }')
15615
15616                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15617                 [ $((user_rec1 + 1)) == $first_rec ] ||
15618                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15619         done
15620 }
15621 run_test 160f "changelog garbage collect (timestamped users)"
15622
15623 test_160g() {
15624         remote_mds_nodsh && skip "remote MDS with nodsh"
15625         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15626                 skip "Need MDS version at least 2.10.56"
15627
15628         local mdts=$(comma_list $(mdts_nodes))
15629
15630         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15631         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15632
15633         # Create a user
15634         changelog_register || error "first changelog_register failed"
15635         changelog_register || error "second changelog_register failed"
15636         local cl_users
15637         declare -A cl_user1
15638         declare -A cl_user2
15639         local user_rec1
15640         local user_rec2
15641         local i
15642
15643         # generate some changelog records to accumulate on each MDT
15644         # use all_char because created files should be evenly distributed
15645         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15646                 error "test_mkdir $tdir failed"
15647         for ((i = 0; i < MDSCOUNT; i++)); do
15648                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15649                         error "create $DIR/$tdir/d$i.1 failed"
15650         done
15651
15652         # check changelogs have been generated
15653         local nbcl=$(changelog_dump | wc -l)
15654         (( $nbcl > 0 )) || error "no changelogs found"
15655
15656         # reduce the max_idle_indexes value to make sure we exceed it
15657         for param in "changelog_max_idle_indexes=1" \
15658                      "changelog_gc=1" \
15659                      "changelog_min_gc_interval=2" \
15660                      "changelog_min_free_cat_entries=3"; do
15661                 local MDT0=$(facet_svc $SINGLEMDS)
15662                 local var="${param%=*}"
15663                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15664
15665                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15666                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15667                         error "unable to set mdd.*.$param"
15668         done
15669
15670         # simulate changelog catalog almost full
15671         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15672         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15673
15674         local start=$SECONDS
15675         for i in $(seq $MDSCOUNT); do
15676                 cl_users=(${CL_USERS[mds$i]})
15677                 cl_user1[mds$i]="${cl_users[0]}"
15678                 cl_user2[mds$i]="${cl_users[1]}"
15679
15680                 [ -n "${cl_user1[mds$i]}" ] ||
15681                         error "mds$i: no user registered"
15682                 [ -n "${cl_user2[mds$i]}" ] ||
15683                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15684
15685                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15686                 [ -n "$user_rec1" ] ||
15687                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15688                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15689                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15690                 [ -n "$user_rec2" ] ||
15691                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15692                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15693                      "$user_rec1 + 2 == $user_rec2"
15694                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15695                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15696                               "$user_rec1 + 2, but is $user_rec2"
15697                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15698                 [ -n "$user_rec2" ] ||
15699                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15700                 [ $user_rec1 == $user_rec2 ] ||
15701                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15702                               "$user_rec1, but is $user_rec2"
15703         done
15704
15705         # ensure we are past the previous changelog_min_gc_interval set above
15706         local sleep2=$((start + 2 - SECONDS))
15707         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15708
15709         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15710         # cl_user1 should be OK because it recently processed records.
15711         for ((i = 0; i < MDSCOUNT; i++)); do
15712                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15713                         error "create $DIR/$tdir/d$i.3 failed"
15714         done
15715
15716         # ensure gc thread is done
15717         for i in $(mdts_nodes); do
15718                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15719                         error "$i: GC-thread not done"
15720         done
15721
15722         local first_rec
15723         for (( i = 1; i <= MDSCOUNT; i++ )); do
15724                 # check cl_user1 still registered
15725                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15726                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15727                 # check cl_user2 unregistered
15728                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15729                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15730
15731                 # check changelogs are present and starting at $user_rec1 + 1
15732                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15733                 [ -n "$user_rec1" ] ||
15734                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15735                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15736                             awk '{ print $1; exit; }')
15737
15738                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15739                 [ $((user_rec1 + 1)) == $first_rec ] ||
15740                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15741         done
15742 }
15743 run_test 160g "changelog garbage collect (old users)"
15744
15745 test_160h() {
15746         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15747         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15748                 skip "Need MDS version at least 2.10.56"
15749
15750         local mdts=$(comma_list $(mdts_nodes))
15751
15752         # Create a user
15753         changelog_register || error "first changelog_register failed"
15754         changelog_register || error "second changelog_register failed"
15755         local cl_users
15756         declare -A cl_user1
15757         declare -A cl_user2
15758         local user_rec1
15759         local user_rec2
15760         local i
15761
15762         # generate some changelog records to accumulate on each MDT
15763         # use all_char because created files should be evenly distributed
15764         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15765                 error "test_mkdir $tdir failed"
15766         for ((i = 0; i < MDSCOUNT; i++)); do
15767                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15768                         error "create $DIR/$tdir/d$i.1 failed"
15769         done
15770
15771         # check changelogs have been generated
15772         local nbcl=$(changelog_dump | wc -l)
15773         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15774
15775         for param in "changelog_max_idle_time=10" \
15776                      "changelog_gc=1" \
15777                      "changelog_min_gc_interval=2"; do
15778                 local MDT0=$(facet_svc $SINGLEMDS)
15779                 local var="${param%=*}"
15780                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15781
15782                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15783                 do_nodes $mdts $LCTL set_param mdd.*.$param
15784         done
15785
15786         # force cl_user2 to be idle (1st part)
15787         sleep 9
15788
15789         for i in $(seq $MDSCOUNT); do
15790                 cl_users=(${CL_USERS[mds$i]})
15791                 cl_user1[mds$i]="${cl_users[0]}"
15792                 cl_user2[mds$i]="${cl_users[1]}"
15793
15794                 [ -n "${cl_user1[mds$i]}" ] ||
15795                         error "mds$i: no user registered"
15796                 [ -n "${cl_user2[mds$i]}" ] ||
15797                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15798
15799                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15800                 [ -n "$user_rec1" ] ||
15801                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15802                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15803                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15804                 [ -n "$user_rec2" ] ||
15805                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15806                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15807                      "$user_rec1 + 2 == $user_rec2"
15808                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15809                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15810                               "$user_rec1 + 2, but is $user_rec2"
15811                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15812                 [ -n "$user_rec2" ] ||
15813                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15814                 [ $user_rec1 == $user_rec2 ] ||
15815                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15816                               "$user_rec1, but is $user_rec2"
15817         done
15818
15819         # force cl_user2 to be idle (2nd part) and to reach
15820         # changelog_max_idle_time
15821         sleep 2
15822
15823         # force each GC-thread start and block then
15824         # one per MDT/MDD, set fail_val accordingly
15825         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15826         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15827
15828         # generate more changelogs to trigger fail_loc
15829         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15830                 error "create $DIR/$tdir/${tfile}bis failed"
15831
15832         # stop MDT to stop GC-thread, should be done in back-ground as it will
15833         # block waiting for the thread to be released and exit
15834         declare -A stop_pids
15835         for i in $(seq $MDSCOUNT); do
15836                 stop mds$i &
15837                 stop_pids[mds$i]=$!
15838         done
15839
15840         for i in $(mdts_nodes); do
15841                 local facet
15842                 local nb=0
15843                 local facets=$(facets_up_on_host $i)
15844
15845                 for facet in ${facets//,/ }; do
15846                         if [[ $facet == mds* ]]; then
15847                                 nb=$((nb + 1))
15848                         fi
15849                 done
15850                 # ensure each MDS's gc threads are still present and all in "R"
15851                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15852                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15853                         error "$i: expected $nb GC-thread"
15854                 wait_update $i \
15855                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15856                         "R" 20 ||
15857                         error "$i: GC-thread not found in R-state"
15858                 # check umounts of each MDT on MDS have reached kthread_stop()
15859                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15860                         error "$i: expected $nb umount"
15861                 wait_update $i \
15862                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15863                         error "$i: umount not found in D-state"
15864         done
15865
15866         # release all GC-threads
15867         do_nodes $mdts $LCTL set_param fail_loc=0
15868
15869         # wait for MDT stop to complete
15870         for i in $(seq $MDSCOUNT); do
15871                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15872         done
15873
15874         # XXX
15875         # may try to check if any orphan changelog records are present
15876         # via ldiskfs/zfs and llog_reader...
15877
15878         # re-start/mount MDTs
15879         for i in $(seq $MDSCOUNT); do
15880                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15881                         error "Fail to start mds$i"
15882         done
15883
15884         local first_rec
15885         for i in $(seq $MDSCOUNT); do
15886                 # check cl_user1 still registered
15887                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15888                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15889                 # check cl_user2 unregistered
15890                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15891                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15892
15893                 # check changelogs are present and starting at $user_rec1 + 1
15894                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15895                 [ -n "$user_rec1" ] ||
15896                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15897                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15898                             awk '{ print $1; exit; }')
15899
15900                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15901                 [ $((user_rec1 + 1)) == $first_rec ] ||
15902                         error "mds$i: first index should be $user_rec1 + 1, " \
15903                               "but is $first_rec"
15904         done
15905 }
15906 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15907               "during mount"
15908
15909 test_160i() {
15910
15911         local mdts=$(comma_list $(mdts_nodes))
15912
15913         changelog_register || error "first changelog_register failed"
15914
15915         # generate some changelog records to accumulate on each MDT
15916         # use all_char because created files should be evenly distributed
15917         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15918                 error "test_mkdir $tdir failed"
15919         for ((i = 0; i < MDSCOUNT; i++)); do
15920                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15921                         error "create $DIR/$tdir/d$i.1 failed"
15922         done
15923
15924         # check changelogs have been generated
15925         local nbcl=$(changelog_dump | wc -l)
15926         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15927
15928         # simulate race between register and unregister
15929         # XXX as fail_loc is set per-MDS, with DNE configs the race
15930         # simulation will only occur for one MDT per MDS and for the
15931         # others the normal race scenario will take place
15932         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15933         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15934         do_nodes $mdts $LCTL set_param fail_val=1
15935
15936         # unregister 1st user
15937         changelog_deregister &
15938         local pid1=$!
15939         # wait some time for deregister work to reach race rdv
15940         sleep 2
15941         # register 2nd user
15942         changelog_register || error "2nd user register failed"
15943
15944         wait $pid1 || error "1st user deregister failed"
15945
15946         local i
15947         local last_rec
15948         declare -A LAST_REC
15949         for i in $(seq $MDSCOUNT); do
15950                 if changelog_users mds$i | grep "^cl"; then
15951                         # make sure new records are added with one user present
15952                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15953                                           awk '/^current.index:/ { print $NF }')
15954                 else
15955                         error "mds$i has no user registered"
15956                 fi
15957         done
15958
15959         # generate more changelog records to accumulate on each MDT
15960         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15961                 error "create $DIR/$tdir/${tfile}bis failed"
15962
15963         for i in $(seq $MDSCOUNT); do
15964                 last_rec=$(changelog_users $SINGLEMDS |
15965                            awk '/^current.index:/ { print $NF }')
15966                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15967                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15968                         error "changelogs are off on mds$i"
15969         done
15970 }
15971 run_test 160i "changelog user register/unregister race"
15972
15973 test_160j() {
15974         remote_mds_nodsh && skip "remote MDS with nodsh"
15975         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15976                 skip "Need MDS version at least 2.12.56"
15977
15978         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15979         stack_trap "umount $MOUNT2" EXIT
15980
15981         changelog_register || error "first changelog_register failed"
15982         stack_trap "changelog_deregister" EXIT
15983
15984         # generate some changelog
15985         # use all_char because created files should be evenly distributed
15986         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15987                 error "mkdir $tdir failed"
15988         for ((i = 0; i < MDSCOUNT; i++)); do
15989                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15990                         error "create $DIR/$tdir/d$i.1 failed"
15991         done
15992
15993         # open the changelog device
15994         exec 3>/dev/changelog-$FSNAME-MDT0000
15995         stack_trap "exec 3>&-" EXIT
15996         exec 4</dev/changelog-$FSNAME-MDT0000
15997         stack_trap "exec 4<&-" EXIT
15998
15999         # umount the first lustre mount
16000         umount $MOUNT
16001         stack_trap "mount_client $MOUNT" EXIT
16002
16003         # read changelog, which may or may not fail, but should not crash
16004         cat <&4 >/dev/null
16005
16006         # clear changelog
16007         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16008         changelog_users $SINGLEMDS | grep -q $cl_user ||
16009                 error "User $cl_user not found in changelog_users"
16010
16011         printf 'clear:'$cl_user':0' >&3
16012 }
16013 run_test 160j "client can be umounted while its chanangelog is being used"
16014
16015 test_160k() {
16016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16017         remote_mds_nodsh && skip "remote MDS with nodsh"
16018
16019         mkdir -p $DIR/$tdir/1/1
16020
16021         changelog_register || error "changelog_register failed"
16022         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16023
16024         changelog_users $SINGLEMDS | grep -q $cl_user ||
16025                 error "User '$cl_user' not found in changelog_users"
16026 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16027         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16028         rmdir $DIR/$tdir/1/1 & sleep 1
16029         mkdir $DIR/$tdir/2
16030         touch $DIR/$tdir/2/2
16031         rm -rf $DIR/$tdir/2
16032
16033         wait
16034         sleep 4
16035
16036         changelog_dump | grep rmdir || error "rmdir not recorded"
16037 }
16038 run_test 160k "Verify that changelog records are not lost"
16039
16040 # Verifies that a file passed as a parameter has recently had an operation
16041 # performed on it that has generated an MTIME changelog which contains the
16042 # correct parent FID. As files might reside on a different MDT from the
16043 # parent directory in DNE configurations, the FIDs are translated to paths
16044 # before being compared, which should be identical
16045 compare_mtime_changelog() {
16046         local file="${1}"
16047         local mdtidx
16048         local mtime
16049         local cl_fid
16050         local pdir
16051         local dir
16052
16053         mdtidx=$($LFS getstripe --mdt-index $file)
16054         mdtidx=$(printf "%04x" $mdtidx)
16055
16056         # Obtain the parent FID from the MTIME changelog
16057         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16058         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16059
16060         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16061         [ -z "$cl_fid" ] && error "parent FID not present"
16062
16063         # Verify that the path for the parent FID is the same as the path for
16064         # the test directory
16065         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16066
16067         dir=$(dirname $1)
16068
16069         [[ "${pdir%/}" == "$dir" ]] ||
16070                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16071 }
16072
16073 test_160l() {
16074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16075
16076         remote_mds_nodsh && skip "remote MDS with nodsh"
16077         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16078                 skip "Need MDS version at least 2.13.55"
16079
16080         local cl_user
16081
16082         changelog_register || error "changelog_register failed"
16083         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16084
16085         changelog_users $SINGLEMDS | grep -q $cl_user ||
16086                 error "User '$cl_user' not found in changelog_users"
16087
16088         # Clear some types so that MTIME changelogs are generated
16089         changelog_chmask "-CREAT"
16090         changelog_chmask "-CLOSE"
16091
16092         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16093
16094         # Test CL_MTIME during setattr
16095         touch $DIR/$tdir/$tfile
16096         compare_mtime_changelog $DIR/$tdir/$tfile
16097
16098         # Test CL_MTIME during close
16099         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16100         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16101 }
16102 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16103
16104 test_160m() {
16105         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16106         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16107                 skip "Need MDS version at least 2.14.51"
16108         local cl_users
16109         local cl_user1
16110         local cl_user2
16111         local pid1
16112
16113         # Create a user
16114         changelog_register || error "first changelog_register failed"
16115         changelog_register || error "second changelog_register failed"
16116
16117         cl_users=(${CL_USERS[mds1]})
16118         cl_user1="${cl_users[0]}"
16119         cl_user2="${cl_users[1]}"
16120         # generate some changelog records to accumulate on MDT0
16121         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16122         createmany -m $DIR/$tdir/$tfile 50 ||
16123                 error "create $DIR/$tdir/$tfile failed"
16124         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16125         rm -f $DIR/$tdir
16126
16127         # check changelogs have been generated
16128         local nbcl=$(changelog_dump | wc -l)
16129         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16130
16131 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16132         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16133
16134         __changelog_clear mds1 $cl_user1 +10
16135         __changelog_clear mds1 $cl_user2 0 &
16136         pid1=$!
16137         sleep 2
16138         __changelog_clear mds1 $cl_user1 0 ||
16139                 error "fail to cancel record for $cl_user1"
16140         wait $pid1
16141         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16142 }
16143 run_test 160m "Changelog clear race"
16144
16145 test_160n() {
16146         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16147         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16148                 skip "Need MDS version at least 2.14.51"
16149         local cl_users
16150         local cl_user1
16151         local cl_user2
16152         local pid1
16153         local first_rec
16154         local last_rec=0
16155
16156         # Create a user
16157         changelog_register || error "first changelog_register failed"
16158
16159         cl_users=(${CL_USERS[mds1]})
16160         cl_user1="${cl_users[0]}"
16161
16162         # generate some changelog records to accumulate on MDT0
16163         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16164         first_rec=$(changelog_users $SINGLEMDS |
16165                         awk '/^current.index:/ { print $NF }')
16166         while (( last_rec < (( first_rec + 65000)) )); do
16167                 createmany -m $DIR/$tdir/$tfile 10000 ||
16168                         error "create $DIR/$tdir/$tfile failed"
16169
16170                 for i in $(seq 0 10000); do
16171                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16172                                 > /dev/null
16173                 done
16174
16175                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16176                         error "unlinkmany failed unlink"
16177                 last_rec=$(changelog_users $SINGLEMDS |
16178                         awk '/^current.index:/ { print $NF }')
16179                 echo last record $last_rec
16180                 (( last_rec == 0 )) && error "no changelog found"
16181         done
16182
16183 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16184         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16185
16186         __changelog_clear mds1 $cl_user1 0 &
16187         pid1=$!
16188         sleep 2
16189         __changelog_clear mds1 $cl_user1 0 ||
16190                 error "fail to cancel record for $cl_user1"
16191         wait $pid1
16192         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16193 }
16194 run_test 160n "Changelog destroy race"
16195
16196 test_160o() {
16197         local mdt="$(facet_svc $SINGLEMDS)"
16198
16199         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16200         remote_mds_nodsh && skip "remote MDS with nodsh"
16201         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16202                 skip "Need MDS version at least 2.14.52"
16203
16204         changelog_register --user test_160o -m unlnk+close+open ||
16205                 error "changelog_register failed"
16206         # drop server mask so it doesn't interfere
16207         do_facet $SINGLEMDS $LCTL --device $mdt \
16208                                 changelog_register -u "Tt3_-#" &&
16209                 error "bad symbols in name should fail"
16210
16211         do_facet $SINGLEMDS $LCTL --device $mdt \
16212                                 changelog_register -u test_160o &&
16213                 error "the same name registration should fail"
16214
16215         do_facet $SINGLEMDS $LCTL --device $mdt \
16216                         changelog_register -u test_160toolongname &&
16217                 error "too long name registration should fail"
16218
16219         changelog_chmask "MARK+HSM"
16220         lctl get_param mdd.*.changelog*mask
16221         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16222         changelog_users $SINGLEMDS | grep -q $cl_user ||
16223                 error "User $cl_user not found in changelog_users"
16224         #verify username
16225         echo $cl_user | grep -q test_160o ||
16226                 error "User $cl_user has no specific name 'test160o'"
16227
16228         # change something
16229         changelog_clear 0 || error "changelog_clear failed"
16230         # generate some changelog records to accumulate on MDT0
16231         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16232         touch $DIR/$tdir/$tfile                 # open 1
16233
16234         OPENS=$(changelog_dump | grep -c "OPEN")
16235         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16236
16237         # must be no MKDIR it wasn't set as user mask
16238         MKDIR=$(changelog_dump | grep -c "MKDIR")
16239         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16240
16241         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16242                                 mdd.$mdt.changelog_current_mask -n)
16243         # register maskless user
16244         changelog_register || error "changelog_register failed"
16245         # effective mask should be not changed because it is not minimal
16246         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16247                                 mdd.$mdt.changelog_current_mask -n)
16248         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16249         # set server mask to minimal value
16250         changelog_chmask "MARK"
16251         # check effective mask again, should be treated as DEFMASK now
16252         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16253                                 mdd.$mdt.changelog_current_mask -n)
16254         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16255
16256         do_facet $SINGLEMDS $LCTL --device $mdt \
16257                                 changelog_deregister -u test_160o ||
16258                 error "cannot deregister by name"
16259 }
16260 run_test 160o "changelog user name and mask"
16261
16262 test_160p() {
16263         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16264         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16265                 skip "Need MDS version at least 2.14.51"
16266         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16267         local cl_users
16268         local cl_user1
16269         local entry_count
16270
16271         # Create a user
16272         changelog_register || error "first changelog_register failed"
16273
16274         cl_users=(${CL_USERS[mds1]})
16275         cl_user1="${cl_users[0]}"
16276
16277         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16278         createmany -m $DIR/$tdir/$tfile 50 ||
16279                 error "create $DIR/$tdir/$tfile failed"
16280         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16281         rm -rf $DIR/$tdir
16282
16283         # check changelogs have been generated
16284         entry_count=$(changelog_dump | wc -l)
16285         ((entry_count != 0)) || error "no changelog entries found"
16286
16287         # remove changelog_users and check that orphan entries are removed
16288         stop mds1
16289         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16290         start mds1 || error "cannot start mdt"
16291         entry_count=$(changelog_dump | wc -l)
16292         ((entry_count == 0)) ||
16293                 error "found $entry_count changelog entries, expected none"
16294 }
16295 run_test 160p "Changelog orphan cleanup with no users"
16296
16297 test_161a() {
16298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16299
16300         test_mkdir -c1 $DIR/$tdir
16301         cp /etc/hosts $DIR/$tdir/$tfile
16302         test_mkdir -c1 $DIR/$tdir/foo1
16303         test_mkdir -c1 $DIR/$tdir/foo2
16304         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16305         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16306         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16307         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16308         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16309         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16310                 $LFS fid2path $DIR $FID
16311                 error "bad link ea"
16312         fi
16313         # middle
16314         rm $DIR/$tdir/foo2/zachary
16315         # last
16316         rm $DIR/$tdir/foo2/thor
16317         # first
16318         rm $DIR/$tdir/$tfile
16319         # rename
16320         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16321         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16322                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16323         rm $DIR/$tdir/foo2/maggie
16324
16325         # overflow the EA
16326         local longname=$tfile.avg_len_is_thirty_two_
16327         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16328                 error_noexit 'failed to unlink many hardlinks'" EXIT
16329         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16330                 error "failed to hardlink many files"
16331         links=$($LFS fid2path $DIR $FID | wc -l)
16332         echo -n "${links}/1000 links in link EA"
16333         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16334 }
16335 run_test 161a "link ea sanity"
16336
16337 test_161b() {
16338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16339         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16340
16341         local MDTIDX=1
16342         local remote_dir=$DIR/$tdir/remote_dir
16343
16344         mkdir -p $DIR/$tdir
16345         $LFS mkdir -i $MDTIDX $remote_dir ||
16346                 error "create remote directory failed"
16347
16348         cp /etc/hosts $remote_dir/$tfile
16349         mkdir -p $remote_dir/foo1
16350         mkdir -p $remote_dir/foo2
16351         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16352         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16353         ln $remote_dir/$tfile $remote_dir/foo1/luna
16354         ln $remote_dir/$tfile $remote_dir/foo2/thor
16355
16356         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16357                      tr -d ']')
16358         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16359                 $LFS fid2path $DIR $FID
16360                 error "bad link ea"
16361         fi
16362         # middle
16363         rm $remote_dir/foo2/zachary
16364         # last
16365         rm $remote_dir/foo2/thor
16366         # first
16367         rm $remote_dir/$tfile
16368         # rename
16369         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16370         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16371         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16372                 $LFS fid2path $DIR $FID
16373                 error "bad link rename"
16374         fi
16375         rm $remote_dir/foo2/maggie
16376
16377         # overflow the EA
16378         local longname=filename_avg_len_is_thirty_two_
16379         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16380                 error "failed to hardlink many files"
16381         links=$($LFS fid2path $DIR $FID | wc -l)
16382         echo -n "${links}/1000 links in link EA"
16383         [[ ${links} -gt 60 ]] ||
16384                 error "expected at least 60 links in link EA"
16385         unlinkmany $remote_dir/foo2/$longname 1000 ||
16386         error "failed to unlink many hardlinks"
16387 }
16388 run_test 161b "link ea sanity under remote directory"
16389
16390 test_161c() {
16391         remote_mds_nodsh && skip "remote MDS with nodsh"
16392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16393         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16394                 skip "Need MDS version at least 2.1.5"
16395
16396         # define CLF_RENAME_LAST 0x0001
16397         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16398         changelog_register || error "changelog_register failed"
16399
16400         rm -rf $DIR/$tdir
16401         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16402         touch $DIR/$tdir/foo_161c
16403         touch $DIR/$tdir/bar_161c
16404         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16405         changelog_dump | grep RENME | tail -n 5
16406         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16407         changelog_clear 0 || error "changelog_clear failed"
16408         if [ x$flags != "x0x1" ]; then
16409                 error "flag $flags is not 0x1"
16410         fi
16411
16412         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16413         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16414         touch $DIR/$tdir/foo_161c
16415         touch $DIR/$tdir/bar_161c
16416         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16417         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16418         changelog_dump | grep RENME | tail -n 5
16419         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16420         changelog_clear 0 || error "changelog_clear failed"
16421         if [ x$flags != "x0x0" ]; then
16422                 error "flag $flags is not 0x0"
16423         fi
16424         echo "rename overwrite a target having nlink > 1," \
16425                 "changelog record has flags of $flags"
16426
16427         # rename doesn't overwrite a target (changelog flag 0x0)
16428         touch $DIR/$tdir/foo_161c
16429         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16430         changelog_dump | grep RENME | tail -n 5
16431         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16432         changelog_clear 0 || error "changelog_clear failed"
16433         if [ x$flags != "x0x0" ]; then
16434                 error "flag $flags is not 0x0"
16435         fi
16436         echo "rename doesn't overwrite a target," \
16437                 "changelog record has flags of $flags"
16438
16439         # define CLF_UNLINK_LAST 0x0001
16440         # unlink a file having nlink = 1 (changelog flag 0x1)
16441         rm -f $DIR/$tdir/foo2_161c
16442         changelog_dump | grep UNLNK | tail -n 5
16443         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16444         changelog_clear 0 || error "changelog_clear failed"
16445         if [ x$flags != "x0x1" ]; then
16446                 error "flag $flags is not 0x1"
16447         fi
16448         echo "unlink a file having nlink = 1," \
16449                 "changelog record has flags of $flags"
16450
16451         # unlink a file having nlink > 1 (changelog flag 0x0)
16452         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16453         rm -f $DIR/$tdir/foobar_161c
16454         changelog_dump | grep UNLNK | tail -n 5
16455         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16456         changelog_clear 0 || error "changelog_clear failed"
16457         if [ x$flags != "x0x0" ]; then
16458                 error "flag $flags is not 0x0"
16459         fi
16460         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16461 }
16462 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16463
16464 test_161d() {
16465         remote_mds_nodsh && skip "remote MDS with nodsh"
16466         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16467
16468         local pid
16469         local fid
16470
16471         changelog_register || error "changelog_register failed"
16472
16473         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16474         # interfer with $MOUNT/.lustre/fid/ access
16475         mkdir $DIR/$tdir
16476         [[ $? -eq 0 ]] || error "mkdir failed"
16477
16478         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16479         $LCTL set_param fail_loc=0x8000140c
16480         # 5s pause
16481         $LCTL set_param fail_val=5
16482
16483         # create file
16484         echo foofoo > $DIR/$tdir/$tfile &
16485         pid=$!
16486
16487         # wait for create to be delayed
16488         sleep 2
16489
16490         ps -p $pid
16491         [[ $? -eq 0 ]] || error "create should be blocked"
16492
16493         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16494         stack_trap "rm -f $tempfile"
16495         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16496         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16497         # some delay may occur during ChangeLog publishing and file read just
16498         # above, that could allow file write to happen finally
16499         [[ -s $tempfile ]] && echo "file should be empty"
16500
16501         $LCTL set_param fail_loc=0
16502
16503         wait $pid
16504         [[ $? -eq 0 ]] || error "create failed"
16505 }
16506 run_test 161d "create with concurrent .lustre/fid access"
16507
16508 check_path() {
16509         local expected="$1"
16510         shift
16511         local fid="$2"
16512
16513         local path
16514         path=$($LFS fid2path "$@")
16515         local rc=$?
16516
16517         if [ $rc -ne 0 ]; then
16518                 error "path looked up of '$expected' failed: rc=$rc"
16519         elif [ "$path" != "$expected" ]; then
16520                 error "path looked up '$path' instead of '$expected'"
16521         else
16522                 echo "FID '$fid' resolves to path '$path' as expected"
16523         fi
16524 }
16525
16526 test_162a() { # was test_162
16527         test_mkdir -p -c1 $DIR/$tdir/d2
16528         touch $DIR/$tdir/d2/$tfile
16529         touch $DIR/$tdir/d2/x1
16530         touch $DIR/$tdir/d2/x2
16531         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16532         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16533         # regular file
16534         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16535         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16536
16537         # softlink
16538         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16539         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16540         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16541
16542         # softlink to wrong file
16543         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16544         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16545         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16546
16547         # hardlink
16548         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16549         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16550         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16551         # fid2path dir/fsname should both work
16552         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16553         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16554
16555         # hardlink count: check that there are 2 links
16556         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16557         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16558
16559         # hardlink indexing: remove the first link
16560         rm $DIR/$tdir/d2/p/q/r/hlink
16561         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16562 }
16563 run_test 162a "path lookup sanity"
16564
16565 test_162b() {
16566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16567         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16568
16569         mkdir $DIR/$tdir
16570         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16571                                 error "create striped dir failed"
16572
16573         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16574                                         tail -n 1 | awk '{print $2}')
16575         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16576
16577         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16578         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16579
16580         # regular file
16581         for ((i=0;i<5;i++)); do
16582                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16583                         error "get fid for f$i failed"
16584                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16585
16586                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16587                         error "get fid for d$i failed"
16588                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16589         done
16590
16591         return 0
16592 }
16593 run_test 162b "striped directory path lookup sanity"
16594
16595 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16596 test_162c() {
16597         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16598                 skip "Need MDS version at least 2.7.51"
16599
16600         local lpath=$tdir.local
16601         local rpath=$tdir.remote
16602
16603         test_mkdir $DIR/$lpath
16604         test_mkdir $DIR/$rpath
16605
16606         for ((i = 0; i <= 101; i++)); do
16607                 lpath="$lpath/$i"
16608                 mkdir $DIR/$lpath
16609                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16610                         error "get fid for local directory $DIR/$lpath failed"
16611                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16612
16613                 rpath="$rpath/$i"
16614                 test_mkdir $DIR/$rpath
16615                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16616                         error "get fid for remote directory $DIR/$rpath failed"
16617                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16618         done
16619
16620         return 0
16621 }
16622 run_test 162c "fid2path works with paths 100 or more directories deep"
16623
16624 oalr_event_count() {
16625         local event="${1}"
16626         local trace="${2}"
16627
16628         awk -v name="${FSNAME}-OST0000" \
16629             -v event="${event}" \
16630             '$1 == "TRACE" && $2 == event && $3 == name' \
16631             "${trace}" |
16632         wc -l
16633 }
16634
16635 oalr_expect_event_count() {
16636         local event="${1}"
16637         local trace="${2}"
16638         local expect="${3}"
16639         local count
16640
16641         count=$(oalr_event_count "${event}" "${trace}")
16642         if ((count == expect)); then
16643                 return 0
16644         fi
16645
16646         error_noexit "${event} event count was '${count}', expected ${expect}"
16647         cat "${trace}" >&2
16648         exit 1
16649 }
16650
16651 cleanup_165() {
16652         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16653         stop ost1
16654         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16655 }
16656
16657 setup_165() {
16658         sync # Flush previous IOs so we can count log entries.
16659         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16660         stack_trap cleanup_165 EXIT
16661 }
16662
16663 test_165a() {
16664         local trace="/tmp/${tfile}.trace"
16665         local rc
16666         local count
16667
16668         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16669                 skip "OFD access log unsupported"
16670
16671         setup_165
16672         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16673         sleep 5
16674
16675         do_facet ost1 ofd_access_log_reader --list
16676         stop ost1
16677
16678         do_facet ost1 killall -TERM ofd_access_log_reader
16679         wait
16680         rc=$?
16681
16682         if ((rc != 0)); then
16683                 error "ofd_access_log_reader exited with rc = '${rc}'"
16684         fi
16685
16686         # Parse trace file for discovery events:
16687         oalr_expect_event_count alr_log_add "${trace}" 1
16688         oalr_expect_event_count alr_log_eof "${trace}" 1
16689         oalr_expect_event_count alr_log_free "${trace}" 1
16690 }
16691 run_test 165a "ofd access log discovery"
16692
16693 test_165b() {
16694         local trace="/tmp/${tfile}.trace"
16695         local file="${DIR}/${tfile}"
16696         local pfid1
16697         local pfid2
16698         local -a entry
16699         local rc
16700         local count
16701         local size
16702         local flags
16703
16704         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16705                 skip "OFD access log unsupported"
16706
16707         setup_165
16708         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16709         sleep 5
16710
16711         do_facet ost1 ofd_access_log_reader --list
16712
16713         lfs setstripe -c 1 -i 0 "${file}"
16714         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16715                 error "cannot create '${file}'"
16716
16717         sleep 5
16718         do_facet ost1 killall -TERM ofd_access_log_reader
16719         wait
16720         rc=$?
16721
16722         if ((rc != 0)); then
16723                 error "ofd_access_log_reader exited with rc = '${rc}'"
16724         fi
16725
16726         oalr_expect_event_count alr_log_entry "${trace}" 1
16727
16728         pfid1=$($LFS path2fid "${file}")
16729
16730         # 1     2             3   4    5     6   7    8    9     10
16731         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16732         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16733
16734         echo "entry = '${entry[*]}'" >&2
16735
16736         pfid2=${entry[4]}
16737         if [[ "${pfid1}" != "${pfid2}" ]]; then
16738                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16739         fi
16740
16741         size=${entry[8]}
16742         if ((size != 1048576)); then
16743                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16744         fi
16745
16746         flags=${entry[10]}
16747         if [[ "${flags}" != "w" ]]; then
16748                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16749         fi
16750
16751         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16752         sleep 5
16753
16754         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16755                 error "cannot read '${file}'"
16756         sleep 5
16757
16758         do_facet ost1 killall -TERM ofd_access_log_reader
16759         wait
16760         rc=$?
16761
16762         if ((rc != 0)); then
16763                 error "ofd_access_log_reader exited with rc = '${rc}'"
16764         fi
16765
16766         oalr_expect_event_count alr_log_entry "${trace}" 1
16767
16768         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16769         echo "entry = '${entry[*]}'" >&2
16770
16771         pfid2=${entry[4]}
16772         if [[ "${pfid1}" != "${pfid2}" ]]; then
16773                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16774         fi
16775
16776         size=${entry[8]}
16777         if ((size != 524288)); then
16778                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16779         fi
16780
16781         flags=${entry[10]}
16782         if [[ "${flags}" != "r" ]]; then
16783                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16784         fi
16785 }
16786 run_test 165b "ofd access log entries are produced and consumed"
16787
16788 test_165c() {
16789         local trace="/tmp/${tfile}.trace"
16790         local file="${DIR}/${tdir}/${tfile}"
16791
16792         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16793                 skip "OFD access log unsupported"
16794
16795         test_mkdir "${DIR}/${tdir}"
16796
16797         setup_165
16798         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16799         sleep 5
16800
16801         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16802
16803         # 4096 / 64 = 64. Create twice as many entries.
16804         for ((i = 0; i < 128; i++)); do
16805                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16806                         error "cannot create file"
16807         done
16808
16809         sync
16810
16811         do_facet ost1 killall -TERM ofd_access_log_reader
16812         wait
16813         rc=$?
16814         if ((rc != 0)); then
16815                 error "ofd_access_log_reader exited with rc = '${rc}'"
16816         fi
16817
16818         unlinkmany  "${file}-%d" 128
16819 }
16820 run_test 165c "full ofd access logs do not block IOs"
16821
16822 oal_get_read_count() {
16823         local stats="$1"
16824
16825         # STATS lustre-OST0001 alr_read_count 1
16826
16827         do_facet ost1 cat "${stats}" |
16828         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16829              END { print count; }'
16830 }
16831
16832 oal_expect_read_count() {
16833         local stats="$1"
16834         local count
16835         local expect="$2"
16836
16837         # Ask ofd_access_log_reader to write stats.
16838         do_facet ost1 killall -USR1 ofd_access_log_reader
16839
16840         # Allow some time for things to happen.
16841         sleep 1
16842
16843         count=$(oal_get_read_count "${stats}")
16844         if ((count == expect)); then
16845                 return 0
16846         fi
16847
16848         error_noexit "bad read count, got ${count}, expected ${expect}"
16849         do_facet ost1 cat "${stats}" >&2
16850         exit 1
16851 }
16852
16853 test_165d() {
16854         local stats="/tmp/${tfile}.stats"
16855         local file="${DIR}/${tdir}/${tfile}"
16856         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16857
16858         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16859                 skip "OFD access log unsupported"
16860
16861         test_mkdir "${DIR}/${tdir}"
16862
16863         setup_165
16864         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16865         sleep 5
16866
16867         lfs setstripe -c 1 -i 0 "${file}"
16868
16869         do_facet ost1 lctl set_param "${param}=rw"
16870         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16871                 error "cannot create '${file}'"
16872         oal_expect_read_count "${stats}" 1
16873
16874         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16875                 error "cannot read '${file}'"
16876         oal_expect_read_count "${stats}" 2
16877
16878         do_facet ost1 lctl set_param "${param}=r"
16879         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16880                 error "cannot create '${file}'"
16881         oal_expect_read_count "${stats}" 2
16882
16883         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16884                 error "cannot read '${file}'"
16885         oal_expect_read_count "${stats}" 3
16886
16887         do_facet ost1 lctl set_param "${param}=w"
16888         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16889                 error "cannot create '${file}'"
16890         oal_expect_read_count "${stats}" 4
16891
16892         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16893                 error "cannot read '${file}'"
16894         oal_expect_read_count "${stats}" 4
16895
16896         do_facet ost1 lctl set_param "${param}=0"
16897         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16898                 error "cannot create '${file}'"
16899         oal_expect_read_count "${stats}" 4
16900
16901         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16902                 error "cannot read '${file}'"
16903         oal_expect_read_count "${stats}" 4
16904
16905         do_facet ost1 killall -TERM ofd_access_log_reader
16906         wait
16907         rc=$?
16908         if ((rc != 0)); then
16909                 error "ofd_access_log_reader exited with rc = '${rc}'"
16910         fi
16911 }
16912 run_test 165d "ofd_access_log mask works"
16913
16914 test_165e() {
16915         local stats="/tmp/${tfile}.stats"
16916         local file0="${DIR}/${tdir}-0/${tfile}"
16917         local file1="${DIR}/${tdir}-1/${tfile}"
16918
16919         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16920                 skip "OFD access log unsupported"
16921
16922         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16923
16924         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16925         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16926
16927         lfs setstripe -c 1 -i 0 "${file0}"
16928         lfs setstripe -c 1 -i 0 "${file1}"
16929
16930         setup_165
16931         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16932         sleep 5
16933
16934         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16935                 error "cannot create '${file0}'"
16936         sync
16937         oal_expect_read_count "${stats}" 0
16938
16939         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16940                 error "cannot create '${file1}'"
16941         sync
16942         oal_expect_read_count "${stats}" 1
16943
16944         do_facet ost1 killall -TERM ofd_access_log_reader
16945         wait
16946         rc=$?
16947         if ((rc != 0)); then
16948                 error "ofd_access_log_reader exited with rc = '${rc}'"
16949         fi
16950 }
16951 run_test 165e "ofd_access_log MDT index filter works"
16952
16953 test_165f() {
16954         local trace="/tmp/${tfile}.trace"
16955         local rc
16956         local count
16957
16958         setup_165
16959         do_facet ost1 timeout 60 ofd_access_log_reader \
16960                 --exit-on-close --debug=- --trace=- > "${trace}" &
16961         sleep 5
16962         stop ost1
16963
16964         wait
16965         rc=$?
16966
16967         if ((rc != 0)); then
16968                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16969                 cat "${trace}"
16970                 exit 1
16971         fi
16972 }
16973 run_test 165f "ofd_access_log_reader --exit-on-close works"
16974
16975 test_169() {
16976         # do directio so as not to populate the page cache
16977         log "creating a 10 Mb file"
16978         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16979                 error "multiop failed while creating a file"
16980         log "starting reads"
16981         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16982         log "truncating the file"
16983         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16984                 error "multiop failed while truncating the file"
16985         log "killing dd"
16986         kill %+ || true # reads might have finished
16987         echo "wait until dd is finished"
16988         wait
16989         log "removing the temporary file"
16990         rm -rf $DIR/$tfile || error "tmp file removal failed"
16991 }
16992 run_test 169 "parallel read and truncate should not deadlock"
16993
16994 test_170() {
16995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16996
16997         $LCTL clear     # bug 18514
16998         $LCTL debug_daemon start $TMP/${tfile}_log_good
16999         touch $DIR/$tfile
17000         $LCTL debug_daemon stop
17001         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17002                 error "sed failed to read log_good"
17003
17004         $LCTL debug_daemon start $TMP/${tfile}_log_good
17005         rm -rf $DIR/$tfile
17006         $LCTL debug_daemon stop
17007
17008         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17009                error "lctl df log_bad failed"
17010
17011         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17012         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17013
17014         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17015         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17016
17017         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17018                 error "bad_line good_line1 good_line2 are empty"
17019
17020         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17021         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17022         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17023
17024         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17025         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17026         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17027
17028         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17029                 error "bad_line_new good_line_new are empty"
17030
17031         local expected_good=$((good_line1 + good_line2*2))
17032
17033         rm -f $TMP/${tfile}*
17034         # LU-231, short malformed line may not be counted into bad lines
17035         if [ $bad_line -ne $bad_line_new ] &&
17036                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17037                 error "expected $bad_line bad lines, but got $bad_line_new"
17038                 return 1
17039         fi
17040
17041         if [ $expected_good -ne $good_line_new ]; then
17042                 error "expected $expected_good good lines, but got $good_line_new"
17043                 return 2
17044         fi
17045         true
17046 }
17047 run_test 170 "test lctl df to handle corrupted log ====================="
17048
17049 test_171() { # bug20592
17050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17051
17052         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17053         $LCTL set_param fail_loc=0x50e
17054         $LCTL set_param fail_val=3000
17055         multiop_bg_pause $DIR/$tfile O_s || true
17056         local MULTIPID=$!
17057         kill -USR1 $MULTIPID
17058         # cause log dump
17059         sleep 3
17060         wait $MULTIPID
17061         if dmesg | grep "recursive fault"; then
17062                 error "caught a recursive fault"
17063         fi
17064         $LCTL set_param fail_loc=0
17065         true
17066 }
17067 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17068
17069 # it would be good to share it with obdfilter-survey/iokit-libecho code
17070 setup_obdecho_osc () {
17071         local rc=0
17072         local ost_nid=$1
17073         local obdfilter_name=$2
17074         echo "Creating new osc for $obdfilter_name on $ost_nid"
17075         # make sure we can find loopback nid
17076         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17077
17078         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17079                            ${obdfilter_name}_osc_UUID || rc=2; }
17080         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17081                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17082         return $rc
17083 }
17084
17085 cleanup_obdecho_osc () {
17086         local obdfilter_name=$1
17087         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17088         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17089         return 0
17090 }
17091
17092 obdecho_test() {
17093         local OBD=$1
17094         local node=$2
17095         local pages=${3:-64}
17096         local rc=0
17097         local id
17098
17099         local count=10
17100         local obd_size=$(get_obd_size $node $OBD)
17101         local page_size=$(get_page_size $node)
17102         if [[ -n "$obd_size" ]]; then
17103                 local new_count=$((obd_size / (pages * page_size / 1024)))
17104                 [[ $new_count -ge $count ]] || count=$new_count
17105         fi
17106
17107         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17108         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17109                            rc=2; }
17110         if [ $rc -eq 0 ]; then
17111             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17112             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17113         fi
17114         echo "New object id is $id"
17115         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17116                            rc=4; }
17117         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17118                            "test_brw $count w v $pages $id" || rc=4; }
17119         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17120                            rc=4; }
17121         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17122                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17123         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17124                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17125         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17126         return $rc
17127 }
17128
17129 test_180a() {
17130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17131
17132         if ! [ -d /sys/fs/lustre/echo_client ] &&
17133            ! module_loaded obdecho; then
17134                 load_module obdecho/obdecho &&
17135                         stack_trap "rmmod obdecho" EXIT ||
17136                         error "unable to load obdecho on client"
17137         fi
17138
17139         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17140         local host=$($LCTL get_param -n osc.$osc.import |
17141                      awk '/current_connection:/ { print $2 }' )
17142         local target=$($LCTL get_param -n osc.$osc.import |
17143                        awk '/target:/ { print $2 }' )
17144         target=${target%_UUID}
17145
17146         if [ -n "$target" ]; then
17147                 setup_obdecho_osc $host $target &&
17148                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17149                         { error "obdecho setup failed with $?"; return; }
17150
17151                 obdecho_test ${target}_osc client ||
17152                         error "obdecho_test failed on ${target}_osc"
17153         else
17154                 $LCTL get_param osc.$osc.import
17155                 error "there is no osc.$osc.import target"
17156         fi
17157 }
17158 run_test 180a "test obdecho on osc"
17159
17160 test_180b() {
17161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17162         remote_ost_nodsh && skip "remote OST with nodsh"
17163
17164         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17165                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17166                 error "failed to load module obdecho"
17167
17168         local target=$(do_facet ost1 $LCTL dl |
17169                        awk '/obdfilter/ { print $4; exit; }')
17170
17171         if [ -n "$target" ]; then
17172                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17173         else
17174                 do_facet ost1 $LCTL dl
17175                 error "there is no obdfilter target on ost1"
17176         fi
17177 }
17178 run_test 180b "test obdecho directly on obdfilter"
17179
17180 test_180c() { # LU-2598
17181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17182         remote_ost_nodsh && skip "remote OST with nodsh"
17183         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17184                 skip "Need MDS version at least 2.4.0"
17185
17186         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17187                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17188                 error "failed to load module obdecho"
17189
17190         local target=$(do_facet ost1 $LCTL dl |
17191                        awk '/obdfilter/ { print $4; exit; }')
17192
17193         if [ -n "$target" ]; then
17194                 local pages=16384 # 64MB bulk I/O RPC size
17195
17196                 obdecho_test "$target" ost1 "$pages" ||
17197                         error "obdecho_test with pages=$pages failed with $?"
17198         else
17199                 do_facet ost1 $LCTL dl
17200                 error "there is no obdfilter target on ost1"
17201         fi
17202 }
17203 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17204
17205 test_181() { # bug 22177
17206         test_mkdir $DIR/$tdir
17207         # create enough files to index the directory
17208         createmany -o $DIR/$tdir/foobar 4000
17209         # print attributes for debug purpose
17210         lsattr -d .
17211         # open dir
17212         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17213         MULTIPID=$!
17214         # remove the files & current working dir
17215         unlinkmany $DIR/$tdir/foobar 4000
17216         rmdir $DIR/$tdir
17217         kill -USR1 $MULTIPID
17218         wait $MULTIPID
17219         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17220         return 0
17221 }
17222 run_test 181 "Test open-unlinked dir ========================"
17223
17224 test_182() {
17225         local fcount=1000
17226         local tcount=10
17227
17228         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17229
17230         $LCTL set_param mdc.*.rpc_stats=clear
17231
17232         for (( i = 0; i < $tcount; i++ )) ; do
17233                 mkdir $DIR/$tdir/$i
17234         done
17235
17236         for (( i = 0; i < $tcount; i++ )) ; do
17237                 createmany -o $DIR/$tdir/$i/f- $fcount &
17238         done
17239         wait
17240
17241         for (( i = 0; i < $tcount; i++ )) ; do
17242                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17243         done
17244         wait
17245
17246         $LCTL get_param mdc.*.rpc_stats
17247
17248         rm -rf $DIR/$tdir
17249 }
17250 run_test 182 "Test parallel modify metadata operations ================"
17251
17252 test_183() { # LU-2275
17253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17254         remote_mds_nodsh && skip "remote MDS with nodsh"
17255         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17256                 skip "Need MDS version at least 2.3.56"
17257
17258         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17259         echo aaa > $DIR/$tdir/$tfile
17260
17261 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17262         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17263
17264         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17265         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17266
17267         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17268
17269         # Flush negative dentry cache
17270         touch $DIR/$tdir/$tfile
17271
17272         # We are not checking for any leaked references here, they'll
17273         # become evident next time we do cleanup with module unload.
17274         rm -rf $DIR/$tdir
17275 }
17276 run_test 183 "No crash or request leak in case of strange dispositions ========"
17277
17278 # test suite 184 is for LU-2016, LU-2017
17279 test_184a() {
17280         check_swap_layouts_support
17281
17282         dir0=$DIR/$tdir/$testnum
17283         test_mkdir -p -c1 $dir0
17284         ref1=/etc/passwd
17285         ref2=/etc/group
17286         file1=$dir0/f1
17287         file2=$dir0/f2
17288         $LFS setstripe -c1 $file1
17289         cp $ref1 $file1
17290         $LFS setstripe -c2 $file2
17291         cp $ref2 $file2
17292         gen1=$($LFS getstripe -g $file1)
17293         gen2=$($LFS getstripe -g $file2)
17294
17295         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17296         gen=$($LFS getstripe -g $file1)
17297         [[ $gen1 != $gen ]] ||
17298                 "Layout generation on $file1 does not change"
17299         gen=$($LFS getstripe -g $file2)
17300         [[ $gen2 != $gen ]] ||
17301                 "Layout generation on $file2 does not change"
17302
17303         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17304         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17305
17306         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17307 }
17308 run_test 184a "Basic layout swap"
17309
17310 test_184b() {
17311         check_swap_layouts_support
17312
17313         dir0=$DIR/$tdir/$testnum
17314         mkdir -p $dir0 || error "creating dir $dir0"
17315         file1=$dir0/f1
17316         file2=$dir0/f2
17317         file3=$dir0/f3
17318         dir1=$dir0/d1
17319         dir2=$dir0/d2
17320         mkdir $dir1 $dir2
17321         $LFS setstripe -c1 $file1
17322         $LFS setstripe -c2 $file2
17323         $LFS setstripe -c1 $file3
17324         chown $RUNAS_ID $file3
17325         gen1=$($LFS getstripe -g $file1)
17326         gen2=$($LFS getstripe -g $file2)
17327
17328         $LFS swap_layouts $dir1 $dir2 &&
17329                 error "swap of directories layouts should fail"
17330         $LFS swap_layouts $dir1 $file1 &&
17331                 error "swap of directory and file layouts should fail"
17332         $RUNAS $LFS swap_layouts $file1 $file2 &&
17333                 error "swap of file we cannot write should fail"
17334         $LFS swap_layouts $file1 $file3 &&
17335                 error "swap of file with different owner should fail"
17336         /bin/true # to clear error code
17337 }
17338 run_test 184b "Forbidden layout swap (will generate errors)"
17339
17340 test_184c() {
17341         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17342         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17343         check_swap_layouts_support
17344         check_swap_layout_no_dom $DIR
17345
17346         local dir0=$DIR/$tdir/$testnum
17347         mkdir -p $dir0 || error "creating dir $dir0"
17348
17349         local ref1=$dir0/ref1
17350         local ref2=$dir0/ref2
17351         local file1=$dir0/file1
17352         local file2=$dir0/file2
17353         # create a file large enough for the concurrent test
17354         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17355         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17356         echo "ref file size: ref1($(stat -c %s $ref1))," \
17357              "ref2($(stat -c %s $ref2))"
17358
17359         cp $ref2 $file2
17360         dd if=$ref1 of=$file1 bs=16k &
17361         local DD_PID=$!
17362
17363         # Make sure dd starts to copy file, but wait at most 5 seconds
17364         local loops=0
17365         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17366
17367         $LFS swap_layouts $file1 $file2
17368         local rc=$?
17369         wait $DD_PID
17370         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17371         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17372
17373         # how many bytes copied before swapping layout
17374         local copied=$(stat -c %s $file2)
17375         local remaining=$(stat -c %s $ref1)
17376         remaining=$((remaining - copied))
17377         echo "Copied $copied bytes before swapping layout..."
17378
17379         cmp -n $copied $file1 $ref2 | grep differ &&
17380                 error "Content mismatch [0, $copied) of ref2 and file1"
17381         cmp -n $copied $file2 $ref1 ||
17382                 error "Content mismatch [0, $copied) of ref1 and file2"
17383         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17384                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17385
17386         # clean up
17387         rm -f $ref1 $ref2 $file1 $file2
17388 }
17389 run_test 184c "Concurrent write and layout swap"
17390
17391 test_184d() {
17392         check_swap_layouts_support
17393         check_swap_layout_no_dom $DIR
17394         [ -z "$(which getfattr 2>/dev/null)" ] &&
17395                 skip_env "no getfattr command"
17396
17397         local file1=$DIR/$tdir/$tfile-1
17398         local file2=$DIR/$tdir/$tfile-2
17399         local file3=$DIR/$tdir/$tfile-3
17400         local lovea1
17401         local lovea2
17402
17403         mkdir -p $DIR/$tdir
17404         touch $file1 || error "create $file1 failed"
17405         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17406                 error "create $file2 failed"
17407         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17408                 error "create $file3 failed"
17409         lovea1=$(get_layout_param $file1)
17410
17411         $LFS swap_layouts $file2 $file3 ||
17412                 error "swap $file2 $file3 layouts failed"
17413         $LFS swap_layouts $file1 $file2 ||
17414                 error "swap $file1 $file2 layouts failed"
17415
17416         lovea2=$(get_layout_param $file2)
17417         echo "$lovea1"
17418         echo "$lovea2"
17419         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17420
17421         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17422         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17423 }
17424 run_test 184d "allow stripeless layouts swap"
17425
17426 test_184e() {
17427         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17428                 skip "Need MDS version at least 2.6.94"
17429         check_swap_layouts_support
17430         check_swap_layout_no_dom $DIR
17431         [ -z "$(which getfattr 2>/dev/null)" ] &&
17432                 skip_env "no getfattr command"
17433
17434         local file1=$DIR/$tdir/$tfile-1
17435         local file2=$DIR/$tdir/$tfile-2
17436         local file3=$DIR/$tdir/$tfile-3
17437         local lovea
17438
17439         mkdir -p $DIR/$tdir
17440         touch $file1 || error "create $file1 failed"
17441         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17442                 error "create $file2 failed"
17443         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17444                 error "create $file3 failed"
17445
17446         $LFS swap_layouts $file1 $file2 ||
17447                 error "swap $file1 $file2 layouts failed"
17448
17449         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17450         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17451
17452         echo 123 > $file1 || error "Should be able to write into $file1"
17453
17454         $LFS swap_layouts $file1 $file3 ||
17455                 error "swap $file1 $file3 layouts failed"
17456
17457         echo 123 > $file1 || error "Should be able to write into $file1"
17458
17459         rm -rf $file1 $file2 $file3
17460 }
17461 run_test 184e "Recreate layout after stripeless layout swaps"
17462
17463 test_184f() {
17464         # Create a file with name longer than sizeof(struct stat) ==
17465         # 144 to see if we can get chars from the file name to appear
17466         # in the returned striping. Note that 'f' == 0x66.
17467         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17468
17469         mkdir -p $DIR/$tdir
17470         mcreate $DIR/$tdir/$file
17471         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17472                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17473         fi
17474 }
17475 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17476
17477 test_185() { # LU-2441
17478         # LU-3553 - no volatile file support in old servers
17479         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17480                 skip "Need MDS version at least 2.3.60"
17481
17482         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17483         touch $DIR/$tdir/spoo
17484         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17485         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17486                 error "cannot create/write a volatile file"
17487         [ "$FILESET" == "" ] &&
17488         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17489                 error "FID is still valid after close"
17490
17491         multiop_bg_pause $DIR/$tdir vVw4096_c
17492         local multi_pid=$!
17493
17494         local OLD_IFS=$IFS
17495         IFS=":"
17496         local fidv=($fid)
17497         IFS=$OLD_IFS
17498         # assume that the next FID for this client is sequential, since stdout
17499         # is unfortunately eaten by multiop_bg_pause
17500         local n=$((${fidv[1]} + 1))
17501         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17502         if [ "$FILESET" == "" ]; then
17503                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17504                         error "FID is missing before close"
17505         fi
17506         kill -USR1 $multi_pid
17507         # 1 second delay, so if mtime change we will see it
17508         sleep 1
17509         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17510         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17511 }
17512 run_test 185 "Volatile file support"
17513
17514 function create_check_volatile() {
17515         local idx=$1
17516         local tgt
17517
17518         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17519         local PID=$!
17520         sleep 1
17521         local FID=$(cat /tmp/${tfile}.fid)
17522         [ "$FID" == "" ] && error "can't get FID for volatile"
17523         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17524         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17525         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17526         kill -USR1 $PID
17527         wait
17528         sleep 1
17529         cancel_lru_locks mdc # flush opencache
17530         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17531         return 0
17532 }
17533
17534 test_185a(){
17535         # LU-12516 - volatile creation via .lustre
17536         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17537                 skip "Need MDS version at least 2.3.55"
17538
17539         create_check_volatile 0
17540         [ $MDSCOUNT -lt 2 ] && return 0
17541
17542         # DNE case
17543         create_check_volatile 1
17544
17545         return 0
17546 }
17547 run_test 185a "Volatile file creation in .lustre/fid/"
17548
17549 test_187a() {
17550         remote_mds_nodsh && skip "remote MDS with nodsh"
17551         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17552                 skip "Need MDS version at least 2.3.0"
17553
17554         local dir0=$DIR/$tdir/$testnum
17555         mkdir -p $dir0 || error "creating dir $dir0"
17556
17557         local file=$dir0/file1
17558         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17559         local dv1=$($LFS data_version $file)
17560         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17561         local dv2=$($LFS data_version $file)
17562         [[ $dv1 != $dv2 ]] ||
17563                 error "data version did not change on write $dv1 == $dv2"
17564
17565         # clean up
17566         rm -f $file1
17567 }
17568 run_test 187a "Test data version change"
17569
17570 test_187b() {
17571         remote_mds_nodsh && skip "remote MDS with nodsh"
17572         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17573                 skip "Need MDS version at least 2.3.0"
17574
17575         local dir0=$DIR/$tdir/$testnum
17576         mkdir -p $dir0 || error "creating dir $dir0"
17577
17578         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17579         [[ ${DV[0]} != ${DV[1]} ]] ||
17580                 error "data version did not change on write"\
17581                       " ${DV[0]} == ${DV[1]}"
17582
17583         # clean up
17584         rm -f $file1
17585 }
17586 run_test 187b "Test data version change on volatile file"
17587
17588 test_200() {
17589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17590         remote_mgs_nodsh && skip "remote MGS with nodsh"
17591         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17592
17593         local POOL=${POOL:-cea1}
17594         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17595         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17596         # Pool OST targets
17597         local first_ost=0
17598         local last_ost=$(($OSTCOUNT - 1))
17599         local ost_step=2
17600         local ost_list=$(seq $first_ost $ost_step $last_ost)
17601         local ost_range="$first_ost $last_ost $ost_step"
17602         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17603         local file_dir=$POOL_ROOT/file_tst
17604         local subdir=$test_path/subdir
17605         local rc=0
17606
17607         while : ; do
17608                 # former test_200a test_200b
17609                 pool_add $POOL                          || { rc=$? ; break; }
17610                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17611                 # former test_200c test_200d
17612                 mkdir -p $test_path
17613                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17614                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17615                 mkdir -p $subdir
17616                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17617                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17618                                                         || { rc=$? ; break; }
17619                 # former test_200e test_200f
17620                 local files=$((OSTCOUNT*3))
17621                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17622                                                         || { rc=$? ; break; }
17623                 pool_create_files $POOL $file_dir $files "$ost_list" \
17624                                                         || { rc=$? ; break; }
17625                 # former test_200g test_200h
17626                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17627                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17628
17629                 # former test_201a test_201b test_201c
17630                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17631
17632                 local f=$test_path/$tfile
17633                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17634                 pool_remove $POOL $f                    || { rc=$? ; break; }
17635                 break
17636         done
17637
17638         destroy_test_pools
17639
17640         return $rc
17641 }
17642 run_test 200 "OST pools"
17643
17644 # usage: default_attr <count | size | offset>
17645 default_attr() {
17646         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17647 }
17648
17649 # usage: check_default_stripe_attr
17650 check_default_stripe_attr() {
17651         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17652         case $1 in
17653         --stripe-count|-c)
17654                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17655         --stripe-size|-S)
17656                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17657         --stripe-index|-i)
17658                 EXPECTED=-1;;
17659         *)
17660                 error "unknown getstripe attr '$1'"
17661         esac
17662
17663         [ $ACTUAL == $EXPECTED ] ||
17664                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17665 }
17666
17667 test_204a() {
17668         test_mkdir $DIR/$tdir
17669         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17670
17671         check_default_stripe_attr --stripe-count
17672         check_default_stripe_attr --stripe-size
17673         check_default_stripe_attr --stripe-index
17674 }
17675 run_test 204a "Print default stripe attributes"
17676
17677 test_204b() {
17678         test_mkdir $DIR/$tdir
17679         $LFS setstripe --stripe-count 1 $DIR/$tdir
17680
17681         check_default_stripe_attr --stripe-size
17682         check_default_stripe_attr --stripe-index
17683 }
17684 run_test 204b "Print default stripe size and offset"
17685
17686 test_204c() {
17687         test_mkdir $DIR/$tdir
17688         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17689
17690         check_default_stripe_attr --stripe-count
17691         check_default_stripe_attr --stripe-index
17692 }
17693 run_test 204c "Print default stripe count and offset"
17694
17695 test_204d() {
17696         test_mkdir $DIR/$tdir
17697         $LFS setstripe --stripe-index 0 $DIR/$tdir
17698
17699         check_default_stripe_attr --stripe-count
17700         check_default_stripe_attr --stripe-size
17701 }
17702 run_test 204d "Print default stripe count and size"
17703
17704 test_204e() {
17705         test_mkdir $DIR/$tdir
17706         $LFS setstripe -d $DIR/$tdir
17707
17708         check_default_stripe_attr --stripe-count --raw
17709         check_default_stripe_attr --stripe-size --raw
17710         check_default_stripe_attr --stripe-index --raw
17711 }
17712 run_test 204e "Print raw stripe attributes"
17713
17714 test_204f() {
17715         test_mkdir $DIR/$tdir
17716         $LFS setstripe --stripe-count 1 $DIR/$tdir
17717
17718         check_default_stripe_attr --stripe-size --raw
17719         check_default_stripe_attr --stripe-index --raw
17720 }
17721 run_test 204f "Print raw stripe size and offset"
17722
17723 test_204g() {
17724         test_mkdir $DIR/$tdir
17725         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17726
17727         check_default_stripe_attr --stripe-count --raw
17728         check_default_stripe_attr --stripe-index --raw
17729 }
17730 run_test 204g "Print raw stripe count and offset"
17731
17732 test_204h() {
17733         test_mkdir $DIR/$tdir
17734         $LFS setstripe --stripe-index 0 $DIR/$tdir
17735
17736         check_default_stripe_attr --stripe-count --raw
17737         check_default_stripe_attr --stripe-size --raw
17738 }
17739 run_test 204h "Print raw stripe count and size"
17740
17741 # Figure out which job scheduler is being used, if any,
17742 # or use a fake one
17743 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17744         JOBENV=SLURM_JOB_ID
17745 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17746         JOBENV=LSB_JOBID
17747 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17748         JOBENV=PBS_JOBID
17749 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17750         JOBENV=LOADL_STEP_ID
17751 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17752         JOBENV=JOB_ID
17753 else
17754         $LCTL list_param jobid_name > /dev/null 2>&1
17755         if [ $? -eq 0 ]; then
17756                 JOBENV=nodelocal
17757         else
17758                 JOBENV=FAKE_JOBID
17759         fi
17760 fi
17761 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17762
17763 verify_jobstats() {
17764         local cmd=($1)
17765         shift
17766         local facets="$@"
17767
17768 # we don't really need to clear the stats for this test to work, since each
17769 # command has a unique jobid, but it makes debugging easier if needed.
17770 #       for facet in $facets; do
17771 #               local dev=$(convert_facet2label $facet)
17772 #               # clear old jobstats
17773 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17774 #       done
17775
17776         # use a new JobID for each test, or we might see an old one
17777         [ "$JOBENV" = "FAKE_JOBID" ] &&
17778                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17779
17780         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17781
17782         [ "$JOBENV" = "nodelocal" ] && {
17783                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17784                 $LCTL set_param jobid_name=$FAKE_JOBID
17785                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17786         }
17787
17788         log "Test: ${cmd[*]}"
17789         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17790
17791         if [ $JOBENV = "FAKE_JOBID" ]; then
17792                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17793         else
17794                 ${cmd[*]}
17795         fi
17796
17797         # all files are created on OST0000
17798         for facet in $facets; do
17799                 local stats="*.$(convert_facet2label $facet).job_stats"
17800
17801                 # strip out libtool wrappers for in-tree executables
17802                 if [ $(do_facet $facet lctl get_param $stats |
17803                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17804                         do_facet $facet lctl get_param $stats
17805                         error "No jobstats for $JOBVAL found on $facet::$stats"
17806                 fi
17807         done
17808 }
17809
17810 jobstats_set() {
17811         local new_jobenv=$1
17812
17813         set_persistent_param_and_check client "jobid_var" \
17814                 "$FSNAME.sys.jobid_var" $new_jobenv
17815 }
17816
17817 test_205a() { # Job stats
17818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17819         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17820                 skip "Need MDS version with at least 2.7.1"
17821         remote_mgs_nodsh && skip "remote MGS with nodsh"
17822         remote_mds_nodsh && skip "remote MDS with nodsh"
17823         remote_ost_nodsh && skip "remote OST with nodsh"
17824         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17825                 skip "Server doesn't support jobstats"
17826         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17827
17828         local old_jobenv=$($LCTL get_param -n jobid_var)
17829         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17830
17831         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17832                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17833         else
17834                 stack_trap "do_facet mgs $PERM_CMD \
17835                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17836         fi
17837         changelog_register
17838
17839         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17840                                 mdt.*.job_cleanup_interval | head -n 1)
17841         local new_interval=5
17842         do_facet $SINGLEMDS \
17843                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17844         stack_trap "do_facet $SINGLEMDS \
17845                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17846         local start=$SECONDS
17847
17848         local cmd
17849         # mkdir
17850         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
17851         verify_jobstats "$cmd" "$SINGLEMDS"
17852         # rmdir
17853         cmd="rmdir $DIR/$tdir"
17854         verify_jobstats "$cmd" "$SINGLEMDS"
17855         # mkdir on secondary MDT
17856         if [ $MDSCOUNT -gt 1 ]; then
17857                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17858                 verify_jobstats "$cmd" "mds2"
17859         fi
17860         # mknod
17861         cmd="mknod $DIR/$tfile c 1 3"
17862         verify_jobstats "$cmd" "$SINGLEMDS"
17863         # unlink
17864         cmd="rm -f $DIR/$tfile"
17865         verify_jobstats "$cmd" "$SINGLEMDS"
17866         # create all files on OST0000 so verify_jobstats can find OST stats
17867         # open & close
17868         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17869         verify_jobstats "$cmd" "$SINGLEMDS"
17870         # setattr
17871         cmd="touch $DIR/$tfile"
17872         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17873         # write
17874         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17875         verify_jobstats "$cmd" "ost1"
17876         # read
17877         cancel_lru_locks osc
17878         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17879         verify_jobstats "$cmd" "ost1"
17880         # truncate
17881         cmd="$TRUNCATE $DIR/$tfile 0"
17882         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17883         # rename
17884         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17885         verify_jobstats "$cmd" "$SINGLEMDS"
17886         # jobstats expiry - sleep until old stats should be expired
17887         local left=$((new_interval + 5 - (SECONDS - start)))
17888         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17889                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17890                         "0" $left
17891         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
17892         verify_jobstats "$cmd" "$SINGLEMDS"
17893         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17894             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17895
17896         # Ensure that jobid are present in changelog (if supported by MDS)
17897         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17898                 changelog_dump | tail -10
17899                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17900                 [ $jobids -eq 9 ] ||
17901                         error "Wrong changelog jobid count $jobids != 9"
17902
17903                 # LU-5862
17904                 JOBENV="disable"
17905                 jobstats_set $JOBENV
17906                 touch $DIR/$tfile
17907                 changelog_dump | grep $tfile
17908                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17909                 [ $jobids -eq 0 ] ||
17910                         error "Unexpected jobids when jobid_var=$JOBENV"
17911         fi
17912
17913         # test '%j' access to environment variable - if supported
17914         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17915                 JOBENV="JOBCOMPLEX"
17916                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17917
17918                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17919         fi
17920
17921         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17922                 JOBENV="JOBCOMPLEX"
17923                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17924
17925                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17926         fi
17927
17928         # test '%j' access to per-session jobid - if supported
17929         if lctl list_param jobid_this_session > /dev/null 2>&1
17930         then
17931                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17932                 lctl set_param jobid_this_session=$USER
17933
17934                 JOBENV="JOBCOMPLEX"
17935                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17936
17937                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17938         fi
17939 }
17940 run_test 205a "Verify job stats"
17941
17942 # LU-13117, LU-13597
17943 test_205b() {
17944         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
17945                 skip "Need MDS version at least 2.13.54.91"
17946
17947         job_stats="mdt.*.job_stats"
17948         $LCTL set_param $job_stats=clear
17949         # Setting jobid_var to USER might not be supported
17950         $LCTL set_param jobid_var=USER || true
17951         $LCTL set_param jobid_name="%e.%u"
17952         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17953         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17954                 grep "job_id:.*foolish" &&
17955                         error "Unexpected jobid found"
17956         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17957                 grep "open:.*min.*max.*sum" ||
17958                         error "wrong job_stats format found"
17959 }
17960 run_test 205b "Verify job stats jobid and output format"
17961
17962 # LU-13733
17963 test_205c() {
17964         $LCTL set_param llite.*.stats=0
17965         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17966         $LCTL get_param llite.*.stats
17967         $LCTL get_param llite.*.stats | grep \
17968                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17969                         error "wrong client stats format found"
17970 }
17971 run_test 205c "Verify client stats format"
17972
17973 # LU-1480, LU-1773 and LU-1657
17974 test_206() {
17975         mkdir -p $DIR/$tdir
17976         $LFS setstripe -c -1 $DIR/$tdir
17977 #define OBD_FAIL_LOV_INIT 0x1403
17978         $LCTL set_param fail_loc=0xa0001403
17979         $LCTL set_param fail_val=1
17980         touch $DIR/$tdir/$tfile || true
17981 }
17982 run_test 206 "fail lov_init_raid0() doesn't lbug"
17983
17984 test_207a() {
17985         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17986         local fsz=`stat -c %s $DIR/$tfile`
17987         cancel_lru_locks mdc
17988
17989         # do not return layout in getattr intent
17990 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17991         $LCTL set_param fail_loc=0x170
17992         local sz=`stat -c %s $DIR/$tfile`
17993
17994         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17995
17996         rm -rf $DIR/$tfile
17997 }
17998 run_test 207a "can refresh layout at glimpse"
17999
18000 test_207b() {
18001         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18002         local cksum=`md5sum $DIR/$tfile`
18003         local fsz=`stat -c %s $DIR/$tfile`
18004         cancel_lru_locks mdc
18005         cancel_lru_locks osc
18006
18007         # do not return layout in getattr intent
18008 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18009         $LCTL set_param fail_loc=0x171
18010
18011         # it will refresh layout after the file is opened but before read issues
18012         echo checksum is "$cksum"
18013         echo "$cksum" |md5sum -c --quiet || error "file differs"
18014
18015         rm -rf $DIR/$tfile
18016 }
18017 run_test 207b "can refresh layout at open"
18018
18019 test_208() {
18020         # FIXME: in this test suite, only RD lease is used. This is okay
18021         # for now as only exclusive open is supported. After generic lease
18022         # is done, this test suite should be revised. - Jinshan
18023
18024         remote_mds_nodsh && skip "remote MDS with nodsh"
18025         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18026                 skip "Need MDS version at least 2.4.52"
18027
18028         echo "==== test 1: verify get lease work"
18029         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18030
18031         echo "==== test 2: verify lease can be broken by upcoming open"
18032         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
18033         local PID=$!
18034         sleep 1
18035
18036         $MULTIOP $DIR/$tfile oO_RDONLY:c
18037         kill -USR1 $PID && wait $PID || error "break lease error"
18038
18039         echo "==== test 3: verify lease can't be granted if an open already exists"
18040         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
18041         local PID=$!
18042         sleep 1
18043
18044         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
18045         kill -USR1 $PID && wait $PID || error "open file error"
18046
18047         echo "==== test 4: lease can sustain over recovery"
18048         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18049         PID=$!
18050         sleep 1
18051
18052         fail mds1
18053
18054         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18055
18056         echo "==== test 5: lease broken can't be regained by replay"
18057         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
18058         PID=$!
18059         sleep 1
18060
18061         # open file to break lease and then recovery
18062         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18063         fail mds1
18064
18065         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18066
18067         rm -f $DIR/$tfile
18068 }
18069 run_test 208 "Exclusive open"
18070
18071 test_209() {
18072         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18073                 skip_env "must have disp_stripe"
18074
18075         touch $DIR/$tfile
18076         sync; sleep 5; sync;
18077
18078         echo 3 > /proc/sys/vm/drop_caches
18079         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18080                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18081         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18082
18083         # open/close 500 times
18084         for i in $(seq 500); do
18085                 cat $DIR/$tfile
18086         done
18087
18088         echo 3 > /proc/sys/vm/drop_caches
18089         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18090                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18091         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18092
18093         echo "before: $req_before, after: $req_after"
18094         [ $((req_after - req_before)) -ge 300 ] &&
18095                 error "open/close requests are not freed"
18096         return 0
18097 }
18098 run_test 209 "read-only open/close requests should be freed promptly"
18099
18100 test_210() {
18101         local pid
18102
18103         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18104         pid=$!
18105         sleep 1
18106
18107         $LFS getstripe $DIR/$tfile
18108         kill -USR1 $pid
18109         wait $pid || error "multiop failed"
18110
18111         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18112         pid=$!
18113         sleep 1
18114
18115         $LFS getstripe $DIR/$tfile
18116         kill -USR1 $pid
18117         wait $pid || error "multiop failed"
18118 }
18119 run_test 210 "lfs getstripe does not break leases"
18120
18121 test_212() {
18122         size=`date +%s`
18123         size=$((size % 8192 + 1))
18124         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18125         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18126         rm -f $DIR/f212 $DIR/f212.xyz
18127 }
18128 run_test 212 "Sendfile test ============================================"
18129
18130 test_213() {
18131         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18132         cancel_lru_locks osc
18133         lctl set_param fail_loc=0x8000040f
18134         # generate a read lock
18135         cat $DIR/$tfile > /dev/null
18136         # write to the file, it will try to cancel the above read lock.
18137         cat /etc/hosts >> $DIR/$tfile
18138 }
18139 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18140
18141 test_214() { # for bug 20133
18142         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18143         for (( i=0; i < 340; i++ )) ; do
18144                 touch $DIR/$tdir/d214c/a$i
18145         done
18146
18147         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18148         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18149         ls $DIR/d214c || error "ls $DIR/d214c failed"
18150         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18151         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18152 }
18153 run_test 214 "hash-indexed directory test - bug 20133"
18154
18155 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18156 create_lnet_proc_files() {
18157         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18158 }
18159
18160 # counterpart of create_lnet_proc_files
18161 remove_lnet_proc_files() {
18162         rm -f $TMP/lnet_$1.sys
18163 }
18164
18165 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18166 # 3rd arg as regexp for body
18167 check_lnet_proc_stats() {
18168         local l=$(cat "$TMP/lnet_$1" |wc -l)
18169         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18170
18171         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18172 }
18173
18174 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18175 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18176 # optional and can be regexp for 2nd line (lnet.routes case)
18177 check_lnet_proc_entry() {
18178         local blp=2          # blp stands for 'position of 1st line of body'
18179         [ -z "$5" ] || blp=3 # lnet.routes case
18180
18181         local l=$(cat "$TMP/lnet_$1" |wc -l)
18182         # subtracting one from $blp because the body can be empty
18183         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18184
18185         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18186                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18187
18188         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18189                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18190
18191         # bail out if any unexpected line happened
18192         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18193         [ "$?" != 0 ] || error "$2 misformatted"
18194 }
18195
18196 test_215() { # for bugs 18102, 21079, 21517
18197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18198
18199         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18200         local P='[1-9][0-9]*'           # positive numeric
18201         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18202         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18203         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18204         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18205
18206         local L1 # regexp for 1st line
18207         local L2 # regexp for 2nd line (optional)
18208         local BR # regexp for the rest (body)
18209
18210         # lnet.stats should look as 11 space-separated non-negative numerics
18211         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18212         create_lnet_proc_files "stats"
18213         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18214         remove_lnet_proc_files "stats"
18215
18216         # lnet.routes should look like this:
18217         # Routing disabled/enabled
18218         # net hops priority state router
18219         # where net is a string like tcp0, hops > 0, priority >= 0,
18220         # state is up/down,
18221         # router is a string like 192.168.1.1@tcp2
18222         L1="^Routing (disabled|enabled)$"
18223         L2="^net +hops +priority +state +router$"
18224         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18225         create_lnet_proc_files "routes"
18226         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18227         remove_lnet_proc_files "routes"
18228
18229         # lnet.routers should look like this:
18230         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18231         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18232         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18233         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18234         L1="^ref +rtr_ref +alive +router$"
18235         BR="^$P +$P +(up|down) +$NID$"
18236         create_lnet_proc_files "routers"
18237         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18238         remove_lnet_proc_files "routers"
18239
18240         # lnet.peers should look like this:
18241         # nid refs state last max rtr min tx min queue
18242         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18243         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18244         # numeric (0 or >0 or <0), queue >= 0.
18245         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18246         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18247         create_lnet_proc_files "peers"
18248         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18249         remove_lnet_proc_files "peers"
18250
18251         # lnet.buffers  should look like this:
18252         # pages count credits min
18253         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18254         L1="^pages +count +credits +min$"
18255         BR="^ +$N +$N +$I +$I$"
18256         create_lnet_proc_files "buffers"
18257         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18258         remove_lnet_proc_files "buffers"
18259
18260         # lnet.nis should look like this:
18261         # nid status alive refs peer rtr max tx min
18262         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18263         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18264         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18265         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18266         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18267         create_lnet_proc_files "nis"
18268         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18269         remove_lnet_proc_files "nis"
18270
18271         # can we successfully write to lnet.stats?
18272         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18273 }
18274 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18275
18276 test_216() { # bug 20317
18277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18278         remote_ost_nodsh && skip "remote OST with nodsh"
18279
18280         local node
18281         local facets=$(get_facets OST)
18282         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18283
18284         save_lustre_params client "osc.*.contention_seconds" > $p
18285         save_lustre_params $facets \
18286                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18287         save_lustre_params $facets \
18288                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18289         save_lustre_params $facets \
18290                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18291         clear_stats osc.*.osc_stats
18292
18293         # agressive lockless i/o settings
18294         do_nodes $(comma_list $(osts_nodes)) \
18295                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18296                         ldlm.namespaces.filter-*.contended_locks=0 \
18297                         ldlm.namespaces.filter-*.contention_seconds=60"
18298         lctl set_param -n osc.*.contention_seconds=60
18299
18300         $DIRECTIO write $DIR/$tfile 0 10 4096
18301         $CHECKSTAT -s 40960 $DIR/$tfile
18302
18303         # disable lockless i/o
18304         do_nodes $(comma_list $(osts_nodes)) \
18305                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18306                         ldlm.namespaces.filter-*.contended_locks=32 \
18307                         ldlm.namespaces.filter-*.contention_seconds=0"
18308         lctl set_param -n osc.*.contention_seconds=0
18309         clear_stats osc.*.osc_stats
18310
18311         dd if=/dev/zero of=$DIR/$tfile count=0
18312         $CHECKSTAT -s 0 $DIR/$tfile
18313
18314         restore_lustre_params <$p
18315         rm -f $p
18316         rm $DIR/$tfile
18317 }
18318 run_test 216 "check lockless direct write updates file size and kms correctly"
18319
18320 test_217() { # bug 22430
18321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18322
18323         local node
18324         local nid
18325
18326         for node in $(nodes_list); do
18327                 nid=$(host_nids_address $node $NETTYPE)
18328                 if [[ $nid = *-* ]] ; then
18329                         echo "lctl ping $(h2nettype $nid)"
18330                         lctl ping $(h2nettype $nid)
18331                 else
18332                         echo "skipping $node (no hyphen detected)"
18333                 fi
18334         done
18335 }
18336 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18337
18338 test_218() {
18339        # do directio so as not to populate the page cache
18340        log "creating a 10 Mb file"
18341        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18342        log "starting reads"
18343        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18344        log "truncating the file"
18345        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18346        log "killing dd"
18347        kill %+ || true # reads might have finished
18348        echo "wait until dd is finished"
18349        wait
18350        log "removing the temporary file"
18351        rm -rf $DIR/$tfile || error "tmp file removal failed"
18352 }
18353 run_test 218 "parallel read and truncate should not deadlock"
18354
18355 test_219() {
18356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18357
18358         # write one partial page
18359         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18360         # set no grant so vvp_io_commit_write will do sync write
18361         $LCTL set_param fail_loc=0x411
18362         # write a full page at the end of file
18363         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18364
18365         $LCTL set_param fail_loc=0
18366         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18367         $LCTL set_param fail_loc=0x411
18368         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18369
18370         # LU-4201
18371         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18372         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18373 }
18374 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18375
18376 test_220() { #LU-325
18377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18378         remote_ost_nodsh && skip "remote OST with nodsh"
18379         remote_mds_nodsh && skip "remote MDS with nodsh"
18380         remote_mgs_nodsh && skip "remote MGS with nodsh"
18381
18382         local OSTIDX=0
18383
18384         # create on MDT0000 so the last_id and next_id are correct
18385         mkdir_on_mdt0 $DIR/$tdir
18386         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18387         OST=${OST%_UUID}
18388
18389         # on the mdt's osc
18390         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18391         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18392                         osp.$mdtosc_proc1.prealloc_last_id)
18393         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18394                         osp.$mdtosc_proc1.prealloc_next_id)
18395
18396         $LFS df -i
18397
18398         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18399         #define OBD_FAIL_OST_ENOINO              0x229
18400         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18401         create_pool $FSNAME.$TESTNAME || return 1
18402         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18403
18404         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18405
18406         MDSOBJS=$((last_id - next_id))
18407         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18408
18409         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18410         echo "OST still has $count kbytes free"
18411
18412         echo "create $MDSOBJS files @next_id..."
18413         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18414
18415         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18416                         osp.$mdtosc_proc1.prealloc_last_id)
18417         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18418                         osp.$mdtosc_proc1.prealloc_next_id)
18419
18420         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18421         $LFS df -i
18422
18423         echo "cleanup..."
18424
18425         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18426         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18427
18428         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18429                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18430         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18431                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18432         echo "unlink $MDSOBJS files @$next_id..."
18433         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18434 }
18435 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18436
18437 test_221() {
18438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18439
18440         dd if=`which date` of=$MOUNT/date oflag=sync
18441         chmod +x $MOUNT/date
18442
18443         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18444         $LCTL set_param fail_loc=0x80001401
18445
18446         $MOUNT/date > /dev/null
18447         rm -f $MOUNT/date
18448 }
18449 run_test 221 "make sure fault and truncate race to not cause OOM"
18450
18451 test_222a () {
18452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18453
18454         rm -rf $DIR/$tdir
18455         test_mkdir $DIR/$tdir
18456         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18457         createmany -o $DIR/$tdir/$tfile 10
18458         cancel_lru_locks mdc
18459         cancel_lru_locks osc
18460         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18461         $LCTL set_param fail_loc=0x31a
18462         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18463         $LCTL set_param fail_loc=0
18464         rm -r $DIR/$tdir
18465 }
18466 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18467
18468 test_222b () {
18469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18470
18471         rm -rf $DIR/$tdir
18472         test_mkdir $DIR/$tdir
18473         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18474         createmany -o $DIR/$tdir/$tfile 10
18475         cancel_lru_locks mdc
18476         cancel_lru_locks osc
18477         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18478         $LCTL set_param fail_loc=0x31a
18479         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18480         $LCTL set_param fail_loc=0
18481 }
18482 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18483
18484 test_223 () {
18485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18486
18487         rm -rf $DIR/$tdir
18488         test_mkdir $DIR/$tdir
18489         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18490         createmany -o $DIR/$tdir/$tfile 10
18491         cancel_lru_locks mdc
18492         cancel_lru_locks osc
18493         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18494         $LCTL set_param fail_loc=0x31b
18495         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18496         $LCTL set_param fail_loc=0
18497         rm -r $DIR/$tdir
18498 }
18499 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18500
18501 test_224a() { # LU-1039, MRP-303
18502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18503
18504         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18505         $LCTL set_param fail_loc=0x508
18506         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18507         $LCTL set_param fail_loc=0
18508         df $DIR
18509 }
18510 run_test 224a "Don't panic on bulk IO failure"
18511
18512 test_224b() { # LU-1039, MRP-303
18513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18514
18515         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18516         cancel_lru_locks osc
18517         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18518         $LCTL set_param fail_loc=0x515
18519         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18520         $LCTL set_param fail_loc=0
18521         df $DIR
18522 }
18523 run_test 224b "Don't panic on bulk IO failure"
18524
18525 test_224c() { # LU-6441
18526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18527         remote_mds_nodsh && skip "remote MDS with nodsh"
18528
18529         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18530         save_writethrough $p
18531         set_cache writethrough on
18532
18533         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18534         local at_max=$($LCTL get_param -n at_max)
18535         local timeout=$($LCTL get_param -n timeout)
18536         local test_at="at_max"
18537         local param_at="$FSNAME.sys.at_max"
18538         local test_timeout="timeout"
18539         local param_timeout="$FSNAME.sys.timeout"
18540
18541         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18542
18543         set_persistent_param_and_check client "$test_at" "$param_at" 0
18544         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18545
18546         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18547         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18548         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18549         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18550         sync
18551         do_facet ost1 "$LCTL set_param fail_loc=0"
18552
18553         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18554         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18555                 $timeout
18556
18557         $LCTL set_param -n $pages_per_rpc
18558         restore_lustre_params < $p
18559         rm -f $p
18560 }
18561 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18562
18563 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18564 test_225a () {
18565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18566         if [ -z ${MDSSURVEY} ]; then
18567                 skip_env "mds-survey not found"
18568         fi
18569         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18570                 skip "Need MDS version at least 2.2.51"
18571
18572         local mds=$(facet_host $SINGLEMDS)
18573         local target=$(do_nodes $mds 'lctl dl' |
18574                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18575
18576         local cmd1="file_count=1000 thrhi=4"
18577         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18578         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18579         local cmd="$cmd1 $cmd2 $cmd3"
18580
18581         rm -f ${TMP}/mds_survey*
18582         echo + $cmd
18583         eval $cmd || error "mds-survey with zero-stripe failed"
18584         cat ${TMP}/mds_survey*
18585         rm -f ${TMP}/mds_survey*
18586 }
18587 run_test 225a "Metadata survey sanity with zero-stripe"
18588
18589 test_225b () {
18590         if [ -z ${MDSSURVEY} ]; then
18591                 skip_env "mds-survey not found"
18592         fi
18593         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18594                 skip "Need MDS version at least 2.2.51"
18595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18596         remote_mds_nodsh && skip "remote MDS with nodsh"
18597         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18598                 skip_env "Need to mount OST to test"
18599         fi
18600
18601         local mds=$(facet_host $SINGLEMDS)
18602         local target=$(do_nodes $mds 'lctl dl' |
18603                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18604
18605         local cmd1="file_count=1000 thrhi=4"
18606         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18607         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18608         local cmd="$cmd1 $cmd2 $cmd3"
18609
18610         rm -f ${TMP}/mds_survey*
18611         echo + $cmd
18612         eval $cmd || error "mds-survey with stripe_count failed"
18613         cat ${TMP}/mds_survey*
18614         rm -f ${TMP}/mds_survey*
18615 }
18616 run_test 225b "Metadata survey sanity with stripe_count = 1"
18617
18618 mcreate_path2fid () {
18619         local mode=$1
18620         local major=$2
18621         local minor=$3
18622         local name=$4
18623         local desc=$5
18624         local path=$DIR/$tdir/$name
18625         local fid
18626         local rc
18627         local fid_path
18628
18629         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18630                 error "cannot create $desc"
18631
18632         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18633         rc=$?
18634         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18635
18636         fid_path=$($LFS fid2path $MOUNT $fid)
18637         rc=$?
18638         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18639
18640         [ "$path" == "$fid_path" ] ||
18641                 error "fid2path returned $fid_path, expected $path"
18642
18643         echo "pass with $path and $fid"
18644 }
18645
18646 test_226a () {
18647         rm -rf $DIR/$tdir
18648         mkdir -p $DIR/$tdir
18649
18650         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18651         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18652         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18653         mcreate_path2fid 0040666 0 0 dir "directory"
18654         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18655         mcreate_path2fid 0100666 0 0 file "regular file"
18656         mcreate_path2fid 0120666 0 0 link "symbolic link"
18657         mcreate_path2fid 0140666 0 0 sock "socket"
18658 }
18659 run_test 226a "call path2fid and fid2path on files of all type"
18660
18661 test_226b () {
18662         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18663
18664         local MDTIDX=1
18665
18666         rm -rf $DIR/$tdir
18667         mkdir -p $DIR/$tdir
18668         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18669                 error "create remote directory failed"
18670         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18671         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18672                                 "character special file (null)"
18673         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18674                                 "character special file (no device)"
18675         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18676         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18677                                 "block special file (loop)"
18678         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18679         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18680         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18681 }
18682 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18683
18684 test_226c () {
18685         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18686         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18687                 skip "Need MDS version at least 2.13.55"
18688
18689         local submnt=/mnt/submnt
18690         local srcfile=/etc/passwd
18691         local dstfile=$submnt/passwd
18692         local path
18693         local fid
18694
18695         rm -rf $DIR/$tdir
18696         rm -rf $submnt
18697         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18698                 error "create remote directory failed"
18699         mkdir -p $submnt || error "create $submnt failed"
18700         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18701                 error "mount $submnt failed"
18702         stack_trap "umount $submnt" EXIT
18703
18704         cp $srcfile $dstfile
18705         fid=$($LFS path2fid $dstfile)
18706         path=$($LFS fid2path $submnt "$fid")
18707         [ "$path" = "$dstfile" ] ||
18708                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18709 }
18710 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18711
18712 # LU-1299 Executing or running ldd on a truncated executable does not
18713 # cause an out-of-memory condition.
18714 test_227() {
18715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18716         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18717
18718         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18719         chmod +x $MOUNT/date
18720
18721         $MOUNT/date > /dev/null
18722         ldd $MOUNT/date > /dev/null
18723         rm -f $MOUNT/date
18724 }
18725 run_test 227 "running truncated executable does not cause OOM"
18726
18727 # LU-1512 try to reuse idle OI blocks
18728 test_228a() {
18729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18730         remote_mds_nodsh && skip "remote MDS with nodsh"
18731         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18732
18733         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18734         local myDIR=$DIR/$tdir
18735
18736         mkdir -p $myDIR
18737         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18738         $LCTL set_param fail_loc=0x80001002
18739         createmany -o $myDIR/t- 10000
18740         $LCTL set_param fail_loc=0
18741         # The guard is current the largest FID holder
18742         touch $myDIR/guard
18743         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18744                     tr -d '[')
18745         local IDX=$(($SEQ % 64))
18746
18747         do_facet $SINGLEMDS sync
18748         # Make sure journal flushed.
18749         sleep 6
18750         local blk1=$(do_facet $SINGLEMDS \
18751                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18752                      grep Blockcount | awk '{print $4}')
18753
18754         # Remove old files, some OI blocks will become idle.
18755         unlinkmany $myDIR/t- 10000
18756         # Create new files, idle OI blocks should be reused.
18757         createmany -o $myDIR/t- 2000
18758         do_facet $SINGLEMDS sync
18759         # Make sure journal flushed.
18760         sleep 6
18761         local blk2=$(do_facet $SINGLEMDS \
18762                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18763                      grep Blockcount | awk '{print $4}')
18764
18765         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18766 }
18767 run_test 228a "try to reuse idle OI blocks"
18768
18769 test_228b() {
18770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18771         remote_mds_nodsh && skip "remote MDS with nodsh"
18772         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18773
18774         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18775         local myDIR=$DIR/$tdir
18776
18777         mkdir -p $myDIR
18778         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18779         $LCTL set_param fail_loc=0x80001002
18780         createmany -o $myDIR/t- 10000
18781         $LCTL set_param fail_loc=0
18782         # The guard is current the largest FID holder
18783         touch $myDIR/guard
18784         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18785                     tr -d '[')
18786         local IDX=$(($SEQ % 64))
18787
18788         do_facet $SINGLEMDS sync
18789         # Make sure journal flushed.
18790         sleep 6
18791         local blk1=$(do_facet $SINGLEMDS \
18792                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18793                      grep Blockcount | awk '{print $4}')
18794
18795         # Remove old files, some OI blocks will become idle.
18796         unlinkmany $myDIR/t- 10000
18797
18798         # stop the MDT
18799         stop $SINGLEMDS || error "Fail to stop MDT."
18800         # remount the MDT
18801         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18802
18803         df $MOUNT || error "Fail to df."
18804         # Create new files, idle OI blocks should be reused.
18805         createmany -o $myDIR/t- 2000
18806         do_facet $SINGLEMDS sync
18807         # Make sure journal flushed.
18808         sleep 6
18809         local blk2=$(do_facet $SINGLEMDS \
18810                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18811                      grep Blockcount | awk '{print $4}')
18812
18813         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18814 }
18815 run_test 228b "idle OI blocks can be reused after MDT restart"
18816
18817 #LU-1881
18818 test_228c() {
18819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18820         remote_mds_nodsh && skip "remote MDS with nodsh"
18821         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18822
18823         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18824         local myDIR=$DIR/$tdir
18825
18826         mkdir -p $myDIR
18827         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18828         $LCTL set_param fail_loc=0x80001002
18829         # 20000 files can guarantee there are index nodes in the OI file
18830         createmany -o $myDIR/t- 20000
18831         $LCTL set_param fail_loc=0
18832         # The guard is current the largest FID holder
18833         touch $myDIR/guard
18834         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18835                     tr -d '[')
18836         local IDX=$(($SEQ % 64))
18837
18838         do_facet $SINGLEMDS sync
18839         # Make sure journal flushed.
18840         sleep 6
18841         local blk1=$(do_facet $SINGLEMDS \
18842                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18843                      grep Blockcount | awk '{print $4}')
18844
18845         # Remove old files, some OI blocks will become idle.
18846         unlinkmany $myDIR/t- 20000
18847         rm -f $myDIR/guard
18848         # The OI file should become empty now
18849
18850         # Create new files, idle OI blocks should be reused.
18851         createmany -o $myDIR/t- 2000
18852         do_facet $SINGLEMDS sync
18853         # Make sure journal flushed.
18854         sleep 6
18855         local blk2=$(do_facet $SINGLEMDS \
18856                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18857                      grep Blockcount | awk '{print $4}')
18858
18859         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18860 }
18861 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18862
18863 test_229() { # LU-2482, LU-3448
18864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18865         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18866         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18867                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18868
18869         rm -f $DIR/$tfile
18870
18871         # Create a file with a released layout and stripe count 2.
18872         $MULTIOP $DIR/$tfile H2c ||
18873                 error "failed to create file with released layout"
18874
18875         $LFS getstripe -v $DIR/$tfile
18876
18877         local pattern=$($LFS getstripe -L $DIR/$tfile)
18878         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18879
18880         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18881                 error "getstripe"
18882         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18883         stat $DIR/$tfile || error "failed to stat released file"
18884
18885         chown $RUNAS_ID $DIR/$tfile ||
18886                 error "chown $RUNAS_ID $DIR/$tfile failed"
18887
18888         chgrp $RUNAS_ID $DIR/$tfile ||
18889                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18890
18891         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18892         rm $DIR/$tfile || error "failed to remove released file"
18893 }
18894 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18895
18896 test_230a() {
18897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18898         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18899         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18900                 skip "Need MDS version at least 2.11.52"
18901
18902         local MDTIDX=1
18903
18904         test_mkdir $DIR/$tdir
18905         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18906         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18907         [ $mdt_idx -ne 0 ] &&
18908                 error "create local directory on wrong MDT $mdt_idx"
18909
18910         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18911                         error "create remote directory failed"
18912         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18913         [ $mdt_idx -ne $MDTIDX ] &&
18914                 error "create remote directory on wrong MDT $mdt_idx"
18915
18916         createmany -o $DIR/$tdir/test_230/t- 10 ||
18917                 error "create files on remote directory failed"
18918         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18919         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18920         rm -r $DIR/$tdir || error "unlink remote directory failed"
18921 }
18922 run_test 230a "Create remote directory and files under the remote directory"
18923
18924 test_230b() {
18925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18926         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18927         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18928                 skip "Need MDS version at least 2.11.52"
18929
18930         local MDTIDX=1
18931         local mdt_index
18932         local i
18933         local file
18934         local pid
18935         local stripe_count
18936         local migrate_dir=$DIR/$tdir/migrate_dir
18937         local other_dir=$DIR/$tdir/other_dir
18938
18939         test_mkdir $DIR/$tdir
18940         test_mkdir -i0 -c1 $migrate_dir
18941         test_mkdir -i0 -c1 $other_dir
18942         for ((i=0; i<10; i++)); do
18943                 mkdir -p $migrate_dir/dir_${i}
18944                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18945                         error "create files under remote dir failed $i"
18946         done
18947
18948         cp /etc/passwd $migrate_dir/$tfile
18949         cp /etc/passwd $other_dir/$tfile
18950         chattr +SAD $migrate_dir
18951         chattr +SAD $migrate_dir/$tfile
18952
18953         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18954         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18955         local old_dir_mode=$(stat -c%f $migrate_dir)
18956         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18957
18958         mkdir -p $migrate_dir/dir_default_stripe2
18959         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18960         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18961
18962         mkdir -p $other_dir
18963         ln $migrate_dir/$tfile $other_dir/luna
18964         ln $migrate_dir/$tfile $migrate_dir/sofia
18965         ln $other_dir/$tfile $migrate_dir/david
18966         ln -s $migrate_dir/$tfile $other_dir/zachary
18967         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18968         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18969
18970         local len
18971         local lnktgt
18972
18973         # inline symlink
18974         for len in 58 59 60; do
18975                 lnktgt=$(str_repeat 'l' $len)
18976                 touch $migrate_dir/$lnktgt
18977                 ln -s $lnktgt $migrate_dir/${len}char_ln
18978         done
18979
18980         # PATH_MAX
18981         for len in 4094 4095; do
18982                 lnktgt=$(str_repeat 'l' $len)
18983                 ln -s $lnktgt $migrate_dir/${len}char_ln
18984         done
18985
18986         # NAME_MAX
18987         for len in 254 255; do
18988                 touch $migrate_dir/$(str_repeat 'l' $len)
18989         done
18990
18991         $LFS migrate -m $MDTIDX $migrate_dir ||
18992                 error "fails on migrating remote dir to MDT1"
18993
18994         echo "migratate to MDT1, then checking.."
18995         for ((i = 0; i < 10; i++)); do
18996                 for file in $(find $migrate_dir/dir_${i}); do
18997                         mdt_index=$($LFS getstripe -m $file)
18998                         # broken symlink getstripe will fail
18999                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19000                                 error "$file is not on MDT${MDTIDX}"
19001                 done
19002         done
19003
19004         # the multiple link file should still in MDT0
19005         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19006         [ $mdt_index == 0 ] ||
19007                 error "$file is not on MDT${MDTIDX}"
19008
19009         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19010         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19011                 error " expect $old_dir_flag get $new_dir_flag"
19012
19013         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19014         [ "$old_file_flag" = "$new_file_flag" ] ||
19015                 error " expect $old_file_flag get $new_file_flag"
19016
19017         local new_dir_mode=$(stat -c%f $migrate_dir)
19018         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19019                 error "expect mode $old_dir_mode get $new_dir_mode"
19020
19021         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19022         [ "$old_file_mode" = "$new_file_mode" ] ||
19023                 error "expect mode $old_file_mode get $new_file_mode"
19024
19025         diff /etc/passwd $migrate_dir/$tfile ||
19026                 error "$tfile different after migration"
19027
19028         diff /etc/passwd $other_dir/luna ||
19029                 error "luna different after migration"
19030
19031         diff /etc/passwd $migrate_dir/sofia ||
19032                 error "sofia different after migration"
19033
19034         diff /etc/passwd $migrate_dir/david ||
19035                 error "david different after migration"
19036
19037         diff /etc/passwd $other_dir/zachary ||
19038                 error "zachary different after migration"
19039
19040         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19041                 error "${tfile}_ln different after migration"
19042
19043         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19044                 error "${tfile}_ln_other different after migration"
19045
19046         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19047         [ $stripe_count = 2 ] ||
19048                 error "dir strpe_count $d != 2 after migration."
19049
19050         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19051         [ $stripe_count = 2 ] ||
19052                 error "file strpe_count $d != 2 after migration."
19053
19054         #migrate back to MDT0
19055         MDTIDX=0
19056
19057         $LFS migrate -m $MDTIDX $migrate_dir ||
19058                 error "fails on migrating remote dir to MDT0"
19059
19060         echo "migrate back to MDT0, checking.."
19061         for file in $(find $migrate_dir); do
19062                 mdt_index=$($LFS getstripe -m $file)
19063                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19064                         error "$file is not on MDT${MDTIDX}"
19065         done
19066
19067         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19068         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19069                 error " expect $old_dir_flag get $new_dir_flag"
19070
19071         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19072         [ "$old_file_flag" = "$new_file_flag" ] ||
19073                 error " expect $old_file_flag get $new_file_flag"
19074
19075         local new_dir_mode=$(stat -c%f $migrate_dir)
19076         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19077                 error "expect mode $old_dir_mode get $new_dir_mode"
19078
19079         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19080         [ "$old_file_mode" = "$new_file_mode" ] ||
19081                 error "expect mode $old_file_mode get $new_file_mode"
19082
19083         diff /etc/passwd ${migrate_dir}/$tfile ||
19084                 error "$tfile different after migration"
19085
19086         diff /etc/passwd ${other_dir}/luna ||
19087                 error "luna different after migration"
19088
19089         diff /etc/passwd ${migrate_dir}/sofia ||
19090                 error "sofia different after migration"
19091
19092         diff /etc/passwd ${other_dir}/zachary ||
19093                 error "zachary different after migration"
19094
19095         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19096                 error "${tfile}_ln different after migration"
19097
19098         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19099                 error "${tfile}_ln_other different after migration"
19100
19101         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19102         [ $stripe_count = 2 ] ||
19103                 error "dir strpe_count $d != 2 after migration."
19104
19105         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19106         [ $stripe_count = 2 ] ||
19107                 error "file strpe_count $d != 2 after migration."
19108
19109         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19110 }
19111 run_test 230b "migrate directory"
19112
19113 test_230c() {
19114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19115         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19116         remote_mds_nodsh && skip "remote MDS with nodsh"
19117         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19118                 skip "Need MDS version at least 2.11.52"
19119
19120         local MDTIDX=1
19121         local total=3
19122         local mdt_index
19123         local file
19124         local migrate_dir=$DIR/$tdir/migrate_dir
19125
19126         #If migrating directory fails in the middle, all entries of
19127         #the directory is still accessiable.
19128         test_mkdir $DIR/$tdir
19129         test_mkdir -i0 -c1 $migrate_dir
19130         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19131         stat $migrate_dir
19132         createmany -o $migrate_dir/f $total ||
19133                 error "create files under ${migrate_dir} failed"
19134
19135         # fail after migrating top dir, and this will fail only once, so the
19136         # first sub file migration will fail (currently f3), others succeed.
19137         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19138         do_facet mds1 lctl set_param fail_loc=0x1801
19139         local t=$(ls $migrate_dir | wc -l)
19140         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19141                 error "migrate should fail"
19142         local u=$(ls $migrate_dir | wc -l)
19143         [ "$u" == "$t" ] || error "$u != $t during migration"
19144
19145         # add new dir/file should succeed
19146         mkdir $migrate_dir/dir ||
19147                 error "mkdir failed under migrating directory"
19148         touch $migrate_dir/file ||
19149                 error "create file failed under migrating directory"
19150
19151         # add file with existing name should fail
19152         for file in $migrate_dir/f*; do
19153                 stat $file > /dev/null || error "stat $file failed"
19154                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19155                         error "open(O_CREAT|O_EXCL) $file should fail"
19156                 $MULTIOP $file m && error "create $file should fail"
19157                 touch $DIR/$tdir/remote_dir/$tfile ||
19158                         error "touch $tfile failed"
19159                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19160                         error "link $file should fail"
19161                 mdt_index=$($LFS getstripe -m $file)
19162                 if [ $mdt_index == 0 ]; then
19163                         # file failed to migrate is not allowed to rename to
19164                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19165                                 error "rename to $file should fail"
19166                 else
19167                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19168                                 error "rename to $file failed"
19169                 fi
19170                 echo hello >> $file || error "write $file failed"
19171         done
19172
19173         # resume migration with different options should fail
19174         $LFS migrate -m 0 $migrate_dir &&
19175                 error "migrate -m 0 $migrate_dir should fail"
19176
19177         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19178                 error "migrate -c 2 $migrate_dir should fail"
19179
19180         # resume migration should succeed
19181         $LFS migrate -m $MDTIDX $migrate_dir ||
19182                 error "migrate $migrate_dir failed"
19183
19184         echo "Finish migration, then checking.."
19185         for file in $(find $migrate_dir); do
19186                 mdt_index=$($LFS getstripe -m $file)
19187                 [ $mdt_index == $MDTIDX ] ||
19188                         error "$file is not on MDT${MDTIDX}"
19189         done
19190
19191         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19192 }
19193 run_test 230c "check directory accessiblity if migration failed"
19194
19195 test_230d() {
19196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19197         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19198         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19199                 skip "Need MDS version at least 2.11.52"
19200         # LU-11235
19201         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19202
19203         local migrate_dir=$DIR/$tdir/migrate_dir
19204         local old_index
19205         local new_index
19206         local old_count
19207         local new_count
19208         local new_hash
19209         local mdt_index
19210         local i
19211         local j
19212
19213         old_index=$((RANDOM % MDSCOUNT))
19214         old_count=$((MDSCOUNT - old_index))
19215         new_index=$((RANDOM % MDSCOUNT))
19216         new_count=$((MDSCOUNT - new_index))
19217         new_hash=1 # for all_char
19218
19219         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19220         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19221
19222         test_mkdir $DIR/$tdir
19223         test_mkdir -i $old_index -c $old_count $migrate_dir
19224
19225         for ((i=0; i<100; i++)); do
19226                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19227                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19228                         error "create files under remote dir failed $i"
19229         done
19230
19231         echo -n "Migrate from MDT$old_index "
19232         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19233         echo -n "to MDT$new_index"
19234         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19235         echo
19236
19237         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19238         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19239                 error "migrate remote dir error"
19240
19241         echo "Finish migration, then checking.."
19242         for file in $(find $migrate_dir); do
19243                 mdt_index=$($LFS getstripe -m $file)
19244                 if [ $mdt_index -lt $new_index ] ||
19245                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19246                         error "$file is on MDT$mdt_index"
19247                 fi
19248         done
19249
19250         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19251 }
19252 run_test 230d "check migrate big directory"
19253
19254 test_230e() {
19255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19256         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19257         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19258                 skip "Need MDS version at least 2.11.52"
19259
19260         local i
19261         local j
19262         local a_fid
19263         local b_fid
19264
19265         mkdir_on_mdt0 $DIR/$tdir
19266         mkdir $DIR/$tdir/migrate_dir
19267         mkdir $DIR/$tdir/other_dir
19268         touch $DIR/$tdir/migrate_dir/a
19269         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19270         ls $DIR/$tdir/other_dir
19271
19272         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19273                 error "migrate dir fails"
19274
19275         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19276         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19277
19278         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19279         [ $mdt_index == 0 ] || error "a is not on MDT0"
19280
19281         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19282                 error "migrate dir fails"
19283
19284         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19285         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19286
19287         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19288         [ $mdt_index == 1 ] || error "a is not on MDT1"
19289
19290         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19291         [ $mdt_index == 1 ] || error "b is not on MDT1"
19292
19293         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19294         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19295
19296         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19297
19298         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19299 }
19300 run_test 230e "migrate mulitple local link files"
19301
19302 test_230f() {
19303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19304         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19305         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19306                 skip "Need MDS version at least 2.11.52"
19307
19308         local a_fid
19309         local ln_fid
19310
19311         mkdir -p $DIR/$tdir
19312         mkdir $DIR/$tdir/migrate_dir
19313         $LFS mkdir -i1 $DIR/$tdir/other_dir
19314         touch $DIR/$tdir/migrate_dir/a
19315         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19316         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19317         ls $DIR/$tdir/other_dir
19318
19319         # a should be migrated to MDT1, since no other links on MDT0
19320         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19321                 error "#1 migrate dir fails"
19322         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19323         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19324         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19325         [ $mdt_index == 1 ] || error "a is not on MDT1"
19326
19327         # a should stay on MDT1, because it is a mulitple link file
19328         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19329                 error "#2 migrate dir fails"
19330         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19331         [ $mdt_index == 1 ] || error "a is not on MDT1"
19332
19333         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19334                 error "#3 migrate dir fails"
19335
19336         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19337         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19338         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19339
19340         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19341         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19342
19343         # a should be migrated to MDT0, since no other links on MDT1
19344         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19345                 error "#4 migrate dir fails"
19346         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19347         [ $mdt_index == 0 ] || error "a is not on MDT0"
19348
19349         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19350 }
19351 run_test 230f "migrate mulitple remote link files"
19352
19353 test_230g() {
19354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19355         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19356         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19357                 skip "Need MDS version at least 2.11.52"
19358
19359         mkdir -p $DIR/$tdir/migrate_dir
19360
19361         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19362                 error "migrating dir to non-exist MDT succeeds"
19363         true
19364 }
19365 run_test 230g "migrate dir to non-exist MDT"
19366
19367 test_230h() {
19368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19369         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19370         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19371                 skip "Need MDS version at least 2.11.52"
19372
19373         local mdt_index
19374
19375         mkdir -p $DIR/$tdir/migrate_dir
19376
19377         $LFS migrate -m1 $DIR &&
19378                 error "migrating mountpoint1 should fail"
19379
19380         $LFS migrate -m1 $DIR/$tdir/.. &&
19381                 error "migrating mountpoint2 should fail"
19382
19383         # same as mv
19384         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19385                 error "migrating $tdir/migrate_dir/.. should fail"
19386
19387         true
19388 }
19389 run_test 230h "migrate .. and root"
19390
19391 test_230i() {
19392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19393         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19394         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19395                 skip "Need MDS version at least 2.11.52"
19396
19397         mkdir -p $DIR/$tdir/migrate_dir
19398
19399         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19400                 error "migration fails with a tailing slash"
19401
19402         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19403                 error "migration fails with two tailing slashes"
19404 }
19405 run_test 230i "lfs migrate -m tolerates trailing slashes"
19406
19407 test_230j() {
19408         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19409         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19410                 skip "Need MDS version at least 2.11.52"
19411
19412         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19413         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19414                 error "create $tfile failed"
19415         cat /etc/passwd > $DIR/$tdir/$tfile
19416
19417         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19418
19419         cmp /etc/passwd $DIR/$tdir/$tfile ||
19420                 error "DoM file mismatch after migration"
19421 }
19422 run_test 230j "DoM file data not changed after dir migration"
19423
19424 test_230k() {
19425         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19426         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19427                 skip "Need MDS version at least 2.11.56"
19428
19429         local total=20
19430         local files_on_starting_mdt=0
19431
19432         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19433         $LFS getdirstripe $DIR/$tdir
19434         for i in $(seq $total); do
19435                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19436                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19437                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19438         done
19439
19440         echo "$files_on_starting_mdt files on MDT0"
19441
19442         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19443         $LFS getdirstripe $DIR/$tdir
19444
19445         files_on_starting_mdt=0
19446         for i in $(seq $total); do
19447                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19448                         error "file $tfile.$i mismatch after migration"
19449                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19450                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19451         done
19452
19453         echo "$files_on_starting_mdt files on MDT1 after migration"
19454         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19455
19456         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19457         $LFS getdirstripe $DIR/$tdir
19458
19459         files_on_starting_mdt=0
19460         for i in $(seq $total); do
19461                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19462                         error "file $tfile.$i mismatch after 2nd migration"
19463                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19464                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19465         done
19466
19467         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19468         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19469
19470         true
19471 }
19472 run_test 230k "file data not changed after dir migration"
19473
19474 test_230l() {
19475         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19476         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19477                 skip "Need MDS version at least 2.11.56"
19478
19479         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19480         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19481                 error "create files under remote dir failed $i"
19482         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19483 }
19484 run_test 230l "readdir between MDTs won't crash"
19485
19486 test_230m() {
19487         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19488         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19489                 skip "Need MDS version at least 2.11.56"
19490
19491         local MDTIDX=1
19492         local mig_dir=$DIR/$tdir/migrate_dir
19493         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19494         local shortstr="b"
19495         local val
19496
19497         echo "Creating files and dirs with xattrs"
19498         test_mkdir $DIR/$tdir
19499         test_mkdir -i0 -c1 $mig_dir
19500         mkdir $mig_dir/dir
19501         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19502                 error "cannot set xattr attr1 on dir"
19503         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19504                 error "cannot set xattr attr2 on dir"
19505         touch $mig_dir/dir/f0
19506         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19507                 error "cannot set xattr attr1 on file"
19508         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19509                 error "cannot set xattr attr2 on file"
19510         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19511         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19512         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19513         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19514         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19515         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19516         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19517         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19518         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19519
19520         echo "Migrating to MDT1"
19521         $LFS migrate -m $MDTIDX $mig_dir ||
19522                 error "fails on migrating dir to MDT1"
19523
19524         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19525         echo "Checking xattrs"
19526         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19527         [ "$val" = $longstr ] ||
19528                 error "expecting xattr1 $longstr on dir, found $val"
19529         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19530         [ "$val" = $shortstr ] ||
19531                 error "expecting xattr2 $shortstr on dir, found $val"
19532         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19533         [ "$val" = $longstr ] ||
19534                 error "expecting xattr1 $longstr on file, found $val"
19535         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19536         [ "$val" = $shortstr ] ||
19537                 error "expecting xattr2 $shortstr on file, found $val"
19538 }
19539 run_test 230m "xattrs not changed after dir migration"
19540
19541 test_230n() {
19542         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19543         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19544                 skip "Need MDS version at least 2.13.53"
19545
19546         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19547         cat /etc/hosts > $DIR/$tdir/$tfile
19548         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19549         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19550
19551         cmp /etc/hosts $DIR/$tdir/$tfile ||
19552                 error "File data mismatch after migration"
19553 }
19554 run_test 230n "Dir migration with mirrored file"
19555
19556 test_230o() {
19557         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19558         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19559                 skip "Need MDS version at least 2.13.52"
19560
19561         local mdts=$(comma_list $(mdts_nodes))
19562         local timeout=100
19563         local restripe_status
19564         local delta
19565         local i
19566
19567         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19568
19569         # in case "crush" hash type is not set
19570         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19571
19572         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19573                            mdt.*MDT0000.enable_dir_restripe)
19574         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19575         stack_trap "do_nodes $mdts $LCTL set_param \
19576                     mdt.*.enable_dir_restripe=$restripe_status"
19577
19578         mkdir $DIR/$tdir
19579         createmany -m $DIR/$tdir/f 100 ||
19580                 error "create files under remote dir failed $i"
19581         createmany -d $DIR/$tdir/d 100 ||
19582                 error "create dirs under remote dir failed $i"
19583
19584         for i in $(seq 2 $MDSCOUNT); do
19585                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19586                 $LFS setdirstripe -c $i $DIR/$tdir ||
19587                         error "split -c $i $tdir failed"
19588                 wait_update $HOSTNAME \
19589                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19590                         error "dir split not finished"
19591                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19592                         awk '/migrate/ {sum += $2} END { print sum }')
19593                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19594                 # delta is around total_files/stripe_count
19595                 (( $delta < 200 / (i - 1) + 4 )) ||
19596                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19597         done
19598 }
19599 run_test 230o "dir split"
19600
19601 test_230p() {
19602         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19603         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19604                 skip "Need MDS version at least 2.13.52"
19605
19606         local mdts=$(comma_list $(mdts_nodes))
19607         local timeout=100
19608         local restripe_status
19609         local delta
19610         local i
19611
19612         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19613
19614         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19615
19616         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19617                            mdt.*MDT0000.enable_dir_restripe)
19618         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19619         stack_trap "do_nodes $mdts $LCTL set_param \
19620                     mdt.*.enable_dir_restripe=$restripe_status"
19621
19622         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19623         createmany -m $DIR/$tdir/f 100 ||
19624                 error "create files under remote dir failed $i"
19625         createmany -d $DIR/$tdir/d 100 ||
19626                 error "create dirs under remote dir failed $i"
19627
19628         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19629                 local mdt_hash="crush"
19630
19631                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19632                 $LFS setdirstripe -c $i $DIR/$tdir ||
19633                         error "split -c $i $tdir failed"
19634                 [ $i -eq 1 ] && mdt_hash="none"
19635                 wait_update $HOSTNAME \
19636                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19637                         error "dir merge not finished"
19638                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19639                         awk '/migrate/ {sum += $2} END { print sum }')
19640                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19641                 # delta is around total_files/stripe_count
19642                 (( $delta < 200 / i + 4 )) ||
19643                         error "$delta files migrated >= $((200 / i + 4))"
19644         done
19645 }
19646 run_test 230p "dir merge"
19647
19648 test_230q() {
19649         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19650         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19651                 skip "Need MDS version at least 2.13.52"
19652
19653         local mdts=$(comma_list $(mdts_nodes))
19654         local saved_threshold=$(do_facet mds1 \
19655                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19656         local saved_delta=$(do_facet mds1 \
19657                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19658         local threshold=100
19659         local delta=2
19660         local total=0
19661         local stripe_count=0
19662         local stripe_index
19663         local nr_files
19664         local create
19665
19666         # test with fewer files on ZFS
19667         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19668
19669         stack_trap "do_nodes $mdts $LCTL set_param \
19670                     mdt.*.dir_split_count=$saved_threshold"
19671         stack_trap "do_nodes $mdts $LCTL set_param \
19672                     mdt.*.dir_split_delta=$saved_delta"
19673         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19674         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19675         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19676         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19677         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19678         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19679
19680         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19681         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19682
19683         create=$((threshold * 3 / 2))
19684         while [ $stripe_count -lt $MDSCOUNT ]; do
19685                 createmany -m $DIR/$tdir/f $total $create ||
19686                         error "create sub files failed"
19687                 stat $DIR/$tdir > /dev/null
19688                 total=$((total + create))
19689                 stripe_count=$((stripe_count + delta))
19690                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19691
19692                 wait_update $HOSTNAME \
19693                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19694                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19695
19696                 wait_update $HOSTNAME \
19697                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19698                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19699
19700                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19701                 echo "$nr_files/$total files on MDT$stripe_index after split"
19702                 # allow 10% margin of imbalance with crush hash
19703                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19704                         error "$nr_files files on MDT$stripe_index after split"
19705
19706                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19707                 [ $nr_files -eq $total ] ||
19708                         error "total sub files $nr_files != $total"
19709         done
19710 }
19711 run_test 230q "dir auto split"
19712
19713 test_230r() {
19714         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19715         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19716         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19717                 skip "Need MDS version at least 2.13.54"
19718
19719         # maximum amount of local locks:
19720         # parent striped dir - 2 locks
19721         # new stripe in parent to migrate to - 1 lock
19722         # source and target - 2 locks
19723         # Total 5 locks for regular file
19724         mkdir -p $DIR/$tdir
19725         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19726         touch $DIR/$tdir/dir1/eee
19727
19728         # create 4 hardlink for 4 more locks
19729         # Total: 9 locks > RS_MAX_LOCKS (8)
19730         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19731         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19732         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19733         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19734         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19735         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19736         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19737         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19738
19739         cancel_lru_locks mdc
19740
19741         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19742                 error "migrate dir fails"
19743
19744         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19745 }
19746 run_test 230r "migrate with too many local locks"
19747
19748 test_230s() {
19749         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19750                 skip "Need MDS version at least 2.13.57"
19751
19752         local mdts=$(comma_list $(mdts_nodes))
19753         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19754                                 mdt.*MDT0000.enable_dir_restripe)
19755
19756         stack_trap "do_nodes $mdts $LCTL set_param \
19757                     mdt.*.enable_dir_restripe=$restripe_status"
19758
19759         local st
19760         for st in 0 1; do
19761                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19762                 test_mkdir $DIR/$tdir
19763                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19764                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19765                 rmdir $DIR/$tdir
19766         done
19767 }
19768 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19769
19770 test_230t()
19771 {
19772         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19773         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19774                 skip "Need MDS version at least 2.14.50"
19775
19776         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19777         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19778         $LFS project -p 1 -s $DIR/$tdir ||
19779                 error "set $tdir project id failed"
19780         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19781                 error "set subdir project id failed"
19782         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19783 }
19784 run_test 230t "migrate directory with project ID set"
19785
19786 test_231a()
19787 {
19788         # For simplicity this test assumes that max_pages_per_rpc
19789         # is the same across all OSCs
19790         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19791         local bulk_size=$((max_pages * PAGE_SIZE))
19792         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19793                                        head -n 1)
19794
19795         mkdir -p $DIR/$tdir
19796         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19797                 error "failed to set stripe with -S ${brw_size}M option"
19798
19799         # clear the OSC stats
19800         $LCTL set_param osc.*.stats=0 &>/dev/null
19801         stop_writeback
19802
19803         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19804         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19805                 oflag=direct &>/dev/null || error "dd failed"
19806
19807         sync; sleep 1; sync # just to be safe
19808         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19809         if [ x$nrpcs != "x1" ]; then
19810                 $LCTL get_param osc.*.stats
19811                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19812         fi
19813
19814         start_writeback
19815         # Drop the OSC cache, otherwise we will read from it
19816         cancel_lru_locks osc
19817
19818         # clear the OSC stats
19819         $LCTL set_param osc.*.stats=0 &>/dev/null
19820
19821         # Client reads $bulk_size.
19822         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19823                 iflag=direct &>/dev/null || error "dd failed"
19824
19825         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19826         if [ x$nrpcs != "x1" ]; then
19827                 $LCTL get_param osc.*.stats
19828                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19829         fi
19830 }
19831 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19832
19833 test_231b() {
19834         mkdir -p $DIR/$tdir
19835         local i
19836         for i in {0..1023}; do
19837                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19838                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19839                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19840         done
19841         sync
19842 }
19843 run_test 231b "must not assert on fully utilized OST request buffer"
19844
19845 test_232a() {
19846         mkdir -p $DIR/$tdir
19847         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19848
19849         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19850         do_facet ost1 $LCTL set_param fail_loc=0x31c
19851
19852         # ignore dd failure
19853         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19854
19855         do_facet ost1 $LCTL set_param fail_loc=0
19856         umount_client $MOUNT || error "umount failed"
19857         mount_client $MOUNT || error "mount failed"
19858         stop ost1 || error "cannot stop ost1"
19859         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19860 }
19861 run_test 232a "failed lock should not block umount"
19862
19863 test_232b() {
19864         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19865                 skip "Need MDS version at least 2.10.58"
19866
19867         mkdir -p $DIR/$tdir
19868         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19869         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19870         sync
19871         cancel_lru_locks osc
19872
19873         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19874         do_facet ost1 $LCTL set_param fail_loc=0x31c
19875
19876         # ignore failure
19877         $LFS data_version $DIR/$tdir/$tfile || true
19878
19879         do_facet ost1 $LCTL set_param fail_loc=0
19880         umount_client $MOUNT || error "umount failed"
19881         mount_client $MOUNT || error "mount failed"
19882         stop ost1 || error "cannot stop ost1"
19883         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19884 }
19885 run_test 232b "failed data version lock should not block umount"
19886
19887 test_233a() {
19888         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19889                 skip "Need MDS version at least 2.3.64"
19890         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19891
19892         local fid=$($LFS path2fid $MOUNT)
19893
19894         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19895                 error "cannot access $MOUNT using its FID '$fid'"
19896 }
19897 run_test 233a "checking that OBF of the FS root succeeds"
19898
19899 test_233b() {
19900         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19901                 skip "Need MDS version at least 2.5.90"
19902         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19903
19904         local fid=$($LFS path2fid $MOUNT/.lustre)
19905
19906         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19907                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19908
19909         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19910         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19911                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19912 }
19913 run_test 233b "checking that OBF of the FS .lustre succeeds"
19914
19915 test_234() {
19916         local p="$TMP/sanityN-$TESTNAME.parameters"
19917         save_lustre_params client "llite.*.xattr_cache" > $p
19918         lctl set_param llite.*.xattr_cache 1 ||
19919                 skip_env "xattr cache is not supported"
19920
19921         mkdir -p $DIR/$tdir || error "mkdir failed"
19922         touch $DIR/$tdir/$tfile || error "touch failed"
19923         # OBD_FAIL_LLITE_XATTR_ENOMEM
19924         $LCTL set_param fail_loc=0x1405
19925         getfattr -n user.attr $DIR/$tdir/$tfile &&
19926                 error "getfattr should have failed with ENOMEM"
19927         $LCTL set_param fail_loc=0x0
19928         rm -rf $DIR/$tdir
19929
19930         restore_lustre_params < $p
19931         rm -f $p
19932 }
19933 run_test 234 "xattr cache should not crash on ENOMEM"
19934
19935 test_235() {
19936         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19937                 skip "Need MDS version at least 2.4.52"
19938
19939         flock_deadlock $DIR/$tfile
19940         local RC=$?
19941         case $RC in
19942                 0)
19943                 ;;
19944                 124) error "process hangs on a deadlock"
19945                 ;;
19946                 *) error "error executing flock_deadlock $DIR/$tfile"
19947                 ;;
19948         esac
19949 }
19950 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19951
19952 #LU-2935
19953 test_236() {
19954         check_swap_layouts_support
19955
19956         local ref1=/etc/passwd
19957         local ref2=/etc/group
19958         local file1=$DIR/$tdir/f1
19959         local file2=$DIR/$tdir/f2
19960
19961         test_mkdir -c1 $DIR/$tdir
19962         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19963         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19964         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19965         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19966         local fd=$(free_fd)
19967         local cmd="exec $fd<>$file2"
19968         eval $cmd
19969         rm $file2
19970         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19971                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19972         cmd="exec $fd>&-"
19973         eval $cmd
19974         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19975
19976         #cleanup
19977         rm -rf $DIR/$tdir
19978 }
19979 run_test 236 "Layout swap on open unlinked file"
19980
19981 # LU-4659 linkea consistency
19982 test_238() {
19983         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19984                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19985                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19986                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19987
19988         touch $DIR/$tfile
19989         ln $DIR/$tfile $DIR/$tfile.lnk
19990         touch $DIR/$tfile.new
19991         mv $DIR/$tfile.new $DIR/$tfile
19992         local fid1=$($LFS path2fid $DIR/$tfile)
19993         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19994         local path1=$($LFS fid2path $FSNAME "$fid1")
19995         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19996         local path2=$($LFS fid2path $FSNAME "$fid2")
19997         [ $tfile.lnk == $path2 ] ||
19998                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19999         rm -f $DIR/$tfile*
20000 }
20001 run_test 238 "Verify linkea consistency"
20002
20003 test_239A() { # was test_239
20004         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20005                 skip "Need MDS version at least 2.5.60"
20006
20007         local list=$(comma_list $(mdts_nodes))
20008
20009         mkdir -p $DIR/$tdir
20010         createmany -o $DIR/$tdir/f- 5000
20011         unlinkmany $DIR/$tdir/f- 5000
20012         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20013                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20014         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20015                         osp.*MDT*.sync_in_flight" | calc_sum)
20016         [ "$changes" -eq 0 ] || error "$changes not synced"
20017 }
20018 run_test 239A "osp_sync test"
20019
20020 test_239a() { #LU-5297
20021         remote_mds_nodsh && skip "remote MDS with nodsh"
20022
20023         touch $DIR/$tfile
20024         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20025         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20026         chgrp $RUNAS_GID $DIR/$tfile
20027         wait_delete_completed
20028 }
20029 run_test 239a "process invalid osp sync record correctly"
20030
20031 test_239b() { #LU-5297
20032         remote_mds_nodsh && skip "remote MDS with nodsh"
20033
20034         touch $DIR/$tfile1
20035         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20036         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20037         chgrp $RUNAS_GID $DIR/$tfile1
20038         wait_delete_completed
20039         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20040         touch $DIR/$tfile2
20041         chgrp $RUNAS_GID $DIR/$tfile2
20042         wait_delete_completed
20043 }
20044 run_test 239b "process osp sync record with ENOMEM error correctly"
20045
20046 test_240() {
20047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20048         remote_mds_nodsh && skip "remote MDS with nodsh"
20049
20050         mkdir -p $DIR/$tdir
20051
20052         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20053                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20054         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20055                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20056
20057         umount_client $MOUNT || error "umount failed"
20058         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20059         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20060         mount_client $MOUNT || error "failed to mount client"
20061
20062         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20063         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20064 }
20065 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20066
20067 test_241_bio() {
20068         local count=$1
20069         local bsize=$2
20070
20071         for LOOP in $(seq $count); do
20072                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20073                 cancel_lru_locks $OSC || true
20074         done
20075 }
20076
20077 test_241_dio() {
20078         local count=$1
20079         local bsize=$2
20080
20081         for LOOP in $(seq $1); do
20082                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20083                         2>/dev/null
20084         done
20085 }
20086
20087 test_241a() { # was test_241
20088         local bsize=$PAGE_SIZE
20089
20090         (( bsize < 40960 )) && bsize=40960
20091         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20092         ls -la $DIR/$tfile
20093         cancel_lru_locks $OSC
20094         test_241_bio 1000 $bsize &
20095         PID=$!
20096         test_241_dio 1000 $bsize
20097         wait $PID
20098 }
20099 run_test 241a "bio vs dio"
20100
20101 test_241b() {
20102         local bsize=$PAGE_SIZE
20103
20104         (( bsize < 40960 )) && bsize=40960
20105         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20106         ls -la $DIR/$tfile
20107         test_241_dio 1000 $bsize &
20108         PID=$!
20109         test_241_dio 1000 $bsize
20110         wait $PID
20111 }
20112 run_test 241b "dio vs dio"
20113
20114 test_242() {
20115         remote_mds_nodsh && skip "remote MDS with nodsh"
20116
20117         mkdir_on_mdt0 $DIR/$tdir
20118         touch $DIR/$tdir/$tfile
20119
20120         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20121         do_facet mds1 lctl set_param fail_loc=0x105
20122         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20123
20124         do_facet mds1 lctl set_param fail_loc=0
20125         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20126 }
20127 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20128
20129 test_243()
20130 {
20131         test_mkdir $DIR/$tdir
20132         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20133 }
20134 run_test 243 "various group lock tests"
20135
20136 test_244a()
20137 {
20138         test_mkdir $DIR/$tdir
20139         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20140         sendfile_grouplock $DIR/$tdir/$tfile || \
20141                 error "sendfile+grouplock failed"
20142         rm -rf $DIR/$tdir
20143 }
20144 run_test 244a "sendfile with group lock tests"
20145
20146 test_244b()
20147 {
20148         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20149
20150         local threads=50
20151         local size=$((1024*1024))
20152
20153         test_mkdir $DIR/$tdir
20154         for i in $(seq 1 $threads); do
20155                 local file=$DIR/$tdir/file_$((i / 10))
20156                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20157                 local pids[$i]=$!
20158         done
20159         for i in $(seq 1 $threads); do
20160                 wait ${pids[$i]}
20161         done
20162 }
20163 run_test 244b "multi-threaded write with group lock"
20164
20165 test_245() {
20166         local flagname="multi_mod_rpcs"
20167         local connect_data_name="max_mod_rpcs"
20168         local out
20169
20170         # check if multiple modify RPCs flag is set
20171         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20172                 grep "connect_flags:")
20173         echo "$out"
20174
20175         echo "$out" | grep -qw $flagname
20176         if [ $? -ne 0 ]; then
20177                 echo "connect flag $flagname is not set"
20178                 return
20179         fi
20180
20181         # check if multiple modify RPCs data is set
20182         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20183         echo "$out"
20184
20185         echo "$out" | grep -qw $connect_data_name ||
20186                 error "import should have connect data $connect_data_name"
20187 }
20188 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20189
20190 cleanup_247() {
20191         local submount=$1
20192
20193         trap 0
20194         umount_client $submount
20195         rmdir $submount
20196 }
20197
20198 test_247a() {
20199         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20200                 grep -q subtree ||
20201                 skip_env "Fileset feature is not supported"
20202
20203         local submount=${MOUNT}_$tdir
20204
20205         mkdir $MOUNT/$tdir
20206         mkdir -p $submount || error "mkdir $submount failed"
20207         FILESET="$FILESET/$tdir" mount_client $submount ||
20208                 error "mount $submount failed"
20209         trap "cleanup_247 $submount" EXIT
20210         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20211         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20212                 error "read $MOUNT/$tdir/$tfile failed"
20213         cleanup_247 $submount
20214 }
20215 run_test 247a "mount subdir as fileset"
20216
20217 test_247b() {
20218         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20219                 skip_env "Fileset feature is not supported"
20220
20221         local submount=${MOUNT}_$tdir
20222
20223         rm -rf $MOUNT/$tdir
20224         mkdir -p $submount || error "mkdir $submount failed"
20225         SKIP_FILESET=1
20226         FILESET="$FILESET/$tdir" mount_client $submount &&
20227                 error "mount $submount should fail"
20228         rmdir $submount
20229 }
20230 run_test 247b "mount subdir that dose not exist"
20231
20232 test_247c() {
20233         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20234                 skip_env "Fileset feature is not supported"
20235
20236         local submount=${MOUNT}_$tdir
20237
20238         mkdir -p $MOUNT/$tdir/dir1
20239         mkdir -p $submount || error "mkdir $submount failed"
20240         trap "cleanup_247 $submount" EXIT
20241         FILESET="$FILESET/$tdir" mount_client $submount ||
20242                 error "mount $submount failed"
20243         local fid=$($LFS path2fid $MOUNT/)
20244         $LFS fid2path $submount $fid && error "fid2path should fail"
20245         cleanup_247 $submount
20246 }
20247 run_test 247c "running fid2path outside subdirectory root"
20248
20249 test_247d() {
20250         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20251                 skip "Fileset feature is not supported"
20252
20253         local submount=${MOUNT}_$tdir
20254
20255         mkdir -p $MOUNT/$tdir/dir1
20256         mkdir -p $submount || error "mkdir $submount failed"
20257         FILESET="$FILESET/$tdir" mount_client $submount ||
20258                 error "mount $submount failed"
20259         trap "cleanup_247 $submount" EXIT
20260
20261         local td=$submount/dir1
20262         local fid=$($LFS path2fid $td)
20263         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20264
20265         # check that we get the same pathname back
20266         local rootpath
20267         local found
20268         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20269                 echo "$rootpath $fid"
20270                 found=$($LFS fid2path $rootpath "$fid")
20271                 [ -n "found" ] || error "fid2path should succeed"
20272                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20273         done
20274         # check wrong root path format
20275         rootpath=$submount"_wrong"
20276         found=$($LFS fid2path $rootpath "$fid")
20277         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20278
20279         cleanup_247 $submount
20280 }
20281 run_test 247d "running fid2path inside subdirectory root"
20282
20283 # LU-8037
20284 test_247e() {
20285         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20286                 grep -q subtree ||
20287                 skip "Fileset feature is not supported"
20288
20289         local submount=${MOUNT}_$tdir
20290
20291         mkdir $MOUNT/$tdir
20292         mkdir -p $submount || error "mkdir $submount failed"
20293         FILESET="$FILESET/.." mount_client $submount &&
20294                 error "mount $submount should fail"
20295         rmdir $submount
20296 }
20297 run_test 247e "mount .. as fileset"
20298
20299 test_247f() {
20300         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20301         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20302                 skip "Need at least version 2.13.52"
20303         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20304                 skip "Need at least version 2.14.50"
20305         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20306                 grep -q subtree ||
20307                 skip "Fileset feature is not supported"
20308
20309         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20310         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20311                 error "mkdir remote failed"
20312         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
20313         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20314                 error "mkdir striped failed"
20315         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20316
20317         local submount=${MOUNT}_$tdir
20318
20319         mkdir -p $submount || error "mkdir $submount failed"
20320         stack_trap "rmdir $submount"
20321
20322         local dir
20323         local stat
20324         local fileset=$FILESET
20325         local mdts=$(comma_list $(mdts_nodes))
20326
20327         stat=$(do_facet mds1 $LCTL get_param -n \
20328                 mdt.*MDT0000.enable_remote_subdir_mount)
20329         stack_trap "do_nodes $mdts $LCTL set_param \
20330                 mdt.*.enable_remote_subdir_mount=$stat"
20331
20332         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20333         stack_trap "umount_client $submount"
20334         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20335                 error "mount remote dir $dir should fail"
20336
20337         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20338                 $tdir/striped/. ; do
20339                 FILESET="$fileset/$dir" mount_client $submount ||
20340                         error "mount $dir failed"
20341                 umount_client $submount
20342         done
20343
20344         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20345         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20346                 error "mount $tdir/remote failed"
20347 }
20348 run_test 247f "mount striped or remote directory as fileset"
20349
20350 test_247g() {
20351         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20352         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20353                 skip "Need at least version 2.14.50"
20354
20355         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20356                 error "mkdir $tdir failed"
20357         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20358
20359         local submount=${MOUNT}_$tdir
20360
20361         mkdir -p $submount || error "mkdir $submount failed"
20362         stack_trap "rmdir $submount"
20363
20364         FILESET="$fileset/$tdir" mount_client $submount ||
20365                 error "mount $dir failed"
20366         stack_trap "umount $submount"
20367
20368         local mdts=$(comma_list $(mdts_nodes))
20369
20370         local nrpcs
20371
20372         stat $submount > /dev/null
20373         cancel_lru_locks $MDC
20374         stat $submount > /dev/null
20375         stat $submount/$tfile > /dev/null
20376         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20377         stat $submount/$tfile > /dev/null
20378         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20379                 awk '/getattr/ {sum += $2} END {print sum}')
20380
20381         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20382 }
20383 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20384
20385 test_248a() {
20386         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20387         [ -z "$fast_read_sav" ] && skip "no fast read support"
20388
20389         # create a large file for fast read verification
20390         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20391
20392         # make sure the file is created correctly
20393         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20394                 { rm -f $DIR/$tfile; skip "file creation error"; }
20395
20396         echo "Test 1: verify that fast read is 4 times faster on cache read"
20397
20398         # small read with fast read enabled
20399         $LCTL set_param -n llite.*.fast_read=1
20400         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20401                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20402                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20403         # small read with fast read disabled
20404         $LCTL set_param -n llite.*.fast_read=0
20405         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20406                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20407                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20408
20409         # verify that fast read is 4 times faster for cache read
20410         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20411                 error_not_in_vm "fast read was not 4 times faster: " \
20412                            "$t_fast vs $t_slow"
20413
20414         echo "Test 2: verify the performance between big and small read"
20415         $LCTL set_param -n llite.*.fast_read=1
20416
20417         # 1k non-cache read
20418         cancel_lru_locks osc
20419         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20420                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20421                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20422
20423         # 1M non-cache read
20424         cancel_lru_locks osc
20425         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20426                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20427                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20428
20429         # verify that big IO is not 4 times faster than small IO
20430         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20431                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20432
20433         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20434         rm -f $DIR/$tfile
20435 }
20436 run_test 248a "fast read verification"
20437
20438 test_248b() {
20439         # Default short_io_bytes=16384, try both smaller and larger sizes.
20440         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20441         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20442         echo "bs=53248 count=113 normal buffered write"
20443         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20444                 error "dd of initial data file failed"
20445         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20446
20447         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20448         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20449                 error "dd with sync normal writes failed"
20450         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20451
20452         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20453         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20454                 error "dd with sync small writes failed"
20455         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20456
20457         cancel_lru_locks osc
20458
20459         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20460         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20461         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20462         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20463                 iflag=direct || error "dd with O_DIRECT small read failed"
20464         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20465         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20466                 error "compare $TMP/$tfile.1 failed"
20467
20468         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20469         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20470
20471         # just to see what the maximum tunable value is, and test parsing
20472         echo "test invalid parameter 2MB"
20473         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20474                 error "too-large short_io_bytes allowed"
20475         echo "test maximum parameter 512KB"
20476         # if we can set a larger short_io_bytes, run test regardless of version
20477         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20478                 # older clients may not allow setting it this large, that's OK
20479                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20480                         skip "Need at least client version 2.13.50"
20481                 error "medium short_io_bytes failed"
20482         fi
20483         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20484         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20485
20486         echo "test large parameter 64KB"
20487         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20488         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20489
20490         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20491         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20492                 error "dd with sync large writes failed"
20493         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20494
20495         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20496         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20497         num=$((113 * 4096 / PAGE_SIZE))
20498         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20499         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20500                 error "dd with O_DIRECT large writes failed"
20501         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20502                 error "compare $DIR/$tfile.3 failed"
20503
20504         cancel_lru_locks osc
20505
20506         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20507         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20508                 error "dd with O_DIRECT large read failed"
20509         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20510                 error "compare $TMP/$tfile.2 failed"
20511
20512         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20513         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20514                 error "dd with O_DIRECT large read failed"
20515         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20516                 error "compare $TMP/$tfile.3 failed"
20517 }
20518 run_test 248b "test short_io read and write for both small and large sizes"
20519
20520 test_249() { # LU-7890
20521         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20522                 skip "Need at least version 2.8.54"
20523
20524         rm -f $DIR/$tfile
20525         $LFS setstripe -c 1 $DIR/$tfile
20526         # Offset 2T == 4k * 512M
20527         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20528                 error "dd to 2T offset failed"
20529 }
20530 run_test 249 "Write above 2T file size"
20531
20532 test_250() {
20533         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20534          && skip "no 16TB file size limit on ZFS"
20535
20536         $LFS setstripe -c 1 $DIR/$tfile
20537         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20538         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20539         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20540         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20541                 conv=notrunc,fsync && error "append succeeded"
20542         return 0
20543 }
20544 run_test 250 "Write above 16T limit"
20545
20546 test_251() {
20547         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20548
20549         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20550         #Skip once - writing the first stripe will succeed
20551         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20552         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20553                 error "short write happened"
20554
20555         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20556         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20557                 error "short read happened"
20558
20559         rm -f $DIR/$tfile
20560 }
20561 run_test 251 "Handling short read and write correctly"
20562
20563 test_252() {
20564         remote_mds_nodsh && skip "remote MDS with nodsh"
20565         remote_ost_nodsh && skip "remote OST with nodsh"
20566         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20567                 skip_env "ldiskfs only test"
20568         fi
20569
20570         local tgt
20571         local dev
20572         local out
20573         local uuid
20574         local num
20575         local gen
20576
20577         # check lr_reader on OST0000
20578         tgt=ost1
20579         dev=$(facet_device $tgt)
20580         out=$(do_facet $tgt $LR_READER $dev)
20581         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20582         echo "$out"
20583         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20584         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20585                 error "Invalid uuid returned by $LR_READER on target $tgt"
20586         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20587
20588         # check lr_reader -c on MDT0000
20589         tgt=mds1
20590         dev=$(facet_device $tgt)
20591         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20592                 skip "$LR_READER does not support additional options"
20593         fi
20594         out=$(do_facet $tgt $LR_READER -c $dev)
20595         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20596         echo "$out"
20597         num=$(echo "$out" | grep -c "mdtlov")
20598         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20599                 error "Invalid number of mdtlov clients returned by $LR_READER"
20600         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20601
20602         # check lr_reader -cr on MDT0000
20603         out=$(do_facet $tgt $LR_READER -cr $dev)
20604         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20605         echo "$out"
20606         echo "$out" | grep -q "^reply_data:$" ||
20607                 error "$LR_READER should have returned 'reply_data' section"
20608         num=$(echo "$out" | grep -c "client_generation")
20609         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20610 }
20611 run_test 252 "check lr_reader tool"
20612
20613 test_253() {
20614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20615         remote_mds_nodsh && skip "remote MDS with nodsh"
20616         remote_mgs_nodsh && skip "remote MGS with nodsh"
20617
20618         local ostidx=0
20619         local rc=0
20620         local ost_name=$(ostname_from_index $ostidx)
20621
20622         # on the mdt's osc
20623         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20624         do_facet $SINGLEMDS $LCTL get_param -n \
20625                 osp.$mdtosc_proc1.reserved_mb_high ||
20626                 skip  "remote MDS does not support reserved_mb_high"
20627
20628         rm -rf $DIR/$tdir
20629         wait_mds_ost_sync
20630         wait_delete_completed
20631         mkdir $DIR/$tdir
20632
20633         pool_add $TESTNAME || error "Pool creation failed"
20634         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20635
20636         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20637                 error "Setstripe failed"
20638
20639         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20640
20641         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20642                     grep "watermarks")
20643         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20644
20645         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20646                         osp.$mdtosc_proc1.prealloc_status)
20647         echo "prealloc_status $oa_status"
20648
20649         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20650                 error "File creation should fail"
20651
20652         #object allocation was stopped, but we still able to append files
20653         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20654                 oflag=append || error "Append failed"
20655
20656         rm -f $DIR/$tdir/$tfile.0
20657
20658         # For this test, we want to delete the files we created to go out of
20659         # space but leave the watermark, so we remain nearly out of space
20660         ost_watermarks_enospc_delete_files $tfile $ostidx
20661
20662         wait_delete_completed
20663
20664         sleep_maxage
20665
20666         for i in $(seq 10 12); do
20667                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20668                         2>/dev/null || error "File creation failed after rm"
20669         done
20670
20671         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20672                         osp.$mdtosc_proc1.prealloc_status)
20673         echo "prealloc_status $oa_status"
20674
20675         if (( oa_status != 0 )); then
20676                 error "Object allocation still disable after rm"
20677         fi
20678 }
20679 run_test 253 "Check object allocation limit"
20680
20681 test_254() {
20682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20683         remote_mds_nodsh && skip "remote MDS with nodsh"
20684         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20685                 skip "MDS does not support changelog_size"
20686
20687         local cl_user
20688         local MDT0=$(facet_svc $SINGLEMDS)
20689
20690         changelog_register || error "changelog_register failed"
20691
20692         changelog_clear 0 || error "changelog_clear failed"
20693
20694         local size1=$(do_facet $SINGLEMDS \
20695                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20696         echo "Changelog size $size1"
20697
20698         rm -rf $DIR/$tdir
20699         $LFS mkdir -i 0 $DIR/$tdir
20700         # change something
20701         mkdir -p $DIR/$tdir/pics/2008/zachy
20702         touch $DIR/$tdir/pics/2008/zachy/timestamp
20703         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20704         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20705         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20706         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20707         rm $DIR/$tdir/pics/desktop.jpg
20708
20709         local size2=$(do_facet $SINGLEMDS \
20710                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20711         echo "Changelog size after work $size2"
20712
20713         (( $size2 > $size1 )) ||
20714                 error "new Changelog size=$size2 less than old size=$size1"
20715 }
20716 run_test 254 "Check changelog size"
20717
20718 ladvise_no_type()
20719 {
20720         local type=$1
20721         local file=$2
20722
20723         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20724                 awk -F: '{print $2}' | grep $type > /dev/null
20725         if [ $? -ne 0 ]; then
20726                 return 0
20727         fi
20728         return 1
20729 }
20730
20731 ladvise_no_ioctl()
20732 {
20733         local file=$1
20734
20735         lfs ladvise -a willread $file > /dev/null 2>&1
20736         if [ $? -eq 0 ]; then
20737                 return 1
20738         fi
20739
20740         lfs ladvise -a willread $file 2>&1 |
20741                 grep "Inappropriate ioctl for device" > /dev/null
20742         if [ $? -eq 0 ]; then
20743                 return 0
20744         fi
20745         return 1
20746 }
20747
20748 percent() {
20749         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20750 }
20751
20752 # run a random read IO workload
20753 # usage: random_read_iops <filename> <filesize> <iosize>
20754 random_read_iops() {
20755         local file=$1
20756         local fsize=$2
20757         local iosize=${3:-4096}
20758
20759         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20760                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20761 }
20762
20763 drop_file_oss_cache() {
20764         local file="$1"
20765         local nodes="$2"
20766
20767         $LFS ladvise -a dontneed $file 2>/dev/null ||
20768                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20769 }
20770
20771 ladvise_willread_performance()
20772 {
20773         local repeat=10
20774         local average_origin=0
20775         local average_cache=0
20776         local average_ladvise=0
20777
20778         for ((i = 1; i <= $repeat; i++)); do
20779                 echo "Iter $i/$repeat: reading without willread hint"
20780                 cancel_lru_locks osc
20781                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20782                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20783                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20784                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20785
20786                 cancel_lru_locks osc
20787                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20788                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20789                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20790
20791                 cancel_lru_locks osc
20792                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20793                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20794                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20795                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20796                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20797         done
20798         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20799         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20800         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20801
20802         speedup_cache=$(percent $average_cache $average_origin)
20803         speedup_ladvise=$(percent $average_ladvise $average_origin)
20804
20805         echo "Average uncached read: $average_origin"
20806         echo "Average speedup with OSS cached read: " \
20807                 "$average_cache = +$speedup_cache%"
20808         echo "Average speedup with ladvise willread: " \
20809                 "$average_ladvise = +$speedup_ladvise%"
20810
20811         local lowest_speedup=20
20812         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20813                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20814                         "got $average_cache%. Skipping ladvise willread check."
20815                 return 0
20816         fi
20817
20818         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20819         # it is still good to run until then to exercise 'ladvise willread'
20820         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20821                 [ "$ost1_FSTYPE" = "zfs" ] &&
20822                 echo "osd-zfs does not support dontneed or drop_caches" &&
20823                 return 0
20824
20825         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20826         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20827                 error_not_in_vm "Speedup with willread is less than " \
20828                         "$lowest_speedup%, got $average_ladvise%"
20829 }
20830
20831 test_255a() {
20832         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20833                 skip "lustre < 2.8.54 does not support ladvise "
20834         remote_ost_nodsh && skip "remote OST with nodsh"
20835
20836         stack_trap "rm -f $DIR/$tfile"
20837         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20838
20839         ladvise_no_type willread $DIR/$tfile &&
20840                 skip "willread ladvise is not supported"
20841
20842         ladvise_no_ioctl $DIR/$tfile &&
20843                 skip "ladvise ioctl is not supported"
20844
20845         local size_mb=100
20846         local size=$((size_mb * 1048576))
20847         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20848                 error "dd to $DIR/$tfile failed"
20849
20850         lfs ladvise -a willread $DIR/$tfile ||
20851                 error "Ladvise failed with no range argument"
20852
20853         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20854                 error "Ladvise failed with no -l or -e argument"
20855
20856         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20857                 error "Ladvise failed with only -e argument"
20858
20859         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20860                 error "Ladvise failed with only -l argument"
20861
20862         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20863                 error "End offset should not be smaller than start offset"
20864
20865         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20866                 error "End offset should not be equal to start offset"
20867
20868         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20869                 error "Ladvise failed with overflowing -s argument"
20870
20871         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20872                 error "Ladvise failed with overflowing -e argument"
20873
20874         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20875                 error "Ladvise failed with overflowing -l argument"
20876
20877         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20878                 error "Ladvise succeeded with conflicting -l and -e arguments"
20879
20880         echo "Synchronous ladvise should wait"
20881         local delay=4
20882 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20883         do_nodes $(comma_list $(osts_nodes)) \
20884                 $LCTL set_param fail_val=$delay fail_loc=0x237
20885
20886         local start_ts=$SECONDS
20887         lfs ladvise -a willread $DIR/$tfile ||
20888                 error "Ladvise failed with no range argument"
20889         local end_ts=$SECONDS
20890         local inteval_ts=$((end_ts - start_ts))
20891
20892         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20893                 error "Synchronous advice didn't wait reply"
20894         fi
20895
20896         echo "Asynchronous ladvise shouldn't wait"
20897         local start_ts=$SECONDS
20898         lfs ladvise -a willread -b $DIR/$tfile ||
20899                 error "Ladvise failed with no range argument"
20900         local end_ts=$SECONDS
20901         local inteval_ts=$((end_ts - start_ts))
20902
20903         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20904                 error "Asynchronous advice blocked"
20905         fi
20906
20907         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20908         ladvise_willread_performance
20909 }
20910 run_test 255a "check 'lfs ladvise -a willread'"
20911
20912 facet_meminfo() {
20913         local facet=$1
20914         local info=$2
20915
20916         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20917 }
20918
20919 test_255b() {
20920         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20921                 skip "lustre < 2.8.54 does not support ladvise "
20922         remote_ost_nodsh && skip "remote OST with nodsh"
20923
20924         stack_trap "rm -f $DIR/$tfile"
20925         lfs setstripe -c 1 -i 0 $DIR/$tfile
20926
20927         ladvise_no_type dontneed $DIR/$tfile &&
20928                 skip "dontneed ladvise is not supported"
20929
20930         ladvise_no_ioctl $DIR/$tfile &&
20931                 skip "ladvise ioctl is not supported"
20932
20933         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20934                 [ "$ost1_FSTYPE" = "zfs" ] &&
20935                 skip "zfs-osd does not support 'ladvise dontneed'"
20936
20937         local size_mb=100
20938         local size=$((size_mb * 1048576))
20939         # In order to prevent disturbance of other processes, only check 3/4
20940         # of the memory usage
20941         local kibibytes=$((size_mb * 1024 * 3 / 4))
20942
20943         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20944                 error "dd to $DIR/$tfile failed"
20945
20946         #force write to complete before dropping OST cache & checking memory
20947         sync
20948
20949         local total=$(facet_meminfo ost1 MemTotal)
20950         echo "Total memory: $total KiB"
20951
20952         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20953         local before_read=$(facet_meminfo ost1 Cached)
20954         echo "Cache used before read: $before_read KiB"
20955
20956         lfs ladvise -a willread $DIR/$tfile ||
20957                 error "Ladvise willread failed"
20958         local after_read=$(facet_meminfo ost1 Cached)
20959         echo "Cache used after read: $after_read KiB"
20960
20961         lfs ladvise -a dontneed $DIR/$tfile ||
20962                 error "Ladvise dontneed again failed"
20963         local no_read=$(facet_meminfo ost1 Cached)
20964         echo "Cache used after dontneed ladvise: $no_read KiB"
20965
20966         if [ $total -lt $((before_read + kibibytes)) ]; then
20967                 echo "Memory is too small, abort checking"
20968                 return 0
20969         fi
20970
20971         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20972                 error "Ladvise willread should use more memory" \
20973                         "than $kibibytes KiB"
20974         fi
20975
20976         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20977                 error "Ladvise dontneed should release more memory" \
20978                         "than $kibibytes KiB"
20979         fi
20980 }
20981 run_test 255b "check 'lfs ladvise -a dontneed'"
20982
20983 test_255c() {
20984         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20985                 skip "lustre < 2.10.50 does not support lockahead"
20986
20987         local ost1_imp=$(get_osc_import_name client ost1)
20988         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20989                          cut -d'.' -f2)
20990         local count
20991         local new_count
20992         local difference
20993         local i
20994         local rc
20995
20996         test_mkdir -p $DIR/$tdir
20997         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20998
20999         #test 10 returns only success/failure
21000         i=10
21001         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21002         rc=$?
21003         if [ $rc -eq 255 ]; then
21004                 error "Ladvise test${i} failed, ${rc}"
21005         fi
21006
21007         #test 11 counts lock enqueue requests, all others count new locks
21008         i=11
21009         count=$(do_facet ost1 \
21010                 $LCTL get_param -n ost.OSS.ost.stats)
21011         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21012
21013         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21014         rc=$?
21015         if [ $rc -eq 255 ]; then
21016                 error "Ladvise test${i} failed, ${rc}"
21017         fi
21018
21019         new_count=$(do_facet ost1 \
21020                 $LCTL get_param -n ost.OSS.ost.stats)
21021         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21022                    awk '{ print $2 }')
21023
21024         difference="$((new_count - count))"
21025         if [ $difference -ne $rc ]; then
21026                 error "Ladvise test${i}, bad enqueue count, returned " \
21027                       "${rc}, actual ${difference}"
21028         fi
21029
21030         for i in $(seq 12 21); do
21031                 # If we do not do this, we run the risk of having too many
21032                 # locks and starting lock cancellation while we are checking
21033                 # lock counts.
21034                 cancel_lru_locks osc
21035
21036                 count=$($LCTL get_param -n \
21037                        ldlm.namespaces.$imp_name.lock_unused_count)
21038
21039                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21040                 rc=$?
21041                 if [ $rc -eq 255 ]; then
21042                         error "Ladvise test ${i} failed, ${rc}"
21043                 fi
21044
21045                 new_count=$($LCTL get_param -n \
21046                        ldlm.namespaces.$imp_name.lock_unused_count)
21047                 difference="$((new_count - count))"
21048
21049                 # Test 15 output is divided by 100 to map down to valid return
21050                 if [ $i -eq 15 ]; then
21051                         rc="$((rc * 100))"
21052                 fi
21053
21054                 if [ $difference -ne $rc ]; then
21055                         error "Ladvise test ${i}, bad lock count, returned " \
21056                               "${rc}, actual ${difference}"
21057                 fi
21058         done
21059
21060         #test 22 returns only success/failure
21061         i=22
21062         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21063         rc=$?
21064         if [ $rc -eq 255 ]; then
21065                 error "Ladvise test${i} failed, ${rc}"
21066         fi
21067 }
21068 run_test 255c "suite of ladvise lockahead tests"
21069
21070 test_256() {
21071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21072         remote_mds_nodsh && skip "remote MDS with nodsh"
21073         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21074         changelog_users $SINGLEMDS | grep "^cl" &&
21075                 skip "active changelog user"
21076
21077         local cl_user
21078         local cat_sl
21079         local mdt_dev
21080
21081         mdt_dev=$(mdsdevname 1)
21082         echo $mdt_dev
21083
21084         changelog_register || error "changelog_register failed"
21085
21086         rm -rf $DIR/$tdir
21087         mkdir_on_mdt0 $DIR/$tdir
21088
21089         changelog_clear 0 || error "changelog_clear failed"
21090
21091         # change something
21092         touch $DIR/$tdir/{1..10}
21093
21094         # stop the MDT
21095         stop $SINGLEMDS || error "Fail to stop MDT"
21096
21097         # remount the MDT
21098
21099         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21100
21101         #after mount new plainllog is used
21102         touch $DIR/$tdir/{11..19}
21103         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21104         stack_trap "rm -f $tmpfile"
21105         cat_sl=$(do_facet $SINGLEMDS "sync; \
21106                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21107                  llog_reader $tmpfile | grep -c type=1064553b")
21108         do_facet $SINGLEMDS llog_reader $tmpfile
21109
21110         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21111
21112         changelog_clear 0 || error "changelog_clear failed"
21113
21114         cat_sl=$(do_facet $SINGLEMDS "sync; \
21115                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21116                  llog_reader $tmpfile | grep -c type=1064553b")
21117
21118         if (( cat_sl == 2 )); then
21119                 error "Empty plain llog was not deleted from changelog catalog"
21120         elif (( cat_sl != 1 )); then
21121                 error "Active plain llog shouldn't be deleted from catalog"
21122         fi
21123 }
21124 run_test 256 "Check llog delete for empty and not full state"
21125
21126 test_257() {
21127         remote_mds_nodsh && skip "remote MDS with nodsh"
21128         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21129                 skip "Need MDS version at least 2.8.55"
21130
21131         test_mkdir $DIR/$tdir
21132
21133         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21134                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21135         stat $DIR/$tdir
21136
21137 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21138         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21139         local facet=mds$((mdtidx + 1))
21140         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21141         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21142
21143         stop $facet || error "stop MDS failed"
21144         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21145                 error "start MDS fail"
21146         wait_recovery_complete $facet
21147 }
21148 run_test 257 "xattr locks are not lost"
21149
21150 # Verify we take the i_mutex when security requires it
21151 test_258a() {
21152 #define OBD_FAIL_IMUTEX_SEC 0x141c
21153         $LCTL set_param fail_loc=0x141c
21154         touch $DIR/$tfile
21155         chmod u+s $DIR/$tfile
21156         chmod a+rwx $DIR/$tfile
21157         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21158         RC=$?
21159         if [ $RC -ne 0 ]; then
21160                 error "error, failed to take i_mutex, rc=$?"
21161         fi
21162         rm -f $DIR/$tfile
21163 }
21164 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21165
21166 # Verify we do NOT take the i_mutex in the normal case
21167 test_258b() {
21168 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21169         $LCTL set_param fail_loc=0x141d
21170         touch $DIR/$tfile
21171         chmod a+rwx $DIR
21172         chmod a+rw $DIR/$tfile
21173         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21174         RC=$?
21175         if [ $RC -ne 0 ]; then
21176                 error "error, took i_mutex unnecessarily, rc=$?"
21177         fi
21178         rm -f $DIR/$tfile
21179
21180 }
21181 run_test 258b "verify i_mutex security behavior"
21182
21183 test_259() {
21184         local file=$DIR/$tfile
21185         local before
21186         local after
21187
21188         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21189
21190         stack_trap "rm -f $file" EXIT
21191
21192         wait_delete_completed
21193         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21194         echo "before: $before"
21195
21196         $LFS setstripe -i 0 -c 1 $file
21197         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21198         sync_all_data
21199         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21200         echo "after write: $after"
21201
21202 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21203         do_facet ost1 $LCTL set_param fail_loc=0x2301
21204         $TRUNCATE $file 0
21205         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21206         echo "after truncate: $after"
21207
21208         stop ost1
21209         do_facet ost1 $LCTL set_param fail_loc=0
21210         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21211         sleep 2
21212         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21213         echo "after restart: $after"
21214         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21215                 error "missing truncate?"
21216
21217         return 0
21218 }
21219 run_test 259 "crash at delayed truncate"
21220
21221 test_260() {
21222 #define OBD_FAIL_MDC_CLOSE               0x806
21223         $LCTL set_param fail_loc=0x80000806
21224         touch $DIR/$tfile
21225
21226 }
21227 run_test 260 "Check mdc_close fail"
21228
21229 ### Data-on-MDT sanity tests ###
21230 test_270a() {
21231         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21232                 skip "Need MDS version at least 2.10.55 for DoM"
21233
21234         # create DoM file
21235         local dom=$DIR/$tdir/dom_file
21236         local tmp=$DIR/$tdir/tmp_file
21237
21238         mkdir_on_mdt0 $DIR/$tdir
21239
21240         # basic checks for DoM component creation
21241         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21242                 error "Can set MDT layout to non-first entry"
21243
21244         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21245                 error "Can define multiple entries as MDT layout"
21246
21247         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21248
21249         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21250         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21251         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21252
21253         local mdtidx=$($LFS getstripe -m $dom)
21254         local mdtname=MDT$(printf %04x $mdtidx)
21255         local facet=mds$((mdtidx + 1))
21256         local space_check=1
21257
21258         # Skip free space checks with ZFS
21259         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21260
21261         # write
21262         sync
21263         local size_tmp=$((65536 * 3))
21264         local mdtfree1=$(do_facet $facet \
21265                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21266
21267         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21268         # check also direct IO along write
21269         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21270         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21271         sync
21272         cmp $tmp $dom || error "file data is different"
21273         [ $(stat -c%s $dom) == $size_tmp ] ||
21274                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21275         if [ $space_check == 1 ]; then
21276                 local mdtfree2=$(do_facet $facet \
21277                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21278
21279                 # increase in usage from by $size_tmp
21280                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21281                         error "MDT free space wrong after write: " \
21282                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21283         fi
21284
21285         # truncate
21286         local size_dom=10000
21287
21288         $TRUNCATE $dom $size_dom
21289         [ $(stat -c%s $dom) == $size_dom ] ||
21290                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21291         if [ $space_check == 1 ]; then
21292                 mdtfree1=$(do_facet $facet \
21293                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21294                 # decrease in usage from $size_tmp to new $size_dom
21295                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21296                   $(((size_tmp - size_dom) / 1024)) ] ||
21297                         error "MDT free space is wrong after truncate: " \
21298                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21299         fi
21300
21301         # append
21302         cat $tmp >> $dom
21303         sync
21304         size_dom=$((size_dom + size_tmp))
21305         [ $(stat -c%s $dom) == $size_dom ] ||
21306                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21307         if [ $space_check == 1 ]; then
21308                 mdtfree2=$(do_facet $facet \
21309                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21310                 # increase in usage by $size_tmp from previous
21311                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21312                         error "MDT free space is wrong after append: " \
21313                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21314         fi
21315
21316         # delete
21317         rm $dom
21318         if [ $space_check == 1 ]; then
21319                 mdtfree1=$(do_facet $facet \
21320                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21321                 # decrease in usage by $size_dom from previous
21322                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21323                         error "MDT free space is wrong after removal: " \
21324                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21325         fi
21326
21327         # combined striping
21328         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21329                 error "Can't create DoM + OST striping"
21330
21331         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21332         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21333         # check also direct IO along write
21334         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21335         sync
21336         cmp $tmp $dom || error "file data is different"
21337         [ $(stat -c%s $dom) == $size_tmp ] ||
21338                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21339         rm $dom $tmp
21340
21341         return 0
21342 }
21343 run_test 270a "DoM: basic functionality tests"
21344
21345 test_270b() {
21346         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21347                 skip "Need MDS version at least 2.10.55"
21348
21349         local dom=$DIR/$tdir/dom_file
21350         local max_size=1048576
21351
21352         mkdir -p $DIR/$tdir
21353         $LFS setstripe -E $max_size -L mdt $dom
21354
21355         # truncate over the limit
21356         $TRUNCATE $dom $(($max_size + 1)) &&
21357                 error "successful truncate over the maximum size"
21358         # write over the limit
21359         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21360                 error "successful write over the maximum size"
21361         # append over the limit
21362         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21363         echo "12345" >> $dom && error "successful append over the maximum size"
21364         rm $dom
21365
21366         return 0
21367 }
21368 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21369
21370 test_270c() {
21371         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21372                 skip "Need MDS version at least 2.10.55"
21373
21374         mkdir -p $DIR/$tdir
21375         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21376
21377         # check files inherit DoM EA
21378         touch $DIR/$tdir/first
21379         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21380                 error "bad pattern"
21381         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21382                 error "bad stripe count"
21383         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21384                 error "bad stripe size"
21385
21386         # check directory inherits DoM EA and uses it as default
21387         mkdir $DIR/$tdir/subdir
21388         touch $DIR/$tdir/subdir/second
21389         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21390                 error "bad pattern in sub-directory"
21391         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21392                 error "bad stripe count in sub-directory"
21393         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21394                 error "bad stripe size in sub-directory"
21395         return 0
21396 }
21397 run_test 270c "DoM: DoM EA inheritance tests"
21398
21399 test_270d() {
21400         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21401                 skip "Need MDS version at least 2.10.55"
21402
21403         mkdir -p $DIR/$tdir
21404         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21405
21406         # inherit default DoM striping
21407         mkdir $DIR/$tdir/subdir
21408         touch $DIR/$tdir/subdir/f1
21409
21410         # change default directory striping
21411         $LFS setstripe -c 1 $DIR/$tdir/subdir
21412         touch $DIR/$tdir/subdir/f2
21413         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21414                 error "wrong default striping in file 2"
21415         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21416                 error "bad pattern in file 2"
21417         return 0
21418 }
21419 run_test 270d "DoM: change striping from DoM to RAID0"
21420
21421 test_270e() {
21422         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21423                 skip "Need MDS version at least 2.10.55"
21424
21425         mkdir -p $DIR/$tdir/dom
21426         mkdir -p $DIR/$tdir/norm
21427         DOMFILES=20
21428         NORMFILES=10
21429         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21430         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21431
21432         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21433         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21434
21435         # find DoM files by layout
21436         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21437         [ $NUM -eq  $DOMFILES ] ||
21438                 error "lfs find -L: found $NUM, expected $DOMFILES"
21439         echo "Test 1: lfs find 20 DOM files by layout: OK"
21440
21441         # there should be 1 dir with default DOM striping
21442         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21443         [ $NUM -eq  1 ] ||
21444                 error "lfs find -L: found $NUM, expected 1 dir"
21445         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21446
21447         # find DoM files by stripe size
21448         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21449         [ $NUM -eq  $DOMFILES ] ||
21450                 error "lfs find -S: found $NUM, expected $DOMFILES"
21451         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21452
21453         # find files by stripe offset except DoM files
21454         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21455         [ $NUM -eq  $NORMFILES ] ||
21456                 error "lfs find -i: found $NUM, expected $NORMFILES"
21457         echo "Test 5: lfs find no DOM files by stripe index: OK"
21458         return 0
21459 }
21460 run_test 270e "DoM: lfs find with DoM files test"
21461
21462 test_270f() {
21463         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21464                 skip "Need MDS version at least 2.10.55"
21465
21466         local mdtname=${FSNAME}-MDT0000-mdtlov
21467         local dom=$DIR/$tdir/dom_file
21468         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21469                                                 lod.$mdtname.dom_stripesize)
21470         local dom_limit=131072
21471
21472         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21473         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21474                                                 lod.$mdtname.dom_stripesize)
21475         [ ${dom_limit} -eq ${dom_current} ] ||
21476                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21477
21478         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21479         $LFS setstripe -d $DIR/$tdir
21480         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21481                 error "Can't set directory default striping"
21482
21483         # exceed maximum stripe size
21484         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21485                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21486         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21487                 error "Able to create DoM component size more than LOD limit"
21488
21489         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21490         dom_current=$(do_facet mds1 $LCTL get_param -n \
21491                                                 lod.$mdtname.dom_stripesize)
21492         [ 0 -eq ${dom_current} ] ||
21493                 error "Can't set zero DoM stripe limit"
21494         rm $dom
21495
21496         # attempt to create DoM file on server with disabled DoM should
21497         # remove DoM entry from layout and be succeed
21498         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21499                 error "Can't create DoM file (DoM is disabled)"
21500         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21501                 error "File has DoM component while DoM is disabled"
21502         rm $dom
21503
21504         # attempt to create DoM file with only DoM stripe should return error
21505         $LFS setstripe -E $dom_limit -L mdt $dom &&
21506                 error "Able to create DoM-only file while DoM is disabled"
21507
21508         # too low values to be aligned with smallest stripe size 64K
21509         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21510         dom_current=$(do_facet mds1 $LCTL get_param -n \
21511                                                 lod.$mdtname.dom_stripesize)
21512         [ 30000 -eq ${dom_current} ] &&
21513                 error "Can set too small DoM stripe limit"
21514
21515         # 64K is a minimal stripe size in Lustre, expect limit of that size
21516         [ 65536 -eq ${dom_current} ] ||
21517                 error "Limit is not set to 64K but ${dom_current}"
21518
21519         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21520         dom_current=$(do_facet mds1 $LCTL get_param -n \
21521                                                 lod.$mdtname.dom_stripesize)
21522         echo $dom_current
21523         [ 2147483648 -eq ${dom_current} ] &&
21524                 error "Can set too large DoM stripe limit"
21525
21526         do_facet mds1 $LCTL set_param -n \
21527                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21528         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21529                 error "Can't create DoM component size after limit change"
21530         do_facet mds1 $LCTL set_param -n \
21531                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21532         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21533                 error "Can't create DoM file after limit decrease"
21534         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21535                 error "Can create big DoM component after limit decrease"
21536         touch ${dom}_def ||
21537                 error "Can't create file with old default layout"
21538
21539         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21540         return 0
21541 }
21542 run_test 270f "DoM: maximum DoM stripe size checks"
21543
21544 test_270g() {
21545         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21546                 skip "Need MDS version at least 2.13.52"
21547         local dom=$DIR/$tdir/$tfile
21548
21549         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21550         local lodname=${FSNAME}-MDT0000-mdtlov
21551
21552         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21553         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21554         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21555         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21556
21557         local dom_limit=1024
21558         local dom_threshold="50%"
21559
21560         $LFS setstripe -d $DIR/$tdir
21561         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21562                 error "Can't set directory default striping"
21563
21564         do_facet mds1 $LCTL set_param -n \
21565                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21566         # set 0 threshold and create DOM file to change tunable stripesize
21567         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21568         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21569                 error "Failed to create $dom file"
21570         # now tunable dom_cur_stripesize should reach maximum
21571         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21572                                         lod.${lodname}.dom_stripesize_cur_kb)
21573         [[ $dom_current == $dom_limit ]] ||
21574                 error "Current DOM stripesize is not maximum"
21575         rm $dom
21576
21577         # set threshold for further tests
21578         do_facet mds1 $LCTL set_param -n \
21579                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21580         echo "DOM threshold is $dom_threshold free space"
21581         local dom_def
21582         local dom_set
21583         # Spoof bfree to exceed threshold
21584         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21585         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21586         for spfree in 40 20 0 15 30 55; do
21587                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21588                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21589                         error "Failed to create $dom file"
21590                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21591                                         lod.${lodname}.dom_stripesize_cur_kb)
21592                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21593                 [[ $dom_def != $dom_current ]] ||
21594                         error "Default stripe size was not changed"
21595                 if [[ $spfree > 0 ]] ; then
21596                         dom_set=$($LFS getstripe -S $dom)
21597                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21598                                 error "DOM component size is still old"
21599                 else
21600                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21601                                 error "DoM component is set with no free space"
21602                 fi
21603                 rm $dom
21604                 dom_current=$dom_def
21605         done
21606 }
21607 run_test 270g "DoM: default DoM stripe size depends on free space"
21608
21609 test_270h() {
21610         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21611                 skip "Need MDS version at least 2.13.53"
21612
21613         local mdtname=${FSNAME}-MDT0000-mdtlov
21614         local dom=$DIR/$tdir/$tfile
21615         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21616
21617         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21618         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21619
21620         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21621         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21622                 error "can't create OST file"
21623         # mirrored file with DOM entry in the second mirror
21624         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21625                 error "can't create mirror with DoM component"
21626
21627         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21628
21629         # DOM component in the middle and has other enries in the same mirror,
21630         # should succeed but lost DoM component
21631         $LFS setstripe --copy=${dom}_1 $dom ||
21632                 error "Can't create file from OST|DOM mirror layout"
21633         # check new file has no DoM layout after all
21634         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21635                 error "File has DoM component while DoM is disabled"
21636 }
21637 run_test 270h "DoM: DoM stripe removal when disabled on server"
21638
21639 test_271a() {
21640         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21641                 skip "Need MDS version at least 2.10.55"
21642
21643         local dom=$DIR/$tdir/dom
21644
21645         mkdir -p $DIR/$tdir
21646
21647         $LFS setstripe -E 1024K -L mdt $dom
21648
21649         lctl set_param -n mdc.*.stats=clear
21650         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21651         cat $dom > /dev/null
21652         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21653         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21654         ls $dom
21655         rm -f $dom
21656 }
21657 run_test 271a "DoM: data is cached for read after write"
21658
21659 test_271b() {
21660         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21661                 skip "Need MDS version at least 2.10.55"
21662
21663         local dom=$DIR/$tdir/dom
21664
21665         mkdir -p $DIR/$tdir
21666
21667         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21668
21669         lctl set_param -n mdc.*.stats=clear
21670         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21671         cancel_lru_locks mdc
21672         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21673         # second stat to check size is cached on client
21674         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21675         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21676         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21677         rm -f $dom
21678 }
21679 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21680
21681 test_271ba() {
21682         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21683                 skip "Need MDS version at least 2.10.55"
21684
21685         local dom=$DIR/$tdir/dom
21686
21687         mkdir -p $DIR/$tdir
21688
21689         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21690
21691         lctl set_param -n mdc.*.stats=clear
21692         lctl set_param -n osc.*.stats=clear
21693         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21694         cancel_lru_locks mdc
21695         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21696         # second stat to check size is cached on client
21697         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21698         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21699         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21700         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21701         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21702         rm -f $dom
21703 }
21704 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21705
21706
21707 get_mdc_stats() {
21708         local mdtidx=$1
21709         local param=$2
21710         local mdt=MDT$(printf %04x $mdtidx)
21711
21712         if [ -z $param ]; then
21713                 lctl get_param -n mdc.*$mdt*.stats
21714         else
21715                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21716         fi
21717 }
21718
21719 test_271c() {
21720         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21721                 skip "Need MDS version at least 2.10.55"
21722
21723         local dom=$DIR/$tdir/dom
21724
21725         mkdir -p $DIR/$tdir
21726
21727         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21728
21729         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21730         local facet=mds$((mdtidx + 1))
21731
21732         cancel_lru_locks mdc
21733         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21734         createmany -o $dom 1000
21735         lctl set_param -n mdc.*.stats=clear
21736         smalliomany -w $dom 1000 200
21737         get_mdc_stats $mdtidx
21738         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21739         # Each file has 1 open, 1 IO enqueues, total 2000
21740         # but now we have also +1 getxattr for security.capability, total 3000
21741         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21742         unlinkmany $dom 1000
21743
21744         cancel_lru_locks mdc
21745         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21746         createmany -o $dom 1000
21747         lctl set_param -n mdc.*.stats=clear
21748         smalliomany -w $dom 1000 200
21749         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21750         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21751         # for OPEN and IO lock.
21752         [ $((enq - enq_2)) -ge 1000 ] ||
21753                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21754         unlinkmany $dom 1000
21755         return 0
21756 }
21757 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21758
21759 cleanup_271def_tests() {
21760         trap 0
21761         rm -f $1
21762 }
21763
21764 test_271d() {
21765         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21766                 skip "Need MDS version at least 2.10.57"
21767
21768         local dom=$DIR/$tdir/dom
21769         local tmp=$TMP/$tfile
21770         trap "cleanup_271def_tests $tmp" EXIT
21771
21772         mkdir -p $DIR/$tdir
21773
21774         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21775
21776         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21777
21778         cancel_lru_locks mdc
21779         dd if=/dev/urandom of=$tmp bs=1000 count=1
21780         dd if=$tmp of=$dom bs=1000 count=1
21781         cancel_lru_locks mdc
21782
21783         cat /etc/hosts >> $tmp
21784         lctl set_param -n mdc.*.stats=clear
21785
21786         # append data to the same file it should update local page
21787         echo "Append to the same page"
21788         cat /etc/hosts >> $dom
21789         local num=$(get_mdc_stats $mdtidx ost_read)
21790         local ra=$(get_mdc_stats $mdtidx req_active)
21791         local rw=$(get_mdc_stats $mdtidx req_waittime)
21792
21793         [ -z $num ] || error "$num READ RPC occured"
21794         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21795         echo "... DONE"
21796
21797         # compare content
21798         cmp $tmp $dom || error "file miscompare"
21799
21800         cancel_lru_locks mdc
21801         lctl set_param -n mdc.*.stats=clear
21802
21803         echo "Open and read file"
21804         cat $dom > /dev/null
21805         local num=$(get_mdc_stats $mdtidx ost_read)
21806         local ra=$(get_mdc_stats $mdtidx req_active)
21807         local rw=$(get_mdc_stats $mdtidx req_waittime)
21808
21809         [ -z $num ] || error "$num READ RPC occured"
21810         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21811         echo "... DONE"
21812
21813         # compare content
21814         cmp $tmp $dom || error "file miscompare"
21815
21816         return 0
21817 }
21818 run_test 271d "DoM: read on open (1K file in reply buffer)"
21819
21820 test_271f() {
21821         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21822                 skip "Need MDS version at least 2.10.57"
21823
21824         local dom=$DIR/$tdir/dom
21825         local tmp=$TMP/$tfile
21826         trap "cleanup_271def_tests $tmp" EXIT
21827
21828         mkdir -p $DIR/$tdir
21829
21830         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21831
21832         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21833
21834         cancel_lru_locks mdc
21835         dd if=/dev/urandom of=$tmp bs=265000 count=1
21836         dd if=$tmp of=$dom bs=265000 count=1
21837         cancel_lru_locks mdc
21838         cat /etc/hosts >> $tmp
21839         lctl set_param -n mdc.*.stats=clear
21840
21841         echo "Append to the same page"
21842         cat /etc/hosts >> $dom
21843         local num=$(get_mdc_stats $mdtidx ost_read)
21844         local ra=$(get_mdc_stats $mdtidx req_active)
21845         local rw=$(get_mdc_stats $mdtidx req_waittime)
21846
21847         [ -z $num ] || error "$num READ RPC occured"
21848         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21849         echo "... DONE"
21850
21851         # compare content
21852         cmp $tmp $dom || error "file miscompare"
21853
21854         cancel_lru_locks mdc
21855         lctl set_param -n mdc.*.stats=clear
21856
21857         echo "Open and read file"
21858         cat $dom > /dev/null
21859         local num=$(get_mdc_stats $mdtidx ost_read)
21860         local ra=$(get_mdc_stats $mdtidx req_active)
21861         local rw=$(get_mdc_stats $mdtidx req_waittime)
21862
21863         [ -z $num ] && num=0
21864         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21865         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21866         echo "... DONE"
21867
21868         # compare content
21869         cmp $tmp $dom || error "file miscompare"
21870
21871         return 0
21872 }
21873 run_test 271f "DoM: read on open (200K file and read tail)"
21874
21875 test_271g() {
21876         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21877                 skip "Skipping due to old client or server version"
21878
21879         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21880         # to get layout
21881         $CHECKSTAT -t file $DIR1/$tfile
21882
21883         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21884         MULTIOP_PID=$!
21885         sleep 1
21886         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21887         $LCTL set_param fail_loc=0x80000314
21888         rm $DIR1/$tfile || error "Unlink fails"
21889         RC=$?
21890         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21891         [ $RC -eq 0 ] || error "Failed write to stale object"
21892 }
21893 run_test 271g "Discard DoM data vs client flush race"
21894
21895 test_272a() {
21896         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21897                 skip "Need MDS version at least 2.11.50"
21898
21899         local dom=$DIR/$tdir/dom
21900         mkdir -p $DIR/$tdir
21901
21902         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21903         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21904                 error "failed to write data into $dom"
21905         local old_md5=$(md5sum $dom)
21906
21907         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21908                 error "failed to migrate to the same DoM component"
21909
21910         local new_md5=$(md5sum $dom)
21911
21912         [ "$old_md5" == "$new_md5" ] ||
21913                 error "md5sum differ: $old_md5, $new_md5"
21914
21915         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21916                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21917 }
21918 run_test 272a "DoM migration: new layout with the same DOM component"
21919
21920 test_272b() {
21921         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21922                 skip "Need MDS version at least 2.11.50"
21923
21924         local dom=$DIR/$tdir/dom
21925         mkdir -p $DIR/$tdir
21926         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21927
21928         local mdtidx=$($LFS getstripe -m $dom)
21929         local mdtname=MDT$(printf %04x $mdtidx)
21930         local facet=mds$((mdtidx + 1))
21931
21932         local mdtfree1=$(do_facet $facet \
21933                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21934         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21935                 error "failed to write data into $dom"
21936         local old_md5=$(md5sum $dom)
21937         cancel_lru_locks mdc
21938         local mdtfree1=$(do_facet $facet \
21939                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21940
21941         $LFS migrate -c2 $dom ||
21942                 error "failed to migrate to the new composite layout"
21943         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21944                 error "MDT stripe was not removed"
21945
21946         cancel_lru_locks mdc
21947         local new_md5=$(md5sum $dom)
21948         [ "$old_md5" == "$new_md5" ] ||
21949                 error "$old_md5 != $new_md5"
21950
21951         # Skip free space checks with ZFS
21952         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21953                 local mdtfree2=$(do_facet $facet \
21954                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21955                 [ $mdtfree2 -gt $mdtfree1 ] ||
21956                         error "MDT space is not freed after migration"
21957         fi
21958         return 0
21959 }
21960 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21961
21962 test_272c() {
21963         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21964                 skip "Need MDS version at least 2.11.50"
21965
21966         local dom=$DIR/$tdir/$tfile
21967         mkdir -p $DIR/$tdir
21968         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21969
21970         local mdtidx=$($LFS getstripe -m $dom)
21971         local mdtname=MDT$(printf %04x $mdtidx)
21972         local facet=mds$((mdtidx + 1))
21973
21974         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21975                 error "failed to write data into $dom"
21976         local old_md5=$(md5sum $dom)
21977         cancel_lru_locks mdc
21978         local mdtfree1=$(do_facet $facet \
21979                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21980
21981         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21982                 error "failed to migrate to the new composite layout"
21983         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21984                 error "MDT stripe was not removed"
21985
21986         cancel_lru_locks mdc
21987         local new_md5=$(md5sum $dom)
21988         [ "$old_md5" == "$new_md5" ] ||
21989                 error "$old_md5 != $new_md5"
21990
21991         # Skip free space checks with ZFS
21992         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21993                 local mdtfree2=$(do_facet $facet \
21994                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21995                 [ $mdtfree2 -gt $mdtfree1 ] ||
21996                         error "MDS space is not freed after migration"
21997         fi
21998         return 0
21999 }
22000 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22001
22002 test_272d() {
22003         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22004                 skip "Need MDS version at least 2.12.55"
22005
22006         local dom=$DIR/$tdir/$tfile
22007         mkdir -p $DIR/$tdir
22008         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22009
22010         local mdtidx=$($LFS getstripe -m $dom)
22011         local mdtname=MDT$(printf %04x $mdtidx)
22012         local facet=mds$((mdtidx + 1))
22013
22014         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22015                 error "failed to write data into $dom"
22016         local old_md5=$(md5sum $dom)
22017         cancel_lru_locks mdc
22018         local mdtfree1=$(do_facet $facet \
22019                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22020
22021         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22022                 error "failed mirroring to the new composite layout"
22023         $LFS mirror resync $dom ||
22024                 error "failed mirror resync"
22025         $LFS mirror split --mirror-id 1 -d $dom ||
22026                 error "failed mirror split"
22027
22028         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22029                 error "MDT stripe was not removed"
22030
22031         cancel_lru_locks mdc
22032         local new_md5=$(md5sum $dom)
22033         [ "$old_md5" == "$new_md5" ] ||
22034                 error "$old_md5 != $new_md5"
22035
22036         # Skip free space checks with ZFS
22037         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22038                 local mdtfree2=$(do_facet $facet \
22039                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22040                 [ $mdtfree2 -gt $mdtfree1 ] ||
22041                         error "MDS space is not freed after DOM mirror deletion"
22042         fi
22043         return 0
22044 }
22045 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22046
22047 test_272e() {
22048         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22049                 skip "Need MDS version at least 2.12.55"
22050
22051         local dom=$DIR/$tdir/$tfile
22052         mkdir -p $DIR/$tdir
22053         $LFS setstripe -c 2 $dom
22054
22055         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22056                 error "failed to write data into $dom"
22057         local old_md5=$(md5sum $dom)
22058         cancel_lru_locks mdc
22059
22060         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22061                 error "failed mirroring to the DOM layout"
22062         $LFS mirror resync $dom ||
22063                 error "failed mirror resync"
22064         $LFS mirror split --mirror-id 1 -d $dom ||
22065                 error "failed mirror split"
22066
22067         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22068                 error "MDT stripe was not removed"
22069
22070         cancel_lru_locks mdc
22071         local new_md5=$(md5sum $dom)
22072         [ "$old_md5" == "$new_md5" ] ||
22073                 error "$old_md5 != $new_md5"
22074
22075         return 0
22076 }
22077 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22078
22079 test_272f() {
22080         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22081                 skip "Need MDS version at least 2.12.55"
22082
22083         local dom=$DIR/$tdir/$tfile
22084         mkdir -p $DIR/$tdir
22085         $LFS setstripe -c 2 $dom
22086
22087         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22088                 error "failed to write data into $dom"
22089         local old_md5=$(md5sum $dom)
22090         cancel_lru_locks mdc
22091
22092         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22093                 error "failed migrating to the DOM file"
22094
22095         cancel_lru_locks mdc
22096         local new_md5=$(md5sum $dom)
22097         [ "$old_md5" != "$new_md5" ] &&
22098                 error "$old_md5 != $new_md5"
22099
22100         return 0
22101 }
22102 run_test 272f "DoM migration: OST-striped file to DOM file"
22103
22104 test_273a() {
22105         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22106                 skip "Need MDS version at least 2.11.50"
22107
22108         # Layout swap cannot be done if either file has DOM component,
22109         # this will never be supported, migration should be used instead
22110
22111         local dom=$DIR/$tdir/$tfile
22112         mkdir -p $DIR/$tdir
22113
22114         $LFS setstripe -c2 ${dom}_plain
22115         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22116         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22117                 error "can swap layout with DoM component"
22118         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22119                 error "can swap layout with DoM component"
22120
22121         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22122         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22123                 error "can swap layout with DoM component"
22124         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22125                 error "can swap layout with DoM component"
22126         return 0
22127 }
22128 run_test 273a "DoM: layout swapping should fail with DOM"
22129
22130 test_273b() {
22131         mkdir -p $DIR/$tdir
22132         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22133
22134 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22135         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22136
22137         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22138 }
22139 run_test 273b "DoM: race writeback and object destroy"
22140
22141 test_275() {
22142         remote_ost_nodsh && skip "remote OST with nodsh"
22143         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22144                 skip "Need OST version >= 2.10.57"
22145
22146         local file=$DIR/$tfile
22147         local oss
22148
22149         oss=$(comma_list $(osts_nodes))
22150
22151         dd if=/dev/urandom of=$file bs=1M count=2 ||
22152                 error "failed to create a file"
22153         cancel_lru_locks osc
22154
22155         #lock 1
22156         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22157                 error "failed to read a file"
22158
22159 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22160         $LCTL set_param fail_loc=0x8000031f
22161
22162         cancel_lru_locks osc &
22163         sleep 1
22164
22165 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22166         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22167         #IO takes another lock, but matches the PENDING one
22168         #and places it to the IO RPC
22169         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22170                 error "failed to read a file with PENDING lock"
22171 }
22172 run_test 275 "Read on a canceled duplicate lock"
22173
22174 test_276() {
22175         remote_ost_nodsh && skip "remote OST with nodsh"
22176         local pid
22177
22178         do_facet ost1 "(while true; do \
22179                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22180                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22181         pid=$!
22182
22183         for LOOP in $(seq 20); do
22184                 stop ost1
22185                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22186         done
22187         kill -9 $pid
22188         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22189                 rm $TMP/sanity_276_pid"
22190 }
22191 run_test 276 "Race between mount and obd_statfs"
22192
22193 test_277() {
22194         $LCTL set_param ldlm.namespaces.*.lru_size=0
22195         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22196         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22197                         grep ^used_mb | awk '{print $2}')
22198         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22199         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22200                 oflag=direct conv=notrunc
22201         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22202                         grep ^used_mb | awk '{print $2}')
22203         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22204 }
22205 run_test 277 "Direct IO shall drop page cache"
22206
22207 test_278() {
22208         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22209         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22210         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22211                 skip "needs the same host for mdt1 mdt2" && return
22212
22213         local pid1
22214         local pid2
22215
22216 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22217         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22218         stop mds2 &
22219         pid2=$!
22220
22221         stop mds1
22222
22223         echo "Starting MDTs"
22224         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22225         wait $pid2
22226 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22227 #will return NULL
22228         do_facet mds2 $LCTL set_param fail_loc=0
22229
22230         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22231         wait_recovery_complete mds2
22232 }
22233 run_test 278 "Race starting MDS between MDTs stop/start"
22234
22235 test_280() {
22236         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22237                 skip "Need MGS version at least 2.13.52"
22238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22239         combined_mgs_mds || skip "needs combined MGS/MDT"
22240
22241         umount_client $MOUNT
22242 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22243         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22244
22245         mount_client $MOUNT &
22246         sleep 1
22247         stop mgs || error "stop mgs failed"
22248         #for a race mgs would crash
22249         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22250         # make sure we unmount client before remounting
22251         wait
22252         umount_client $MOUNT
22253         mount_client $MOUNT || error "mount client failed"
22254 }
22255 run_test 280 "Race between MGS umount and client llog processing"
22256
22257 cleanup_test_300() {
22258         trap 0
22259         umask $SAVE_UMASK
22260 }
22261 test_striped_dir() {
22262         local mdt_index=$1
22263         local stripe_count
22264         local stripe_index
22265
22266         mkdir -p $DIR/$tdir
22267
22268         SAVE_UMASK=$(umask)
22269         trap cleanup_test_300 RETURN EXIT
22270
22271         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22272                                                 $DIR/$tdir/striped_dir ||
22273                 error "set striped dir error"
22274
22275         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22276         [ "$mode" = "755" ] || error "expect 755 got $mode"
22277
22278         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22279                 error "getdirstripe failed"
22280         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22281         if [ "$stripe_count" != "2" ]; then
22282                 error "1:stripe_count is $stripe_count, expect 2"
22283         fi
22284         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22285         if [ "$stripe_count" != "2" ]; then
22286                 error "2:stripe_count is $stripe_count, expect 2"
22287         fi
22288
22289         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22290         if [ "$stripe_index" != "$mdt_index" ]; then
22291                 error "stripe_index is $stripe_index, expect $mdt_index"
22292         fi
22293
22294         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22295                 error "nlink error after create striped dir"
22296
22297         mkdir $DIR/$tdir/striped_dir/a
22298         mkdir $DIR/$tdir/striped_dir/b
22299
22300         stat $DIR/$tdir/striped_dir/a ||
22301                 error "create dir under striped dir failed"
22302         stat $DIR/$tdir/striped_dir/b ||
22303                 error "create dir under striped dir failed"
22304
22305         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22306                 error "nlink error after mkdir"
22307
22308         rmdir $DIR/$tdir/striped_dir/a
22309         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22310                 error "nlink error after rmdir"
22311
22312         rmdir $DIR/$tdir/striped_dir/b
22313         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22314                 error "nlink error after rmdir"
22315
22316         chattr +i $DIR/$tdir/striped_dir
22317         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22318                 error "immutable flags not working under striped dir!"
22319         chattr -i $DIR/$tdir/striped_dir
22320
22321         rmdir $DIR/$tdir/striped_dir ||
22322                 error "rmdir striped dir error"
22323
22324         cleanup_test_300
22325
22326         true
22327 }
22328
22329 test_300a() {
22330         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22331                 skip "skipped for lustre < 2.7.0"
22332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22334
22335         test_striped_dir 0 || error "failed on striped dir on MDT0"
22336         test_striped_dir 1 || error "failed on striped dir on MDT0"
22337 }
22338 run_test 300a "basic striped dir sanity test"
22339
22340 test_300b() {
22341         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22342                 skip "skipped for lustre < 2.7.0"
22343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22344         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22345
22346         local i
22347         local mtime1
22348         local mtime2
22349         local mtime3
22350
22351         test_mkdir $DIR/$tdir || error "mkdir fail"
22352         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22353                 error "set striped dir error"
22354         for i in {0..9}; do
22355                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22356                 sleep 1
22357                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22358                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22359                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22360                 sleep 1
22361                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22362                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22363                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22364         done
22365         true
22366 }
22367 run_test 300b "check ctime/mtime for striped dir"
22368
22369 test_300c() {
22370         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22371                 skip "skipped for lustre < 2.7.0"
22372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22373         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22374
22375         local file_count
22376
22377         mkdir_on_mdt0 $DIR/$tdir
22378         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22379                 error "set striped dir error"
22380
22381         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22382                 error "chown striped dir failed"
22383
22384         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22385                 error "create 5k files failed"
22386
22387         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22388
22389         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22390
22391         rm -rf $DIR/$tdir
22392 }
22393 run_test 300c "chown && check ls under striped directory"
22394
22395 test_300d() {
22396         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22397                 skip "skipped for lustre < 2.7.0"
22398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22399         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22400
22401         local stripe_count
22402         local file
22403
22404         mkdir -p $DIR/$tdir
22405         $LFS setstripe -c 2 $DIR/$tdir
22406
22407         #local striped directory
22408         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22409                 error "set striped dir error"
22410         #look at the directories for debug purposes
22411         ls -l $DIR/$tdir
22412         $LFS getdirstripe $DIR/$tdir
22413         ls -l $DIR/$tdir/striped_dir
22414         $LFS getdirstripe $DIR/$tdir/striped_dir
22415         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22416                 error "create 10 files failed"
22417
22418         #remote striped directory
22419         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22420                 error "set striped dir error"
22421         #look at the directories for debug purposes
22422         ls -l $DIR/$tdir
22423         $LFS getdirstripe $DIR/$tdir
22424         ls -l $DIR/$tdir/remote_striped_dir
22425         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22426         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22427                 error "create 10 files failed"
22428
22429         for file in $(find $DIR/$tdir); do
22430                 stripe_count=$($LFS getstripe -c $file)
22431                 [ $stripe_count -eq 2 ] ||
22432                         error "wrong stripe $stripe_count for $file"
22433         done
22434
22435         rm -rf $DIR/$tdir
22436 }
22437 run_test 300d "check default stripe under striped directory"
22438
22439 test_300e() {
22440         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22441                 skip "Need MDS version at least 2.7.55"
22442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22443         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22444
22445         local stripe_count
22446         local file
22447
22448         mkdir -p $DIR/$tdir
22449
22450         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22451                 error "set striped dir error"
22452
22453         touch $DIR/$tdir/striped_dir/a
22454         touch $DIR/$tdir/striped_dir/b
22455         touch $DIR/$tdir/striped_dir/c
22456
22457         mkdir $DIR/$tdir/striped_dir/dir_a
22458         mkdir $DIR/$tdir/striped_dir/dir_b
22459         mkdir $DIR/$tdir/striped_dir/dir_c
22460
22461         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22462                 error "set striped adir under striped dir error"
22463
22464         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22465                 error "set striped bdir under striped dir error"
22466
22467         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22468                 error "set striped cdir under striped dir error"
22469
22470         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22471                 error "rename dir under striped dir fails"
22472
22473         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22474                 error "rename dir under different stripes fails"
22475
22476         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22477                 error "rename file under striped dir should succeed"
22478
22479         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22480                 error "rename dir under striped dir should succeed"
22481
22482         rm -rf $DIR/$tdir
22483 }
22484 run_test 300e "check rename under striped directory"
22485
22486 test_300f() {
22487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22488         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22489         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22490                 skip "Need MDS version at least 2.7.55"
22491
22492         local stripe_count
22493         local file
22494
22495         rm -rf $DIR/$tdir
22496         mkdir -p $DIR/$tdir
22497
22498         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22499                 error "set striped dir error"
22500
22501         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22502                 error "set striped dir error"
22503
22504         touch $DIR/$tdir/striped_dir/a
22505         mkdir $DIR/$tdir/striped_dir/dir_a
22506         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22507                 error "create striped dir under striped dir fails"
22508
22509         touch $DIR/$tdir/striped_dir1/b
22510         mkdir $DIR/$tdir/striped_dir1/dir_b
22511         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22512                 error "create striped dir under striped dir fails"
22513
22514         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22515                 error "rename dir under different striped dir should fail"
22516
22517         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22518                 error "rename striped dir under diff striped dir should fail"
22519
22520         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22521                 error "rename file under diff striped dirs fails"
22522
22523         rm -rf $DIR/$tdir
22524 }
22525 run_test 300f "check rename cross striped directory"
22526
22527 test_300_check_default_striped_dir()
22528 {
22529         local dirname=$1
22530         local default_count=$2
22531         local default_index=$3
22532         local stripe_count
22533         local stripe_index
22534         local dir_stripe_index
22535         local dir
22536
22537         echo "checking $dirname $default_count $default_index"
22538         $LFS setdirstripe -D -c $default_count -i $default_index \
22539                                 -H all_char $DIR/$tdir/$dirname ||
22540                 error "set default stripe on striped dir error"
22541         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22542         [ $stripe_count -eq $default_count ] ||
22543                 error "expect $default_count get $stripe_count for $dirname"
22544
22545         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22546         [ $stripe_index -eq $default_index ] ||
22547                 error "expect $default_index get $stripe_index for $dirname"
22548
22549         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22550                                                 error "create dirs failed"
22551
22552         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22553         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22554         for dir in $(find $DIR/$tdir/$dirname/*); do
22555                 stripe_count=$($LFS getdirstripe -c $dir)
22556                 (( $stripe_count == $default_count )) ||
22557                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22558                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22559                 error "stripe count $default_count != $stripe_count for $dir"
22560
22561                 stripe_index=$($LFS getdirstripe -i $dir)
22562                 [ $default_index -eq -1 ] ||
22563                         [ $stripe_index -eq $default_index ] ||
22564                         error "$stripe_index != $default_index for $dir"
22565
22566                 #check default stripe
22567                 stripe_count=$($LFS getdirstripe -D -c $dir)
22568                 [ $stripe_count -eq $default_count ] ||
22569                 error "default count $default_count != $stripe_count for $dir"
22570
22571                 stripe_index=$($LFS getdirstripe -D -i $dir)
22572                 [ $stripe_index -eq $default_index ] ||
22573                 error "default index $default_index != $stripe_index for $dir"
22574         done
22575         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22576 }
22577
22578 test_300g() {
22579         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22580         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22581                 skip "Need MDS version at least 2.7.55"
22582
22583         local dir
22584         local stripe_count
22585         local stripe_index
22586
22587         mkdir_on_mdt0 $DIR/$tdir
22588         mkdir $DIR/$tdir/normal_dir
22589
22590         #Checking when client cache stripe index
22591         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22592         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22593                 error "create striped_dir failed"
22594
22595         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22596                 error "create dir0 fails"
22597         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22598         [ $stripe_index -eq 0 ] ||
22599                 error "dir0 expect index 0 got $stripe_index"
22600
22601         mkdir $DIR/$tdir/striped_dir/dir1 ||
22602                 error "create dir1 fails"
22603         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22604         [ $stripe_index -eq 1 ] ||
22605                 error "dir1 expect index 1 got $stripe_index"
22606
22607         #check default stripe count/stripe index
22608         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22609         test_300_check_default_striped_dir normal_dir 1 0
22610         test_300_check_default_striped_dir normal_dir -1 1
22611         test_300_check_default_striped_dir normal_dir 2 -1
22612
22613         #delete default stripe information
22614         echo "delete default stripeEA"
22615         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22616                 error "set default stripe on striped dir error"
22617
22618         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22619         for dir in $(find $DIR/$tdir/normal_dir/*); do
22620                 stripe_count=$($LFS getdirstripe -c $dir)
22621                 [ $stripe_count -eq 0 ] ||
22622                         error "expect 1 get $stripe_count for $dir"
22623                 stripe_index=$($LFS getdirstripe -i $dir)
22624                 [ $stripe_index -eq 0 ] ||
22625                         error "expect 0 get $stripe_index for $dir"
22626         done
22627 }
22628 run_test 300g "check default striped directory for normal directory"
22629
22630 test_300h() {
22631         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22632         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22633                 skip "Need MDS version at least 2.7.55"
22634
22635         local dir
22636         local stripe_count
22637
22638         mkdir $DIR/$tdir
22639         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22640                 error "set striped dir error"
22641
22642         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22643         test_300_check_default_striped_dir striped_dir 1 0
22644         test_300_check_default_striped_dir striped_dir -1 1
22645         test_300_check_default_striped_dir striped_dir 2 -1
22646
22647         #delete default stripe information
22648         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22649                 error "set default stripe on striped dir error"
22650
22651         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22652         for dir in $(find $DIR/$tdir/striped_dir/*); do
22653                 stripe_count=$($LFS getdirstripe -c $dir)
22654                 [ $stripe_count -eq 0 ] ||
22655                         error "expect 1 get $stripe_count for $dir"
22656         done
22657 }
22658 run_test 300h "check default striped directory for striped directory"
22659
22660 test_300i() {
22661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22662         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22663         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22664                 skip "Need MDS version at least 2.7.55"
22665
22666         local stripe_count
22667         local file
22668
22669         mkdir $DIR/$tdir
22670
22671         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22672                 error "set striped dir error"
22673
22674         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22675                 error "create files under striped dir failed"
22676
22677         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22678                 error "set striped hashdir error"
22679
22680         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22681                 error "create dir0 under hash dir failed"
22682         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22683                 error "create dir1 under hash dir failed"
22684         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22685                 error "create dir2 under hash dir failed"
22686
22687         # unfortunately, we need to umount to clear dir layout cache for now
22688         # once we fully implement dir layout, we can drop this
22689         umount_client $MOUNT || error "umount failed"
22690         mount_client $MOUNT || error "mount failed"
22691
22692         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22693         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22694         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22695
22696         #set the stripe to be unknown hash type
22697         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22698         $LCTL set_param fail_loc=0x1901
22699         for ((i = 0; i < 10; i++)); do
22700                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22701                         error "stat f-$i failed"
22702                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22703         done
22704
22705         touch $DIR/$tdir/striped_dir/f0 &&
22706                 error "create under striped dir with unknown hash should fail"
22707
22708         $LCTL set_param fail_loc=0
22709
22710         umount_client $MOUNT || error "umount failed"
22711         mount_client $MOUNT || error "mount failed"
22712
22713         return 0
22714 }
22715 run_test 300i "client handle unknown hash type striped directory"
22716
22717 test_300j() {
22718         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22720         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22721                 skip "Need MDS version at least 2.7.55"
22722
22723         local stripe_count
22724         local file
22725
22726         mkdir $DIR/$tdir
22727
22728         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22729         $LCTL set_param fail_loc=0x1702
22730         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22731                 error "set striped dir error"
22732
22733         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22734                 error "create files under striped dir failed"
22735
22736         $LCTL set_param fail_loc=0
22737
22738         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22739
22740         return 0
22741 }
22742 run_test 300j "test large update record"
22743
22744 test_300k() {
22745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22746         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22747         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22748                 skip "Need MDS version at least 2.7.55"
22749
22750         # this test needs a huge transaction
22751         local kb
22752         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22753              osd*.$FSNAME-MDT0000.kbytestotal")
22754         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22755
22756         local stripe_count
22757         local file
22758
22759         mkdir $DIR/$tdir
22760
22761         #define OBD_FAIL_LARGE_STRIPE   0x1703
22762         $LCTL set_param fail_loc=0x1703
22763         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22764                 error "set striped dir error"
22765         $LCTL set_param fail_loc=0
22766
22767         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22768                 error "getstripeddir fails"
22769         rm -rf $DIR/$tdir/striped_dir ||
22770                 error "unlink striped dir fails"
22771
22772         return 0
22773 }
22774 run_test 300k "test large striped directory"
22775
22776 test_300l() {
22777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22778         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22779         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22780                 skip "Need MDS version at least 2.7.55"
22781
22782         local stripe_index
22783
22784         test_mkdir -p $DIR/$tdir/striped_dir
22785         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22786                         error "chown $RUNAS_ID failed"
22787         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22788                 error "set default striped dir failed"
22789
22790         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22791         $LCTL set_param fail_loc=0x80000158
22792         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22793
22794         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22795         [ $stripe_index -eq 1 ] ||
22796                 error "expect 1 get $stripe_index for $dir"
22797 }
22798 run_test 300l "non-root user to create dir under striped dir with stale layout"
22799
22800 test_300m() {
22801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22802         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22803         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22804                 skip "Need MDS version at least 2.7.55"
22805
22806         mkdir -p $DIR/$tdir/striped_dir
22807         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22808                 error "set default stripes dir error"
22809
22810         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22811
22812         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22813         [ $stripe_count -eq 0 ] ||
22814                         error "expect 0 get $stripe_count for a"
22815
22816         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22817                 error "set default stripes dir error"
22818
22819         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22820
22821         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22822         [ $stripe_count -eq 0 ] ||
22823                         error "expect 0 get $stripe_count for b"
22824
22825         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22826                 error "set default stripes dir error"
22827
22828         mkdir $DIR/$tdir/striped_dir/c &&
22829                 error "default stripe_index is invalid, mkdir c should fails"
22830
22831         rm -rf $DIR/$tdir || error "rmdir fails"
22832 }
22833 run_test 300m "setstriped directory on single MDT FS"
22834
22835 cleanup_300n() {
22836         local list=$(comma_list $(mdts_nodes))
22837
22838         trap 0
22839         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22840 }
22841
22842 test_300n() {
22843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22844         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22845         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22846                 skip "Need MDS version at least 2.7.55"
22847         remote_mds_nodsh && skip "remote MDS with nodsh"
22848
22849         local stripe_index
22850         local list=$(comma_list $(mdts_nodes))
22851
22852         trap cleanup_300n RETURN EXIT
22853         mkdir -p $DIR/$tdir
22854         chmod 777 $DIR/$tdir
22855         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22856                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22857                 error "create striped dir succeeds with gid=0"
22858
22859         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22860         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22861                 error "create striped dir fails with gid=-1"
22862
22863         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22864         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22865                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22866                 error "set default striped dir succeeds with gid=0"
22867
22868
22869         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22870         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22871                 error "set default striped dir fails with gid=-1"
22872
22873
22874         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22875         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22876                                         error "create test_dir fails"
22877         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22878                                         error "create test_dir1 fails"
22879         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22880                                         error "create test_dir2 fails"
22881         cleanup_300n
22882 }
22883 run_test 300n "non-root user to create dir under striped dir with default EA"
22884
22885 test_300o() {
22886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22887         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22888         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22889                 skip "Need MDS version at least 2.7.55"
22890
22891         local numfree1
22892         local numfree2
22893
22894         mkdir -p $DIR/$tdir
22895
22896         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22897         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22898         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22899                 skip "not enough free inodes $numfree1 $numfree2"
22900         fi
22901
22902         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22903         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22904         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22905                 skip "not enough free space $numfree1 $numfree2"
22906         fi
22907
22908         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22909                 error "setdirstripe fails"
22910
22911         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22912                 error "create dirs fails"
22913
22914         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22915         ls $DIR/$tdir/striped_dir > /dev/null ||
22916                 error "ls striped dir fails"
22917         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22918                 error "unlink big striped dir fails"
22919 }
22920 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22921
22922 test_300p() {
22923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22924         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22925         remote_mds_nodsh && skip "remote MDS with nodsh"
22926
22927         mkdir_on_mdt0 $DIR/$tdir
22928
22929         #define OBD_FAIL_OUT_ENOSPC     0x1704
22930         do_facet mds2 lctl set_param fail_loc=0x80001704
22931         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22932                  && error "create striped directory should fail"
22933
22934         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22935
22936         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22937         true
22938 }
22939 run_test 300p "create striped directory without space"
22940
22941 test_300q() {
22942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22943         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22944
22945         local fd=$(free_fd)
22946         local cmd="exec $fd<$tdir"
22947         cd $DIR
22948         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22949         eval $cmd
22950         cmd="exec $fd<&-"
22951         trap "eval $cmd" EXIT
22952         cd $tdir || error "cd $tdir fails"
22953         rmdir  ../$tdir || error "rmdir $tdir fails"
22954         mkdir local_dir && error "create dir succeeds"
22955         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22956         eval $cmd
22957         return 0
22958 }
22959 run_test 300q "create remote directory under orphan directory"
22960
22961 test_300r() {
22962         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22963                 skip "Need MDS version at least 2.7.55" && return
22964         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22965
22966         mkdir $DIR/$tdir
22967
22968         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22969                 error "set striped dir error"
22970
22971         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22972                 error "getstripeddir fails"
22973
22974         local stripe_count
22975         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22976                       awk '/lmv_stripe_count:/ { print $2 }')
22977
22978         [ $MDSCOUNT -ne $stripe_count ] &&
22979                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22980
22981         rm -rf $DIR/$tdir/striped_dir ||
22982                 error "unlink striped dir fails"
22983 }
22984 run_test 300r "test -1 striped directory"
22985
22986 test_300s_helper() {
22987         local count=$1
22988
22989         local stripe_dir=$DIR/$tdir/striped_dir.$count
22990
22991         $LFS mkdir -c $count $stripe_dir ||
22992                 error "lfs mkdir -c error"
22993
22994         $LFS getdirstripe $stripe_dir ||
22995                 error "lfs getdirstripe fails"
22996
22997         local stripe_count
22998         stripe_count=$($LFS getdirstripe $stripe_dir |
22999                       awk '/lmv_stripe_count:/ { print $2 }')
23000
23001         [ $count -ne $stripe_count ] &&
23002                 error_noexit "bad stripe count $stripe_count expected $count"
23003
23004         local dupe_stripes
23005         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23006                 awk '/0x/ {count[$1] += 1}; END {
23007                         for (idx in count) {
23008                                 if (count[idx]>1) {
23009                                         print "index " idx " count " count[idx]
23010                                 }
23011                         }
23012                 }')
23013
23014         if [[ -n "$dupe_stripes" ]] ; then
23015                 lfs getdirstripe $stripe_dir
23016                 error_noexit "Dupe MDT above: $dupe_stripes "
23017         fi
23018
23019         rm -rf $stripe_dir ||
23020                 error_noexit "unlink $stripe_dir fails"
23021 }
23022
23023 test_300s() {
23024         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23025                 skip "Need MDS version at least 2.7.55" && return
23026         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23027
23028         mkdir $DIR/$tdir
23029         for count in $(seq 2 $MDSCOUNT); do
23030                 test_300s_helper $count
23031         done
23032 }
23033 run_test 300s "test lfs mkdir -c without -i"
23034
23035
23036 prepare_remote_file() {
23037         mkdir $DIR/$tdir/src_dir ||
23038                 error "create remote source failed"
23039
23040         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23041                  error "cp to remote source failed"
23042         touch $DIR/$tdir/src_dir/a
23043
23044         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23045                 error "create remote target dir failed"
23046
23047         touch $DIR/$tdir/tgt_dir/b
23048
23049         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23050                 error "rename dir cross MDT failed!"
23051
23052         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23053                 error "src_child still exists after rename"
23054
23055         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23056                 error "missing file(a) after rename"
23057
23058         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23059                 error "diff after rename"
23060 }
23061
23062 test_310a() {
23063         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23065
23066         local remote_file=$DIR/$tdir/tgt_dir/b
23067
23068         mkdir -p $DIR/$tdir
23069
23070         prepare_remote_file || error "prepare remote file failed"
23071
23072         #open-unlink file
23073         $OPENUNLINK $remote_file $remote_file ||
23074                 error "openunlink $remote_file failed"
23075         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23076 }
23077 run_test 310a "open unlink remote file"
23078
23079 test_310b() {
23080         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23082
23083         local remote_file=$DIR/$tdir/tgt_dir/b
23084
23085         mkdir -p $DIR/$tdir
23086
23087         prepare_remote_file || error "prepare remote file failed"
23088
23089         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23090         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23091         $CHECKSTAT -t file $remote_file || error "check file failed"
23092 }
23093 run_test 310b "unlink remote file with multiple links while open"
23094
23095 test_310c() {
23096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23097         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23098
23099         local remote_file=$DIR/$tdir/tgt_dir/b
23100
23101         mkdir -p $DIR/$tdir
23102
23103         prepare_remote_file || error "prepare remote file failed"
23104
23105         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23106         multiop_bg_pause $remote_file O_uc ||
23107                         error "mulitop failed for remote file"
23108         MULTIPID=$!
23109         $MULTIOP $DIR/$tfile Ouc
23110         kill -USR1 $MULTIPID
23111         wait $MULTIPID
23112 }
23113 run_test 310c "open-unlink remote file with multiple links"
23114
23115 #LU-4825
23116 test_311() {
23117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23118         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23119         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23120                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23121         remote_mds_nodsh && skip "remote MDS with nodsh"
23122
23123         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23124         local mdts=$(comma_list $(mdts_nodes))
23125
23126         mkdir -p $DIR/$tdir
23127         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23128         createmany -o $DIR/$tdir/$tfile. 1000
23129
23130         # statfs data is not real time, let's just calculate it
23131         old_iused=$((old_iused + 1000))
23132
23133         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23134                         osp.*OST0000*MDT0000.create_count")
23135         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23136                                 osp.*OST0000*MDT0000.max_create_count")
23137         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23138
23139         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23140         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23141         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23142
23143         unlinkmany $DIR/$tdir/$tfile. 1000
23144
23145         do_nodes $mdts "$LCTL set_param -n \
23146                         osp.*OST0000*.max_create_count=$max_count"
23147         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23148                 do_nodes $mdts "$LCTL set_param -n \
23149                                 osp.*OST0000*.create_count=$count"
23150         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23151                         grep "=0" && error "create_count is zero"
23152
23153         local new_iused
23154         for i in $(seq 120); do
23155                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23156                 # system may be too busy to destroy all objs in time, use
23157                 # a somewhat small value to not fail autotest
23158                 [ $((old_iused - new_iused)) -gt 400 ] && break
23159                 sleep 1
23160         done
23161
23162         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23163         [ $((old_iused - new_iused)) -gt 400 ] ||
23164                 error "objs not destroyed after unlink"
23165 }
23166 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23167
23168 zfs_oid_to_objid()
23169 {
23170         local ost=$1
23171         local objid=$2
23172
23173         local vdevdir=$(dirname $(facet_vdevice $ost))
23174         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23175         local zfs_zapid=$(do_facet $ost $cmd |
23176                           grep -w "/O/0/d$((objid%32))" -C 5 |
23177                           awk '/Object/{getline; print $1}')
23178         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23179                           awk "/$objid = /"'{printf $3}')
23180
23181         echo $zfs_objid
23182 }
23183
23184 zfs_object_blksz() {
23185         local ost=$1
23186         local objid=$2
23187
23188         local vdevdir=$(dirname $(facet_vdevice $ost))
23189         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23190         local blksz=$(do_facet $ost $cmd $objid |
23191                       awk '/dblk/{getline; printf $4}')
23192
23193         case "${blksz: -1}" in
23194                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23195                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23196                 *) ;;
23197         esac
23198
23199         echo $blksz
23200 }
23201
23202 test_312() { # LU-4856
23203         remote_ost_nodsh && skip "remote OST with nodsh"
23204         [ "$ost1_FSTYPE" = "zfs" ] ||
23205                 skip_env "the test only applies to zfs"
23206
23207         local max_blksz=$(do_facet ost1 \
23208                           $ZFS get -p recordsize $(facet_device ost1) |
23209                           awk '!/VALUE/{print $3}')
23210
23211         # to make life a little bit easier
23212         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23213         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23214
23215         local tf=$DIR/$tdir/$tfile
23216         touch $tf
23217         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23218
23219         # Get ZFS object id
23220         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23221         # block size change by sequential overwrite
23222         local bs
23223
23224         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23225                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23226
23227                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23228                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23229         done
23230         rm -f $tf
23231
23232         # block size change by sequential append write
23233         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23234         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23235         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23236         local count
23237
23238         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23239                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23240                         oflag=sync conv=notrunc
23241
23242                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23243                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23244                         error "blksz error, actual $blksz, " \
23245                                 "expected: 2 * $count * $PAGE_SIZE"
23246         done
23247         rm -f $tf
23248
23249         # random write
23250         touch $tf
23251         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23252         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23253
23254         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23255         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23256         [ $blksz -eq $PAGE_SIZE ] ||
23257                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23258
23259         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23260         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23261         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23262
23263         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23264         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23265         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23266 }
23267 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23268
23269 test_313() {
23270         remote_ost_nodsh && skip "remote OST with nodsh"
23271
23272         local file=$DIR/$tfile
23273
23274         rm -f $file
23275         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23276
23277         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23278         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23279         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23280                 error "write should failed"
23281         do_facet ost1 "$LCTL set_param fail_loc=0"
23282         rm -f $file
23283 }
23284 run_test 313 "io should fail after last_rcvd update fail"
23285
23286 test_314() {
23287         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23288
23289         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23290         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23291         rm -f $DIR/$tfile
23292         wait_delete_completed
23293         do_facet ost1 "$LCTL set_param fail_loc=0"
23294 }
23295 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23296
23297 test_315() { # LU-618
23298         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23299
23300         local file=$DIR/$tfile
23301         rm -f $file
23302
23303         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23304                 error "multiop file write failed"
23305         $MULTIOP $file oO_RDONLY:r4063232_c &
23306         PID=$!
23307
23308         sleep 2
23309
23310         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23311         kill -USR1 $PID
23312
23313         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23314         rm -f $file
23315 }
23316 run_test 315 "read should be accounted"
23317
23318 test_316() {
23319         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23320         large_xattr_enabled || skip_env "ea_inode feature disabled"
23321
23322         rm -rf $DIR/$tdir/d
23323         mkdir -p $DIR/$tdir/d
23324         chown nobody $DIR/$tdir/d
23325         touch $DIR/$tdir/d/file
23326
23327         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23328 }
23329 run_test 316 "lfs mv"
23330
23331 test_317() {
23332         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23333                 skip "Need MDS version at least 2.11.53"
23334         if [ "$ost1_FSTYPE" == "zfs" ]; then
23335                 skip "LU-10370: no implementation for ZFS"
23336         fi
23337
23338         local trunc_sz
23339         local grant_blk_size
23340
23341         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23342                         awk '/grant_block_size:/ { print $2; exit; }')
23343         #
23344         # Create File of size 5M. Truncate it to below size's and verify
23345         # blocks count.
23346         #
23347         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23348                 error "Create file $DIR/$tfile failed"
23349         stack_trap "rm -f $DIR/$tfile" EXIT
23350
23351         for trunc_sz in 2097152 4097 4000 509 0; do
23352                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23353                         error "truncate $tfile to $trunc_sz failed"
23354                 local sz=$(stat --format=%s $DIR/$tfile)
23355                 local blk=$(stat --format=%b $DIR/$tfile)
23356                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23357                                      grant_blk_size) * 8))
23358
23359                 if [[ $blk -ne $trunc_blk ]]; then
23360                         $(which stat) $DIR/$tfile
23361                         error "Expected Block $trunc_blk got $blk for $tfile"
23362                 fi
23363
23364                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23365                         error "Expected Size $trunc_sz got $sz for $tfile"
23366         done
23367
23368         #
23369         # sparse file test
23370         # Create file with a hole and write actual two blocks. Block count
23371         # must be 16.
23372         #
23373         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23374                 conv=fsync || error "Create file : $DIR/$tfile"
23375
23376         # Calculate the final truncate size.
23377         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23378
23379         #
23380         # truncate to size $trunc_sz bytes. Strip the last block
23381         # The block count must drop to 8
23382         #
23383         $TRUNCATE $DIR/$tfile $trunc_sz ||
23384                 error "truncate $tfile to $trunc_sz failed"
23385
23386         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23387         sz=$(stat --format=%s $DIR/$tfile)
23388         blk=$(stat --format=%b $DIR/$tfile)
23389
23390         if [[ $blk -ne $trunc_bsz ]]; then
23391                 $(which stat) $DIR/$tfile
23392                 error "Expected Block $trunc_bsz got $blk for $tfile"
23393         fi
23394
23395         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23396                 error "Expected Size $trunc_sz got $sz for $tfile"
23397 }
23398 run_test 317 "Verify blocks get correctly update after truncate"
23399
23400 test_318() {
23401         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23402         local old_max_active=$($LCTL get_param -n \
23403                             ${llite_name}.max_read_ahead_async_active \
23404                             2>/dev/null)
23405
23406         $LCTL set_param llite.*.max_read_ahead_async_active=256
23407         local max_active=$($LCTL get_param -n \
23408                            ${llite_name}.max_read_ahead_async_active \
23409                            2>/dev/null)
23410         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23411
23412         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23413                 error "set max_read_ahead_async_active should succeed"
23414
23415         $LCTL set_param llite.*.max_read_ahead_async_active=512
23416         max_active=$($LCTL get_param -n \
23417                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23418         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23419
23420         # restore @max_active
23421         [ $old_max_active -ne 0 ] && $LCTL set_param \
23422                 llite.*.max_read_ahead_async_active=$old_max_active
23423
23424         local old_threshold=$($LCTL get_param -n \
23425                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23426         local max_per_file_mb=$($LCTL get_param -n \
23427                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23428
23429         local invalid=$(($max_per_file_mb + 1))
23430         $LCTL set_param \
23431                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23432                         && error "set $invalid should fail"
23433
23434         local valid=$(($invalid - 1))
23435         $LCTL set_param \
23436                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23437                         error "set $valid should succeed"
23438         local threshold=$($LCTL get_param -n \
23439                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23440         [ $threshold -eq $valid ] || error \
23441                 "expect threshold $valid got $threshold"
23442         $LCTL set_param \
23443                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23444 }
23445 run_test 318 "Verify async readahead tunables"
23446
23447 test_319() {
23448         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23449
23450         local before=$(date +%s)
23451         local evict
23452         local mdir=$DIR/$tdir
23453         local file=$mdir/xxx
23454
23455         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23456         touch $file
23457
23458 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23459         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23460         $LFS mv -m1 $file &
23461
23462         sleep 1
23463         dd if=$file of=/dev/null
23464         wait
23465         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23466           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23467
23468         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23469 }
23470 run_test 319 "lost lease lock on migrate error"
23471
23472 test_398a() { # LU-4198
23473         local ost1_imp=$(get_osc_import_name client ost1)
23474         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23475                          cut -d'.' -f2)
23476
23477         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23478         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23479
23480         # request a new lock on client
23481         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23482
23483         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23484         local lock_count=$($LCTL get_param -n \
23485                            ldlm.namespaces.$imp_name.lru_size)
23486         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23487
23488         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23489
23490         # no lock cached, should use lockless IO and not enqueue new lock
23491         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23492         lock_count=$($LCTL get_param -n \
23493                      ldlm.namespaces.$imp_name.lru_size)
23494         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23495 }
23496 run_test 398a "direct IO should cancel lock otherwise lockless"
23497
23498 test_398b() { # LU-4198
23499         which fio || skip_env "no fio installed"
23500         $LFS setstripe -c -1 $DIR/$tfile
23501
23502         local size=12
23503         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23504
23505         local njobs=4
23506         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23507         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23508                 --numjobs=$njobs --fallocate=none \
23509                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23510                 --filename=$DIR/$tfile &
23511         bg_pid=$!
23512
23513         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23514         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23515                 --numjobs=$njobs --fallocate=none \
23516                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23517                 --filename=$DIR/$tfile || true
23518         wait $bg_pid
23519
23520         rm -f $DIR/$tfile
23521 }
23522 run_test 398b "DIO and buffer IO race"
23523
23524 test_398c() { # LU-4198
23525         local ost1_imp=$(get_osc_import_name client ost1)
23526         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23527                          cut -d'.' -f2)
23528
23529         which fio || skip_env "no fio installed"
23530
23531         saved_debug=$($LCTL get_param -n debug)
23532         $LCTL set_param debug=0
23533
23534         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23535         ((size /= 1024)) # by megabytes
23536         ((size /= 2)) # write half of the OST at most
23537         [ $size -gt 40 ] && size=40 #reduce test time anyway
23538
23539         $LFS setstripe -c 1 $DIR/$tfile
23540
23541         # it seems like ldiskfs reserves more space than necessary if the
23542         # writing blocks are not mapped, so it extends the file firstly
23543         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23544         cancel_lru_locks osc
23545
23546         # clear and verify rpc_stats later
23547         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23548
23549         local njobs=4
23550         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23551         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23552                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23553                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23554                 --filename=$DIR/$tfile
23555         [ $? -eq 0 ] || error "fio write error"
23556
23557         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23558                 error "Locks were requested while doing AIO"
23559
23560         # get the percentage of 1-page I/O
23561         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23562                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23563                 awk '{print $7}')
23564         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23565
23566         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23567         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23568                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23569                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23570                 --filename=$DIR/$tfile
23571         [ $? -eq 0 ] || error "fio mixed read write error"
23572
23573         echo "AIO with large block size ${size}M"
23574         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23575                 --numjobs=1 --fallocate=none --ioengine=libaio \
23576                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23577                 --filename=$DIR/$tfile
23578         [ $? -eq 0 ] || error "fio large block size failed"
23579
23580         rm -f $DIR/$tfile
23581         $LCTL set_param debug="$saved_debug"
23582 }
23583 run_test 398c "run fio to test AIO"
23584
23585 test_398d() { #  LU-13846
23586         which aiocp || skip_env "no aiocp installed"
23587         local aio_file=$DIR/$tfile.aio
23588
23589         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23590
23591         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23592         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23593         stack_trap "rm -f $DIR/$tfile $aio_file"
23594
23595         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23596
23597         # make sure we don't crash and fail properly
23598         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23599                 error "aio not aligned with PAGE SIZE should fail"
23600
23601         rm -f $DIR/$tfile $aio_file
23602 }
23603 run_test 398d "run aiocp to verify block size > stripe size"
23604
23605 test_398e() {
23606         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23607         touch $DIR/$tfile.new
23608         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23609 }
23610 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23611
23612 test_398f() { #  LU-14687
23613         which aiocp || skip_env "no aiocp installed"
23614         local aio_file=$DIR/$tfile.aio
23615
23616         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23617
23618         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23619         stack_trap "rm -f $DIR/$tfile $aio_file"
23620
23621         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23622         $LCTL set_param fail_loc=0x1418
23623         # make sure we don't crash and fail properly
23624         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23625                 error "aio with page allocation failure succeeded"
23626         $LCTL set_param fail_loc=0
23627         diff $DIR/$tfile $aio_file
23628         [[ $? != 0 ]] || error "no diff after failed aiocp"
23629 }
23630 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23631
23632 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
23633 # stripe and i/o size must be > stripe size
23634 # Old style synchronous DIO waits after submitting each chunk, resulting in a
23635 # single RPC in flight.  This test shows async DIO submission is working by
23636 # showing multiple RPCs in flight.
23637 test_398g() { #  LU-13798
23638         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23639
23640         # We need to do some i/o first to acquire enough grant to put our RPCs
23641         # in flight; otherwise a new connection may not have enough grant
23642         # available
23643         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23644                 error "parallel dio failed"
23645         stack_trap "rm -f $DIR/$tfile"
23646
23647         # Reduce RPC size to 1M to avoid combination in to larger RPCs
23648         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23649         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23650         stack_trap "$LCTL set_param -n $pages_per_rpc"
23651
23652         # Recreate file so it's empty
23653         rm -f $DIR/$tfile
23654         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23655         #Pause rpc completion to guarantee we see multiple rpcs in flight
23656         #define OBD_FAIL_OST_BRW_PAUSE_BULK
23657         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
23658         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23659
23660         # Clear rpc stats
23661         $LCTL set_param osc.*.rpc_stats=c
23662
23663         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23664                 error "parallel dio failed"
23665         stack_trap "rm -f $DIR/$tfile"
23666
23667         $LCTL get_param osc.*-OST0000-*.rpc_stats
23668         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23669                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23670                 grep "8:" | awk '{print $8}')
23671         # We look at the "8 rpcs in flight" field, and verify A) it is present
23672         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
23673         # as expected for an 8M DIO to a file with 1M stripes.
23674         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
23675
23676         # Verify turning off parallel dio works as expected
23677         # Clear rpc stats
23678         $LCTL set_param osc.*.rpc_stats=c
23679         $LCTL set_param llite.*.parallel_dio=0
23680         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
23681
23682         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23683                 error "dio with parallel dio disabled failed"
23684
23685         # Ideally, we would see only one RPC in flight here, but there is an
23686         # unavoidable race between i/o completion and RPC in flight counting,
23687         # so while only 1 i/o is in flight at a time, the RPC in flight counter
23688         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
23689         # So instead we just verify it's always < 8.
23690         $LCTL get_param osc.*-OST0000-*.rpc_stats
23691         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23692                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23693                 grep '^$' -B1 | grep . | awk '{print $1}')
23694         [ $ret != "8:" ] ||
23695                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
23696 }
23697 run_test 398g "verify parallel dio async RPC submission"
23698
23699 test_398h() { #  LU-13798
23700         local dio_file=$DIR/$tfile.dio
23701
23702         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23703
23704         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23705         stack_trap "rm -f $DIR/$tfile $dio_file"
23706
23707         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
23708                 error "parallel dio failed"
23709         diff $DIR/$tfile $dio_file
23710         [[ $? == 0 ]] || error "file diff after aiocp"
23711 }
23712 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
23713
23714 test_398i() { #  LU-13798
23715         local dio_file=$DIR/$tfile.dio
23716
23717         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23718
23719         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23720         stack_trap "rm -f $DIR/$tfile $dio_file"
23721
23722         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23723         $LCTL set_param fail_loc=0x1418
23724         # make sure we don't crash and fail properly
23725         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
23726                 error "parallel dio page allocation failure succeeded"
23727         diff $DIR/$tfile $dio_file
23728         [[ $? != 0 ]] || error "no diff after failed aiocp"
23729 }
23730 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
23731
23732 test_398j() { #  LU-13798
23733         # Stripe size > RPC size but less than i/o size tests split across
23734         # stripes and RPCs for individual i/o op
23735         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
23736
23737         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
23738         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23739         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23740         stack_trap "$LCTL set_param -n $pages_per_rpc"
23741
23742         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23743                 error "parallel dio write failed"
23744         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
23745
23746         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
23747                 error "parallel dio read failed"
23748         diff $DIR/$tfile $DIR/$tfile.2
23749         [[ $? == 0 ]] || error "file diff after parallel dio read"
23750 }
23751 run_test 398j "test parallel dio where stripe size > rpc_size"
23752
23753 test_398k() { #  LU-13798
23754         wait_delete_completed
23755         wait_mds_ost_sync
23756
23757         # 4 stripe file; we will cause out of space on OST0
23758         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23759
23760         # Fill OST0 (if it's not too large)
23761         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23762                    head -n1)
23763         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23764                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23765         fi
23766         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23767         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23768                 error "dd should fill OST0"
23769         stack_trap "rm -f $DIR/$tfile.1"
23770
23771         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23772         err=$?
23773
23774         ls -la $DIR/$tfile
23775         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
23776                 error "file is not 0 bytes in size"
23777
23778         # dd above should not succeed, but don't error until here so we can
23779         # get debug info above
23780         [[ $err != 0 ]] ||
23781                 error "parallel dio write with enospc succeeded"
23782         stack_trap "rm -f $DIR/$tfile"
23783 }
23784 run_test 398k "test enospc on first stripe"
23785
23786 test_398l() { #  LU-13798
23787         wait_delete_completed
23788         wait_mds_ost_sync
23789
23790         # 4 stripe file; we will cause out of space on OST0
23791         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
23792         # happens on the second i/o chunk we issue
23793         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
23794
23795         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
23796         stack_trap "rm -f $DIR/$tfile"
23797
23798         # Fill OST0 (if it's not too large)
23799         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23800                    head -n1)
23801         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23802                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23803         fi
23804         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23805         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23806                 error "dd should fill OST0"
23807         stack_trap "rm -f $DIR/$tfile.1"
23808
23809         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
23810         err=$?
23811         stack_trap "rm -f $DIR/$tfile.2"
23812
23813         # Check that short write completed as expected
23814         ls -la $DIR/$tfile.2
23815         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
23816                 error "file is not 1M in size"
23817
23818         # dd above should not succeed, but don't error until here so we can
23819         # get debug info above
23820         [[ $err != 0 ]] ||
23821                 error "parallel dio write with enospc succeeded"
23822
23823         # Truncate source file to same length as output file and diff them
23824         $TRUNCATE $DIR/$tfile 1048576
23825         diff $DIR/$tfile $DIR/$tfile.2
23826         [[ $? == 0 ]] || error "data incorrect after short write"
23827 }
23828 run_test 398l "test enospc on intermediate stripe/RPC"
23829
23830 test_398m() { #  LU-13798
23831         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23832
23833         lctl set_param *debug=-1 debug_mb=10000
23834
23835         # Set up failure on OST0, the first stripe:
23836         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
23837         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
23838         # So this fail_val specifies OST0
23839         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
23840         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23841
23842         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
23843                 error "parallel dio write with failure on first stripe succeeded"
23844         stack_trap "rm -f $DIR/$tfile"
23845         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23846
23847         # Place data in file for read
23848         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23849                 error "parallel dio write failed"
23850
23851         # Fail read on OST0, first stripe
23852         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
23853         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
23854         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
23855                 error "parallel dio read with error on first stripe succeeded"
23856         rm -f $DIR/$tfile.2
23857         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23858
23859         # Switch to testing on OST1, second stripe
23860         # Clear file contents, maintain striping
23861         echo > $DIR/$tfile
23862         # Set up failure on OST1, second stripe:
23863         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
23864         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23865
23866         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
23867                 error "parallel dio write with failure on first stripe succeeded"
23868         stack_trap "rm -f $DIR/$tfile"
23869         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23870
23871         # Place data in file for read
23872         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23873                 error "parallel dio write failed"
23874
23875         # Fail read on OST1, second stripe
23876         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
23877         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
23878         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
23879                 error "parallel dio read with error on first stripe succeeded"
23880         rm -f $DIR/$tfile.2
23881         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
23882 }
23883 run_test 398m "test RPC failures with parallel dio"
23884
23885 # Parallel submission of DIO should not cause problems for append, but it's
23886 # important to verify.
23887 test_398n() { #  LU-13798
23888         $LFS setstripe -C 2 -S 1M $DIR/$tfile
23889
23890         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
23891                 error "dd to create source file failed"
23892         stack_trap "rm -f $DIR/$tfile"
23893
23894         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
23895                 error "parallel dio write with failure on second stripe succeeded"
23896         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
23897         diff $DIR/$tfile $DIR/$tfile.1
23898         [[ $? == 0 ]] || error "data incorrect after append"
23899
23900 }
23901 run_test 398n "test append with parallel DIO"
23902
23903 test_fake_rw() {
23904         local read_write=$1
23905         if [ "$read_write" = "write" ]; then
23906                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23907         elif [ "$read_write" = "read" ]; then
23908                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23909         else
23910                 error "argument error"
23911         fi
23912
23913         # turn off debug for performance testing
23914         local saved_debug=$($LCTL get_param -n debug)
23915         $LCTL set_param debug=0
23916
23917         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23918
23919         # get ost1 size - $FSNAME-OST0000
23920         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23921         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23922         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23923
23924         if [ "$read_write" = "read" ]; then
23925                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23926         fi
23927
23928         local start_time=$(date +%s.%N)
23929         $dd_cmd bs=1M count=$blocks oflag=sync ||
23930                 error "real dd $read_write error"
23931         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23932
23933         if [ "$read_write" = "write" ]; then
23934                 rm -f $DIR/$tfile
23935         fi
23936
23937         # define OBD_FAIL_OST_FAKE_RW           0x238
23938         do_facet ost1 $LCTL set_param fail_loc=0x238
23939
23940         local start_time=$(date +%s.%N)
23941         $dd_cmd bs=1M count=$blocks oflag=sync ||
23942                 error "fake dd $read_write error"
23943         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23944
23945         if [ "$read_write" = "write" ]; then
23946                 # verify file size
23947                 cancel_lru_locks osc
23948                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23949                         error "$tfile size not $blocks MB"
23950         fi
23951         do_facet ost1 $LCTL set_param fail_loc=0
23952
23953         echo "fake $read_write $duration_fake vs. normal $read_write" \
23954                 "$duration in seconds"
23955         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23956                 error_not_in_vm "fake write is slower"
23957
23958         $LCTL set_param -n debug="$saved_debug"
23959         rm -f $DIR/$tfile
23960 }
23961 test_399a() { # LU-7655 for OST fake write
23962         remote_ost_nodsh && skip "remote OST with nodsh"
23963
23964         test_fake_rw write
23965 }
23966 run_test 399a "fake write should not be slower than normal write"
23967
23968 test_399b() { # LU-8726 for OST fake read
23969         remote_ost_nodsh && skip "remote OST with nodsh"
23970         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23971                 skip_env "ldiskfs only test"
23972         fi
23973
23974         test_fake_rw read
23975 }
23976 run_test 399b "fake read should not be slower than normal read"
23977
23978 test_400a() { # LU-1606, was conf-sanity test_74
23979         if ! which $CC > /dev/null 2>&1; then
23980                 skip_env "$CC is not installed"
23981         fi
23982
23983         local extra_flags=''
23984         local out=$TMP/$tfile
23985         local prefix=/usr/include/lustre
23986         local prog
23987
23988         # Oleg removes c files in his test rig so test if any c files exist
23989         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23990                 skip_env "Needed c test files are missing"
23991
23992         if ! [[ -d $prefix ]]; then
23993                 # Assume we're running in tree and fixup the include path.
23994                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23995                 extra_flags+=" -L$LUSTRE/utils/.lib"
23996         fi
23997
23998         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23999                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24000                         error "client api broken"
24001         done
24002         rm -f $out
24003 }
24004 run_test 400a "Lustre client api program can compile and link"
24005
24006 test_400b() { # LU-1606, LU-5011
24007         local header
24008         local out=$TMP/$tfile
24009         local prefix=/usr/include/linux/lustre
24010
24011         # We use a hard coded prefix so that this test will not fail
24012         # when run in tree. There are headers in lustre/include/lustre/
24013         # that are not packaged (like lustre_idl.h) and have more
24014         # complicated include dependencies (like config.h and lnet/types.h).
24015         # Since this test about correct packaging we just skip them when
24016         # they don't exist (see below) rather than try to fixup cppflags.
24017
24018         if ! which $CC > /dev/null 2>&1; then
24019                 skip_env "$CC is not installed"
24020         fi
24021
24022         for header in $prefix/*.h; do
24023                 if ! [[ -f "$header" ]]; then
24024                         continue
24025                 fi
24026
24027                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24028                         continue # lustre_ioctl.h is internal header
24029                 fi
24030
24031                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24032                         error "cannot compile '$header'"
24033         done
24034         rm -f $out
24035 }
24036 run_test 400b "packaged headers can be compiled"
24037
24038 test_401a() { #LU-7437
24039         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24040         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24041
24042         #count the number of parameters by "list_param -R"
24043         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24044         #count the number of parameters by listing proc files
24045         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
24046         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24047         echo "proc_dirs='$proc_dirs'"
24048         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24049         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24050                       sort -u | wc -l)
24051
24052         [ $params -eq $procs ] ||
24053                 error "found $params parameters vs. $procs proc files"
24054
24055         # test the list_param -D option only returns directories
24056         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24057         #count the number of parameters by listing proc directories
24058         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24059                 sort -u | wc -l)
24060
24061         [ $params -eq $procs ] ||
24062                 error "found $params parameters vs. $procs proc files"
24063 }
24064 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24065
24066 test_401b() {
24067         # jobid_var may not allow arbitrary values, so use jobid_name
24068         # if available
24069         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24070                 local testname=jobid_name tmp='testing%p'
24071         else
24072                 local testname=jobid_var tmp=testing
24073         fi
24074
24075         local save=$($LCTL get_param -n $testname)
24076
24077         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24078                 error "no error returned when setting bad parameters"
24079
24080         local jobid_new=$($LCTL get_param -n foe $testname baz)
24081         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24082
24083         $LCTL set_param -n fog=bam $testname=$save bat=fog
24084         local jobid_old=$($LCTL get_param -n foe $testname bag)
24085         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24086 }
24087 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24088
24089 test_401c() {
24090         # jobid_var may not allow arbitrary values, so use jobid_name
24091         # if available
24092         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24093                 local testname=jobid_name
24094         else
24095                 local testname=jobid_var
24096         fi
24097
24098         local jobid_var_old=$($LCTL get_param -n $testname)
24099         local jobid_var_new
24100
24101         $LCTL set_param $testname= &&
24102                 error "no error returned for 'set_param a='"
24103
24104         jobid_var_new=$($LCTL get_param -n $testname)
24105         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24106                 error "$testname was changed by setting without value"
24107
24108         $LCTL set_param $testname &&
24109                 error "no error returned for 'set_param a'"
24110
24111         jobid_var_new=$($LCTL get_param -n $testname)
24112         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24113                 error "$testname was changed by setting without value"
24114 }
24115 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24116
24117 test_401d() {
24118         # jobid_var may not allow arbitrary values, so use jobid_name
24119         # if available
24120         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24121                 local testname=jobid_name new_value='foo=bar%p'
24122         else
24123                 local testname=jobid_var new_valuie=foo=bar
24124         fi
24125
24126         local jobid_var_old=$($LCTL get_param -n $testname)
24127         local jobid_var_new
24128
24129         $LCTL set_param $testname=$new_value ||
24130                 error "'set_param a=b' did not accept a value containing '='"
24131
24132         jobid_var_new=$($LCTL get_param -n $testname)
24133         [[ "$jobid_var_new" == "$new_value" ]] ||
24134                 error "'set_param a=b' failed on a value containing '='"
24135
24136         # Reset the $testname to test the other format
24137         $LCTL set_param $testname=$jobid_var_old
24138         jobid_var_new=$($LCTL get_param -n $testname)
24139         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24140                 error "failed to reset $testname"
24141
24142         $LCTL set_param $testname $new_value ||
24143                 error "'set_param a b' did not accept a value containing '='"
24144
24145         jobid_var_new=$($LCTL get_param -n $testname)
24146         [[ "$jobid_var_new" == "$new_value" ]] ||
24147                 error "'set_param a b' failed on a value containing '='"
24148
24149         $LCTL set_param $testname $jobid_var_old
24150         jobid_var_new=$($LCTL get_param -n $testname)
24151         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24152                 error "failed to reset $testname"
24153 }
24154 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24155
24156 test_402() {
24157         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24158         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24159                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24160         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24161                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24162                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24163         remote_mds_nodsh && skip "remote MDS with nodsh"
24164
24165         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24166 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24167         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24168         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24169                 echo "Touch failed - OK"
24170 }
24171 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24172
24173 test_403() {
24174         local file1=$DIR/$tfile.1
24175         local file2=$DIR/$tfile.2
24176         local tfile=$TMP/$tfile
24177
24178         rm -f $file1 $file2 $tfile
24179
24180         touch $file1
24181         ln $file1 $file2
24182
24183         # 30 sec OBD_TIMEOUT in ll_getattr()
24184         # right before populating st_nlink
24185         $LCTL set_param fail_loc=0x80001409
24186         stat -c %h $file1 > $tfile &
24187
24188         # create an alias, drop all locks and reclaim the dentry
24189         < $file2
24190         cancel_lru_locks mdc
24191         cancel_lru_locks osc
24192         sysctl -w vm.drop_caches=2
24193
24194         wait
24195
24196         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24197
24198         rm -f $tfile $file1 $file2
24199 }
24200 run_test 403 "i_nlink should not drop to zero due to aliasing"
24201
24202 test_404() { # LU-6601
24203         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24204                 skip "Need server version newer than 2.8.52"
24205         remote_mds_nodsh && skip "remote MDS with nodsh"
24206
24207         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24208                 awk '/osp .*-osc-MDT/ { print $4}')
24209
24210         local osp
24211         for osp in $mosps; do
24212                 echo "Deactivate: " $osp
24213                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24214                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24215                         awk -vp=$osp '$4 == p { print $2 }')
24216                 [ $stat = IN ] || {
24217                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24218                         error "deactivate error"
24219                 }
24220                 echo "Activate: " $osp
24221                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24222                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24223                         awk -vp=$osp '$4 == p { print $2 }')
24224                 [ $stat = UP ] || {
24225                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24226                         error "activate error"
24227                 }
24228         done
24229 }
24230 run_test 404 "validate manual {de}activated works properly for OSPs"
24231
24232 test_405() {
24233         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24234         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24235                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24236                         skip "Layout swap lock is not supported"
24237
24238         check_swap_layouts_support
24239         check_swap_layout_no_dom $DIR
24240
24241         test_mkdir $DIR/$tdir
24242         swap_lock_test -d $DIR/$tdir ||
24243                 error "One layout swap locked test failed"
24244 }
24245 run_test 405 "Various layout swap lock tests"
24246
24247 test_406() {
24248         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24249         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24250         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24252         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24253                 skip "Need MDS version at least 2.8.50"
24254
24255         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24256         local test_pool=$TESTNAME
24257
24258         pool_add $test_pool || error "pool_add failed"
24259         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24260                 error "pool_add_targets failed"
24261
24262         save_layout_restore_at_exit $MOUNT
24263
24264         # parent set default stripe count only, child will stripe from both
24265         # parent and fs default
24266         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24267                 error "setstripe $MOUNT failed"
24268         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24269         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24270         for i in $(seq 10); do
24271                 local f=$DIR/$tdir/$tfile.$i
24272                 touch $f || error "touch failed"
24273                 local count=$($LFS getstripe -c $f)
24274                 [ $count -eq $OSTCOUNT ] ||
24275                         error "$f stripe count $count != $OSTCOUNT"
24276                 local offset=$($LFS getstripe -i $f)
24277                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24278                 local size=$($LFS getstripe -S $f)
24279                 [ $size -eq $((def_stripe_size * 2)) ] ||
24280                         error "$f stripe size $size != $((def_stripe_size * 2))"
24281                 local pool=$($LFS getstripe -p $f)
24282                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24283         done
24284
24285         # change fs default striping, delete parent default striping, now child
24286         # will stripe from new fs default striping only
24287         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24288                 error "change $MOUNT default stripe failed"
24289         $LFS setstripe -c 0 $DIR/$tdir ||
24290                 error "delete $tdir default stripe failed"
24291         for i in $(seq 11 20); do
24292                 local f=$DIR/$tdir/$tfile.$i
24293                 touch $f || error "touch $f failed"
24294                 local count=$($LFS getstripe -c $f)
24295                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24296                 local offset=$($LFS getstripe -i $f)
24297                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24298                 local size=$($LFS getstripe -S $f)
24299                 [ $size -eq $def_stripe_size ] ||
24300                         error "$f stripe size $size != $def_stripe_size"
24301                 local pool=$($LFS getstripe -p $f)
24302                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24303         done
24304
24305         unlinkmany $DIR/$tdir/$tfile. 1 20
24306
24307         local f=$DIR/$tdir/$tfile
24308         pool_remove_all_targets $test_pool $f
24309         pool_remove $test_pool $f
24310 }
24311 run_test 406 "DNE support fs default striping"
24312
24313 test_407() {
24314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24315         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24316                 skip "Need MDS version at least 2.8.55"
24317         remote_mds_nodsh && skip "remote MDS with nodsh"
24318
24319         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24320                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24321         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24322                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24323         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24324
24325         #define OBD_FAIL_DT_TXN_STOP    0x2019
24326         for idx in $(seq $MDSCOUNT); do
24327                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24328         done
24329         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24330         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24331                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24332         true
24333 }
24334 run_test 407 "transaction fail should cause operation fail"
24335
24336 test_408() {
24337         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24338
24339         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24340         lctl set_param fail_loc=0x8000040a
24341         # let ll_prepare_partial_page() fail
24342         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24343
24344         rm -f $DIR/$tfile
24345
24346         # create at least 100 unused inodes so that
24347         # shrink_icache_memory(0) should not return 0
24348         touch $DIR/$tfile-{0..100}
24349         rm -f $DIR/$tfile-{0..100}
24350         sync
24351
24352         echo 2 > /proc/sys/vm/drop_caches
24353 }
24354 run_test 408 "drop_caches should not hang due to page leaks"
24355
24356 test_409()
24357 {
24358         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24359
24360         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24361         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24362         touch $DIR/$tdir/guard || error "(2) Fail to create"
24363
24364         local PREFIX=$(str_repeat 'A' 128)
24365         echo "Create 1K hard links start at $(date)"
24366         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24367                 error "(3) Fail to hard link"
24368
24369         echo "Links count should be right although linkEA overflow"
24370         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24371         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24372         [ $linkcount -eq 1001 ] ||
24373                 error "(5) Unexpected hard links count: $linkcount"
24374
24375         echo "List all links start at $(date)"
24376         ls -l $DIR/$tdir/foo > /dev/null ||
24377                 error "(6) Fail to list $DIR/$tdir/foo"
24378
24379         echo "Unlink hard links start at $(date)"
24380         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24381                 error "(7) Fail to unlink"
24382         echo "Unlink hard links finished at $(date)"
24383 }
24384 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24385
24386 test_410()
24387 {
24388         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24389                 skip "Need client version at least 2.9.59"
24390         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24391                 skip "Need MODULES build"
24392
24393         # Create a file, and stat it from the kernel
24394         local testfile=$DIR/$tfile
24395         touch $testfile
24396
24397         local run_id=$RANDOM
24398         local my_ino=$(stat --format "%i" $testfile)
24399
24400         # Try to insert the module. This will always fail as the
24401         # module is designed to not be inserted.
24402         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24403             &> /dev/null
24404
24405         # Anything but success is a test failure
24406         dmesg | grep -q \
24407             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24408             error "no inode match"
24409 }
24410 run_test 410 "Test inode number returned from kernel thread"
24411
24412 cleanup_test411_cgroup() {
24413         trap 0
24414         rmdir "$1"
24415 }
24416
24417 test_411() {
24418         local cg_basedir=/sys/fs/cgroup/memory
24419         # LU-9966
24420         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24421                 skip "no setup for cgroup"
24422
24423         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24424                 error "test file creation failed"
24425         cancel_lru_locks osc
24426
24427         # Create a very small memory cgroup to force a slab allocation error
24428         local cgdir=$cg_basedir/osc_slab_alloc
24429         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24430         trap "cleanup_test411_cgroup $cgdir" EXIT
24431         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24432         echo 1M > $cgdir/memory.limit_in_bytes
24433
24434         # Should not LBUG, just be killed by oom-killer
24435         # dd will return 0 even allocation failure in some environment.
24436         # So don't check return value
24437         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24438         cleanup_test411_cgroup $cgdir
24439
24440         return 0
24441 }
24442 run_test 411 "Slab allocation error with cgroup does not LBUG"
24443
24444 test_412() {
24445         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24446         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24447                 skip "Need server version at least 2.10.55"
24448         fi
24449
24450         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24451                 error "mkdir failed"
24452         $LFS getdirstripe $DIR/$tdir
24453         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24454         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24455                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24456         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24457         [ $stripe_count -eq 2 ] ||
24458                 error "expect 2 get $stripe_count"
24459 }
24460 run_test 412 "mkdir on specific MDTs"
24461
24462 test_qos_mkdir() {
24463         local mkdir_cmd=$1
24464         local stripe_count=$2
24465         local mdts=$(comma_list $(mdts_nodes))
24466
24467         local testdir
24468         local lmv_qos_prio_free
24469         local lmv_qos_threshold_rr
24470         local lmv_qos_maxage
24471         local lod_qos_prio_free
24472         local lod_qos_threshold_rr
24473         local lod_qos_maxage
24474         local count
24475         local i
24476
24477         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24478         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24479         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24480                 head -n1)
24481         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24482         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24483         stack_trap "$LCTL set_param \
24484                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
24485         stack_trap "$LCTL set_param \
24486                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
24487         stack_trap "$LCTL set_param \
24488                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
24489
24490         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24491                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24492         lod_qos_prio_free=${lod_qos_prio_free%%%}
24493         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24494                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24495         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24496         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24497                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24498         stack_trap "do_nodes $mdts $LCTL set_param \
24499                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
24500         stack_trap "do_nodes $mdts $LCTL set_param \
24501                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
24502                 EXIT
24503         stack_trap "do_nodes $mdts $LCTL set_param \
24504                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
24505
24506         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24507         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24508
24509         testdir=$DIR/$tdir-s$stripe_count/rr
24510
24511         local stripe_index=$($LFS getstripe -m $testdir)
24512         local test_mkdir_rr=true
24513
24514         getfattr -d -m dmv $testdir | grep dmv
24515         if [ $? -eq 0 ] && [ $MDS1_VERSION -ge $(version_code 2.14.51) ]; then
24516                 local inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
24517
24518                 (( $inherit_rr == 0 )) && test_mkdir_rr=false
24519         fi
24520
24521         echo
24522         $test_mkdir_rr &&
24523                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24524                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24525
24526         for i in $(seq $((100 * MDSCOUNT))); do
24527                 eval $mkdir_cmd $testdir/subdir$i ||
24528                         error "$mkdir_cmd subdir$i failed"
24529         done
24530
24531         for i in $(seq $MDSCOUNT); do
24532                 count=$($LFS getdirstripe -i $testdir/* |
24533                                 grep ^$((i - 1))$ | wc -l)
24534                 echo "$count directories created on MDT$((i - 1))"
24535                 if $test_mkdir_rr; then
24536                         (( $count == 100 )) ||
24537                                 error "subdirs are not evenly distributed"
24538                 elif [ $((i - 1)) -eq $stripe_index ]; then
24539                         (( $count == 100 * MDSCOUNT )) ||
24540                                 error "$count subdirs created on MDT$((i - 1))"
24541                 else
24542                         (( $count == 0 )) ||
24543                                 error "$count subdirs created on MDT$((i - 1))"
24544                 fi
24545
24546                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24547                         count=$($LFS getdirstripe $testdir/* |
24548                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24549                         echo "$count stripes created on MDT$((i - 1))"
24550                         # deviation should < 5% of average
24551                         (( $count < 95 * stripe_count )) ||
24552                         (( $count > 105 * stripe_count)) &&
24553                                 error "stripes are not evenly distributed"
24554                 fi
24555         done
24556
24557         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
24558         do_nodes $mdts $LCTL set_param \
24559                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
24560
24561         echo
24562         echo "Check for uneven MDTs: "
24563
24564         local ffree
24565         local bavail
24566         local max
24567         local min
24568         local max_index
24569         local min_index
24570         local tmp
24571
24572         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24573         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24574         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24575
24576         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24577         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24578         max_index=0
24579         min_index=0
24580         for ((i = 1; i < ${#ffree[@]}; i++)); do
24581                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24582                 if [ $tmp -gt $max ]; then
24583                         max=$tmp
24584                         max_index=$i
24585                 fi
24586                 if [ $tmp -lt $min ]; then
24587                         min=$tmp
24588                         min_index=$i
24589                 fi
24590         done
24591
24592         (( ${ffree[min_index]} == 0 )) &&
24593                 skip "no free files in MDT$min_index"
24594         (( ${ffree[min_index]} > 100000000 )) &&
24595                 skip "too many free files in MDT$min_index"
24596
24597         # Check if we need to generate uneven MDTs
24598         local threshold=50
24599         local diff=$(((max - min) * 100 / min))
24600         local value="$(generate_string 1024)"
24601
24602         while [ $diff -lt $threshold ]; do
24603                 # generate uneven MDTs, create till $threshold% diff
24604                 echo -n "weight diff=$diff% must be > $threshold% ..."
24605                 count=$((${ffree[min_index]} / 10))
24606                 # 50 sec per 10000 files in vm
24607                 (( $count < 100000 )) || [ "$SLOW" != "no" ] ||
24608                         skip "$count files to create"
24609                 echo "Fill MDT$min_index with $count files"
24610                 [ -d $DIR/$tdir-MDT$min_index ] ||
24611                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
24612                         error "mkdir $tdir-MDT$min_index failed"
24613                 createmany -d $DIR/$tdir-MDT$min_index/d $count ||
24614                         error "create d$count failed"
24615
24616                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24617                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24618                 max=$(((${ffree[max_index]} >> 8) * \
24619                         (${bavail[max_index]} * bsize >> 16)))
24620                 min=$(((${ffree[min_index]} >> 8) * \
24621                         (${bavail[min_index]} * bsize >> 16)))
24622                 diff=$(((max - min) * 100 / min))
24623         done
24624
24625         echo "MDT filesfree available: ${ffree[@]}"
24626         echo "MDT blocks available: ${bavail[@]}"
24627         echo "weight diff=$diff%"
24628
24629         echo
24630         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24631
24632         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24633         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24634         # decrease statfs age, so that it can be updated in time
24635         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24636         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24637
24638         sleep 1
24639
24640         testdir=$DIR/$tdir-s$stripe_count/qos
24641
24642         for i in $(seq $((100 * MDSCOUNT))); do
24643                 eval $mkdir_cmd $testdir/subdir$i ||
24644                         error "$mkdir_cmd subdir$i failed"
24645         done
24646
24647         for i in $(seq $MDSCOUNT); do
24648                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
24649                         wc -l)
24650                 echo "$count directories created on MDT$((i - 1))"
24651
24652                 if [ $stripe_count -gt 1 ]; then
24653                         count=$($LFS getdirstripe $testdir/* |
24654                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24655                         echo "$count stripes created on MDT$((i - 1))"
24656                 fi
24657         done
24658
24659         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
24660         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
24661
24662         # D-value should > 10% of averge
24663         (( $max - $min < 10 )) &&
24664                 error "subdirs shouldn't be evenly distributed"
24665
24666         # ditto
24667         if [ $stripe_count -gt 1 ]; then
24668                 max=$($LFS getdirstripe $testdir/* |
24669                         grep -P "^\s+$max_index\t" | wc -l)
24670                 min=$($LFS getdirstripe $testdir/* |
24671                         grep -P "^\s+$min_index\t" | wc -l)
24672                 (( $max - $min < 10 * $stripe_count )) &&
24673                         error "stripes shouldn't be evenly distributed"|| true
24674         fi
24675 }
24676
24677 test_413a() {
24678         [ $MDSCOUNT -lt 2 ] &&
24679                 skip "We need at least 2 MDTs for this test"
24680
24681         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24682                 skip "Need server version at least 2.12.52"
24683
24684         local stripe_count
24685
24686         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24687                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24688                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24689                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
24690                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
24691         done
24692 }
24693 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24694
24695 test_413b() {
24696         [ $MDSCOUNT -lt 2 ] &&
24697                 skip "We need at least 2 MDTs for this test"
24698
24699         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24700                 skip "Need server version at least 2.12.52"
24701
24702         local testdir
24703         local stripe_count
24704
24705         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24706                 testdir=$DIR/$tdir-s$stripe_count
24707                 mkdir $testdir || error "mkdir $testdir failed"
24708                 mkdir $testdir/rr || error "mkdir rr failed"
24709                 mkdir $testdir/qos || error "mkdir qos failed"
24710                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24711                         $testdir/rr || error "setdirstripe rr failed"
24712                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24713                         error "setdirstripe failed"
24714                 test_qos_mkdir "mkdir" $stripe_count
24715         done
24716 }
24717 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24718
24719 test_413c() {
24720         [ $MDSCOUNT -ge 2 ] ||
24721                 skip "We need at least 2 MDTs for this test"
24722
24723         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] ||
24724                 skip "Need server version at least 2.14.50"
24725
24726         local testdir
24727         local inherit
24728         local inherit_rr
24729
24730         testdir=$DIR/${tdir}-s1
24731         mkdir $testdir || error "mkdir $testdir failed"
24732         mkdir $testdir/rr || error "mkdir rr failed"
24733         mkdir $testdir/qos || error "mkdir qos failed"
24734         # default max_inherit is -1, default max_inherit_rr is 0
24735         $LFS setdirstripe -D -c 1 $testdir/rr ||
24736                 error "setdirstripe rr failed"
24737         $LFS setdirstripe -D -c 1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24738                 error "setdirstripe qos failed"
24739         test_qos_mkdir "mkdir" 1
24740
24741         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24742         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24743         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24744         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24745         (( $inherit_rr == 0 )) ||
24746                 error "rr/level1 inherit-rr $inherit_rr != 0"
24747
24748         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24749         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24750         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24751         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24752         (( $inherit_rr == 0 )) ||
24753                 error "qos/level1 inherit-rr $inherit_rr !=0"
24754         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24755         getfattr -d -m dmv $testdir/qos/level1/level2 | grep dmv &&
24756                 error "level2 shouldn't have default LMV" || true
24757 }
24758 run_test 413c "mkdir with default LMV max inherit rr"
24759
24760 test_414() {
24761 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24762         $LCTL set_param fail_loc=0x80000521
24763         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24764         rm -f $DIR/$tfile
24765 }
24766 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24767
24768 test_415() {
24769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24770         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24771                 skip "Need server version at least 2.11.52"
24772
24773         # LU-11102
24774         local total
24775         local setattr_pid
24776         local start_time
24777         local end_time
24778         local duration
24779
24780         total=500
24781         # this test may be slow on ZFS
24782         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24783
24784         # though this test is designed for striped directory, let's test normal
24785         # directory too since lock is always saved as CoS lock.
24786         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24787         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24788
24789         (
24790                 while true; do
24791                         touch $DIR/$tdir
24792                 done
24793         ) &
24794         setattr_pid=$!
24795
24796         start_time=$(date +%s)
24797         for i in $(seq $total); do
24798                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24799                         > /dev/null
24800         done
24801         end_time=$(date +%s)
24802         duration=$((end_time - start_time))
24803
24804         kill -9 $setattr_pid
24805
24806         echo "rename $total files took $duration sec"
24807         [ $duration -lt 100 ] || error "rename took $duration sec"
24808 }
24809 run_test 415 "lock revoke is not missing"
24810
24811 test_416() {
24812         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24813                 skip "Need server version at least 2.11.55"
24814
24815         # define OBD_FAIL_OSD_TXN_START    0x19a
24816         do_facet mds1 lctl set_param fail_loc=0x19a
24817
24818         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24819
24820         true
24821 }
24822 run_test 416 "transaction start failure won't cause system hung"
24823
24824 cleanup_417() {
24825         trap 0
24826         do_nodes $(comma_list $(mdts_nodes)) \
24827                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24828         do_nodes $(comma_list $(mdts_nodes)) \
24829                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24830         do_nodes $(comma_list $(mdts_nodes)) \
24831                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24832 }
24833
24834 test_417() {
24835         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24836         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24837                 skip "Need MDS version at least 2.11.56"
24838
24839         trap cleanup_417 RETURN EXIT
24840
24841         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24842         do_nodes $(comma_list $(mdts_nodes)) \
24843                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24844         $LFS migrate -m 0 $DIR/$tdir.1 &&
24845                 error "migrate dir $tdir.1 should fail"
24846
24847         do_nodes $(comma_list $(mdts_nodes)) \
24848                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24849         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24850                 error "create remote dir $tdir.2 should fail"
24851
24852         do_nodes $(comma_list $(mdts_nodes)) \
24853                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24854         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24855                 error "create striped dir $tdir.3 should fail"
24856         true
24857 }
24858 run_test 417 "disable remote dir, striped dir and dir migration"
24859
24860 # Checks that the outputs of df [-i] and lfs df [-i] match
24861 #
24862 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24863 check_lfs_df() {
24864         local dir=$2
24865         local inodes
24866         local df_out
24867         local lfs_df_out
24868         local count
24869         local passed=false
24870
24871         # blocks or inodes
24872         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24873
24874         for count in {1..100}; do
24875                 cancel_lru_locks
24876                 sync; sleep 0.2
24877
24878                 # read the lines of interest
24879                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24880                         error "df $inodes $dir | tail -n +2 failed"
24881                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24882                         error "lfs df $inodes $dir | grep summary: failed"
24883
24884                 # skip first substrings of each output as they are different
24885                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24886                 # compare the two outputs
24887                 passed=true
24888                 for i in {1..5}; do
24889                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24890                 done
24891                 $passed && break
24892         done
24893
24894         if ! $passed; then
24895                 df -P $inodes $dir
24896                 echo
24897                 lfs df $inodes $dir
24898                 error "df and lfs df $1 output mismatch: "      \
24899                       "df ${inodes}: ${df_out[*]}, "            \
24900                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24901         fi
24902 }
24903
24904 test_418() {
24905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24906
24907         local dir=$DIR/$tdir
24908         local numfiles=$((RANDOM % 4096 + 2))
24909         local numblocks=$((RANDOM % 256 + 1))
24910
24911         wait_delete_completed
24912         test_mkdir $dir
24913
24914         # check block output
24915         check_lfs_df blocks $dir
24916         # check inode output
24917         check_lfs_df inodes $dir
24918
24919         # create a single file and retest
24920         echo "Creating a single file and testing"
24921         createmany -o $dir/$tfile- 1 &>/dev/null ||
24922                 error "creating 1 file in $dir failed"
24923         check_lfs_df blocks $dir
24924         check_lfs_df inodes $dir
24925
24926         # create a random number of files
24927         echo "Creating $((numfiles - 1)) files and testing"
24928         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24929                 error "creating $((numfiles - 1)) files in $dir failed"
24930
24931         # write a random number of blocks to the first test file
24932         echo "Writing $numblocks 4K blocks and testing"
24933         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24934                 count=$numblocks &>/dev/null ||
24935                 error "dd to $dir/${tfile}-0 failed"
24936
24937         # retest
24938         check_lfs_df blocks $dir
24939         check_lfs_df inodes $dir
24940
24941         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24942                 error "unlinking $numfiles files in $dir failed"
24943 }
24944 run_test 418 "df and lfs df outputs match"
24945
24946 test_419()
24947 {
24948         local dir=$DIR/$tdir
24949
24950         mkdir -p $dir
24951         touch $dir/file
24952
24953         cancel_lru_locks mdc
24954
24955         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24956         $LCTL set_param fail_loc=0x1410
24957         cat $dir/file
24958         $LCTL set_param fail_loc=0
24959         rm -rf $dir
24960 }
24961 run_test 419 "Verify open file by name doesn't crash kernel"
24962
24963 test_420()
24964 {
24965         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24966                 skip "Need MDS version at least 2.12.53"
24967
24968         local SAVE_UMASK=$(umask)
24969         local dir=$DIR/$tdir
24970         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24971
24972         mkdir -p $dir
24973         umask 0000
24974         mkdir -m03777 $dir/testdir
24975         ls -dn $dir/testdir
24976         # Need to remove trailing '.' when SELinux is enabled
24977         local dirperms=$(ls -dn $dir/testdir |
24978                          awk '{ sub(/\.$/, "", $1); print $1}')
24979         [ $dirperms == "drwxrwsrwt" ] ||
24980                 error "incorrect perms on $dir/testdir"
24981
24982         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24983                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24984         ls -n $dir/testdir/testfile
24985         local fileperms=$(ls -n $dir/testdir/testfile |
24986                           awk '{ sub(/\.$/, "", $1); print $1}')
24987         [ $fileperms == "-rwxr-xr-x" ] ||
24988                 error "incorrect perms on $dir/testdir/testfile"
24989
24990         umask $SAVE_UMASK
24991 }
24992 run_test 420 "clear SGID bit on non-directories for non-members"
24993
24994 test_421a() {
24995         local cnt
24996         local fid1
24997         local fid2
24998
24999         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25000                 skip "Need MDS version at least 2.12.54"
25001
25002         test_mkdir $DIR/$tdir
25003         createmany -o $DIR/$tdir/f 3
25004         cnt=$(ls -1 $DIR/$tdir | wc -l)
25005         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25006
25007         fid1=$(lfs path2fid $DIR/$tdir/f1)
25008         fid2=$(lfs path2fid $DIR/$tdir/f2)
25009         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25010
25011         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25012         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25013
25014         cnt=$(ls -1 $DIR/$tdir | wc -l)
25015         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25016
25017         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25018         createmany -o $DIR/$tdir/f 3
25019         cnt=$(ls -1 $DIR/$tdir | wc -l)
25020         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25021
25022         fid1=$(lfs path2fid $DIR/$tdir/f1)
25023         fid2=$(lfs path2fid $DIR/$tdir/f2)
25024         echo "remove using fsname $FSNAME"
25025         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25026
25027         cnt=$(ls -1 $DIR/$tdir | wc -l)
25028         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25029 }
25030 run_test 421a "simple rm by fid"
25031
25032 test_421b() {
25033         local cnt
25034         local FID1
25035         local FID2
25036
25037         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25038                 skip "Need MDS version at least 2.12.54"
25039
25040         test_mkdir $DIR/$tdir
25041         createmany -o $DIR/$tdir/f 3
25042         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25043         MULTIPID=$!
25044
25045         FID1=$(lfs path2fid $DIR/$tdir/f1)
25046         FID2=$(lfs path2fid $DIR/$tdir/f2)
25047         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25048
25049         kill -USR1 $MULTIPID
25050         wait
25051
25052         cnt=$(ls $DIR/$tdir | wc -l)
25053         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25054 }
25055 run_test 421b "rm by fid on open file"
25056
25057 test_421c() {
25058         local cnt
25059         local FIDS
25060
25061         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25062                 skip "Need MDS version at least 2.12.54"
25063
25064         test_mkdir $DIR/$tdir
25065         createmany -o $DIR/$tdir/f 3
25066         touch $DIR/$tdir/$tfile
25067         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25068         cnt=$(ls -1 $DIR/$tdir | wc -l)
25069         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25070
25071         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25072         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25073
25074         cnt=$(ls $DIR/$tdir | wc -l)
25075         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25076 }
25077 run_test 421c "rm by fid against hardlinked files"
25078
25079 test_421d() {
25080         local cnt
25081         local FIDS
25082
25083         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25084                 skip "Need MDS version at least 2.12.54"
25085
25086         test_mkdir $DIR/$tdir
25087         createmany -o $DIR/$tdir/f 4097
25088         cnt=$(ls -1 $DIR/$tdir | wc -l)
25089         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25090
25091         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25092         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25093
25094         cnt=$(ls $DIR/$tdir | wc -l)
25095         rm -rf $DIR/$tdir
25096         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25097 }
25098 run_test 421d "rmfid en masse"
25099
25100 test_421e() {
25101         local cnt
25102         local FID
25103
25104         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25105         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25106                 skip "Need MDS version at least 2.12.54"
25107
25108         mkdir -p $DIR/$tdir
25109         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25110         createmany -o $DIR/$tdir/striped_dir/f 512
25111         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25112         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25113
25114         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25115                 sed "s/[/][^:]*://g")
25116         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25117
25118         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25119         rm -rf $DIR/$tdir
25120         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25121 }
25122 run_test 421e "rmfid in DNE"
25123
25124 test_421f() {
25125         local cnt
25126         local FID
25127
25128         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25129                 skip "Need MDS version at least 2.12.54"
25130
25131         test_mkdir $DIR/$tdir
25132         touch $DIR/$tdir/f
25133         cnt=$(ls -1 $DIR/$tdir | wc -l)
25134         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25135
25136         FID=$(lfs path2fid $DIR/$tdir/f)
25137         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25138         # rmfid should fail
25139         cnt=$(ls -1 $DIR/$tdir | wc -l)
25140         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25141
25142         chmod a+rw $DIR/$tdir
25143         ls -la $DIR/$tdir
25144         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25145         # rmfid should fail
25146         cnt=$(ls -1 $DIR/$tdir | wc -l)
25147         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25148
25149         rm -f $DIR/$tdir/f
25150         $RUNAS touch $DIR/$tdir/f
25151         FID=$(lfs path2fid $DIR/$tdir/f)
25152         echo "rmfid as root"
25153         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25154         cnt=$(ls -1 $DIR/$tdir | wc -l)
25155         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25156
25157         rm -f $DIR/$tdir/f
25158         $RUNAS touch $DIR/$tdir/f
25159         cnt=$(ls -1 $DIR/$tdir | wc -l)
25160         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25161         FID=$(lfs path2fid $DIR/$tdir/f)
25162         # rmfid w/o user_fid2path mount option should fail
25163         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25164         cnt=$(ls -1 $DIR/$tdir | wc -l)
25165         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25166
25167         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25168         stack_trap "rmdir $tmpdir"
25169         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25170                 error "failed to mount client'"
25171         stack_trap "umount_client $tmpdir"
25172
25173         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25174         # rmfid should succeed
25175         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25176         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25177
25178         # rmfid shouldn't allow to remove files due to dir's permission
25179         chmod a+rwx $tmpdir/$tdir
25180         touch $tmpdir/$tdir/f
25181         ls -la $tmpdir/$tdir
25182         FID=$(lfs path2fid $tmpdir/$tdir/f)
25183         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25184         return 0
25185 }
25186 run_test 421f "rmfid checks permissions"
25187
25188 test_421g() {
25189         local cnt
25190         local FIDS
25191
25192         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25193         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25194                 skip "Need MDS version at least 2.12.54"
25195
25196         mkdir -p $DIR/$tdir
25197         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25198         createmany -o $DIR/$tdir/striped_dir/f 512
25199         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25200         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25201
25202         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25203                 sed "s/[/][^:]*://g")
25204
25205         rm -f $DIR/$tdir/striped_dir/f1*
25206         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25207         removed=$((512 - cnt))
25208
25209         # few files have been just removed, so we expect
25210         # rmfid to fail on their fids
25211         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25212         [ $removed != $errors ] && error "$errors != $removed"
25213
25214         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25215         rm -rf $DIR/$tdir
25216         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25217 }
25218 run_test 421g "rmfid to return errors properly"
25219
25220 test_422() {
25221         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25222         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25223         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25224         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25225         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25226
25227         local amc=$(at_max_get client)
25228         local amo=$(at_max_get mds1)
25229         local timeout=`lctl get_param -n timeout`
25230
25231         at_max_set 0 client
25232         at_max_set 0 mds1
25233
25234 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25235         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25236                         fail_val=$(((2*timeout + 10)*1000))
25237         touch $DIR/$tdir/d3/file &
25238         sleep 2
25239 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25240         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25241                         fail_val=$((2*timeout + 5))
25242         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25243         local pid=$!
25244         sleep 1
25245         kill -9 $pid
25246         sleep $((2 * timeout))
25247         echo kill $pid
25248         kill -9 $pid
25249         lctl mark touch
25250         touch $DIR/$tdir/d2/file3
25251         touch $DIR/$tdir/d2/file4
25252         touch $DIR/$tdir/d2/file5
25253
25254         wait
25255         at_max_set $amc client
25256         at_max_set $amo mds1
25257
25258         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
25259         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
25260                 error "Watchdog is always throttled"
25261 }
25262 run_test 422 "kill a process with RPC in progress"
25263
25264 stat_test() {
25265     df -h $MOUNT &
25266     df -h $MOUNT &
25267     df -h $MOUNT &
25268     df -h $MOUNT &
25269     df -h $MOUNT &
25270     df -h $MOUNT &
25271 }
25272
25273 test_423() {
25274     local _stats
25275     # ensure statfs cache is expired
25276     sleep 2;
25277
25278     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
25279     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
25280
25281     return 0
25282 }
25283 run_test 423 "statfs should return a right data"
25284
25285 test_424() {
25286 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
25287         $LCTL set_param fail_loc=0x80000522
25288         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25289         rm -f $DIR/$tfile
25290 }
25291 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
25292
25293 test_425() {
25294         test_mkdir -c -1 $DIR/$tdir
25295         $LFS setstripe -c -1 $DIR/$tdir
25296
25297         lru_resize_disable "" 100
25298         stack_trap "lru_resize_enable" EXIT
25299
25300         sleep 5
25301
25302         for i in $(seq $((MDSCOUNT * 125))); do
25303                 local t=$DIR/$tdir/$tfile_$i
25304
25305                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
25306                         error_noexit "Create file $t"
25307         done
25308         stack_trap "rm -rf $DIR/$tdir" EXIT
25309
25310         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
25311                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
25312                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
25313
25314                 [ $lock_count -le $lru_size ] ||
25315                         error "osc lock count $lock_count > lru size $lru_size"
25316         done
25317
25318         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
25319                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
25320                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
25321
25322                 [ $lock_count -le $lru_size ] ||
25323                         error "mdc lock count $lock_count > lru size $lru_size"
25324         done
25325 }
25326 run_test 425 "lock count should not exceed lru size"
25327
25328 test_426() {
25329         splice-test -r $DIR/$tfile
25330         splice-test -rd $DIR/$tfile
25331         splice-test $DIR/$tfile
25332         splice-test -d $DIR/$tfile
25333 }
25334 run_test 426 "splice test on Lustre"
25335
25336 test_427() {
25337         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25338         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25339                 skip "Need MDS version at least 2.12.4"
25340         local log
25341
25342         mkdir $DIR/$tdir
25343         mkdir $DIR/$tdir/1
25344         mkdir $DIR/$tdir/2
25345         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25346         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25347
25348         $LFS getdirstripe $DIR/$tdir/1/dir
25349
25350         #first setfattr for creating updatelog
25351         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
25352
25353 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
25354         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
25355         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
25356         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
25357
25358         sleep 2
25359         fail mds2
25360         wait_recovery_complete mds2 $((2*TIMEOUT))
25361
25362         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
25363         echo $log | grep "get update log failed" &&
25364                 error "update log corruption is detected" || true
25365 }
25366 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
25367
25368 test_428() {
25369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25370         local cache_limit=$CACHE_MAX
25371
25372         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
25373         $LCTL set_param -n llite.*.max_cached_mb=64
25374
25375         mkdir $DIR/$tdir
25376         $LFS setstripe -c 1 $DIR/$tdir
25377         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
25378         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25379         #test write
25380         for f in $(seq 4); do
25381                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25382         done
25383         wait
25384
25385         cancel_lru_locks osc
25386         # Test read
25387         for f in $(seq 4); do
25388                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25389         done
25390         wait
25391 }
25392 run_test 428 "large block size IO should not hang"
25393
25394 test_429() { # LU-7915 / LU-10948
25395         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25396         local testfile=$DIR/$tfile
25397         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25398         local new_flag=1
25399         local first_rpc
25400         local second_rpc
25401         local third_rpc
25402
25403         $LCTL get_param $ll_opencache_threshold_count ||
25404                 skip "client does not have opencache parameter"
25405
25406         set_opencache $new_flag
25407         stack_trap "restore_opencache"
25408         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25409                 error "enable opencache failed"
25410         touch $testfile
25411         # drop MDC DLM locks
25412         cancel_lru_locks mdc
25413         # clear MDC RPC stats counters
25414         $LCTL set_param $mdc_rpcstats=clear
25415
25416         # According to the current implementation, we need to run 3 times
25417         # open & close file to verify if opencache is enabled correctly.
25418         # 1st, RPCs are sent for lookup/open and open handle is released on
25419         #      close finally.
25420         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25421         #      so open handle won't be released thereafter.
25422         # 3rd, No RPC is sent out.
25423         $MULTIOP $testfile oc || error "multiop failed"
25424         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25425         echo "1st: $first_rpc RPCs in flight"
25426
25427         $MULTIOP $testfile oc || error "multiop failed"
25428         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25429         echo "2nd: $second_rpc RPCs in flight"
25430
25431         $MULTIOP $testfile oc || error "multiop failed"
25432         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25433         echo "3rd: $third_rpc RPCs in flight"
25434
25435         #verify no MDC RPC is sent
25436         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25437 }
25438 run_test 429 "verify if opencache flag on client side does work"
25439
25440 lseek_test_430() {
25441         local offset
25442         local file=$1
25443
25444         # data at [200K, 400K)
25445         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25446                 error "256K->512K dd fails"
25447         # data at [2M, 3M)
25448         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25449                 error "2M->3M dd fails"
25450         # data at [4M, 5M)
25451         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25452                 error "4M->5M dd fails"
25453         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25454         # start at first component hole #1
25455         printf "Seeking hole from 1000 ... "
25456         offset=$(lseek_test -l 1000 $file)
25457         echo $offset
25458         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25459         printf "Seeking data from 1000 ... "
25460         offset=$(lseek_test -d 1000 $file)
25461         echo $offset
25462         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25463
25464         # start at first component data block
25465         printf "Seeking hole from 300000 ... "
25466         offset=$(lseek_test -l 300000 $file)
25467         echo $offset
25468         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25469         printf "Seeking data from 300000 ... "
25470         offset=$(lseek_test -d 300000 $file)
25471         echo $offset
25472         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25473
25474         # start at the first component but beyond end of object size
25475         printf "Seeking hole from 1000000 ... "
25476         offset=$(lseek_test -l 1000000 $file)
25477         echo $offset
25478         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25479         printf "Seeking data from 1000000 ... "
25480         offset=$(lseek_test -d 1000000 $file)
25481         echo $offset
25482         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25483
25484         # start at second component stripe 2 (empty file)
25485         printf "Seeking hole from 1500000 ... "
25486         offset=$(lseek_test -l 1500000 $file)
25487         echo $offset
25488         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25489         printf "Seeking data from 1500000 ... "
25490         offset=$(lseek_test -d 1500000 $file)
25491         echo $offset
25492         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25493
25494         # start at second component stripe 1 (all data)
25495         printf "Seeking hole from 3000000 ... "
25496         offset=$(lseek_test -l 3000000 $file)
25497         echo $offset
25498         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25499         printf "Seeking data from 3000000 ... "
25500         offset=$(lseek_test -d 3000000 $file)
25501         echo $offset
25502         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25503
25504         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25505                 error "2nd dd fails"
25506         echo "Add data block at 640K...1280K"
25507
25508         # start at before new data block, in hole
25509         printf "Seeking hole from 600000 ... "
25510         offset=$(lseek_test -l 600000 $file)
25511         echo $offset
25512         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25513         printf "Seeking data from 600000 ... "
25514         offset=$(lseek_test -d 600000 $file)
25515         echo $offset
25516         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25517
25518         # start at the first component new data block
25519         printf "Seeking hole from 1000000 ... "
25520         offset=$(lseek_test -l 1000000 $file)
25521         echo $offset
25522         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25523         printf "Seeking data from 1000000 ... "
25524         offset=$(lseek_test -d 1000000 $file)
25525         echo $offset
25526         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25527
25528         # start at second component stripe 2, new data
25529         printf "Seeking hole from 1200000 ... "
25530         offset=$(lseek_test -l 1200000 $file)
25531         echo $offset
25532         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25533         printf "Seeking data from 1200000 ... "
25534         offset=$(lseek_test -d 1200000 $file)
25535         echo $offset
25536         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25537
25538         # start beyond file end
25539         printf "Using offset > filesize ... "
25540         lseek_test -l 4000000 $file && error "lseek should fail"
25541         printf "Using offset > filesize ... "
25542         lseek_test -d 4000000 $file && error "lseek should fail"
25543
25544         printf "Done\n\n"
25545 }
25546
25547 test_430a() {
25548         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25549                 skip "MDT does not support SEEK_HOLE"
25550
25551         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25552                 skip "OST does not support SEEK_HOLE"
25553
25554         local file=$DIR/$tdir/$tfile
25555
25556         mkdir -p $DIR/$tdir
25557
25558         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25559         # OST stripe #1 will have continuous data at [1M, 3M)
25560         # OST stripe #2 is empty
25561         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25562         lseek_test_430 $file
25563         rm $file
25564         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25565         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25566         lseek_test_430 $file
25567         rm $file
25568         $LFS setstripe -c2 -S 512K $file
25569         echo "Two stripes, stripe size 512K"
25570         lseek_test_430 $file
25571         rm $file
25572         # FLR with stale mirror
25573         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25574                        -N -c2 -S 1M $file
25575         echo "Mirrored file:"
25576         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25577         echo "Plain 2 stripes 1M"
25578         lseek_test_430 $file
25579         rm $file
25580 }
25581 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25582
25583 test_430b() {
25584         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25585                 skip "OST does not support SEEK_HOLE"
25586
25587         local offset
25588         local file=$DIR/$tdir/$tfile
25589
25590         mkdir -p $DIR/$tdir
25591         # Empty layout lseek should fail
25592         $MCREATE $file
25593         # seek from 0
25594         printf "Seeking hole from 0 ... "
25595         lseek_test -l 0 $file && error "lseek should fail"
25596         printf "Seeking data from 0 ... "
25597         lseek_test -d 0 $file && error "lseek should fail"
25598         rm $file
25599
25600         # 1M-hole file
25601         $LFS setstripe -E 1M -c2 -E eof $file
25602         $TRUNCATE $file 1048576
25603         printf "Seeking hole from 1000000 ... "
25604         offset=$(lseek_test -l 1000000 $file)
25605         echo $offset
25606         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25607         printf "Seeking data from 1000000 ... "
25608         lseek_test -d 1000000 $file && error "lseek should fail"
25609         rm $file
25610
25611         # full component followed by non-inited one
25612         $LFS setstripe -E 1M -c2 -E eof $file
25613         dd if=/dev/urandom of=$file bs=1M count=1
25614         printf "Seeking hole from 1000000 ... "
25615         offset=$(lseek_test -l 1000000 $file)
25616         echo $offset
25617         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25618         printf "Seeking hole from 1048576 ... "
25619         lseek_test -l 1048576 $file && error "lseek should fail"
25620         # init second component and truncate back
25621         echo "123" >> $file
25622         $TRUNCATE $file 1048576
25623         printf "Seeking hole from 1000000 ... "
25624         offset=$(lseek_test -l 1000000 $file)
25625         echo $offset
25626         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25627         printf "Seeking hole from 1048576 ... "
25628         lseek_test -l 1048576 $file && error "lseek should fail"
25629         # boundary checks for big values
25630         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25631         offset=$(lseek_test -d 0 $file.10g)
25632         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25633         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25634         offset=$(lseek_test -d 0 $file.100g)
25635         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25636         return 0
25637 }
25638 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25639
25640 test_430c() {
25641         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25642                 skip "OST does not support SEEK_HOLE"
25643
25644         local file=$DIR/$tdir/$tfile
25645         local start
25646
25647         mkdir -p $DIR/$tdir
25648         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25649
25650         # cp version 8.33+ prefers lseek over fiemap
25651         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25652                 start=$SECONDS
25653                 time cp $file /dev/null
25654                 (( SECONDS - start < 5 )) ||
25655                         error "cp: too long runtime $((SECONDS - start))"
25656
25657         fi
25658         # tar version 1.29+ supports SEEK_HOLE/DATA
25659         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25660                 start=$SECONDS
25661                 time tar cS $file - | cat > /dev/null
25662                 (( SECONDS - start < 5 )) ||
25663                         error "tar: too long runtime $((SECONDS - start))"
25664         fi
25665 }
25666 run_test 430c "lseek: external tools check"
25667
25668 test_431() { # LU-14187
25669         local file=$DIR/$tdir/$tfile
25670
25671         mkdir -p $DIR/$tdir
25672         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25673         dd if=/dev/urandom of=$file bs=4k count=1
25674         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25675         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25676         #define OBD_FAIL_OST_RESTART_IO 0x251
25677         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25678         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25679         cp $file $file.0
25680         cancel_lru_locks
25681         sync_all_data
25682         echo 3 > /proc/sys/vm/drop_caches
25683         diff  $file $file.0 || error "data diff"
25684 }
25685 run_test 431 "Restart transaction for IO"
25686
25687 prep_801() {
25688         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25689         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25690                 skip "Need server version at least 2.9.55"
25691
25692         start_full_debug_logging
25693 }
25694
25695 post_801() {
25696         stop_full_debug_logging
25697 }
25698
25699 barrier_stat() {
25700         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25701                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25702                            awk '/The barrier for/ { print $7 }')
25703                 echo $st
25704         else
25705                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25706                 echo \'$st\'
25707         fi
25708 }
25709
25710 barrier_expired() {
25711         local expired
25712
25713         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25714                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25715                           awk '/will be expired/ { print $7 }')
25716         else
25717                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25718         fi
25719
25720         echo $expired
25721 }
25722
25723 test_801a() {
25724         prep_801
25725
25726         echo "Start barrier_freeze at: $(date)"
25727         #define OBD_FAIL_BARRIER_DELAY          0x2202
25728         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25729         # Do not reduce barrier time - See LU-11873
25730         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25731
25732         sleep 2
25733         local b_status=$(barrier_stat)
25734         echo "Got barrier status at: $(date)"
25735         [ "$b_status" = "'freezing_p1'" ] ||
25736                 error "(1) unexpected barrier status $b_status"
25737
25738         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25739         wait
25740         b_status=$(barrier_stat)
25741         [ "$b_status" = "'frozen'" ] ||
25742                 error "(2) unexpected barrier status $b_status"
25743
25744         local expired=$(barrier_expired)
25745         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25746         sleep $((expired + 3))
25747
25748         b_status=$(barrier_stat)
25749         [ "$b_status" = "'expired'" ] ||
25750                 error "(3) unexpected barrier status $b_status"
25751
25752         # Do not reduce barrier time - See LU-11873
25753         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25754                 error "(4) fail to freeze barrier"
25755
25756         b_status=$(barrier_stat)
25757         [ "$b_status" = "'frozen'" ] ||
25758                 error "(5) unexpected barrier status $b_status"
25759
25760         echo "Start barrier_thaw at: $(date)"
25761         #define OBD_FAIL_BARRIER_DELAY          0x2202
25762         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25763         do_facet mgs $LCTL barrier_thaw $FSNAME &
25764
25765         sleep 2
25766         b_status=$(barrier_stat)
25767         echo "Got barrier status at: $(date)"
25768         [ "$b_status" = "'thawing'" ] ||
25769                 error "(6) unexpected barrier status $b_status"
25770
25771         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25772         wait
25773         b_status=$(barrier_stat)
25774         [ "$b_status" = "'thawed'" ] ||
25775                 error "(7) unexpected barrier status $b_status"
25776
25777         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25778         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25779         do_facet mgs $LCTL barrier_freeze $FSNAME
25780
25781         b_status=$(barrier_stat)
25782         [ "$b_status" = "'failed'" ] ||
25783                 error "(8) unexpected barrier status $b_status"
25784
25785         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25786         do_facet mgs $LCTL barrier_thaw $FSNAME
25787
25788         post_801
25789 }
25790 run_test 801a "write barrier user interfaces and stat machine"
25791
25792 test_801b() {
25793         prep_801
25794
25795         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25796         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25797         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25798         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25799         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25800
25801         cancel_lru_locks mdc
25802
25803         # 180 seconds should be long enough
25804         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25805
25806         local b_status=$(barrier_stat)
25807         [ "$b_status" = "'frozen'" ] ||
25808                 error "(6) unexpected barrier status $b_status"
25809
25810         mkdir $DIR/$tdir/d0/d10 &
25811         mkdir_pid=$!
25812
25813         touch $DIR/$tdir/d1/f13 &
25814         touch_pid=$!
25815
25816         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25817         ln_pid=$!
25818
25819         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
25820         mv_pid=$!
25821
25822         rm -f $DIR/$tdir/d4/f12 &
25823         rm_pid=$!
25824
25825         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
25826
25827         # To guarantee taht the 'stat' is not blocked
25828         b_status=$(barrier_stat)
25829         [ "$b_status" = "'frozen'" ] ||
25830                 error "(8) unexpected barrier status $b_status"
25831
25832         # let above commands to run at background
25833         sleep 5
25834
25835         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
25836         ps -p $touch_pid || error "(10) touch should be blocked"
25837         ps -p $ln_pid || error "(11) link should be blocked"
25838         ps -p $mv_pid || error "(12) rename should be blocked"
25839         ps -p $rm_pid || error "(13) unlink should be blocked"
25840
25841         b_status=$(barrier_stat)
25842         [ "$b_status" = "'frozen'" ] ||
25843                 error "(14) unexpected barrier status $b_status"
25844
25845         do_facet mgs $LCTL barrier_thaw $FSNAME
25846         b_status=$(barrier_stat)
25847         [ "$b_status" = "'thawed'" ] ||
25848                 error "(15) unexpected barrier status $b_status"
25849
25850         wait $mkdir_pid || error "(16) mkdir should succeed"
25851         wait $touch_pid || error "(17) touch should succeed"
25852         wait $ln_pid || error "(18) link should succeed"
25853         wait $mv_pid || error "(19) rename should succeed"
25854         wait $rm_pid || error "(20) unlink should succeed"
25855
25856         post_801
25857 }
25858 run_test 801b "modification will be blocked by write barrier"
25859
25860 test_801c() {
25861         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25862
25863         prep_801
25864
25865         stop mds2 || error "(1) Fail to stop mds2"
25866
25867         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25868
25869         local b_status=$(barrier_stat)
25870         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25871                 do_facet mgs $LCTL barrier_thaw $FSNAME
25872                 error "(2) unexpected barrier status $b_status"
25873         }
25874
25875         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25876                 error "(3) Fail to rescan barrier bitmap"
25877
25878         # Do not reduce barrier time - See LU-11873
25879         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25880
25881         b_status=$(barrier_stat)
25882         [ "$b_status" = "'frozen'" ] ||
25883                 error "(4) unexpected barrier status $b_status"
25884
25885         do_facet mgs $LCTL barrier_thaw $FSNAME
25886         b_status=$(barrier_stat)
25887         [ "$b_status" = "'thawed'" ] ||
25888                 error "(5) unexpected barrier status $b_status"
25889
25890         local devname=$(mdsdevname 2)
25891
25892         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25893
25894         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25895                 error "(7) Fail to rescan barrier bitmap"
25896
25897         post_801
25898 }
25899 run_test 801c "rescan barrier bitmap"
25900
25901 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25902 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25903 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25904 saved_MOUNT_OPTS=$MOUNT_OPTS
25905
25906 cleanup_802a() {
25907         trap 0
25908
25909         stopall
25910         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25911         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25912         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25913         MOUNT_OPTS=$saved_MOUNT_OPTS
25914         setupall
25915 }
25916
25917 test_802a() {
25918         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25919         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25920         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25921                 skip "Need server version at least 2.9.55"
25922
25923         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25924
25925         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25926
25927         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25928                 error "(2) Fail to copy"
25929
25930         trap cleanup_802a EXIT
25931
25932         # sync by force before remount as readonly
25933         sync; sync_all_data; sleep 3; sync_all_data
25934
25935         stopall
25936
25937         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25938         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25939         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25940
25941         echo "Mount the server as read only"
25942         setupall server_only || error "(3) Fail to start servers"
25943
25944         echo "Mount client without ro should fail"
25945         mount_client $MOUNT &&
25946                 error "(4) Mount client without 'ro' should fail"
25947
25948         echo "Mount client with ro should succeed"
25949         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25950         mount_client $MOUNT ||
25951                 error "(5) Mount client with 'ro' should succeed"
25952
25953         echo "Modify should be refused"
25954         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25955
25956         echo "Read should be allowed"
25957         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25958                 error "(7) Read should succeed under ro mode"
25959
25960         cleanup_802a
25961 }
25962 run_test 802a "simulate readonly device"
25963
25964 test_802b() {
25965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25966         remote_mds_nodsh && skip "remote MDS with nodsh"
25967
25968         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25969                 skip "readonly option not available"
25970
25971         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25972
25973         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25974                 error "(2) Fail to copy"
25975
25976         # write back all cached data before setting MDT to readonly
25977         cancel_lru_locks
25978         sync_all_data
25979
25980         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25981         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25982
25983         echo "Modify should be refused"
25984         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25985
25986         echo "Read should be allowed"
25987         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25988                 error "(7) Read should succeed under ro mode"
25989
25990         # disable readonly
25991         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25992 }
25993 run_test 802b "be able to set MDTs to readonly"
25994
25995 test_803a() {
25996         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25997         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25998                 skip "MDS needs to be newer than 2.10.54"
25999
26000         mkdir_on_mdt0 $DIR/$tdir
26001         # Create some objects on all MDTs to trigger related logs objects
26002         for idx in $(seq $MDSCOUNT); do
26003                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26004                         $DIR/$tdir/dir${idx} ||
26005                         error "Fail to create $DIR/$tdir/dir${idx}"
26006         done
26007
26008         sync; sleep 3
26009         wait_delete_completed # ensure old test cleanups are finished
26010         echo "before create:"
26011         $LFS df -i $MOUNT
26012         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26013
26014         for i in {1..10}; do
26015                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26016                         error "Fail to create $DIR/$tdir/foo$i"
26017         done
26018
26019         sync; sleep 3
26020         echo "after create:"
26021         $LFS df -i $MOUNT
26022         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26023
26024         # allow for an llog to be cleaned up during the test
26025         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26026                 error "before ($before_used) + 10 > after ($after_used)"
26027
26028         for i in {1..10}; do
26029                 rm -rf $DIR/$tdir/foo$i ||
26030                         error "Fail to remove $DIR/$tdir/foo$i"
26031         done
26032
26033         sleep 3 # avoid MDT return cached statfs
26034         wait_delete_completed
26035         echo "after unlink:"
26036         $LFS df -i $MOUNT
26037         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26038
26039         # allow for an llog to be created during the test
26040         [ $after_used -le $((before_used + 1)) ] ||
26041                 error "after ($after_used) > before ($before_used) + 1"
26042 }
26043 run_test 803a "verify agent object for remote object"
26044
26045 test_803b() {
26046         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26047         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26048                 skip "MDS needs to be newer than 2.13.56"
26049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26050
26051         for i in $(seq 0 $((MDSCOUNT - 1))); do
26052                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26053         done
26054
26055         local before=0
26056         local after=0
26057
26058         local tmp
26059
26060         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26061         for i in $(seq 0 $((MDSCOUNT - 1))); do
26062                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26063                         awk '/getattr/ { print $2 }')
26064                 before=$((before + tmp))
26065         done
26066         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26067         for i in $(seq 0 $((MDSCOUNT - 1))); do
26068                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26069                         awk '/getattr/ { print $2 }')
26070                 after=$((after + tmp))
26071         done
26072
26073         [ $before -eq $after ] || error "getattr count $before != $after"
26074 }
26075 run_test 803b "remote object can getattr from cache"
26076
26077 test_804() {
26078         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26079         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26080                 skip "MDS needs to be newer than 2.10.54"
26081         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26082
26083         mkdir -p $DIR/$tdir
26084         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26085                 error "Fail to create $DIR/$tdir/dir0"
26086
26087         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26088         local dev=$(mdsdevname 2)
26089
26090         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26091                 grep ${fid} || error "NOT found agent entry for dir0"
26092
26093         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26094                 error "Fail to create $DIR/$tdir/dir1"
26095
26096         touch $DIR/$tdir/dir1/foo0 ||
26097                 error "Fail to create $DIR/$tdir/dir1/foo0"
26098         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26099         local rc=0
26100
26101         for idx in $(seq $MDSCOUNT); do
26102                 dev=$(mdsdevname $idx)
26103                 do_facet mds${idx} \
26104                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26105                         grep ${fid} && rc=$idx
26106         done
26107
26108         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26109                 error "Fail to rename foo0 to foo1"
26110         if [ $rc -eq 0 ]; then
26111                 for idx in $(seq $MDSCOUNT); do
26112                         dev=$(mdsdevname $idx)
26113                         do_facet mds${idx} \
26114                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26115                         grep ${fid} && rc=$idx
26116                 done
26117         fi
26118
26119         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26120                 error "Fail to rename foo1 to foo2"
26121         if [ $rc -eq 0 ]; then
26122                 for idx in $(seq $MDSCOUNT); do
26123                         dev=$(mdsdevname $idx)
26124                         do_facet mds${idx} \
26125                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26126                         grep ${fid} && rc=$idx
26127                 done
26128         fi
26129
26130         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26131
26132         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26133                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26134         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26135                 error "Fail to rename foo2 to foo0"
26136         unlink $DIR/$tdir/dir1/foo0 ||
26137                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26138         rm -rf $DIR/$tdir/dir0 ||
26139                 error "Fail to rm $DIR/$tdir/dir0"
26140
26141         for idx in $(seq $MDSCOUNT); do
26142                 dev=$(mdsdevname $idx)
26143                 rc=0
26144
26145                 stop mds${idx}
26146                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26147                         rc=$?
26148                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26149                         error "mount mds$idx failed"
26150                 df $MOUNT > /dev/null 2>&1
26151
26152                 # e2fsck should not return error
26153                 [ $rc -eq 0 ] ||
26154                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26155         done
26156 }
26157 run_test 804 "verify agent entry for remote entry"
26158
26159 cleanup_805() {
26160         do_facet $SINGLEMDS zfs set quota=$old $fsset
26161         unlinkmany $DIR/$tdir/f- 1000000
26162         trap 0
26163 }
26164
26165 test_805() {
26166         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26167         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26168         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26169                 skip "netfree not implemented before 0.7"
26170         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26171                 skip "Need MDS version at least 2.10.57"
26172
26173         local fsset
26174         local freekb
26175         local usedkb
26176         local old
26177         local quota
26178         local pref="osd-zfs.$FSNAME-MDT0000."
26179
26180         # limit available space on MDS dataset to meet nospace issue
26181         # quickly. then ZFS 0.7.2 can use reserved space if asked
26182         # properly (using netfree flag in osd_declare_destroy()
26183         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26184         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26185                 gawk '{print $3}')
26186         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26187         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26188         let "usedkb=usedkb-freekb"
26189         let "freekb=freekb/2"
26190         if let "freekb > 5000"; then
26191                 let "freekb=5000"
26192         fi
26193         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26194         trap cleanup_805 EXIT
26195         mkdir_on_mdt0 $DIR/$tdir
26196         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26197                 error "Can't set PFL layout"
26198         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26199         rm -rf $DIR/$tdir || error "not able to remove"
26200         do_facet $SINGLEMDS zfs set quota=$old $fsset
26201         trap 0
26202 }
26203 run_test 805 "ZFS can remove from full fs"
26204
26205 # Size-on-MDS test
26206 check_lsom_data()
26207 {
26208         local file=$1
26209         local expect=$(stat -c %s $file)
26210
26211         check_lsom_size $1 $expect
26212
26213         local blocks=$($LFS getsom -b $file)
26214         expect=$(stat -c %b $file)
26215         [[ $blocks == $expect ]] ||
26216                 error "$file expected blocks: $expect, got: $blocks"
26217 }
26218
26219 check_lsom_size()
26220 {
26221         local size
26222         local expect=$2
26223
26224         cancel_lru_locks mdc
26225
26226         size=$($LFS getsom -s $1)
26227         [[ $size == $expect ]] ||
26228                 error "$file expected size: $expect, got: $size"
26229 }
26230
26231 test_806() {
26232         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26233                 skip "Need MDS version at least 2.11.52"
26234
26235         local bs=1048576
26236
26237         touch $DIR/$tfile || error "touch $tfile failed"
26238
26239         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26240         save_lustre_params client "llite.*.xattr_cache" > $save
26241         lctl set_param llite.*.xattr_cache=0
26242         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26243
26244         # single-threaded write
26245         echo "Test SOM for single-threaded write"
26246         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
26247                 error "write $tfile failed"
26248         check_lsom_size $DIR/$tfile $bs
26249
26250         local num=32
26251         local size=$(($num * $bs))
26252         local offset=0
26253         local i
26254
26255         echo "Test SOM for single client multi-threaded($num) write"
26256         $TRUNCATE $DIR/$tfile 0
26257         for ((i = 0; i < $num; i++)); do
26258                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26259                 local pids[$i]=$!
26260                 offset=$((offset + $bs))
26261         done
26262         for (( i=0; i < $num; i++ )); do
26263                 wait ${pids[$i]}
26264         done
26265         check_lsom_size $DIR/$tfile $size
26266
26267         $TRUNCATE $DIR/$tfile 0
26268         for ((i = 0; i < $num; i++)); do
26269                 offset=$((offset - $bs))
26270                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26271                 local pids[$i]=$!
26272         done
26273         for (( i=0; i < $num; i++ )); do
26274                 wait ${pids[$i]}
26275         done
26276         check_lsom_size $DIR/$tfile $size
26277
26278         # multi-client writes
26279         num=$(get_node_count ${CLIENTS//,/ })
26280         size=$(($num * $bs))
26281         offset=0
26282         i=0
26283
26284         echo "Test SOM for multi-client ($num) writes"
26285         $TRUNCATE $DIR/$tfile 0
26286         for client in ${CLIENTS//,/ }; do
26287                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26288                 local pids[$i]=$!
26289                 i=$((i + 1))
26290                 offset=$((offset + $bs))
26291         done
26292         for (( i=0; i < $num; i++ )); do
26293                 wait ${pids[$i]}
26294         done
26295         check_lsom_size $DIR/$tfile $offset
26296
26297         i=0
26298         $TRUNCATE $DIR/$tfile 0
26299         for client in ${CLIENTS//,/ }; do
26300                 offset=$((offset - $bs))
26301                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26302                 local pids[$i]=$!
26303                 i=$((i + 1))
26304         done
26305         for (( i=0; i < $num; i++ )); do
26306                 wait ${pids[$i]}
26307         done
26308         check_lsom_size $DIR/$tfile $size
26309
26310         # verify truncate
26311         echo "Test SOM for truncate"
26312         $TRUNCATE $DIR/$tfile 1048576
26313         check_lsom_size $DIR/$tfile 1048576
26314         $TRUNCATE $DIR/$tfile 1234
26315         check_lsom_size $DIR/$tfile 1234
26316
26317         # verify SOM blocks count
26318         echo "Verify SOM block count"
26319         $TRUNCATE $DIR/$tfile 0
26320         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
26321                 error "failed to write file $tfile"
26322         check_lsom_data $DIR/$tfile
26323 }
26324 run_test 806 "Verify Lazy Size on MDS"
26325
26326 test_807() {
26327         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26328         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26329                 skip "Need MDS version at least 2.11.52"
26330
26331         # Registration step
26332         changelog_register || error "changelog_register failed"
26333         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
26334         changelog_users $SINGLEMDS | grep -q $cl_user ||
26335                 error "User $cl_user not found in changelog_users"
26336
26337         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26338         save_lustre_params client "llite.*.xattr_cache" > $save
26339         lctl set_param llite.*.xattr_cache=0
26340         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26341
26342         rm -rf $DIR/$tdir || error "rm $tdir failed"
26343         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26344         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
26345         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
26346         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
26347                 error "truncate $tdir/trunc failed"
26348
26349         local bs=1048576
26350         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
26351                 error "write $tfile failed"
26352
26353         # multi-client wirtes
26354         local num=$(get_node_count ${CLIENTS//,/ })
26355         local offset=0
26356         local i=0
26357
26358         echo "Test SOM for multi-client ($num) writes"
26359         touch $DIR/$tfile || error "touch $tfile failed"
26360         $TRUNCATE $DIR/$tfile 0
26361         for client in ${CLIENTS//,/ }; do
26362                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26363                 local pids[$i]=$!
26364                 i=$((i + 1))
26365                 offset=$((offset + $bs))
26366         done
26367         for (( i=0; i < $num; i++ )); do
26368                 wait ${pids[$i]}
26369         done
26370
26371         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
26372         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
26373         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
26374         check_lsom_data $DIR/$tdir/trunc
26375         check_lsom_data $DIR/$tdir/single_dd
26376         check_lsom_data $DIR/$tfile
26377
26378         rm -rf $DIR/$tdir
26379         # Deregistration step
26380         changelog_deregister || error "changelog_deregister failed"
26381 }
26382 run_test 807 "verify LSOM syncing tool"
26383
26384 check_som_nologged()
26385 {
26386         local lines=$($LFS changelog $FSNAME-MDT0000 |
26387                 grep 'x=trusted.som' | wc -l)
26388         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26389 }
26390
26391 test_808() {
26392         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26393                 skip "Need MDS version at least 2.11.55"
26394
26395         # Registration step
26396         changelog_register || error "changelog_register failed"
26397
26398         touch $DIR/$tfile || error "touch $tfile failed"
26399         check_som_nologged
26400
26401         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26402                 error "write $tfile failed"
26403         check_som_nologged
26404
26405         $TRUNCATE $DIR/$tfile 1234
26406         check_som_nologged
26407
26408         $TRUNCATE $DIR/$tfile 1048576
26409         check_som_nologged
26410
26411         # Deregistration step
26412         changelog_deregister || error "changelog_deregister failed"
26413 }
26414 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26415
26416 check_som_nodata()
26417 {
26418         $LFS getsom $1
26419         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26420 }
26421
26422 test_809() {
26423         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26424                 skip "Need MDS version at least 2.11.56"
26425
26426         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26427                 error "failed to create DoM-only file $DIR/$tfile"
26428         touch $DIR/$tfile || error "touch $tfile failed"
26429         check_som_nodata $DIR/$tfile
26430
26431         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26432                 error "write $tfile failed"
26433         check_som_nodata $DIR/$tfile
26434
26435         $TRUNCATE $DIR/$tfile 1234
26436         check_som_nodata $DIR/$tfile
26437
26438         $TRUNCATE $DIR/$tfile 4097
26439         check_som_nodata $DIR/$file
26440 }
26441 run_test 809 "Verify no SOM xattr store for DoM-only files"
26442
26443 test_810() {
26444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26445         $GSS && skip_env "could not run with gss"
26446         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26447                 skip "OST < 2.12.58 doesn't align checksum"
26448
26449         set_checksums 1
26450         stack_trap "set_checksums $ORIG_CSUM" EXIT
26451         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26452
26453         local csum
26454         local before
26455         local after
26456         for csum in $CKSUM_TYPES; do
26457                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26458                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26459                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26460                         eval set -- $i
26461                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26462                         before=$(md5sum $DIR/$tfile)
26463                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26464                         after=$(md5sum $DIR/$tfile)
26465                         [ "$before" == "$after" ] ||
26466                                 error "$csum: $before != $after bs=$1 seek=$2"
26467                 done
26468         done
26469 }
26470 run_test 810 "partial page writes on ZFS (LU-11663)"
26471
26472 test_812a() {
26473         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26474                 skip "OST < 2.12.51 doesn't support this fail_loc"
26475
26476         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26477         # ensure ost1 is connected
26478         stat $DIR/$tfile >/dev/null || error "can't stat"
26479         wait_osc_import_state client ost1 FULL
26480         # no locks, no reqs to let the connection idle
26481         cancel_lru_locks osc
26482
26483         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26484 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26485         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26486         wait_osc_import_state client ost1 CONNECTING
26487         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26488
26489         stat $DIR/$tfile >/dev/null || error "can't stat file"
26490 }
26491 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26492
26493 test_812b() { # LU-12378
26494         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26495                 skip "OST < 2.12.51 doesn't support this fail_loc"
26496
26497         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26498         # ensure ost1 is connected
26499         stat $DIR/$tfile >/dev/null || error "can't stat"
26500         wait_osc_import_state client ost1 FULL
26501         # no locks, no reqs to let the connection idle
26502         cancel_lru_locks osc
26503
26504         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26505 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26506         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26507         wait_osc_import_state client ost1 CONNECTING
26508         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26509
26510         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26511         wait_osc_import_state client ost1 IDLE
26512 }
26513 run_test 812b "do not drop no resend request for idle connect"
26514
26515 test_812c() {
26516         local old
26517
26518         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26519
26520         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26521         $LFS getstripe $DIR/$tfile
26522         $LCTL set_param osc.*.idle_timeout=10
26523         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26524         # ensure ost1 is connected
26525         stat $DIR/$tfile >/dev/null || error "can't stat"
26526         wait_osc_import_state client ost1 FULL
26527         # no locks, no reqs to let the connection idle
26528         cancel_lru_locks osc
26529
26530 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26531         $LCTL set_param fail_loc=0x80000533
26532         sleep 15
26533         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26534 }
26535 run_test 812c "idle import vs lock enqueue race"
26536
26537 test_813() {
26538         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26539         [ -z "$file_heat_sav" ] && skip "no file heat support"
26540
26541         local readsample
26542         local writesample
26543         local readbyte
26544         local writebyte
26545         local readsample1
26546         local writesample1
26547         local readbyte1
26548         local writebyte1
26549
26550         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26551         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26552
26553         $LCTL set_param -n llite.*.file_heat=1
26554         echo "Turn on file heat"
26555         echo "Period second: $period_second, Decay percentage: $decay_pct"
26556
26557         echo "QQQQ" > $DIR/$tfile
26558         echo "QQQQ" > $DIR/$tfile
26559         echo "QQQQ" > $DIR/$tfile
26560         cat $DIR/$tfile > /dev/null
26561         cat $DIR/$tfile > /dev/null
26562         cat $DIR/$tfile > /dev/null
26563         cat $DIR/$tfile > /dev/null
26564
26565         local out=$($LFS heat_get $DIR/$tfile)
26566
26567         $LFS heat_get $DIR/$tfile
26568         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26569         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26570         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26571         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26572
26573         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26574         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26575         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26576         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26577
26578         sleep $((period_second + 3))
26579         echo "Sleep $((period_second + 3)) seconds..."
26580         # The recursion formula to calculate the heat of the file f is as
26581         # follow:
26582         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26583         # Where Hi is the heat value in the period between time points i*I and
26584         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26585         # to the weight of Ci.
26586         out=$($LFS heat_get $DIR/$tfile)
26587         $LFS heat_get $DIR/$tfile
26588         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26589         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26590         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26591         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26592
26593         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26594                 error "read sample ($readsample) is wrong"
26595         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26596                 error "write sample ($writesample) is wrong"
26597         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26598                 error "read bytes ($readbyte) is wrong"
26599         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26600                 error "write bytes ($writebyte) is wrong"
26601
26602         echo "QQQQ" > $DIR/$tfile
26603         echo "QQQQ" > $DIR/$tfile
26604         echo "QQQQ" > $DIR/$tfile
26605         cat $DIR/$tfile > /dev/null
26606         cat $DIR/$tfile > /dev/null
26607         cat $DIR/$tfile > /dev/null
26608         cat $DIR/$tfile > /dev/null
26609
26610         sleep $((period_second + 3))
26611         echo "Sleep $((period_second + 3)) seconds..."
26612
26613         out=$($LFS heat_get $DIR/$tfile)
26614         $LFS heat_get $DIR/$tfile
26615         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26616         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26617         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26618         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26619
26620         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26621                 4 * $decay_pct) / 100") -eq 1 ] ||
26622                 error "read sample ($readsample1) is wrong"
26623         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26624                 3 * $decay_pct) / 100") -eq 1 ] ||
26625                 error "write sample ($writesample1) is wrong"
26626         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26627                 20 * $decay_pct) / 100") -eq 1 ] ||
26628                 error "read bytes ($readbyte1) is wrong"
26629         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26630                 15 * $decay_pct) / 100") -eq 1 ] ||
26631                 error "write bytes ($writebyte1) is wrong"
26632
26633         echo "Turn off file heat for the file $DIR/$tfile"
26634         $LFS heat_set -o $DIR/$tfile
26635
26636         echo "QQQQ" > $DIR/$tfile
26637         echo "QQQQ" > $DIR/$tfile
26638         echo "QQQQ" > $DIR/$tfile
26639         cat $DIR/$tfile > /dev/null
26640         cat $DIR/$tfile > /dev/null
26641         cat $DIR/$tfile > /dev/null
26642         cat $DIR/$tfile > /dev/null
26643
26644         out=$($LFS heat_get $DIR/$tfile)
26645         $LFS heat_get $DIR/$tfile
26646         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26647         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26648         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26649         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26650
26651         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26652         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26653         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26654         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26655
26656         echo "Trun on file heat for the file $DIR/$tfile"
26657         $LFS heat_set -O $DIR/$tfile
26658
26659         echo "QQQQ" > $DIR/$tfile
26660         echo "QQQQ" > $DIR/$tfile
26661         echo "QQQQ" > $DIR/$tfile
26662         cat $DIR/$tfile > /dev/null
26663         cat $DIR/$tfile > /dev/null
26664         cat $DIR/$tfile > /dev/null
26665         cat $DIR/$tfile > /dev/null
26666
26667         out=$($LFS heat_get $DIR/$tfile)
26668         $LFS heat_get $DIR/$tfile
26669         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26670         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26671         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26672         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26673
26674         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26675         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26676         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26677         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26678
26679         $LFS heat_set -c $DIR/$tfile
26680         $LCTL set_param -n llite.*.file_heat=0
26681         echo "Turn off file heat support for the Lustre filesystem"
26682
26683         echo "QQQQ" > $DIR/$tfile
26684         echo "QQQQ" > $DIR/$tfile
26685         echo "QQQQ" > $DIR/$tfile
26686         cat $DIR/$tfile > /dev/null
26687         cat $DIR/$tfile > /dev/null
26688         cat $DIR/$tfile > /dev/null
26689         cat $DIR/$tfile > /dev/null
26690
26691         out=$($LFS heat_get $DIR/$tfile)
26692         $LFS heat_get $DIR/$tfile
26693         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26694         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26695         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26696         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26697
26698         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26699         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26700         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26701         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26702
26703         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26704         rm -f $DIR/$tfile
26705 }
26706 run_test 813 "File heat verfication"
26707
26708 test_814()
26709 {
26710         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26711         echo -n y >> $DIR/$tfile
26712         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26713         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26714 }
26715 run_test 814 "sparse cp works as expected (LU-12361)"
26716
26717 test_815()
26718 {
26719         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26720         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26721 }
26722 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26723
26724 test_816() {
26725         local ost1_imp=$(get_osc_import_name client ost1)
26726         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26727                          cut -d'.' -f2)
26728
26729         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26730         # ensure ost1 is connected
26731
26732         stat $DIR/$tfile >/dev/null || error "can't stat"
26733         wait_osc_import_state client ost1 FULL
26734         # no locks, no reqs to let the connection idle
26735         cancel_lru_locks osc
26736         lru_resize_disable osc
26737         local before
26738         local now
26739         before=$($LCTL get_param -n \
26740                  ldlm.namespaces.$imp_name.lru_size)
26741
26742         wait_osc_import_state client ost1 IDLE
26743         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26744         now=$($LCTL get_param -n \
26745               ldlm.namespaces.$imp_name.lru_size)
26746         [ $before == $now ] || error "lru_size changed $before != $now"
26747 }
26748 run_test 816 "do not reset lru_resize on idle reconnect"
26749
26750 cleanup_817() {
26751         umount $tmpdir
26752         exportfs -u localhost:$DIR/nfsexp
26753         rm -rf $DIR/nfsexp
26754 }
26755
26756 test_817() {
26757         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26758
26759         mkdir -p $DIR/nfsexp
26760         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26761                 error "failed to export nfs"
26762
26763         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26764         stack_trap cleanup_817 EXIT
26765
26766         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26767                 error "failed to mount nfs to $tmpdir"
26768
26769         cp /bin/true $tmpdir
26770         $DIR/nfsexp/true || error "failed to execute 'true' command"
26771 }
26772 run_test 817 "nfsd won't cache write lock for exec file"
26773
26774 test_818() {
26775         mkdir $DIR/$tdir
26776         $LFS setstripe -c1 -i0 $DIR/$tfile
26777         $LFS setstripe -c1 -i1 $DIR/$tfile
26778         stop $SINGLEMDS
26779         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26780         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26781         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26782                 error "start $SINGLEMDS failed"
26783         rm -rf $DIR/$tdir
26784 }
26785 run_test 818 "unlink with failed llog"
26786
26787 test_819a() {
26788         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26789         cancel_lru_locks osc
26790         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26791         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26792         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26793         rm -f $TDIR/$tfile
26794 }
26795 run_test 819a "too big niobuf in read"
26796
26797 test_819b() {
26798         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26799         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26800         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26801         cancel_lru_locks osc
26802         sleep 1
26803         rm -f $TDIR/$tfile
26804 }
26805 run_test 819b "too big niobuf in write"
26806
26807
26808 function test_820_start_ost() {
26809         sleep 5
26810
26811         for num in $(seq $OSTCOUNT); do
26812                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26813         done
26814 }
26815
26816 test_820() {
26817         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26818
26819         mkdir $DIR/$tdir
26820         umount_client $MOUNT || error "umount failed"
26821         for num in $(seq $OSTCOUNT); do
26822                 stop ost$num
26823         done
26824
26825         # mount client with no active OSTs
26826         # so that the client can't initialize max LOV EA size
26827         # from OSC notifications
26828         mount_client $MOUNT || error "mount failed"
26829         # delay OST starting to keep this 0 max EA size for a while
26830         test_820_start_ost &
26831
26832         # create a directory on MDS2
26833         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
26834                 error "Failed to create directory"
26835         # open intent should update default EA size
26836         # see mdc_update_max_ea_from_body()
26837         # notice this is the very first RPC to MDS2
26838         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
26839         ret=$?
26840         echo $out
26841         # With SSK, this situation can lead to -EPERM being returned.
26842         # In that case, simply retry.
26843         if [ $ret -ne 0 ] && $SHARED_KEY; then
26844                 if echo "$out" | grep -q "not permitted"; then
26845                         cp /etc/services $DIR/$tdir/mds2
26846                         ret=$?
26847                 fi
26848         fi
26849         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
26850 }
26851 run_test 820 "update max EA from open intent"
26852
26853 test_822() {
26854         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
26855
26856         save_lustre_params mds1 \
26857                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
26858         do_facet $SINGLEMDS "$LCTL set_param -n \
26859                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
26860         do_facet $SINGLEMDS "$LCTL set_param -n \
26861                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
26862
26863         # wait for statfs update to clear OS_STATFS_NOPRECREATE
26864         local maxage=$(do_facet mds1 $LCTL get_param -n \
26865                        osp.$FSNAME-OST0000*MDT0000.maxage)
26866         sleep $((maxage + 1))
26867
26868         #define OBD_FAIL_NET_ERROR_RPC          0x532
26869         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26870
26871         stack_trap "restore_lustre_params < $p; rm $p"
26872
26873         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26874                       osp.$FSNAME-OST0000*MDT0000.create_count")
26875         for i in $(seq 1 $count); do
26876                 touch $DIR/$tfile.${i} || error "touch failed"
26877         done
26878 }
26879 run_test 822 "test precreate failure"
26880
26881 #
26882 # tests that do cleanup/setup should be run at the end
26883 #
26884
26885 test_900() {
26886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26887         local ls
26888
26889         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26890         $LCTL set_param fail_loc=0x903
26891
26892         cancel_lru_locks MGC
26893
26894         FAIL_ON_ERROR=true cleanup
26895         FAIL_ON_ERROR=true setup
26896 }
26897 run_test 900 "umount should not race with any mgc requeue thread"
26898
26899 # LUS-6253/LU-11185
26900 test_901() {
26901         local oldc
26902         local newc
26903         local olds
26904         local news
26905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26906
26907         # some get_param have a bug to handle dot in param name
26908         cancel_lru_locks MGC
26909         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26910         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26911         umount_client $MOUNT || error "umount failed"
26912         mount_client $MOUNT || error "mount failed"
26913         cancel_lru_locks MGC
26914         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26915         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26916
26917         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26918         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26919
26920         return 0
26921 }
26922 run_test 901 "don't leak a mgc lock on client umount"
26923
26924 # LU-13377
26925 test_902() {
26926         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26927                 skip "client does not have LU-13377 fix"
26928         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26929         $LCTL set_param fail_loc=0x1415
26930         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26931         cancel_lru_locks osc
26932         rm -f $DIR/$tfile
26933 }
26934 run_test 902 "test short write doesn't hang lustre"
26935
26936 complete $SECONDS
26937 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26938 check_and_cleanup_lustre
26939 if [ "$I_MOUNTED" != "yes" ]; then
26940         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26941 fi
26942 exit_status