Whamcloud - gitweb
LU-14687 llite: Return errors for aio
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5          12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 # Get the SLES distro version
96 #
97 # Returns a version string that should only be used in comparing
98 # strings returned by version_code()
99 sles_version_code()
100 {
101         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
102
103         # All SuSE Linux versions have one decimal. version_code expects two
104         local sles_version=$version.0
105         version_code $sles_version
106 }
107
108 # Check if we are running on Ubuntu or SLES so we can make decisions on
109 # what tests to run
110 if [ -r /etc/SuSE-release ]; then
111         sles_version=$(sles_version_code)
112         [ $sles_version -lt $(version_code 11.4.0) ] &&
113                 # bug number for skipped test: LU-4341
114                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
115         [ $sles_version -lt $(version_code 12.0.0) ] &&
116                 # bug number for skipped test: LU-3703
117                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
118 elif [ -r /etc/os-release ]; then
119         if grep -qi ubuntu /etc/os-release; then
120                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
121                                                 -e 's/^VERSION=//p' \
122                                                 /etc/os-release |
123                                                 awk '{ print $1 }'))
124
125                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
126                         # bug number for skipped test:
127                         #                LU-10334 LU-10366
128                         ALWAYS_EXCEPT+=" 103a     410"
129                 fi
130         fi
131 fi
132
133 build_test_filter
134 FAIL_ON_ERROR=false
135
136 cleanup() {
137         echo -n "cln.."
138         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
139         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
140 }
141 setup() {
142         echo -n "mnt.."
143         load_modules
144         setupall || exit 10
145         echo "done"
146 }
147
148 check_swap_layouts_support()
149 {
150         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
151                 skip "Does not support layout lock."
152 }
153
154 check_swap_layout_no_dom()
155 {
156         local FOLDER=$1
157         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
158         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
159 }
160
161 check_and_setup_lustre
162 DIR=${DIR:-$MOUNT}
163 assert_DIR
164
165 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
166
167 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
168 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
169 rm -rf $DIR/[Rdfs][0-9]*
170
171 # $RUNAS_ID may get set incorrectly somewhere else
172 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
173         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
174
175 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
176
177 if [ "${ONLY}" = "MOUNT" ] ; then
178         echo "Lustre is up, please go on"
179         exit
180 fi
181
182 echo "preparing for tests involving mounts"
183 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
184 touch $EXT2_DEV
185 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
186 echo # add a newline after mke2fs.
187
188 umask 077
189
190 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
191 lctl set_param debug=-1 2> /dev/null || true
192 test_0a() {
193         touch $DIR/$tfile
194         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
195         rm $DIR/$tfile
196         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
197 }
198 run_test 0a "touch; rm ====================="
199
200 test_0b() {
201         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
202         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
203 }
204 run_test 0b "chmod 0755 $DIR ============================="
205
206 test_0c() {
207         $LCTL get_param mdc.*.import | grep "state: FULL" ||
208                 error "import not FULL"
209         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
210                 error "bad target"
211 }
212 run_test 0c "check import proc"
213
214 test_0d() { # LU-3397
215         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
216                 skip "proc exports not supported before 2.10.57"
217
218         local mgs_exp="mgs.MGS.exports"
219         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
220         local exp_client_nid
221         local exp_client_version
222         local exp_val
223         local imp_val
224         local temp_imp=$DIR/$tfile.import
225         local temp_exp=$DIR/$tfile.export
226
227         # save mgc import file to $temp_imp
228         $LCTL get_param mgc.*.import | tee $temp_imp
229         # Check if client uuid is found in MGS export
230         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
231                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
232                         $client_uuid ] &&
233                         break;
234         done
235         # save mgs export file to $temp_exp
236         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
237
238         # Compare the value of field "connect_flags"
239         imp_val=$(grep "connect_flags" $temp_imp)
240         exp_val=$(grep "connect_flags" $temp_exp)
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export flags '$exp_val' != import flags '$imp_val'"
243
244         # Compare client versions.  Only compare top-3 fields for compatibility
245         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
246         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
247         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
248         [ "$exp_val" == "$imp_val" ] ||
249                 error "exp version '$exp_client_version'($exp_val) != " \
250                         "'$(lustre_build_version client)'($imp_val)"
251 }
252 run_test 0d "check export proc ============================="
253
254 test_1() {
255         test_mkdir $DIR/$tdir
256         test_mkdir $DIR/$tdir/d2
257         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
258         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
259         rmdir $DIR/$tdir/d2
260         rmdir $DIR/$tdir
261         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
262 }
263 run_test 1 "mkdir; remkdir; rmdir"
264
265 test_2() {
266         test_mkdir $DIR/$tdir
267         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
268         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
269         rm -r $DIR/$tdir
270         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
271 }
272 run_test 2 "mkdir; touch; rmdir; check file"
273
274 test_3() {
275         test_mkdir $DIR/$tdir
276         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
277         touch $DIR/$tdir/$tfile
278         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
279         rm -r $DIR/$tdir
280         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
281 }
282 run_test 3 "mkdir; touch; rmdir; check dir"
283
284 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
285 test_4() {
286         test_mkdir -i 1 $DIR/$tdir
287
288         touch $DIR/$tdir/$tfile ||
289                 error "Create file under remote directory failed"
290
291         rmdir $DIR/$tdir &&
292                 error "Expect error removing in-use dir $DIR/$tdir"
293
294         test -d $DIR/$tdir || error "Remote directory disappeared"
295
296         rm -rf $DIR/$tdir || error "remove remote dir error"
297 }
298 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
299
300 test_5() {
301         test_mkdir $DIR/$tdir
302         test_mkdir $DIR/$tdir/d2
303         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
304         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
305         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
306 }
307 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
308
309 test_6a() {
310         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
311         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
312         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
313                 error "$tfile does not have perm 0666 or UID $UID"
314         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
315         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
316                 error "$tfile should be 0666 and owned by UID $UID"
317 }
318 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
319
320 test_6c() {
321         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
322
323         touch $DIR/$tfile
324         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
325         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
326                 error "$tfile should be owned by UID $RUNAS_ID"
327         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
328         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
329                 error "$tfile should be owned by UID $RUNAS_ID"
330 }
331 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
332
333 test_6e() {
334         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
335
336         touch $DIR/$tfile
337         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
338         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
339                 error "$tfile should be owned by GID $UID"
340         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
341         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
342                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
343 }
344 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
345
346 test_6g() {
347         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
348
349         test_mkdir $DIR/$tdir
350         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
351         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
352         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
353         test_mkdir $DIR/$tdir/d/subdir
354         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
355                 error "$tdir/d/subdir should be GID $RUNAS_GID"
356         if [[ $MDSCOUNT -gt 1 ]]; then
357                 # check remote dir sgid inherite
358                 $LFS mkdir -i 0 $DIR/$tdir.local ||
359                         error "mkdir $tdir.local failed"
360                 chmod g+s $DIR/$tdir.local ||
361                         error "chmod $tdir.local failed"
362                 chgrp $RUNAS_GID $DIR/$tdir.local ||
363                         error "chgrp $tdir.local failed"
364                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
365                         error "mkdir $tdir.remote failed"
366                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
367                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
368                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
369                         error "$tdir.remote should be mode 02755"
370         fi
371 }
372 run_test 6g "verify new dir in sgid dir inherits group"
373
374 test_6h() { # bug 7331
375         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
376
377         touch $DIR/$tfile || error "touch failed"
378         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
379         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
380                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
381         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
382                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
383 }
384 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
385
386 test_7a() {
387         test_mkdir $DIR/$tdir
388         $MCREATE $DIR/$tdir/$tfile
389         chmod 0666 $DIR/$tdir/$tfile
390         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
391                 error "$tdir/$tfile should be mode 0666"
392 }
393 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
394
395 test_7b() {
396         if [ ! -d $DIR/$tdir ]; then
397                 test_mkdir $DIR/$tdir
398         fi
399         $MCREATE $DIR/$tdir/$tfile
400         echo -n foo > $DIR/$tdir/$tfile
401         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
402         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
403 }
404 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
405
406 test_8() {
407         test_mkdir $DIR/$tdir
408         touch $DIR/$tdir/$tfile
409         chmod 0666 $DIR/$tdir/$tfile
410         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
411                 error "$tfile mode not 0666"
412 }
413 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
414
415 test_9() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         test_mkdir $DIR/$tdir/d2/d3
419         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
420 }
421 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
422
423 test_10() {
424         test_mkdir $DIR/$tdir
425         test_mkdir $DIR/$tdir/d2
426         touch $DIR/$tdir/d2/$tfile
427         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
428                 error "$tdir/d2/$tfile not a file"
429 }
430 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
431
432 test_11() {
433         test_mkdir $DIR/$tdir
434         test_mkdir $DIR/$tdir/d2
435         chmod 0666 $DIR/$tdir/d2
436         chmod 0705 $DIR/$tdir/d2
437         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
438                 error "$tdir/d2 mode not 0705"
439 }
440 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
441
442 test_12() {
443         test_mkdir $DIR/$tdir
444         touch $DIR/$tdir/$tfile
445         chmod 0666 $DIR/$tdir/$tfile
446         chmod 0654 $DIR/$tdir/$tfile
447         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
448                 error "$tdir/d2 mode not 0654"
449 }
450 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
451
452 test_13() {
453         test_mkdir $DIR/$tdir
454         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
455         >  $DIR/$tdir/$tfile
456         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
457                 error "$tdir/$tfile size not 0 after truncate"
458 }
459 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
460
461 test_14() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         rm $DIR/$tdir/$tfile
465         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
466 }
467 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
468
469 test_15() {
470         test_mkdir $DIR/$tdir
471         touch $DIR/$tdir/$tfile
472         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
473         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
474                 error "$tdir/${tfile_2} not a file after rename"
475         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
476 }
477 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
478
479 test_16() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         rm -rf $DIR/$tdir/$tfile
483         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
484 }
485 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
486
487 test_17a() {
488         test_mkdir $DIR/$tdir
489         touch $DIR/$tdir/$tfile
490         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
491         ls -l $DIR/$tdir
492         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
493                 error "$tdir/l-exist not a symlink"
494         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
495                 error "$tdir/l-exist not referencing a file"
496         rm -f $DIR/$tdir/l-exist
497         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
498 }
499 run_test 17a "symlinks: create, remove (real)"
500
501 test_17b() {
502         test_mkdir $DIR/$tdir
503         ln -s no-such-file $DIR/$tdir/l-dangle
504         ls -l $DIR/$tdir
505         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
506                 error "$tdir/l-dangle not referencing no-such-file"
507         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
508                 error "$tdir/l-dangle not referencing non-existent file"
509         rm -f $DIR/$tdir/l-dangle
510         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
511 }
512 run_test 17b "symlinks: create, remove (dangling)"
513
514 test_17c() { # bug 3440 - don't save failed open RPC for replay
515         test_mkdir $DIR/$tdir
516         ln -s foo $DIR/$tdir/$tfile
517         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
518 }
519 run_test 17c "symlinks: open dangling (should return error)"
520
521 test_17d() {
522         test_mkdir $DIR/$tdir
523         ln -s foo $DIR/$tdir/$tfile
524         touch $DIR/$tdir/$tfile || error "creating to new symlink"
525 }
526 run_test 17d "symlinks: create dangling"
527
528 test_17e() {
529         test_mkdir $DIR/$tdir
530         local foo=$DIR/$tdir/$tfile
531         ln -s $foo $foo || error "create symlink failed"
532         ls -l $foo || error "ls -l failed"
533         ls $foo && error "ls not failed" || true
534 }
535 run_test 17e "symlinks: create recursive symlink (should return error)"
536
537 test_17f() {
538         test_mkdir $DIR/$tdir
539         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
540         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
541         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
542         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
543         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
544         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
545         ls -l  $DIR/$tdir
546 }
547 run_test 17f "symlinks: long and very long symlink name"
548
549 # str_repeat(S, N) generate a string that is string S repeated N times
550 str_repeat() {
551         local s=$1
552         local n=$2
553         local ret=''
554         while [ $((n -= 1)) -ge 0 ]; do
555                 ret=$ret$s
556         done
557         echo $ret
558 }
559
560 # Long symlinks and LU-2241
561 test_17g() {
562         test_mkdir $DIR/$tdir
563         local TESTS="59 60 61 4094 4095"
564
565         # Fix for inode size boundary in 2.1.4
566         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
567                 TESTS="4094 4095"
568
569         # Patch not applied to 2.2 or 2.3 branches
570         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
571         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
572                 TESTS="4094 4095"
573
574         for i in $TESTS; do
575                 local SYMNAME=$(str_repeat 'x' $i)
576                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
577                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
578         done
579 }
580 run_test 17g "symlinks: really long symlink name and inode boundaries"
581
582 test_17h() { #bug 17378
583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
584         remote_mds_nodsh && skip "remote MDS with nodsh"
585
586         local mdt_idx
587
588         test_mkdir $DIR/$tdir
589         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
590         $LFS setstripe -c -1 $DIR/$tdir
591         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
592         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
593         touch $DIR/$tdir/$tfile || true
594 }
595 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
596
597 test_17i() { #bug 20018
598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
599         remote_mds_nodsh && skip "remote MDS with nodsh"
600
601         local foo=$DIR/$tdir/$tfile
602         local mdt_idx
603
604         test_mkdir -c1 $DIR/$tdir
605         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
606         ln -s $foo $foo || error "create symlink failed"
607 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
608         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
609         ls -l $foo && error "error not detected"
610         return 0
611 }
612 run_test 17i "don't panic on short symlink (should return error)"
613
614 test_17k() { #bug 22301
615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
616         [[ -z "$(which rsync 2>/dev/null)" ]] &&
617                 skip "no rsync command"
618         rsync --help | grep -q xattr ||
619                 skip_env "$(rsync --version | head -n1) does not support xattrs"
620         test_mkdir $DIR/$tdir
621         test_mkdir $DIR/$tdir.new
622         touch $DIR/$tdir/$tfile
623         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
624         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
625                 error "rsync failed with xattrs enabled"
626 }
627 run_test 17k "symlinks: rsync with xattrs enabled"
628
629 test_17l() { # LU-279
630         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
631                 skip "no getfattr command"
632
633         test_mkdir $DIR/$tdir
634         touch $DIR/$tdir/$tfile
635         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
636         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
637                 # -h to not follow symlinks. -m '' to list all the xattrs.
638                 # grep to remove first line: '# file: $path'.
639                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
640                 do
641                         lgetxattr_size_check $path $xattr ||
642                                 error "lgetxattr_size_check $path $xattr failed"
643                 done
644         done
645 }
646 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
647
648 # LU-1540
649 test_17m() {
650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
651         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
652         remote_mds_nodsh && skip "remote MDS with nodsh"
653         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
654         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
655                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
656
657         local short_sym="0123456789"
658         local wdir=$DIR/$tdir
659         local i
660
661         test_mkdir $wdir
662         long_sym=$short_sym
663         # create a long symlink file
664         for ((i = 0; i < 4; ++i)); do
665                 long_sym=${long_sym}${long_sym}
666         done
667
668         echo "create 512 short and long symlink files under $wdir"
669         for ((i = 0; i < 256; ++i)); do
670                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
671                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
672         done
673
674         echo "erase them"
675         rm -f $wdir/*
676         sync
677         wait_delete_completed
678
679         echo "recreate the 512 symlink files with a shorter string"
680         for ((i = 0; i < 512; ++i)); do
681                 # rewrite the symlink file with a shorter string
682                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
683                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
684         done
685
686         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
687         local devname=$(mdsdevname $mds_index)
688
689         echo "stop and checking mds${mds_index}:"
690         # e2fsck should not return error
691         stop mds${mds_index}
692         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
693         rc=$?
694
695         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
696                 error "start mds${mds_index} failed"
697         df $MOUNT > /dev/null 2>&1
698         [ $rc -eq 0 ] ||
699                 error "e2fsck detected error for short/long symlink: rc=$rc"
700         rm -f $wdir/*
701 }
702 run_test 17m "run e2fsck against MDT which contains short/long symlink"
703
704 check_fs_consistency_17n() {
705         local mdt_index
706         local rc=0
707
708         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
709         # so it only check MDT1/MDT2 instead of all of MDTs.
710         for mdt_index in 1 2; do
711                 local devname=$(mdsdevname $mdt_index)
712                 # e2fsck should not return error
713                 stop mds${mdt_index}
714                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
715                         rc=$((rc + $?))
716
717                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
718                         error "mount mds$mdt_index failed"
719                 df $MOUNT > /dev/null 2>&1
720         done
721         return $rc
722 }
723
724 test_17n() {
725         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
727         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
728         remote_mds_nodsh && skip "remote MDS with nodsh"
729         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
730         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
731                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
732
733         local i
734
735         test_mkdir $DIR/$tdir
736         for ((i=0; i<10; i++)); do
737                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
738                         error "create remote dir error $i"
739                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
740                         error "create files under remote dir failed $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after create files under remote dir"
745
746         for ((i = 0; i < 10; i++)); do
747                 rm -rf $DIR/$tdir/remote_dir_${i} ||
748                         error "destroy remote dir error $i"
749         done
750
751         check_fs_consistency_17n ||
752                 error "e2fsck report error after unlink files under remote dir"
753
754         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
755                 skip "lustre < 2.4.50 does not support migrate mv"
756
757         for ((i = 0; i < 10; i++)); do
758                 mkdir -p $DIR/$tdir/remote_dir_${i}
759                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
760                         error "create files under remote dir failed $i"
761                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
762                         error "migrate remote dir error $i"
763         done
764         check_fs_consistency_17n || error "e2fsck report error after migration"
765
766         for ((i = 0; i < 10; i++)); do
767                 rm -rf $DIR/$tdir/remote_dir_${i} ||
768                         error "destroy remote dir error $i"
769         done
770
771         check_fs_consistency_17n || error "e2fsck report error after unlink"
772 }
773 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
774
775 test_17o() {
776         remote_mds_nodsh && skip "remote MDS with nodsh"
777         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
778                 skip "Need MDS version at least 2.3.64"
779
780         local wdir=$DIR/${tdir}o
781         local mdt_index
782         local rc=0
783
784         test_mkdir $wdir
785         touch $wdir/$tfile
786         mdt_index=$($LFS getstripe -m $wdir/$tfile)
787         mdt_index=$((mdt_index + 1))
788
789         cancel_lru_locks mdc
790         #fail mds will wait the failover finish then set
791         #following fail_loc to avoid interfer the recovery process.
792         fail mds${mdt_index}
793
794         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
795         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
796         ls -l $wdir/$tfile && rc=1
797         do_facet mds${mdt_index} lctl set_param fail_loc=0
798         [[ $rc -eq 0 ]] || error "stat file should fail"
799 }
800 run_test 17o "stat file with incompat LMA feature"
801
802 test_18() {
803         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
804         ls $DIR || error "Failed to ls $DIR: $?"
805 }
806 run_test 18 "touch .../f ; ls ... =============================="
807
808 test_19a() {
809         touch $DIR/$tfile
810         ls -l $DIR
811         rm $DIR/$tfile
812         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
813 }
814 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
815
816 test_19b() {
817         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
818 }
819 run_test 19b "ls -l .../f19 (should return error) =============="
820
821 test_19c() {
822         [ $RUNAS_ID -eq $UID ] &&
823                 skip_env "RUNAS_ID = UID = $UID -- skipping"
824
825         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
826 }
827 run_test 19c "$RUNAS touch .../f19 (should return error) =="
828
829 test_19d() {
830         cat $DIR/f19 && error || true
831 }
832 run_test 19d "cat .../f19 (should return error) =============="
833
834 test_20() {
835         touch $DIR/$tfile
836         rm $DIR/$tfile
837         touch $DIR/$tfile
838         rm $DIR/$tfile
839         touch $DIR/$tfile
840         rm $DIR/$tfile
841         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
842 }
843 run_test 20 "touch .../f ; ls -l ..."
844
845 test_21() {
846         test_mkdir $DIR/$tdir
847         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
848         ln -s dangle $DIR/$tdir/link
849         echo foo >> $DIR/$tdir/link
850         cat $DIR/$tdir/dangle
851         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
852         $CHECKSTAT -f -t file $DIR/$tdir/link ||
853                 error "$tdir/link not linked to a file"
854 }
855 run_test 21 "write to dangling link"
856
857 test_22() {
858         local wdir=$DIR/$tdir
859         test_mkdir $wdir
860         chown $RUNAS_ID:$RUNAS_GID $wdir
861         (cd $wdir || error "cd $wdir failed";
862                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
863                 $RUNAS tar xf -)
864         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
865         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
866         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
867                 error "checkstat -u failed"
868 }
869 run_test 22 "unpack tar archive as non-root user"
870
871 # was test_23
872 test_23a() {
873         test_mkdir $DIR/$tdir
874         local file=$DIR/$tdir/$tfile
875
876         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
877         openfile -f O_CREAT:O_EXCL $file &&
878                 error "$file recreate succeeded" || true
879 }
880 run_test 23a "O_CREAT|O_EXCL in subdir"
881
882 test_23b() { # bug 18988
883         test_mkdir $DIR/$tdir
884         local file=$DIR/$tdir/$tfile
885
886         rm -f $file
887         echo foo > $file || error "write filed"
888         echo bar >> $file || error "append filed"
889         $CHECKSTAT -s 8 $file || error "wrong size"
890         rm $file
891 }
892 run_test 23b "O_APPEND check"
893
894 # LU-9409, size with O_APPEND and tiny writes
895 test_23c() {
896         local file=$DIR/$tfile
897
898         # single dd
899         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
900         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
901         rm -f $file
902
903         # racing tiny writes
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
905         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
906         wait
907         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
908         rm -f $file
909
910         #racing tiny & normal writes
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
912         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
913         wait
914         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
915         rm -f $file
916
917         #racing tiny & normal writes 2, ugly numbers
918         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
919         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
920         wait
921         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
922         rm -f $file
923 }
924 run_test 23c "O_APPEND size checks for tiny writes"
925
926 # LU-11069 file offset is correct after appending writes
927 test_23d() {
928         local file=$DIR/$tfile
929         local offset
930
931         echo CentaurHauls > $file
932         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
933         if ((offset != 26)); then
934                 error "wrong offset, expected 26, got '$offset'"
935         fi
936 }
937 run_test 23d "file offset is correct after appending writes"
938
939 # rename sanity
940 test_24a() {
941         echo '-- same directory rename'
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.1
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
946 }
947 run_test 24a "rename file to non-existent target"
948
949 test_24b() {
950         test_mkdir $DIR/$tdir
951         touch $DIR/$tdir/$tfile.{1,2}
952         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
953         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
954         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
955 }
956 run_test 24b "rename file to existing target"
957
958 test_24c() {
959         test_mkdir $DIR/$tdir
960         test_mkdir $DIR/$tdir/d$testnum.1
961         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
962         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
963         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
964 }
965 run_test 24c "rename directory to non-existent target"
966
967 test_24d() {
968         test_mkdir -c1 $DIR/$tdir
969         test_mkdir -c1 $DIR/$tdir/d$testnum.1
970         test_mkdir -c1 $DIR/$tdir/d$testnum.2
971         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
972         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
973         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
974 }
975 run_test 24d "rename directory to existing target"
976
977 test_24e() {
978         echo '-- cross directory renames --'
979         test_mkdir $DIR/R5a
980         test_mkdir $DIR/R5b
981         touch $DIR/R5a/f
982         mv $DIR/R5a/f $DIR/R5b/g
983         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
984         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
985 }
986 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
987
988 test_24f() {
989         test_mkdir $DIR/R6a
990         test_mkdir $DIR/R6b
991         touch $DIR/R6a/f $DIR/R6b/g
992         mv $DIR/R6a/f $DIR/R6b/g
993         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
994         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
995 }
996 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
997
998 test_24g() {
999         test_mkdir $DIR/R7a
1000         test_mkdir $DIR/R7b
1001         test_mkdir $DIR/R7a/d
1002         mv $DIR/R7a/d $DIR/R7b/e
1003         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1004         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1005 }
1006 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1007
1008 test_24h() {
1009         test_mkdir -c1 $DIR/R8a
1010         test_mkdir -c1 $DIR/R8b
1011         test_mkdir -c1 $DIR/R8a/d
1012         test_mkdir -c1 $DIR/R8b/e
1013         mrename $DIR/R8a/d $DIR/R8b/e
1014         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1015         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1016 }
1017 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1018
1019 test_24i() {
1020         echo "-- rename error cases"
1021         test_mkdir $DIR/R9
1022         test_mkdir $DIR/R9/a
1023         touch $DIR/R9/f
1024         mrename $DIR/R9/f $DIR/R9/a
1025         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1026         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1027         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1028 }
1029 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1030
1031 test_24j() {
1032         test_mkdir $DIR/R10
1033         mrename $DIR/R10/f $DIR/R10/g
1034         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1035         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1036         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1037 }
1038 run_test 24j "source does not exist ============================"
1039
1040 test_24k() {
1041         test_mkdir $DIR/R11a
1042         test_mkdir $DIR/R11a/d
1043         touch $DIR/R11a/f
1044         mv $DIR/R11a/f $DIR/R11a/d
1045         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1046         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1047 }
1048 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1049
1050 # bug 2429 - rename foo foo foo creates invalid file
1051 test_24l() {
1052         f="$DIR/f24l"
1053         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1054 }
1055 run_test 24l "Renaming a file to itself ========================"
1056
1057 test_24m() {
1058         f="$DIR/f24m"
1059         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1060         # on ext3 this does not remove either the source or target files
1061         # though the "expected" operation would be to remove the source
1062         $CHECKSTAT -t file ${f} || error "${f} missing"
1063         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1064 }
1065 run_test 24m "Renaming a file to a hard link to itself ========="
1066
1067 test_24n() {
1068     f="$DIR/f24n"
1069     # this stats the old file after it was renamed, so it should fail
1070     touch ${f}
1071     $CHECKSTAT ${f} || error "${f} missing"
1072     mv ${f} ${f}.rename
1073     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1074     $CHECKSTAT -a ${f} || error "${f} exists"
1075 }
1076 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1077
1078 test_24o() {
1079         test_mkdir $DIR/$tdir
1080         rename_many -s random -v -n 10 $DIR/$tdir
1081 }
1082 run_test 24o "rename of files during htree split"
1083
1084 test_24p() {
1085         test_mkdir $DIR/R12a
1086         test_mkdir $DIR/R12b
1087         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1088         mrename $DIR/R12a $DIR/R12b
1089         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1090         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1091         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1092         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1093 }
1094 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1095
1096 cleanup_multiop_pause() {
1097         trap 0
1098         kill -USR1 $MULTIPID
1099 }
1100
1101 test_24q() {
1102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1103
1104         test_mkdir $DIR/R13a
1105         test_mkdir $DIR/R13b
1106         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1107         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1108         MULTIPID=$!
1109
1110         trap cleanup_multiop_pause EXIT
1111         mrename $DIR/R13a $DIR/R13b
1112         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1113         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1114         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1115         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1116         cleanup_multiop_pause
1117         wait $MULTIPID || error "multiop close failed"
1118 }
1119 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1120
1121 test_24r() { #bug 3789
1122         test_mkdir $DIR/R14a
1123         test_mkdir $DIR/R14a/b
1124         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1125         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1126         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1127 }
1128 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1129
1130 test_24s() {
1131         test_mkdir $DIR/R15a
1132         test_mkdir $DIR/R15a/b
1133         test_mkdir $DIR/R15a/b/c
1134         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1135         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1136         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1137 }
1138 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1139 test_24t() {
1140         test_mkdir $DIR/R16a
1141         test_mkdir $DIR/R16a/b
1142         test_mkdir $DIR/R16a/b/c
1143         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1144         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1145         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1146 }
1147 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1148
1149 test_24u() { # bug12192
1150         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1151         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1152 }
1153 run_test 24u "create stripe file"
1154
1155 simple_cleanup_common() {
1156         local rc=0
1157         trap 0
1158         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1159
1160         local start=$SECONDS
1161         rm -rf $DIR/$tdir
1162         rc=$?
1163         wait_delete_completed
1164         echo "cleanup time $((SECONDS - start))"
1165         return $rc
1166 }
1167
1168 max_pages_per_rpc() {
1169         local mdtname="$(printf "MDT%04x" ${1:-0})"
1170         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1171 }
1172
1173 test_24v() {
1174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1175
1176         local nrfiles=${COUNT:-100000}
1177         local fname="$DIR/$tdir/$tfile"
1178
1179         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1180         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1181
1182         test_mkdir "$(dirname $fname)"
1183         # assume MDT0000 has the fewest inodes
1184         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1185         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1186         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1187
1188         trap simple_cleanup_common EXIT
1189
1190         createmany -m "$fname" $nrfiles
1191
1192         cancel_lru_locks mdc
1193         lctl set_param mdc.*.stats clear
1194
1195         # was previously test_24D: LU-6101
1196         # readdir() returns correct number of entries after cursor reload
1197         local num_ls=$(ls $DIR/$tdir | wc -l)
1198         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1199         local num_all=$(ls -a $DIR/$tdir | wc -l)
1200         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1201                 [ $num_all -ne $((nrfiles + 2)) ]; then
1202                         error "Expected $nrfiles files, got $num_ls " \
1203                                 "($num_uniq unique $num_all .&..)"
1204         fi
1205         # LU-5 large readdir
1206         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1207         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1208         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1209         # take into account of overhead in lu_dirpage header and end mark in
1210         # each page, plus one in rpc_num calculation.
1211         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1212         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1213         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1214         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1215         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1216         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1217         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1218         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1219                 error "large readdir doesn't take effect: " \
1220                       "$mds_readpage should be about $rpc_max"
1221
1222         simple_cleanup_common
1223 }
1224 run_test 24v "list large directory (test hash collision, b=17560)"
1225
1226 test_24w() { # bug21506
1227         SZ1=234852
1228         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1229         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1230         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1231         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1232         [[ "$SZ1" -eq "$SZ2" ]] ||
1233                 error "Error reading at the end of the file $tfile"
1234 }
1235 run_test 24w "Reading a file larger than 4Gb"
1236
1237 test_24x() {
1238         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1240         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1241                 skip "Need MDS version at least 2.7.56"
1242
1243         local MDTIDX=1
1244         local remote_dir=$DIR/$tdir/remote_dir
1245
1246         test_mkdir $DIR/$tdir
1247         $LFS mkdir -i $MDTIDX $remote_dir ||
1248                 error "create remote directory failed"
1249
1250         test_mkdir $DIR/$tdir/src_dir
1251         touch $DIR/$tdir/src_file
1252         test_mkdir $remote_dir/tgt_dir
1253         touch $remote_dir/tgt_file
1254
1255         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1256                 error "rename dir cross MDT failed!"
1257
1258         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1259                 error "rename file cross MDT failed!"
1260
1261         touch $DIR/$tdir/ln_file
1262         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1263                 error "ln file cross MDT failed"
1264
1265         rm -rf $DIR/$tdir || error "Can not delete directories"
1266 }
1267 run_test 24x "cross MDT rename/link"
1268
1269 test_24y() {
1270         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1272
1273         local remote_dir=$DIR/$tdir/remote_dir
1274         local mdtidx=1
1275
1276         test_mkdir $DIR/$tdir
1277         $LFS mkdir -i $mdtidx $remote_dir ||
1278                 error "create remote directory failed"
1279
1280         test_mkdir $remote_dir/src_dir
1281         touch $remote_dir/src_file
1282         test_mkdir $remote_dir/tgt_dir
1283         touch $remote_dir/tgt_file
1284
1285         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1286                 error "rename subdir in the same remote dir failed!"
1287
1288         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1289                 error "rename files in the same remote dir failed!"
1290
1291         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1292                 error "link files in the same remote dir failed!"
1293
1294         rm -rf $DIR/$tdir || error "Can not delete directories"
1295 }
1296 run_test 24y "rename/link on the same dir should succeed"
1297
1298 test_24z() {
1299         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1300         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1301                 skip "Need MDS version at least 2.12.51"
1302
1303         local index
1304
1305         for index in 0 1; do
1306                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1307                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1308         done
1309
1310         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1311
1312         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1313         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1314
1315         local mdts=$(comma_list $(mdts_nodes))
1316
1317         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1318         stack_trap "do_nodes $mdts $LCTL \
1319                 set_param mdt.*.enable_remote_rename=1" EXIT
1320
1321         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1322
1323         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1324         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1325 }
1326 run_test 24z "cross-MDT rename is done as cp"
1327
1328 test_24A() { # LU-3182
1329         local NFILES=5000
1330
1331         rm -rf $DIR/$tdir
1332         test_mkdir $DIR/$tdir
1333         trap simple_cleanup_common EXIT
1334         createmany -m $DIR/$tdir/$tfile $NFILES
1335         local t=$(ls $DIR/$tdir | wc -l)
1336         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1337         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1338         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1339            [ $v -ne $((NFILES + 2)) ] ; then
1340                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1341         fi
1342
1343         simple_cleanup_common || error "Can not delete directories"
1344 }
1345 run_test 24A "readdir() returns correct number of entries."
1346
1347 test_24B() { # LU-4805
1348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1349
1350         local count
1351
1352         test_mkdir $DIR/$tdir
1353         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1354                 error "create striped dir failed"
1355
1356         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1357         [ $count -eq 2 ] || error "Expected 2, got $count"
1358
1359         touch $DIR/$tdir/striped_dir/a
1360
1361         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1362         [ $count -eq 3 ] || error "Expected 3, got $count"
1363
1364         touch $DIR/$tdir/striped_dir/.f
1365
1366         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1367         [ $count -eq 4 ] || error "Expected 4, got $count"
1368
1369         rm -rf $DIR/$tdir || error "Can not delete directories"
1370 }
1371 run_test 24B "readdir for striped dir return correct number of entries"
1372
1373 test_24C() {
1374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1375
1376         mkdir $DIR/$tdir
1377         mkdir $DIR/$tdir/d0
1378         mkdir $DIR/$tdir/d1
1379
1380         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1381                 error "create striped dir failed"
1382
1383         cd $DIR/$tdir/d0/striped_dir
1384
1385         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1386         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1387         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d0_ino" = "$parent_ino" ] ||
1390                 error ".. wrong, expect $d0_ino, get $parent_ino"
1391
1392         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1393                 error "mv striped dir failed"
1394
1395         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1396
1397         [ "$d1_ino" = "$parent_ino" ] ||
1398                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1399 }
1400 run_test 24C "check .. in striped dir"
1401
1402 test_24E() {
1403         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1405
1406         mkdir -p $DIR/$tdir
1407         mkdir $DIR/$tdir/src_dir
1408         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1409                 error "create remote source failed"
1410
1411         touch $DIR/$tdir/src_dir/src_child/a
1412
1413         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1414                 error "create remote target dir failed"
1415
1416         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1417                 error "create remote target child failed"
1418
1419         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1420                 error "rename dir cross MDT failed!"
1421
1422         find $DIR/$tdir
1423
1424         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1425                 error "src_child still exists after rename"
1426
1427         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1428                 error "missing file(a) after rename"
1429
1430         rm -rf $DIR/$tdir || error "Can not delete directories"
1431 }
1432 run_test 24E "cross MDT rename/link"
1433
1434 test_24F () {
1435         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1436
1437         local repeats=1000
1438         [ "$SLOW" = "no" ] && repeats=100
1439
1440         mkdir -p $DIR/$tdir
1441
1442         echo "$repeats repeats"
1443         for ((i = 0; i < repeats; i++)); do
1444                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1445                 touch $DIR/$tdir/test/a || error "touch fails"
1446                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1447                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1448         done
1449
1450         true
1451 }
1452 run_test 24F "hash order vs readdir (LU-11330)"
1453
1454 test_24G () {
1455         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1456
1457         local ino1
1458         local ino2
1459
1460         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1461         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1462         touch $DIR/$tdir-0/f1 || error "touch f1"
1463         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1464         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1465         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1466         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1467         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1468 }
1469 run_test 24G "migrate symlink in rename"
1470
1471 test_25a() {
1472         echo '== symlink sanity ============================================='
1473
1474         test_mkdir $DIR/d25
1475         ln -s d25 $DIR/s25
1476         touch $DIR/s25/foo ||
1477                 error "File creation in symlinked directory failed"
1478 }
1479 run_test 25a "create file in symlinked directory ==============="
1480
1481 test_25b() {
1482         [ ! -d $DIR/d25 ] && test_25a
1483         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1484 }
1485 run_test 25b "lookup file in symlinked directory ==============="
1486
1487 test_26a() {
1488         test_mkdir $DIR/d26
1489         test_mkdir $DIR/d26/d26-2
1490         ln -s d26/d26-2 $DIR/s26
1491         touch $DIR/s26/foo || error "File creation failed"
1492 }
1493 run_test 26a "multiple component symlink ======================="
1494
1495 test_26b() {
1496         test_mkdir -p $DIR/$tdir/d26-2
1497         ln -s $tdir/d26-2/foo $DIR/s26-2
1498         touch $DIR/s26-2 || error "File creation failed"
1499 }
1500 run_test 26b "multiple component symlink at end of lookup ======"
1501
1502 test_26c() {
1503         test_mkdir $DIR/d26.2
1504         touch $DIR/d26.2/foo
1505         ln -s d26.2 $DIR/s26.2-1
1506         ln -s s26.2-1 $DIR/s26.2-2
1507         ln -s s26.2-2 $DIR/s26.2-3
1508         chmod 0666 $DIR/s26.2-3/foo
1509 }
1510 run_test 26c "chain of symlinks"
1511
1512 # recursive symlinks (bug 439)
1513 test_26d() {
1514         ln -s d26-3/foo $DIR/d26-3
1515 }
1516 run_test 26d "create multiple component recursive symlink"
1517
1518 test_26e() {
1519         [ ! -h $DIR/d26-3 ] && test_26d
1520         rm $DIR/d26-3
1521 }
1522 run_test 26e "unlink multiple component recursive symlink"
1523
1524 # recursive symlinks (bug 7022)
1525 test_26f() {
1526         test_mkdir $DIR/$tdir
1527         test_mkdir $DIR/$tdir/$tfile
1528         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1529         test_mkdir -p lndir/bar1
1530         test_mkdir $DIR/$tdir/$tfile/$tfile
1531         cd $tfile                || error "cd $tfile failed"
1532         ln -s .. dotdot          || error "ln dotdot failed"
1533         ln -s dotdot/lndir lndir || error "ln lndir failed"
1534         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1535         output=`ls $tfile/$tfile/lndir/bar1`
1536         [ "$output" = bar1 ] && error "unexpected output"
1537         rm -r $tfile             || error "rm $tfile failed"
1538         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1539 }
1540 run_test 26f "rm -r of a directory which has recursive symlink"
1541
1542 test_27a() {
1543         test_mkdir $DIR/$tdir
1544         $LFS getstripe $DIR/$tdir
1545         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1546         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1547         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1548 }
1549 run_test 27a "one stripe file"
1550
1551 test_27b() {
1552         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1553
1554         test_mkdir $DIR/$tdir
1555         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1556         $LFS getstripe -c $DIR/$tdir/$tfile
1557         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1558                 error "two-stripe file doesn't have two stripes"
1559
1560         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1561 }
1562 run_test 27b "create and write to two stripe file"
1563
1564 # 27c family tests specific striping, setstripe -o
1565 test_27ca() {
1566         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1567         test_mkdir -p $DIR/$tdir
1568         local osts="1"
1569
1570         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1571         $LFS getstripe -i $DIR/$tdir/$tfile
1572         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1573                 error "stripe not on specified OST"
1574
1575         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1576 }
1577 run_test 27ca "one stripe on specified OST"
1578
1579 test_27cb() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1581         test_mkdir -p $DIR/$tdir
1582         local osts="1,0"
1583         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1584         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1585         echo "$getstripe"
1586
1587         # Strip getstripe output to a space separated list of OSTs
1588         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1589                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1590         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1591                 error "stripes not on specified OSTs"
1592
1593         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1594 }
1595 run_test 27cb "two stripes on specified OSTs"
1596
1597 test_27cc() {
1598         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1599         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1600                 skip "server does not support overstriping"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts="0,0"
1604         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1605         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1606         echo "$getstripe"
1607
1608         # Strip getstripe output to a space separated list of OSTs
1609         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1610                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1611         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1612                 error "stripes not on specified OSTs"
1613
1614         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1615 }
1616 run_test 27cc "two stripes on the same OST"
1617
1618 test_27cd() {
1619         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1620         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1621                 skip "server does not support overstriping"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="0,1,1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cd "four stripes on two OSTs"
1637
1638 test_27ce() {
1639         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1640                 skip_env "too many osts, skipping"
1641         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1642                 skip "server does not support overstriping"
1643         # We do one more stripe than we have OSTs
1644         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1645                 skip_env "ea_inode feature disabled"
1646
1647         test_mkdir -p $DIR/$tdir
1648         local osts=""
1649         for i in $(seq 0 $OSTCOUNT);
1650         do
1651                 osts=$osts"0"
1652                 if [ $i -ne $OSTCOUNT ]; then
1653                         osts=$osts","
1654                 fi
1655         done
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27ce "more stripes than OSTs with -o"
1669
1670 test_27cf() {
1671         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1672         local pid=0
1673
1674         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1675         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1676         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1677         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1678                 error "failed to set $osp_proc=0"
1679
1680         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1681         pid=$!
1682         sleep 1
1683         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1684         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1685                 error "failed to set $osp_proc=1"
1686         wait $pid
1687         [[ $pid -ne 0 ]] ||
1688                 error "should return error due to $osp_proc=0"
1689 }
1690 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1691
1692 test_27d() {
1693         test_mkdir $DIR/$tdir
1694         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1695                 error "setstripe failed"
1696         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1698 }
1699 run_test 27d "create file with default settings"
1700
1701 test_27e() {
1702         # LU-5839 adds check for existed layout before setting it
1703         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1704                 skip "Need MDS version at least 2.7.56"
1705
1706         test_mkdir $DIR/$tdir
1707         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1708         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1709         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1710 }
1711 run_test 27e "setstripe existing file (should return error)"
1712
1713 test_27f() {
1714         test_mkdir $DIR/$tdir
1715         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1716                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1717         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1718                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1719         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1720         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1721 }
1722 run_test 27f "setstripe with bad stripe size (should return error)"
1723
1724 test_27g() {
1725         test_mkdir $DIR/$tdir
1726         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1727         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1728                 error "$DIR/$tdir/$tfile has object"
1729 }
1730 run_test 27g "$LFS getstripe with no objects"
1731
1732 test_27ga() {
1733         test_mkdir $DIR/$tdir
1734         touch $DIR/$tdir/$tfile || error "touch failed"
1735         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1736         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1737         local rc=$?
1738         (( rc == 2 )) || error "getstripe did not return ENOENT"
1739 }
1740 run_test 27ga "$LFS getstripe with missing file (should return error)"
1741
1742 test_27i() {
1743         test_mkdir $DIR/$tdir
1744         touch $DIR/$tdir/$tfile || error "touch failed"
1745         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1746                 error "missing objects"
1747 }
1748 run_test 27i "$LFS getstripe with some objects"
1749
1750 test_27j() {
1751         test_mkdir $DIR/$tdir
1752         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1753                 error "setstripe failed" || true
1754 }
1755 run_test 27j "setstripe with bad stripe offset (should return error)"
1756
1757 test_27k() { # bug 2844
1758         test_mkdir $DIR/$tdir
1759         local file=$DIR/$tdir/$tfile
1760         local ll_max_blksize=$((4 * 1024 * 1024))
1761         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1762         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1763         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1764         dd if=/dev/zero of=$file bs=4k count=1
1765         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1766         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1767 }
1768 run_test 27k "limit i_blksize for broken user apps"
1769
1770 test_27l() {
1771         mcreate $DIR/$tfile || error "creating file"
1772         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1773                 error "setstripe should have failed" || true
1774 }
1775 run_test 27l "check setstripe permissions (should return error)"
1776
1777 test_27m() {
1778         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1779
1780         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1781                 skip_env "multiple clients -- skipping"
1782
1783         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1784                    head -n1)
1785         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1786                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1787         fi
1788         trap simple_cleanup_common EXIT
1789         test_mkdir $DIR/$tdir
1790         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1791         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1792                 error "dd should fill OST0"
1793         i=2
1794         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1795                 i=$((i + 1))
1796                 [ $i -gt 256 ] && break
1797         done
1798         i=$((i + 1))
1799         touch $DIR/$tdir/$tfile.$i
1800         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1801             awk '{print $1}'| grep -w "0") ] &&
1802                 error "OST0 was full but new created file still use it"
1803         i=$((i + 1))
1804         touch $DIR/$tdir/$tfile.$i
1805         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1806             awk '{print $1}'| grep -w "0") ] &&
1807                 error "OST0 was full but new created file still use it"
1808         simple_cleanup_common
1809 }
1810 run_test 27m "create file while OST0 was full"
1811
1812 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1813 # if the OST isn't full anymore.
1814 reset_enospc() {
1815         local ostidx=${1:-""}
1816         local delay
1817         local ready
1818         local get_prealloc
1819
1820         local list=$(comma_list $(osts_nodes))
1821         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1822
1823         do_nodes $list lctl set_param fail_loc=0
1824         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1825         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1826                 awk '{print $1 * 2;exit;}')
1827         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1828                         grep -v \"^0$\""
1829         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1830 }
1831
1832 __exhaust_precreations() {
1833         local OSTIDX=$1
1834         local FAILLOC=$2
1835         local FAILIDX=${3:-$OSTIDX}
1836         local ofacet=ost$((OSTIDX + 1))
1837
1838         test_mkdir -p -c1 $DIR/$tdir
1839         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1840         local mfacet=mds$((mdtidx + 1))
1841         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1842
1843         local OST=$(ostname_from_index $OSTIDX)
1844
1845         # on the mdt's osc
1846         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1847         local last_id=$(do_facet $mfacet lctl get_param -n \
1848                         osp.$mdtosc_proc1.prealloc_last_id)
1849         local next_id=$(do_facet $mfacet lctl get_param -n \
1850                         osp.$mdtosc_proc1.prealloc_next_id)
1851
1852         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1853         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1854
1855         test_mkdir -p $DIR/$tdir/${OST}
1856         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1857 #define OBD_FAIL_OST_ENOSPC              0x215
1858         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1859         echo "Creating to objid $last_id on ost $OST..."
1860         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1861         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1862         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1863 }
1864
1865 exhaust_precreations() {
1866         __exhaust_precreations $1 $2 $3
1867         sleep_maxage
1868 }
1869
1870 exhaust_all_precreations() {
1871         local i
1872         for (( i=0; i < OSTCOUNT; i++ )) ; do
1873                 __exhaust_precreations $i $1 -1
1874         done
1875         sleep_maxage
1876 }
1877
1878 test_27n() {
1879         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1881         remote_mds_nodsh && skip "remote MDS with nodsh"
1882         remote_ost_nodsh && skip "remote OST with nodsh"
1883
1884         reset_enospc
1885         rm -f $DIR/$tdir/$tfile
1886         exhaust_precreations 0 0x80000215
1887         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1888         touch $DIR/$tdir/$tfile || error "touch failed"
1889         $LFS getstripe $DIR/$tdir/$tfile
1890         reset_enospc
1891 }
1892 run_test 27n "create file with some full OSTs"
1893
1894 test_27o() {
1895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1897         remote_mds_nodsh && skip "remote MDS with nodsh"
1898         remote_ost_nodsh && skip "remote OST with nodsh"
1899
1900         reset_enospc
1901         rm -f $DIR/$tdir/$tfile
1902         exhaust_all_precreations 0x215
1903
1904         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1905
1906         reset_enospc
1907         rm -rf $DIR/$tdir/*
1908 }
1909 run_test 27o "create file with all full OSTs (should error)"
1910
1911 function create_and_checktime() {
1912         local fname=$1
1913         local loops=$2
1914         local i
1915
1916         for ((i=0; i < $loops; i++)); do
1917                 local start=$SECONDS
1918                 multiop $fname-$i Oc
1919                 ((SECONDS-start < TIMEOUT)) ||
1920                         error "creation took " $((SECONDS-$start)) && return 1
1921         done
1922 }
1923
1924 test_27oo() {
1925         local mdts=$(comma_list $(mdts_nodes))
1926
1927         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1928                 skip "Need MDS version at least 2.13.57"
1929
1930         local f0=$DIR/${tfile}-0
1931         local f1=$DIR/${tfile}-1
1932
1933         wait_delete_completed
1934
1935         # refill precreated objects
1936         $LFS setstripe -i0 -c1 $f0
1937
1938         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1939         # force QoS allocation policy
1940         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1941         stack_trap "do_nodes $mdts $LCTL set_param \
1942                 lov.*.qos_threshold_rr=$saved" EXIT
1943         sleep_maxage
1944
1945         # one OST is unavailable, but still have few objects preallocated
1946         stop ost1
1947         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1948                 rm -rf $f1 $DIR/$tdir*" EXIT
1949
1950         for ((i=0; i < 7; i++)); do
1951                 mkdir $DIR/$tdir$i || error "can't create dir"
1952                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1953                         error "can't set striping"
1954         done
1955         for ((i=0; i < 7; i++)); do
1956                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1957         done
1958         wait
1959 }
1960 run_test 27oo "don't let few threads to reserve too many objects"
1961
1962 test_27p() {
1963         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1965         remote_mds_nodsh && skip "remote MDS with nodsh"
1966         remote_ost_nodsh && skip "remote OST with nodsh"
1967
1968         reset_enospc
1969         rm -f $DIR/$tdir/$tfile
1970         test_mkdir $DIR/$tdir
1971
1972         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1973         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1974         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1975
1976         exhaust_precreations 0 0x80000215
1977         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1978         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1979         $LFS getstripe $DIR/$tdir/$tfile
1980
1981         reset_enospc
1982 }
1983 run_test 27p "append to a truncated file with some full OSTs"
1984
1985 test_27q() {
1986         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1988         remote_mds_nodsh && skip "remote MDS with nodsh"
1989         remote_ost_nodsh && skip "remote OST with nodsh"
1990
1991         reset_enospc
1992         rm -f $DIR/$tdir/$tfile
1993
1994         test_mkdir $DIR/$tdir
1995         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1996         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1997                 error "truncate $DIR/$tdir/$tfile failed"
1998         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1999
2000         exhaust_all_precreations 0x215
2001
2002         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2003         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2004
2005         reset_enospc
2006 }
2007 run_test 27q "append to truncated file with all OSTs full (should error)"
2008
2009 test_27r() {
2010         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2012         remote_mds_nodsh && skip "remote MDS with nodsh"
2013         remote_ost_nodsh && skip "remote OST with nodsh"
2014
2015         reset_enospc
2016         rm -f $DIR/$tdir/$tfile
2017         exhaust_precreations 0 0x80000215
2018
2019         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2020
2021         reset_enospc
2022 }
2023 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2024
2025 test_27s() { # bug 10725
2026         test_mkdir $DIR/$tdir
2027         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2028         local stripe_count=0
2029         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2030         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2031                 error "stripe width >= 2^32 succeeded" || true
2032
2033 }
2034 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2035
2036 test_27t() { # bug 10864
2037         WDIR=$(pwd)
2038         WLFS=$(which lfs)
2039         cd $DIR
2040         touch $tfile
2041         $WLFS getstripe $tfile
2042         cd $WDIR
2043 }
2044 run_test 27t "check that utils parse path correctly"
2045
2046 test_27u() { # bug 4900
2047         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2048         remote_mds_nodsh && skip "remote MDS with nodsh"
2049
2050         local index
2051         local list=$(comma_list $(mdts_nodes))
2052
2053 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2054         do_nodes $list $LCTL set_param fail_loc=0x139
2055         test_mkdir -p $DIR/$tdir
2056         trap simple_cleanup_common EXIT
2057         createmany -o $DIR/$tdir/t- 1000
2058         do_nodes $list $LCTL set_param fail_loc=0
2059
2060         TLOG=$TMP/$tfile.getstripe
2061         $LFS getstripe $DIR/$tdir > $TLOG
2062         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2063         unlinkmany $DIR/$tdir/t- 1000
2064         trap 0
2065         [[ $OBJS -gt 0 ]] &&
2066                 error "$OBJS objects created on OST-0. See $TLOG" ||
2067                 rm -f $TLOG
2068 }
2069 run_test 27u "skip object creation on OSC w/o objects"
2070
2071 test_27v() { # bug 4900
2072         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2074         remote_mds_nodsh && skip "remote MDS with nodsh"
2075         remote_ost_nodsh && skip "remote OST with nodsh"
2076
2077         exhaust_all_precreations 0x215
2078         reset_enospc
2079
2080         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2081
2082         touch $DIR/$tdir/$tfile
2083         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2084         # all except ost1
2085         for (( i=1; i < OSTCOUNT; i++ )); do
2086                 do_facet ost$i lctl set_param fail_loc=0x705
2087         done
2088         local START=`date +%s`
2089         createmany -o $DIR/$tdir/$tfile 32
2090
2091         local FINISH=`date +%s`
2092         local TIMEOUT=`lctl get_param -n timeout`
2093         local PROCESS=$((FINISH - START))
2094         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2095                error "$FINISH - $START >= $TIMEOUT / 2"
2096         sleep $((TIMEOUT / 2 - PROCESS))
2097         reset_enospc
2098 }
2099 run_test 27v "skip object creation on slow OST"
2100
2101 test_27w() { # bug 10997
2102         test_mkdir $DIR/$tdir
2103         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2104         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2105                 error "stripe size $size != 65536" || true
2106         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2107                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2108 }
2109 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2110
2111 test_27wa() {
2112         [[ $OSTCOUNT -lt 2 ]] &&
2113                 skip_env "skipping multiple stripe count/offset test"
2114
2115         test_mkdir $DIR/$tdir
2116         for i in $(seq 1 $OSTCOUNT); do
2117                 offset=$((i - 1))
2118                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2119                         error "setstripe -c $i -i $offset failed"
2120                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2121                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2122                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2123                 [ $index -ne $offset ] &&
2124                         error "stripe offset $index != $offset" || true
2125         done
2126 }
2127 run_test 27wa "check $LFS setstripe -c -i options"
2128
2129 test_27x() {
2130         remote_ost_nodsh && skip "remote OST with nodsh"
2131         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2133
2134         OFFSET=$(($OSTCOUNT - 1))
2135         OSTIDX=0
2136         local OST=$(ostname_from_index $OSTIDX)
2137
2138         test_mkdir $DIR/$tdir
2139         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2140         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2141         sleep_maxage
2142         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2143         for i in $(seq 0 $OFFSET); do
2144                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2145                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2146                 error "OST0 was degraded but new created file still use it"
2147         done
2148         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2149 }
2150 run_test 27x "create files while OST0 is degraded"
2151
2152 test_27y() {
2153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2154         remote_mds_nodsh && skip "remote MDS with nodsh"
2155         remote_ost_nodsh && skip "remote OST with nodsh"
2156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2157
2158         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2159         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2160                 osp.$mdtosc.prealloc_last_id)
2161         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2162                 osp.$mdtosc.prealloc_next_id)
2163         local fcount=$((last_id - next_id))
2164         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2165         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2166
2167         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2168                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2169         local OST_DEACTIVE_IDX=-1
2170         local OSC
2171         local OSTIDX
2172         local OST
2173
2174         for OSC in $MDS_OSCS; do
2175                 OST=$(osc_to_ost $OSC)
2176                 OSTIDX=$(index_from_ostuuid $OST)
2177                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2178                         OST_DEACTIVE_IDX=$OSTIDX
2179                 fi
2180                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2181                         echo $OSC "is Deactivated:"
2182                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2183                 fi
2184         done
2185
2186         OSTIDX=$(index_from_ostuuid $OST)
2187         test_mkdir $DIR/$tdir
2188         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2189
2190         for OSC in $MDS_OSCS; do
2191                 OST=$(osc_to_ost $OSC)
2192                 OSTIDX=$(index_from_ostuuid $OST)
2193                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2194                         echo $OST "is degraded:"
2195                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2196                                                 obdfilter.$OST.degraded=1
2197                 fi
2198         done
2199
2200         sleep_maxage
2201         createmany -o $DIR/$tdir/$tfile $fcount
2202
2203         for OSC in $MDS_OSCS; do
2204                 OST=$(osc_to_ost $OSC)
2205                 OSTIDX=$(index_from_ostuuid $OST)
2206                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2207                         echo $OST "is recovered from degraded:"
2208                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2209                                                 obdfilter.$OST.degraded=0
2210                 else
2211                         do_facet $SINGLEMDS lctl --device %$OSC activate
2212                 fi
2213         done
2214
2215         # all osp devices get activated, hence -1 stripe count restored
2216         local stripe_count=0
2217
2218         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2219         # devices get activated.
2220         sleep_maxage
2221         $LFS setstripe -c -1 $DIR/$tfile
2222         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2223         rm -f $DIR/$tfile
2224         [ $stripe_count -ne $OSTCOUNT ] &&
2225                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2226         return 0
2227 }
2228 run_test 27y "create files while OST0 is degraded and the rest inactive"
2229
2230 check_seq_oid()
2231 {
2232         log "check file $1"
2233
2234         lmm_count=$($LFS getstripe -c $1)
2235         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2236         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2237
2238         local old_ifs="$IFS"
2239         IFS=$'[:]'
2240         fid=($($LFS path2fid $1))
2241         IFS="$old_ifs"
2242
2243         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2244         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2245
2246         # compare lmm_seq and lu_fid->f_seq
2247         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2248         # compare lmm_object_id and lu_fid->oid
2249         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2250
2251         # check the trusted.fid attribute of the OST objects of the file
2252         local have_obdidx=false
2253         local stripe_nr=0
2254         $LFS getstripe $1 | while read obdidx oid hex seq; do
2255                 # skip lines up to and including "obdidx"
2256                 [ -z "$obdidx" ] && break
2257                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2258                 $have_obdidx || continue
2259
2260                 local ost=$((obdidx + 1))
2261                 local dev=$(ostdevname $ost)
2262                 local oid_hex
2263
2264                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2265
2266                 seq=$(echo $seq | sed -e "s/^0x//g")
2267                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2268                         oid_hex=$(echo $oid)
2269                 else
2270                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2271                 fi
2272                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2273
2274                 local ff=""
2275                 #
2276                 # Don't unmount/remount the OSTs if we don't need to do that.
2277                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2278                 # update too, until that use mount/ll_decode_filter_fid/mount.
2279                 # Re-enable when debugfs will understand new filter_fid.
2280                 #
2281                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2282                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2283                                 $dev 2>/dev/null" | grep "parent=")
2284                 fi
2285                 if [ -z "$ff" ]; then
2286                         stop ost$ost
2287                         mount_fstype ost$ost
2288                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2289                                 $(facet_mntpt ost$ost)/$obj_file)
2290                         unmount_fstype ost$ost
2291                         start ost$ost $dev $OST_MOUNT_OPTS
2292                         clients_up
2293                 fi
2294
2295                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2296
2297                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2298
2299                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2300                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2301                 #
2302                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2303                 #       stripe_size=1048576 component_id=1 component_start=0 \
2304                 #       component_end=33554432
2305                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2306                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2307                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2308                 local ff_pstripe
2309                 if grep -q 'stripe=' <<<$ff; then
2310                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2311                 else
2312                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2313                         # into f_ver in this case.  See comment on ff_parent.
2314                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2315                 fi
2316
2317                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2318                 [ $ff_pseq = $lmm_seq ] ||
2319                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2320                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2321                 [ $ff_poid = $lmm_oid ] ||
2322                         error "FF parent OID $ff_poid != $lmm_oid"
2323                 (($ff_pstripe == $stripe_nr)) ||
2324                         error "FF stripe $ff_pstripe != $stripe_nr"
2325
2326                 stripe_nr=$((stripe_nr + 1))
2327                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2328                         continue
2329                 if grep -q 'stripe_count=' <<<$ff; then
2330                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2331                                             -e 's/ .*//' <<<$ff)
2332                         [ $lmm_count = $ff_scnt ] ||
2333                                 error "FF stripe count $lmm_count != $ff_scnt"
2334                 fi
2335         done
2336 }
2337
2338 test_27z() {
2339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2340         remote_ost_nodsh && skip "remote OST with nodsh"
2341
2342         test_mkdir $DIR/$tdir
2343         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2344                 { error "setstripe -c -1 failed"; return 1; }
2345         # We need to send a write to every object to get parent FID info set.
2346         # This _should_ also work for setattr, but does not currently.
2347         # touch $DIR/$tdir/$tfile-1 ||
2348         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2349                 { error "dd $tfile-1 failed"; return 2; }
2350         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2351                 { error "setstripe -c -1 failed"; return 3; }
2352         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2353                 { error "dd $tfile-2 failed"; return 4; }
2354
2355         # make sure write RPCs have been sent to OSTs
2356         sync; sleep 5; sync
2357
2358         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2359         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2360 }
2361 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2362
2363 test_27A() { # b=19102
2364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2365
2366         save_layout_restore_at_exit $MOUNT
2367         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2368         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2369                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2370         local default_size=$($LFS getstripe -S $MOUNT)
2371         local default_offset=$($LFS getstripe -i $MOUNT)
2372         local dsize=$(do_facet $SINGLEMDS \
2373                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2374         [ $default_size -eq $dsize ] ||
2375                 error "stripe size $default_size != $dsize"
2376         [ $default_offset -eq -1 ] ||
2377                 error "stripe offset $default_offset != -1"
2378 }
2379 run_test 27A "check filesystem-wide default LOV EA values"
2380
2381 test_27B() { # LU-2523
2382         test_mkdir $DIR/$tdir
2383         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2384         touch $DIR/$tdir/f0
2385         # open f1 with O_LOV_DELAY_CREATE
2386         # rename f0 onto f1
2387         # call setstripe ioctl on open file descriptor for f1
2388         # close
2389         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2390                 $DIR/$tdir/f0
2391
2392         rm -f $DIR/$tdir/f1
2393         # open f1 with O_LOV_DELAY_CREATE
2394         # unlink f1
2395         # call setstripe ioctl on open file descriptor for f1
2396         # close
2397         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2398
2399         # Allow multiop to fail in imitation of NFS's busted semantics.
2400         true
2401 }
2402 run_test 27B "call setstripe on open unlinked file/rename victim"
2403
2404 # 27C family tests full striping and overstriping
2405 test_27Ca() { #LU-2871
2406         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2407
2408         declare -a ost_idx
2409         local index
2410         local found
2411         local i
2412         local j
2413
2414         test_mkdir $DIR/$tdir
2415         cd $DIR/$tdir
2416         for i in $(seq 0 $((OSTCOUNT - 1))); do
2417                 # set stripe across all OSTs starting from OST$i
2418                 $LFS setstripe -i $i -c -1 $tfile$i
2419                 # get striping information
2420                 ost_idx=($($LFS getstripe $tfile$i |
2421                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2422                 echo ${ost_idx[@]}
2423
2424                 # check the layout
2425                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2426                         error "${#ost_idx[@]} != $OSTCOUNT"
2427
2428                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2429                         found=0
2430                         for j in $(echo ${ost_idx[@]}); do
2431                                 if [ $index -eq $j ]; then
2432                                         found=1
2433                                         break
2434                                 fi
2435                         done
2436                         [ $found = 1 ] ||
2437                                 error "Can not find $index in ${ost_idx[@]}"
2438                 done
2439         done
2440 }
2441 run_test 27Ca "check full striping across all OSTs"
2442
2443 test_27Cb() {
2444         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2445                 skip "server does not support overstriping"
2446         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2447                 skip_env "too many osts, skipping"
2448
2449         test_mkdir -p $DIR/$tdir
2450         local setcount=$(($OSTCOUNT * 2))
2451         [ $setcount -lt 160 ] || large_xattr_enabled ||
2452                 skip_env "ea_inode feature disabled"
2453
2454         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2455                 error "setstripe failed"
2456
2457         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2458         [ $count -eq $setcount ] ||
2459                 error "stripe count $count, should be $setcount"
2460
2461         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2462                 error "overstriped should be set in pattern"
2463
2464         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2465                 error "dd failed"
2466 }
2467 run_test 27Cb "more stripes than OSTs with -C"
2468
2469 test_27Cc() {
2470         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2471                 skip "server does not support overstriping"
2472         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2473
2474         test_mkdir -p $DIR/$tdir
2475         local setcount=$(($OSTCOUNT - 1))
2476
2477         [ $setcount -lt 160 ] || large_xattr_enabled ||
2478                 skip_env "ea_inode feature disabled"
2479
2480         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2481                 error "setstripe failed"
2482
2483         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2484         [ $count -eq $setcount ] ||
2485                 error "stripe count $count, should be $setcount"
2486
2487         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2488                 error "overstriped should not be set in pattern"
2489
2490         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2491                 error "dd failed"
2492 }
2493 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2494
2495 test_27Cd() {
2496         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2497                 skip "server does not support overstriping"
2498         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2499         large_xattr_enabled || skip_env "ea_inode feature disabled"
2500
2501         test_mkdir -p $DIR/$tdir
2502         local setcount=$LOV_MAX_STRIPE_COUNT
2503
2504         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2505                 error "setstripe failed"
2506
2507         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2508         [ $count -eq $setcount ] ||
2509                 error "stripe count $count, should be $setcount"
2510
2511         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2512                 error "overstriped should be set in pattern"
2513
2514         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2515                 error "dd failed"
2516
2517         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2518 }
2519 run_test 27Cd "test maximum stripe count"
2520
2521 test_27Ce() {
2522         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2523                 skip "server does not support overstriping"
2524         test_mkdir -p $DIR/$tdir
2525
2526         pool_add $TESTNAME || error "Pool creation failed"
2527         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2528
2529         local setcount=8
2530
2531         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2532                 error "setstripe failed"
2533
2534         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2535         [ $count -eq $setcount ] ||
2536                 error "stripe count $count, should be $setcount"
2537
2538         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2539                 error "overstriped should be set in pattern"
2540
2541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2542                 error "dd failed"
2543
2544         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2545 }
2546 run_test 27Ce "test pool with overstriping"
2547
2548 test_27Cf() {
2549         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2550                 skip "server does not support overstriping"
2551         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2552                 skip_env "too many osts, skipping"
2553
2554         test_mkdir -p $DIR/$tdir
2555
2556         local setcount=$(($OSTCOUNT * 2))
2557         [ $setcount -lt 160 ] || large_xattr_enabled ||
2558                 skip_env "ea_inode feature disabled"
2559
2560         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2561                 error "setstripe failed"
2562
2563         echo 1 > $DIR/$tdir/$tfile
2564
2565         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2566         [ $count -eq $setcount ] ||
2567                 error "stripe count $count, should be $setcount"
2568
2569         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2570                 error "overstriped should be set in pattern"
2571
2572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2573                 error "dd failed"
2574
2575         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2576 }
2577 run_test 27Cf "test default inheritance with overstriping"
2578
2579 test_27D() {
2580         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2581         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2582         remote_mds_nodsh && skip "remote MDS with nodsh"
2583
2584         local POOL=${POOL:-testpool}
2585         local first_ost=0
2586         local last_ost=$(($OSTCOUNT - 1))
2587         local ost_step=1
2588         local ost_list=$(seq $first_ost $ost_step $last_ost)
2589         local ost_range="$first_ost $last_ost $ost_step"
2590
2591         test_mkdir $DIR/$tdir
2592         pool_add $POOL || error "pool_add failed"
2593         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2594
2595         local skip27D
2596         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2597                 skip27D+="-s 29"
2598         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2599                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2600                         skip27D+=" -s 30,31"
2601         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2602           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2603                 skip27D+=" -s 32,33"
2604         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2605                 skip27D+=" -s 34"
2606         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2607                 error "llapi_layout_test failed"
2608
2609         destroy_test_pools || error "destroy test pools failed"
2610 }
2611 run_test 27D "validate llapi_layout API"
2612
2613 # Verify that default_easize is increased from its initial value after
2614 # accessing a widely striped file.
2615 test_27E() {
2616         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2617         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2618                 skip "client does not have LU-3338 fix"
2619
2620         # 72 bytes is the minimum space required to store striping
2621         # information for a file striped across one OST:
2622         # (sizeof(struct lov_user_md_v3) +
2623         #  sizeof(struct lov_user_ost_data_v1))
2624         local min_easize=72
2625         $LCTL set_param -n llite.*.default_easize $min_easize ||
2626                 error "lctl set_param failed"
2627         local easize=$($LCTL get_param -n llite.*.default_easize)
2628
2629         [ $easize -eq $min_easize ] ||
2630                 error "failed to set default_easize"
2631
2632         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2633                 error "setstripe failed"
2634         # In order to ensure stat() call actually talks to MDS we need to
2635         # do something drastic to this file to shake off all lock, e.g.
2636         # rename it (kills lookup lock forcing cache cleaning)
2637         mv $DIR/$tfile $DIR/${tfile}-1
2638         ls -l $DIR/${tfile}-1
2639         rm $DIR/${tfile}-1
2640
2641         easize=$($LCTL get_param -n llite.*.default_easize)
2642
2643         [ $easize -gt $min_easize ] ||
2644                 error "default_easize not updated"
2645 }
2646 run_test 27E "check that default extended attribute size properly increases"
2647
2648 test_27F() { # LU-5346/LU-7975
2649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2650         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2651         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2652                 skip "Need MDS version at least 2.8.51"
2653         remote_ost_nodsh && skip "remote OST with nodsh"
2654
2655         test_mkdir $DIR/$tdir
2656         rm -f $DIR/$tdir/f0
2657         $LFS setstripe -c 2 $DIR/$tdir
2658
2659         # stop all OSTs to reproduce situation for LU-7975 ticket
2660         for num in $(seq $OSTCOUNT); do
2661                 stop ost$num
2662         done
2663
2664         # open/create f0 with O_LOV_DELAY_CREATE
2665         # truncate f0 to a non-0 size
2666         # close
2667         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2668
2669         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2670         # open/write it again to force delayed layout creation
2671         cat /etc/hosts > $DIR/$tdir/f0 &
2672         catpid=$!
2673
2674         # restart OSTs
2675         for num in $(seq $OSTCOUNT); do
2676                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2677                         error "ost$num failed to start"
2678         done
2679
2680         wait $catpid || error "cat failed"
2681
2682         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2683         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2684                 error "wrong stripecount"
2685
2686 }
2687 run_test 27F "Client resend delayed layout creation with non-zero size"
2688
2689 test_27G() { #LU-10629
2690         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2691                 skip "Need MDS version at least 2.11.51"
2692         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2693         remote_mds_nodsh && skip "remote MDS with nodsh"
2694         local POOL=${POOL:-testpool}
2695         local ostrange="0 0 1"
2696
2697         test_mkdir $DIR/$tdir
2698         touch $DIR/$tdir/$tfile.nopool
2699         pool_add $POOL || error "pool_add failed"
2700         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2701         $LFS setstripe -p $POOL $DIR/$tdir
2702
2703         local pool=$($LFS getstripe -p $DIR/$tdir)
2704
2705         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2706         touch $DIR/$tdir/$tfile.default
2707         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2708         $LFS find $DIR/$tdir -type f --pool $POOL
2709         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2710         [[ "$found" == "2" ]] ||
2711                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2712
2713         $LFS setstripe -d $DIR/$tdir
2714
2715         pool=$($LFS getstripe -p -d $DIR/$tdir)
2716
2717         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2718 }
2719 run_test 27G "Clear OST pool from stripe"
2720
2721 test_27H() {
2722         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2723                 skip "Need MDS version newer than 2.11.54"
2724         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2725         test_mkdir $DIR/$tdir
2726         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2727         touch $DIR/$tdir/$tfile
2728         $LFS getstripe -c $DIR/$tdir/$tfile
2729         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2730                 error "two-stripe file doesn't have two stripes"
2731
2732         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2733         $LFS getstripe -y $DIR/$tdir/$tfile
2734         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2735              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2736                 error "expected l_ost_idx: [02]$ not matched"
2737
2738         # make sure ost list has been cleared
2739         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2740         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2741                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2742         touch $DIR/$tdir/f3
2743         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2744 }
2745 run_test 27H "Set specific OSTs stripe"
2746
2747 test_27I() {
2748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2749         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2750         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2751                 skip "Need MDS version newer than 2.12.52"
2752         local pool=$TESTNAME
2753         local ostrange="1 1 1"
2754
2755         save_layout_restore_at_exit $MOUNT
2756         $LFS setstripe -c 2 -i 0 $MOUNT
2757         pool_add $pool || error "pool_add failed"
2758         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2759         test_mkdir $DIR/$tdir
2760         $LFS setstripe -p $pool $DIR/$tdir
2761         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2762         $LFS getstripe $DIR/$tdir/$tfile
2763 }
2764 run_test 27I "check that root dir striping does not break parent dir one"
2765
2766 test_27J() {
2767         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2768                 skip "Need MDS version newer than 2.12.51"
2769
2770         test_mkdir $DIR/$tdir
2771         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2772         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2773
2774         # create foreign file (raw way)
2775         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2776                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2777
2778         ! $LFS setstripe --foreign --flags foo \
2779                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2780                         error "creating $tfile with '--flags foo' should fail"
2781
2782         ! $LFS setstripe --foreign --flags 0xffffffff \
2783                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2784                         error "creating $tfile w/ 0xffffffff flags should fail"
2785
2786         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2787                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2788
2789         # verify foreign file (raw way)
2790         parse_foreign_file -f $DIR/$tdir/$tfile |
2791                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2792                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2793         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2794                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2795         parse_foreign_file -f $DIR/$tdir/$tfile |
2796                 grep "lov_foreign_size: 73" ||
2797                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2798         parse_foreign_file -f $DIR/$tdir/$tfile |
2799                 grep "lov_foreign_type: 1" ||
2800                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2801         parse_foreign_file -f $DIR/$tdir/$tfile |
2802                 grep "lov_foreign_flags: 0x0000DA08" ||
2803                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2804         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2805                 grep "lov_foreign_value: 0x" |
2806                 sed -e 's/lov_foreign_value: 0x//')
2807         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2808         [[ $lov = ${lov2// /} ]] ||
2809                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2810
2811         # create foreign file (lfs + API)
2812         $LFS setstripe --foreign=none --flags 0xda08 \
2813                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2814                 error "$DIR/$tdir/${tfile}2: create failed"
2815
2816         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2817                 grep "lfm_magic:.*0x0BD70BD0" ||
2818                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2819         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2820         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2821                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2822         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2823                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2824         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2825                 grep "lfm_flags:.*0x0000DA08" ||
2826                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2827         $LFS getstripe $DIR/$tdir/${tfile}2 |
2828                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2829                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2830
2831         # modify striping should fail
2832         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2833                 error "$DIR/$tdir/$tfile: setstripe should fail"
2834         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2835                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2836
2837         # R/W should fail
2838         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2839         cat $DIR/$tdir/${tfile}2 &&
2840                 error "$DIR/$tdir/${tfile}2: read should fail"
2841         cat /etc/passwd > $DIR/$tdir/$tfile &&
2842                 error "$DIR/$tdir/$tfile: write should fail"
2843         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2844                 error "$DIR/$tdir/${tfile}2: write should fail"
2845
2846         # chmod should work
2847         chmod 222 $DIR/$tdir/$tfile ||
2848                 error "$DIR/$tdir/$tfile: chmod failed"
2849         chmod 222 $DIR/$tdir/${tfile}2 ||
2850                 error "$DIR/$tdir/${tfile}2: chmod failed"
2851
2852         # chown should work
2853         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2854                 error "$DIR/$tdir/$tfile: chown failed"
2855         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2856                 error "$DIR/$tdir/${tfile}2: chown failed"
2857
2858         # rename should work
2859         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2860                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2861         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2862                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2863
2864         #remove foreign file
2865         rm $DIR/$tdir/${tfile}.new ||
2866                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2867         rm $DIR/$tdir/${tfile}2.new ||
2868                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2869 }
2870 run_test 27J "basic ops on file with foreign LOV"
2871
2872 test_27K() {
2873         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2874                 skip "Need MDS version newer than 2.12.49"
2875
2876         test_mkdir $DIR/$tdir
2877         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2878         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2879
2880         # create foreign dir (raw way)
2881         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2882                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2883
2884         ! $LFS setdirstripe --foreign --flags foo \
2885                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2886                         error "creating $tdir with '--flags foo' should fail"
2887
2888         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2889                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2890                         error "creating $tdir w/ 0xffffffff flags should fail"
2891
2892         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2893                 error "create_foreign_dir FAILED"
2894
2895         # verify foreign dir (raw way)
2896         parse_foreign_dir -d $DIR/$tdir/$tdir |
2897                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2898                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2899         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2900                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2901         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2902                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2903         parse_foreign_dir -d $DIR/$tdir/$tdir |
2904                 grep "lmv_foreign_flags: 55813$" ||
2905                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2906         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2907                 grep "lmv_foreign_value: 0x" |
2908                 sed 's/lmv_foreign_value: 0x//')
2909         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2910                 sed 's/ //g')
2911         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2912
2913         # create foreign dir (lfs + API)
2914         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2915                 $DIR/$tdir/${tdir}2 ||
2916                 error "$DIR/$tdir/${tdir}2: create failed"
2917
2918         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2919                 grep "lfm_magic:.*0x0CD50CD0" ||
2920                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2921         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2922         # - sizeof(lfm_type) - sizeof(lfm_flags)
2923         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2924                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2925         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2926                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2927         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2928                 grep "lfm_flags:.*0x0000DA05" ||
2929                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2930         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2931                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2932                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2933
2934         # file create in dir should fail
2935         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2936         touch $DIR/$tdir/${tdir}2/$tfile &&
2937                 "$DIR/${tdir}2: file create should fail"
2938
2939         # chmod should work
2940         chmod 777 $DIR/$tdir/$tdir ||
2941                 error "$DIR/$tdir: chmod failed"
2942         chmod 777 $DIR/$tdir/${tdir}2 ||
2943                 error "$DIR/${tdir}2: chmod failed"
2944
2945         # chown should work
2946         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2947                 error "$DIR/$tdir: chown failed"
2948         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2949                 error "$DIR/${tdir}2: chown failed"
2950
2951         # rename should work
2952         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2953                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2954         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2955                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2956
2957         #remove foreign dir
2958         rmdir $DIR/$tdir/${tdir}.new ||
2959                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2960         rmdir $DIR/$tdir/${tdir}2.new ||
2961                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2962 }
2963 run_test 27K "basic ops on dir with foreign LMV"
2964
2965 test_27L() {
2966         remote_mds_nodsh && skip "remote MDS with nodsh"
2967
2968         local POOL=${POOL:-$TESTNAME}
2969
2970         pool_add $POOL || error "pool_add failed"
2971
2972         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2973                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2974                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2975 }
2976 run_test 27L "lfs pool_list gives correct pool name"
2977
2978 test_27M() {
2979         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2980                 skip "Need MDS version >= than 2.12.57"
2981         remote_mds_nodsh && skip "remote MDS with nodsh"
2982         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2983
2984         test_mkdir $DIR/$tdir
2985
2986         # Set default striping on directory
2987         $LFS setstripe -C 4 $DIR/$tdir
2988
2989         echo 1 > $DIR/$tdir/${tfile}.1
2990         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2991         local setcount=4
2992         [ $count -eq $setcount ] ||
2993                 error "(1) stripe count $count, should be $setcount"
2994
2995         # Capture existing append_stripe_count setting for restore
2996         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2997         local mdts=$(comma_list $(mdts_nodes))
2998         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2999
3000         local appendcount=$orig_count
3001         echo 1 >> $DIR/$tdir/${tfile}.2_append
3002         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3003         [ $count -eq $appendcount ] ||
3004                 error "(2)stripe count $count, should be $appendcount for append"
3005
3006         # Disable O_APPEND striping, verify it works
3007         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3008
3009         # Should now get the default striping, which is 4
3010         setcount=4
3011         echo 1 >> $DIR/$tdir/${tfile}.3_append
3012         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3013         [ $count -eq $setcount ] ||
3014                 error "(3) stripe count $count, should be $setcount"
3015
3016         # Try changing the stripe count for append files
3017         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3018
3019         # Append striping is now 2 (directory default is still 4)
3020         appendcount=2
3021         echo 1 >> $DIR/$tdir/${tfile}.4_append
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3023         [ $count -eq $appendcount ] ||
3024                 error "(4) stripe count $count, should be $appendcount for append"
3025
3026         # Test append stripe count of -1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3028         appendcount=$OSTCOUNT
3029         echo 1 >> $DIR/$tdir/${tfile}.5
3030         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3031         [ $count -eq $appendcount ] ||
3032                 error "(5) stripe count $count, should be $appendcount for append"
3033
3034         # Set append striping back to default of 1
3035         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3036
3037         # Try a new default striping, PFL + DOM
3038         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3039
3040         # Create normal DOM file, DOM returns stripe count == 0
3041         setcount=0
3042         touch $DIR/$tdir/${tfile}.6
3043         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3044         [ $count -eq $setcount ] ||
3045                 error "(6) stripe count $count, should be $setcount"
3046
3047         # Show
3048         appendcount=1
3049         echo 1 >> $DIR/$tdir/${tfile}.7_append
3050         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3051         [ $count -eq $appendcount ] ||
3052                 error "(7) stripe count $count, should be $appendcount for append"
3053
3054         # Clean up DOM layout
3055         $LFS setstripe -d $DIR/$tdir
3056
3057         # Now test that append striping works when layout is from root
3058         $LFS setstripe -c 2 $MOUNT
3059         # Make a special directory for this
3060         mkdir $DIR/${tdir}/${tdir}.2
3061         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3062
3063         # Verify for normal file
3064         setcount=2
3065         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3066         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3067         [ $count -eq $setcount ] ||
3068                 error "(8) stripe count $count, should be $setcount"
3069
3070         appendcount=1
3071         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3072         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3073         [ $count -eq $appendcount ] ||
3074                 error "(9) stripe count $count, should be $appendcount for append"
3075
3076         # Now test O_APPEND striping with pools
3077         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3078         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3079
3080         # Create the pool
3081         pool_add $TESTNAME || error "pool creation failed"
3082         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3083
3084         echo 1 >> $DIR/$tdir/${tfile}.10_append
3085
3086         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3087         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3088
3089         # Check that count is still correct
3090         appendcount=1
3091         echo 1 >> $DIR/$tdir/${tfile}.11_append
3092         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3093         [ $count -eq $appendcount ] ||
3094                 error "(11) stripe count $count, should be $appendcount for append"
3095
3096         # Disable O_APPEND stripe count, verify pool works separately
3097         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3098
3099         echo 1 >> $DIR/$tdir/${tfile}.12_append
3100
3101         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3102         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3103
3104         # Remove pool setting, verify it's not applied
3105         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3106
3107         echo 1 >> $DIR/$tdir/${tfile}.13_append
3108
3109         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3110         [ "$pool" = "" ] || error "(13) pool found: $pool"
3111 }
3112 run_test 27M "test O_APPEND striping"
3113
3114 test_27N() {
3115         combined_mgs_mds && skip "needs separate MGS/MDT"
3116
3117         pool_add $TESTNAME || error "pool_add failed"
3118         do_facet mgs "$LCTL pool_list $FSNAME" |
3119                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3120                 error "lctl pool_list on MGS failed"
3121 }
3122 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3123
3124 clean_foreign_symlink() {
3125         trap 0
3126         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3127         for i in $DIR/$tdir/* ; do
3128                 $LFS unlink_foreign $i || true
3129         done
3130 }
3131
3132 test_27O() {
3133         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3134                 skip "Need MDS version newer than 2.12.51"
3135
3136         test_mkdir $DIR/$tdir
3137         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3138         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3139
3140         trap clean_foreign_symlink EXIT
3141
3142         # enable foreign_symlink behaviour
3143         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3144
3145         # foreign symlink LOV format is a partial path by default
3146
3147         # create foreign file (lfs + API)
3148         $LFS setstripe --foreign=symlink --flags 0xda05 \
3149                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3150                 error "$DIR/$tdir/${tfile}: create failed"
3151
3152         $LFS getstripe -v $DIR/$tdir/${tfile} |
3153                 grep "lfm_magic:.*0x0BD70BD0" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3155         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3156                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3157         $LFS getstripe -v $DIR/$tdir/${tfile} |
3158                 grep "lfm_flags:.*0x0000DA05" ||
3159                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3160         $LFS getstripe $DIR/$tdir/${tfile} |
3161                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3162                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3163
3164         # modify striping should fail
3165         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3166                 error "$DIR/$tdir/$tfile: setstripe should fail"
3167
3168         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3169         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3170         cat /etc/passwd > $DIR/$tdir/$tfile &&
3171                 error "$DIR/$tdir/$tfile: write should fail"
3172
3173         # rename should succeed
3174         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3175                 error "$DIR/$tdir/$tfile: rename has failed"
3176
3177         #remove foreign_symlink file should fail
3178         rm $DIR/$tdir/${tfile}.new &&
3179                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3180
3181         #test fake symlink
3182         mkdir /tmp/${uuid1} ||
3183                 error "/tmp/${uuid1}: mkdir has failed"
3184         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3185                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3186         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3187         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3188                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3189         #read should succeed now
3190         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3191                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3192         #write should succeed now
3193         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3195         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3196                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3197         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3198                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3199
3200         #check that getstripe still works
3201         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3203
3204         # chmod should still succeed
3205         chmod 644 $DIR/$tdir/${tfile}.new ||
3206                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3207
3208         # chown should still succeed
3209         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3210                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3211
3212         # rename should still succeed
3213         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3214                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3215
3216         #remove foreign_symlink file should still fail
3217         rm $DIR/$tdir/${tfile} &&
3218                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3219
3220         #use special ioctl() to unlink foreign_symlink file
3221         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3222                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3223
3224 }
3225 run_test 27O "basic ops on foreign file of symlink type"
3226
3227 test_27P() {
3228         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3229                 skip "Need MDS version newer than 2.12.49"
3230
3231         test_mkdir $DIR/$tdir
3232         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3233         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3234
3235         trap clean_foreign_symlink EXIT
3236
3237         # enable foreign_symlink behaviour
3238         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3239
3240         # foreign symlink LMV format is a partial path by default
3241
3242         # create foreign dir (lfs + API)
3243         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3244                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3245                 error "$DIR/$tdir/${tdir}: create failed"
3246
3247         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3248                 grep "lfm_magic:.*0x0CD50CD0" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3250         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3251                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3252         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3253                 grep "lfm_flags:.*0x0000DA05" ||
3254                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3255         $LFS getdirstripe $DIR/$tdir/${tdir} |
3256                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3257                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3258
3259         # file create in dir should fail
3260         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3261         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3262
3263         # rename should succeed
3264         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3265                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3266
3267         #remove foreign_symlink dir should fail
3268         rmdir $DIR/$tdir/${tdir}.new &&
3269                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3270
3271         #test fake symlink
3272         mkdir -p /tmp/${uuid1}/${uuid2} ||
3273                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3274         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3275                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3276         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3277         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3278                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3279         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3280                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3281
3282         #check that getstripe fails now that foreign_symlink enabled
3283         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3284                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3285
3286         # file create in dir should work now
3287         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3288                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3289         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3290                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3291         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3292                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3293
3294         # chmod should still succeed
3295         chmod 755 $DIR/$tdir/${tdir}.new ||
3296                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3297
3298         # chown should still succeed
3299         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3300                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3301
3302         # rename should still succeed
3303         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3305
3306         #remove foreign_symlink dir should still fail
3307         rmdir $DIR/$tdir/${tdir} &&
3308                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3309
3310         #use special ioctl() to unlink foreign_symlink file
3311         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3312                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3313
3314         #created file should still exist
3315         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3316                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3317         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3318                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3319 }
3320 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3321
3322 test_27Q() {
3323         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3324
3325         test_mkdir $DIR/$tdir-1
3326         test_mkdir $DIR/$tdir-2
3327
3328         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3329         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3330
3331         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3332         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3333
3334         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3335         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3336
3337         # Create some bad symlinks and ensure that we don't loop
3338         # forever or something. These should return ELOOP (40) and
3339         # ENOENT (2) but I don't want to test for that because there's
3340         # always some weirdo architecture that needs to ruin
3341         # everything by defining these error numbers differently.
3342
3343         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3344         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3345
3346         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3347         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3348
3349         return 0
3350 }
3351 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3352
3353 # createtest also checks that device nodes are created and
3354 # then visible correctly (#2091)
3355 test_28() { # bug 2091
3356         test_mkdir $DIR/d28
3357         $CREATETEST $DIR/d28/ct || error "createtest failed"
3358 }
3359 run_test 28 "create/mknod/mkdir with bad file types ============"
3360
3361 test_29() {
3362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3363
3364         sync; sleep 1; sync # flush out any dirty pages from previous tests
3365         cancel_lru_locks
3366         test_mkdir $DIR/d29
3367         touch $DIR/d29/foo
3368         log 'first d29'
3369         ls -l $DIR/d29
3370
3371         declare -i LOCKCOUNTORIG=0
3372         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3373                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3374         done
3375         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3376
3377         declare -i LOCKUNUSEDCOUNTORIG=0
3378         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3379                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3380         done
3381
3382         log 'second d29'
3383         ls -l $DIR/d29
3384         log 'done'
3385
3386         declare -i LOCKCOUNTCURRENT=0
3387         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3388                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3389         done
3390
3391         declare -i LOCKUNUSEDCOUNTCURRENT=0
3392         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3393                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3394         done
3395
3396         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3397                 $LCTL set_param -n ldlm.dump_namespaces ""
3398                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3399                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3400                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3401                 return 2
3402         fi
3403         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3404                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3405                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3406                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3407                 return 3
3408         fi
3409 }
3410 run_test 29 "IT_GETATTR regression  ============================"
3411
3412 test_30a() { # was test_30
3413         cp $(which ls) $DIR || cp /bin/ls $DIR
3414         $DIR/ls / || error "Can't execute binary from lustre"
3415         rm $DIR/ls
3416 }
3417 run_test 30a "execute binary from Lustre (execve) =============="
3418
3419 test_30b() {
3420         cp `which ls` $DIR || cp /bin/ls $DIR
3421         chmod go+rx $DIR/ls
3422         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3423         rm $DIR/ls
3424 }
3425 run_test 30b "execute binary from Lustre as non-root ==========="
3426
3427 test_30c() { # b=22376
3428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3429
3430         cp $(which ls) $DIR || cp /bin/ls $DIR
3431         chmod a-rw $DIR/ls
3432         cancel_lru_locks mdc
3433         cancel_lru_locks osc
3434         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3435         rm -f $DIR/ls
3436 }
3437 run_test 30c "execute binary from Lustre without read perms ===="
3438
3439 test_30d() {
3440         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3441
3442         for i in {1..10}; do
3443                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3444                 local PID=$!
3445                 sleep 1
3446                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3447                 wait $PID || error "executing dd from Lustre failed"
3448                 rm -f $DIR/$tfile
3449         done
3450
3451         rm -f $DIR/dd
3452 }
3453 run_test 30d "execute binary from Lustre while clear locks"
3454
3455 test_31a() {
3456         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3457         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3458 }
3459 run_test 31a "open-unlink file =================================="
3460
3461 test_31b() {
3462         touch $DIR/f31 || error "touch $DIR/f31 failed"
3463         ln $DIR/f31 $DIR/f31b || error "ln failed"
3464         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3465         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3466 }
3467 run_test 31b "unlink file with multiple links while open ======="
3468
3469 test_31c() {
3470         touch $DIR/f31 || error "touch $DIR/f31 failed"
3471         ln $DIR/f31 $DIR/f31c || error "ln failed"
3472         multiop_bg_pause $DIR/f31 O_uc ||
3473                 error "multiop_bg_pause for $DIR/f31 failed"
3474         MULTIPID=$!
3475         $MULTIOP $DIR/f31c Ouc
3476         kill -USR1 $MULTIPID
3477         wait $MULTIPID
3478 }
3479 run_test 31c "open-unlink file with multiple links ============="
3480
3481 test_31d() {
3482         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3483         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3484 }
3485 run_test 31d "remove of open directory ========================="
3486
3487 test_31e() { # bug 2904
3488         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3489 }
3490 run_test 31e "remove of open non-empty directory ==============="
3491
3492 test_31f() { # bug 4554
3493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3494
3495         set -vx
3496         test_mkdir $DIR/d31f
3497         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3498         cp /etc/hosts $DIR/d31f
3499         ls -l $DIR/d31f
3500         $LFS getstripe $DIR/d31f/hosts
3501         multiop_bg_pause $DIR/d31f D_c || return 1
3502         MULTIPID=$!
3503
3504         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3505         test_mkdir $DIR/d31f
3506         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3507         cp /etc/hosts $DIR/d31f
3508         ls -l $DIR/d31f
3509         $LFS getstripe $DIR/d31f/hosts
3510         multiop_bg_pause $DIR/d31f D_c || return 1
3511         MULTIPID2=$!
3512
3513         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3514         wait $MULTIPID || error "first opendir $MULTIPID failed"
3515
3516         sleep 6
3517
3518         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3519         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3520         set +vx
3521 }
3522 run_test 31f "remove of open directory with open-unlink file ==="
3523
3524 test_31g() {
3525         echo "-- cross directory link --"
3526         test_mkdir -c1 $DIR/${tdir}ga
3527         test_mkdir -c1 $DIR/${tdir}gb
3528         touch $DIR/${tdir}ga/f
3529         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3530         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3531         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3532         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3533         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3534 }
3535 run_test 31g "cross directory link==============="
3536
3537 test_31h() {
3538         echo "-- cross directory link --"
3539         test_mkdir -c1 $DIR/${tdir}
3540         test_mkdir -c1 $DIR/${tdir}/dir
3541         touch $DIR/${tdir}/f
3542         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3543         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3544         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3545         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3546         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3547 }
3548 run_test 31h "cross directory link under child==============="
3549
3550 test_31i() {
3551         echo "-- cross directory link --"
3552         test_mkdir -c1 $DIR/$tdir
3553         test_mkdir -c1 $DIR/$tdir/dir
3554         touch $DIR/$tdir/dir/f
3555         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3556         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3557         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3558         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3559         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3560 }
3561 run_test 31i "cross directory link under parent==============="
3562
3563 test_31j() {
3564         test_mkdir -c1 -p $DIR/$tdir
3565         test_mkdir -c1 -p $DIR/$tdir/dir1
3566         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3567         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3568         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3569         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3570         return 0
3571 }
3572 run_test 31j "link for directory==============="
3573
3574 test_31k() {
3575         test_mkdir -c1 -p $DIR/$tdir
3576         touch $DIR/$tdir/s
3577         touch $DIR/$tdir/exist
3578         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3579         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3580         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3581         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3582         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3583         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3584         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3585         return 0
3586 }
3587 run_test 31k "link to file: the same, non-existing, dir==============="
3588
3589 test_31m() {
3590         mkdir $DIR/d31m
3591         touch $DIR/d31m/s
3592         mkdir $DIR/d31m2
3593         touch $DIR/d31m2/exist
3594         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3595         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3596         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3597         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3598         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3599         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3600         return 0
3601 }
3602 run_test 31m "link to file: the same, non-existing, dir==============="
3603
3604 test_31n() {
3605         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3606         nlink=$(stat --format=%h $DIR/$tfile)
3607         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3608         local fd=$(free_fd)
3609         local cmd="exec $fd<$DIR/$tfile"
3610         eval $cmd
3611         cmd="exec $fd<&-"
3612         trap "eval $cmd" EXIT
3613         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3614         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3615         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3616         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3617         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3618         eval $cmd
3619 }
3620 run_test 31n "check link count of unlinked file"
3621
3622 link_one() {
3623         local tempfile=$(mktemp $1_XXXXXX)
3624         mlink $tempfile $1 2> /dev/null &&
3625                 echo "$BASHPID: link $tempfile to $1 succeeded"
3626         munlink $tempfile
3627 }
3628
3629 test_31o() { # LU-2901
3630         test_mkdir $DIR/$tdir
3631         for LOOP in $(seq 100); do
3632                 rm -f $DIR/$tdir/$tfile*
3633                 for THREAD in $(seq 8); do
3634                         link_one $DIR/$tdir/$tfile.$LOOP &
3635                 done
3636                 wait
3637                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3638                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3639                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3640                         break || true
3641         done
3642 }
3643 run_test 31o "duplicate hard links with same filename"
3644
3645 test_31p() {
3646         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3647
3648         test_mkdir $DIR/$tdir
3649         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3650         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3651
3652         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3653                 error "open unlink test1 failed"
3654         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3655                 error "open unlink test2 failed"
3656
3657         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3658                 error "test1 still exists"
3659         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3660                 error "test2 still exists"
3661 }
3662 run_test 31p "remove of open striped directory"
3663
3664 test_31q() {
3665         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3666
3667         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3668         index=$($LFS getdirstripe -i $DIR/$tdir)
3669         [ $index -eq 3 ] || error "first stripe index $index != 3"
3670         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3671         [ $index -eq 1 ] || error "second stripe index $index != 1"
3672
3673         # when "-c <stripe_count>" is set, the number of MDTs specified after
3674         # "-i" should equal to the stripe count
3675         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3676 }
3677 run_test 31q "create striped directory on specific MDTs"
3678
3679 cleanup_test32_mount() {
3680         local rc=0
3681         trap 0
3682         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3683         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3684         losetup -d $loopdev || true
3685         rm -rf $DIR/$tdir
3686         return $rc
3687 }
3688
3689 test_32a() {
3690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3691
3692         echo "== more mountpoints and symlinks ================="
3693         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3694         trap cleanup_test32_mount EXIT
3695         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3696         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3697                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3698         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3699                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3700         cleanup_test32_mount
3701 }
3702 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3703
3704 test_32b() {
3705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3706
3707         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3708         trap cleanup_test32_mount EXIT
3709         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3710         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3711                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3712         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3713                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3714         cleanup_test32_mount
3715 }
3716 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3717
3718 test_32c() {
3719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3720
3721         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3722         trap cleanup_test32_mount EXIT
3723         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3724         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3725                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3726         test_mkdir -p $DIR/$tdir/d2/test_dir
3727         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3728                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3729         cleanup_test32_mount
3730 }
3731 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3732
3733 test_32d() {
3734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3735
3736         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3737         trap cleanup_test32_mount EXIT
3738         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3739         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3740                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3741         test_mkdir -p $DIR/$tdir/d2/test_dir
3742         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3743                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3744         cleanup_test32_mount
3745 }
3746 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3747
3748 test_32e() {
3749         rm -fr $DIR/$tdir
3750         test_mkdir -p $DIR/$tdir/tmp
3751         local tmp_dir=$DIR/$tdir/tmp
3752         ln -s $DIR/$tdir $tmp_dir/symlink11
3753         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3754         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3755         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3756 }
3757 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3758
3759 test_32f() {
3760         rm -fr $DIR/$tdir
3761         test_mkdir -p $DIR/$tdir/tmp
3762         local tmp_dir=$DIR/$tdir/tmp
3763         ln -s $DIR/$tdir $tmp_dir/symlink11
3764         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3765         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3766         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3767 }
3768 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3769
3770 test_32g() {
3771         local tmp_dir=$DIR/$tdir/tmp
3772         test_mkdir -p $tmp_dir
3773         test_mkdir $DIR/${tdir}2
3774         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3775         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3776         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3777         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3778         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3779         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3780 }
3781 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3782
3783 test_32h() {
3784         rm -fr $DIR/$tdir $DIR/${tdir}2
3785         tmp_dir=$DIR/$tdir/tmp
3786         test_mkdir -p $tmp_dir
3787         test_mkdir $DIR/${tdir}2
3788         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3789         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3790         ls $tmp_dir/symlink12 || error "listing symlink12"
3791         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3792 }
3793 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3794
3795 test_32i() {
3796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3797
3798         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3799         trap cleanup_test32_mount EXIT
3800         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3801         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3802                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3803         touch $DIR/$tdir/test_file
3804         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3805                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3806         cleanup_test32_mount
3807 }
3808 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3809
3810 test_32j() {
3811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3812
3813         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3814         trap cleanup_test32_mount EXIT
3815         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3816         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3817                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3818         touch $DIR/$tdir/test_file
3819         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3820                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3821         cleanup_test32_mount
3822 }
3823 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3824
3825 test_32k() {
3826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3827
3828         rm -fr $DIR/$tdir
3829         trap cleanup_test32_mount EXIT
3830         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3831         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3832                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3833         test_mkdir -p $DIR/$tdir/d2
3834         touch $DIR/$tdir/d2/test_file || error "touch failed"
3835         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3836                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3837         cleanup_test32_mount
3838 }
3839 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3840
3841 test_32l() {
3842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3843
3844         rm -fr $DIR/$tdir
3845         trap cleanup_test32_mount EXIT
3846         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3847         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3848                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3849         test_mkdir -p $DIR/$tdir/d2
3850         touch $DIR/$tdir/d2/test_file || error "touch failed"
3851         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3852                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3853         cleanup_test32_mount
3854 }
3855 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3856
3857 test_32m() {
3858         rm -fr $DIR/d32m
3859         test_mkdir -p $DIR/d32m/tmp
3860         TMP_DIR=$DIR/d32m/tmp
3861         ln -s $DIR $TMP_DIR/symlink11
3862         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3863         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3864                 error "symlink11 not a link"
3865         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3866                 error "symlink01 not a link"
3867 }
3868 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3869
3870 test_32n() {
3871         rm -fr $DIR/d32n
3872         test_mkdir -p $DIR/d32n/tmp
3873         TMP_DIR=$DIR/d32n/tmp
3874         ln -s $DIR $TMP_DIR/symlink11
3875         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3876         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3877         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3878 }
3879 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3880
3881 test_32o() {
3882         touch $DIR/$tfile
3883         test_mkdir -p $DIR/d32o/tmp
3884         TMP_DIR=$DIR/d32o/tmp
3885         ln -s $DIR/$tfile $TMP_DIR/symlink12
3886         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3887         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3888                 error "symlink12 not a link"
3889         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3890         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3891                 error "$DIR/d32o/tmp/symlink12 not file type"
3892         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3893                 error "$DIR/d32o/symlink02 not file type"
3894 }
3895 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3896
3897 test_32p() {
3898         log 32p_1
3899         rm -fr $DIR/d32p
3900         log 32p_2
3901         rm -f $DIR/$tfile
3902         log 32p_3
3903         touch $DIR/$tfile
3904         log 32p_4
3905         test_mkdir -p $DIR/d32p/tmp
3906         log 32p_5
3907         TMP_DIR=$DIR/d32p/tmp
3908         log 32p_6
3909         ln -s $DIR/$tfile $TMP_DIR/symlink12
3910         log 32p_7
3911         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3912         log 32p_8
3913         cat $DIR/d32p/tmp/symlink12 ||
3914                 error "Can't open $DIR/d32p/tmp/symlink12"
3915         log 32p_9
3916         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3917         log 32p_10
3918 }
3919 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3920
3921 test_32q() {
3922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3923
3924         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3925         trap cleanup_test32_mount EXIT
3926         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3927         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3928         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3929                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3930         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3931         cleanup_test32_mount
3932 }
3933 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3934
3935 test_32r() {
3936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3937
3938         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3939         trap cleanup_test32_mount EXIT
3940         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3941         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3942         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3943                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3944         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3945         cleanup_test32_mount
3946 }
3947 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3948
3949 test_33aa() {
3950         rm -f $DIR/$tfile
3951         touch $DIR/$tfile
3952         chmod 444 $DIR/$tfile
3953         chown $RUNAS_ID $DIR/$tfile
3954         log 33_1
3955         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3956         log 33_2
3957 }
3958 run_test 33aa "write file with mode 444 (should return error)"
3959
3960 test_33a() {
3961         rm -fr $DIR/$tdir
3962         test_mkdir $DIR/$tdir
3963         chown $RUNAS_ID $DIR/$tdir
3964         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3965                 error "$RUNAS create $tdir/$tfile failed"
3966         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3967                 error "open RDWR" || true
3968 }
3969 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3970
3971 test_33b() {
3972         rm -fr $DIR/$tdir
3973         test_mkdir $DIR/$tdir
3974         chown $RUNAS_ID $DIR/$tdir
3975         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3976 }
3977 run_test 33b "test open file with malformed flags (No panic)"
3978
3979 test_33c() {
3980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3981         remote_ost_nodsh && skip "remote OST with nodsh"
3982
3983         local ostnum
3984         local ostname
3985         local write_bytes
3986         local all_zeros
3987
3988         all_zeros=true
3989         test_mkdir $DIR/$tdir
3990         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3991
3992         sync
3993         for ostnum in $(seq $OSTCOUNT); do
3994                 # test-framework's OST numbering is one-based, while Lustre's
3995                 # is zero-based
3996                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3997                 # check if at least some write_bytes stats are counted
3998                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3999                               obdfilter.$ostname.stats |
4000                               awk '/^write_bytes/ {print $7}' )
4001                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4002                 if (( ${write_bytes:-0} > 0 )); then
4003                         all_zeros=false
4004                         break
4005                 fi
4006         done
4007
4008         $all_zeros || return 0
4009
4010         # Write four bytes
4011         echo foo > $DIR/$tdir/bar
4012         # Really write them
4013         sync
4014
4015         # Total up write_bytes after writing.  We'd better find non-zeros.
4016         for ostnum in $(seq $OSTCOUNT); do
4017                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4018                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4019                               obdfilter/$ostname/stats |
4020                               awk '/^write_bytes/ {print $7}' )
4021                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4022                 if (( ${write_bytes:-0} > 0 )); then
4023                         all_zeros=false
4024                         break
4025                 fi
4026         done
4027
4028         if $all_zeros; then
4029                 for ostnum in $(seq $OSTCOUNT); do
4030                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4031                         echo "Check write_bytes is in obdfilter.*.stats:"
4032                         do_facet ost$ostnum lctl get_param -n \
4033                                 obdfilter.$ostname.stats
4034                 done
4035                 error "OST not keeping write_bytes stats (b=22312)"
4036         fi
4037 }
4038 run_test 33c "test write_bytes stats"
4039
4040 test_33d() {
4041         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4043
4044         local MDTIDX=1
4045         local remote_dir=$DIR/$tdir/remote_dir
4046
4047         test_mkdir $DIR/$tdir
4048         $LFS mkdir -i $MDTIDX $remote_dir ||
4049                 error "create remote directory failed"
4050
4051         touch $remote_dir/$tfile
4052         chmod 444 $remote_dir/$tfile
4053         chown $RUNAS_ID $remote_dir/$tfile
4054
4055         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4056
4057         chown $RUNAS_ID $remote_dir
4058         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4059                                         error "create" || true
4060         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4061                                     error "open RDWR" || true
4062         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4063 }
4064 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4065
4066 test_33e() {
4067         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4068
4069         mkdir $DIR/$tdir
4070
4071         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4072         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4073         mkdir $DIR/$tdir/local_dir
4074
4075         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4076         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4077         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4078
4079         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4080                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4081
4082         rmdir $DIR/$tdir/* || error "rmdir failed"
4083
4084         umask 777
4085         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4086         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4087         mkdir $DIR/$tdir/local_dir
4088
4089         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4090         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4091         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4092
4093         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4094                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4095
4096         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4097
4098         umask 000
4099         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4100         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4101         mkdir $DIR/$tdir/local_dir
4102
4103         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4104         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4105         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4106
4107         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4108                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4109 }
4110 run_test 33e "mkdir and striped directory should have same mode"
4111
4112 cleanup_33f() {
4113         trap 0
4114         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4115 }
4116
4117 test_33f() {
4118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4119         remote_mds_nodsh && skip "remote MDS with nodsh"
4120
4121         mkdir $DIR/$tdir
4122         chmod go+rwx $DIR/$tdir
4123         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4124         trap cleanup_33f EXIT
4125
4126         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4127                 error "cannot create striped directory"
4128
4129         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4130                 error "cannot create files in striped directory"
4131
4132         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4133                 error "cannot remove files in striped directory"
4134
4135         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4136                 error "cannot remove striped directory"
4137
4138         cleanup_33f
4139 }
4140 run_test 33f "nonroot user can create, access, and remove a striped directory"
4141
4142 test_33g() {
4143         mkdir -p $DIR/$tdir/dir2
4144
4145         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4146         echo $err
4147         [[ $err =~ "exists" ]] || error "Not exists error"
4148 }
4149 run_test 33g "nonroot user create already existing root created file"
4150
4151 test_33h() {
4152         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4153         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4154                 skip "Need MDS version at least 2.13.50"
4155
4156         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4157                 error "mkdir $tdir failed"
4158         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4159
4160         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4161         local index2
4162
4163         for fname in $DIR/$tdir/$tfile.bak \
4164                      $DIR/$tdir/$tfile.SAV \
4165                      $DIR/$tdir/$tfile.orig \
4166                      $DIR/$tdir/$tfile~; do
4167                 touch $fname  || error "touch $fname failed"
4168                 index2=$($LFS getstripe -m $fname)
4169                 [ $index -eq $index2 ] ||
4170                         error "$fname MDT index mismatch $index != $index2"
4171         done
4172
4173         local failed=0
4174         for i in {1..250}; do
4175                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4176                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4177                         touch $fname  || error "touch $fname failed"
4178                         index2=$($LFS getstripe -m $fname)
4179                         if [[ $index != $index2 ]]; then
4180                                 failed=$((failed + 1))
4181                                 echo "$fname MDT index mismatch $index != $index2"
4182                         fi
4183                 done
4184         done
4185         echo "$failed MDT index mismatches"
4186         (( failed < 20 )) || error "MDT index mismatch $failed times"
4187
4188 }
4189 run_test 33h "temp file is located on the same MDT as target"
4190
4191 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4192 test_34a() {
4193         rm -f $DIR/f34
4194         $MCREATE $DIR/f34 || error "mcreate failed"
4195         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4196                 error "getstripe failed"
4197         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4198         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4199                 error "getstripe failed"
4200         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4201                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4202 }
4203 run_test 34a "truncate file that has not been opened ==========="
4204
4205 test_34b() {
4206         [ ! -f $DIR/f34 ] && test_34a
4207         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4208                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4209         $OPENFILE -f O_RDONLY $DIR/f34
4210         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4211                 error "getstripe failed"
4212         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4213                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4214 }
4215 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4216
4217 test_34c() {
4218         [ ! -f $DIR/f34 ] && test_34a
4219         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4220                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4221         $OPENFILE -f O_RDWR $DIR/f34
4222         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4223                 error "$LFS getstripe failed"
4224         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4225                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4226 }
4227 run_test 34c "O_RDWR opening file-with-size works =============="
4228
4229 test_34d() {
4230         [ ! -f $DIR/f34 ] && test_34a
4231         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4232                 error "dd failed"
4233         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4234                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4235         rm $DIR/f34
4236 }
4237 run_test 34d "write to sparse file ============================="
4238
4239 test_34e() {
4240         rm -f $DIR/f34e
4241         $MCREATE $DIR/f34e || error "mcreate failed"
4242         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4243         $CHECKSTAT -s 1000 $DIR/f34e ||
4244                 error "Size of $DIR/f34e not equal to 1000 bytes"
4245         $OPENFILE -f O_RDWR $DIR/f34e
4246         $CHECKSTAT -s 1000 $DIR/f34e ||
4247                 error "Size of $DIR/f34e not equal to 1000 bytes"
4248 }
4249 run_test 34e "create objects, some with size and some without =="
4250
4251 test_34f() { # bug 6242, 6243
4252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4253
4254         SIZE34F=48000
4255         rm -f $DIR/f34f
4256         $MCREATE $DIR/f34f || error "mcreate failed"
4257         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4258         dd if=$DIR/f34f of=$TMP/f34f
4259         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4260         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4261         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4262         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4263         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4264 }
4265 run_test 34f "read from a file with no objects until EOF ======="
4266
4267 test_34g() {
4268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4269
4270         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4271                 error "dd failed"
4272         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4273         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4274                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4275         cancel_lru_locks osc
4276         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4277                 error "wrong size after lock cancel"
4278
4279         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4280         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4281                 error "expanding truncate failed"
4282         cancel_lru_locks osc
4283         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4284                 error "wrong expanded size after lock cancel"
4285 }
4286 run_test 34g "truncate long file ==============================="
4287
4288 test_34h() {
4289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4290
4291         local gid=10
4292         local sz=1000
4293
4294         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4295         sync # Flush the cache so that multiop below does not block on cache
4296              # flush when getting the group lock
4297         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4298         MULTIPID=$!
4299
4300         # Since just timed wait is not good enough, let's do a sync write
4301         # that way we are sure enough time for a roundtrip + processing
4302         # passed + 2 seconds of extra margin.
4303         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4304         rm $DIR/${tfile}-1
4305         sleep 2
4306
4307         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4308                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4309                 kill -9 $MULTIPID
4310         fi
4311         wait $MULTIPID
4312         local nsz=`stat -c %s $DIR/$tfile`
4313         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4314 }
4315 run_test 34h "ftruncate file under grouplock should not block"
4316
4317 test_35a() {
4318         cp /bin/sh $DIR/f35a
4319         chmod 444 $DIR/f35a
4320         chown $RUNAS_ID $DIR/f35a
4321         $RUNAS $DIR/f35a && error || true
4322         rm $DIR/f35a
4323 }
4324 run_test 35a "exec file with mode 444 (should return and not leak)"
4325
4326 test_36a() {
4327         rm -f $DIR/f36
4328         utime $DIR/f36 || error "utime failed for MDS"
4329 }
4330 run_test 36a "MDS utime check (mknod, utime)"
4331
4332 test_36b() {
4333         echo "" > $DIR/f36
4334         utime $DIR/f36 || error "utime failed for OST"
4335 }
4336 run_test 36b "OST utime check (open, utime)"
4337
4338 test_36c() {
4339         rm -f $DIR/d36/f36
4340         test_mkdir $DIR/d36
4341         chown $RUNAS_ID $DIR/d36
4342         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4343 }
4344 run_test 36c "non-root MDS utime check (mknod, utime)"
4345
4346 test_36d() {
4347         [ ! -d $DIR/d36 ] && test_36c
4348         echo "" > $DIR/d36/f36
4349         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4350 }
4351 run_test 36d "non-root OST utime check (open, utime)"
4352
4353 test_36e() {
4354         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4355
4356         test_mkdir $DIR/$tdir
4357         touch $DIR/$tdir/$tfile
4358         $RUNAS utime $DIR/$tdir/$tfile &&
4359                 error "utime worked, expected failure" || true
4360 }
4361 run_test 36e "utime on non-owned file (should return error)"
4362
4363 subr_36fh() {
4364         local fl="$1"
4365         local LANG_SAVE=$LANG
4366         local LC_LANG_SAVE=$LC_LANG
4367         export LANG=C LC_LANG=C # for date language
4368
4369         DATESTR="Dec 20  2000"
4370         test_mkdir $DIR/$tdir
4371         lctl set_param fail_loc=$fl
4372         date; date +%s
4373         cp /etc/hosts $DIR/$tdir/$tfile
4374         sync & # write RPC generated with "current" inode timestamp, but delayed
4375         sleep 1
4376         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4377         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4378         cancel_lru_locks $OSC
4379         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4380         date; date +%s
4381         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4382                 echo "BEFORE: $LS_BEFORE" && \
4383                 echo "AFTER : $LS_AFTER" && \
4384                 echo "WANT  : $DATESTR" && \
4385                 error "$DIR/$tdir/$tfile timestamps changed" || true
4386
4387         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4388 }
4389
4390 test_36f() {
4391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4392
4393         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4394         subr_36fh "0x80000214"
4395 }
4396 run_test 36f "utime on file racing with OST BRW write =========="
4397
4398 test_36g() {
4399         remote_ost_nodsh && skip "remote OST with nodsh"
4400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4401         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4402                 skip "Need MDS version at least 2.12.51"
4403
4404         local fmd_max_age
4405         local fmd
4406         local facet="ost1"
4407         local tgt="obdfilter"
4408
4409         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4410
4411         test_mkdir $DIR/$tdir
4412         fmd_max_age=$(do_facet $facet \
4413                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4414                 head -n 1")
4415
4416         echo "FMD max age: ${fmd_max_age}s"
4417         touch $DIR/$tdir/$tfile
4418         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4419                 gawk '{cnt=cnt+$1}  END{print cnt}')
4420         echo "FMD before: $fmd"
4421         [[ $fmd == 0 ]] &&
4422                 error "FMD wasn't create by touch"
4423         sleep $((fmd_max_age + 12))
4424         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4425                 gawk '{cnt=cnt+$1}  END{print cnt}')
4426         echo "FMD after: $fmd"
4427         [[ $fmd == 0 ]] ||
4428                 error "FMD wasn't expired by ping"
4429 }
4430 run_test 36g "FMD cache expiry ====================="
4431
4432 test_36h() {
4433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4434
4435         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4436         subr_36fh "0x80000227"
4437 }
4438 run_test 36h "utime on file racing with OST BRW write =========="
4439
4440 test_36i() {
4441         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4442
4443         test_mkdir $DIR/$tdir
4444         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4445
4446         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4447         local new_mtime=$((mtime + 200))
4448
4449         #change Modify time of striped dir
4450         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4451                         error "change mtime failed"
4452
4453         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4454
4455         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4456 }
4457 run_test 36i "change mtime on striped directory"
4458
4459 # test_37 - duplicate with tests 32q 32r
4460
4461 test_38() {
4462         local file=$DIR/$tfile
4463         touch $file
4464         openfile -f O_DIRECTORY $file
4465         local RC=$?
4466         local ENOTDIR=20
4467         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4468         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4469 }
4470 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4471
4472 test_39a() { # was test_39
4473         touch $DIR/$tfile
4474         touch $DIR/${tfile}2
4475 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4476 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4477 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4478         sleep 2
4479         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4480         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4481                 echo "mtime"
4482                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4483                 echo "atime"
4484                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4485                 echo "ctime"
4486                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4487                 error "O_TRUNC didn't change timestamps"
4488         fi
4489 }
4490 run_test 39a "mtime changed on create"
4491
4492 test_39b() {
4493         test_mkdir -c1 $DIR/$tdir
4494         cp -p /etc/passwd $DIR/$tdir/fopen
4495         cp -p /etc/passwd $DIR/$tdir/flink
4496         cp -p /etc/passwd $DIR/$tdir/funlink
4497         cp -p /etc/passwd $DIR/$tdir/frename
4498         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4499
4500         sleep 1
4501         echo "aaaaaa" >> $DIR/$tdir/fopen
4502         echo "aaaaaa" >> $DIR/$tdir/flink
4503         echo "aaaaaa" >> $DIR/$tdir/funlink
4504         echo "aaaaaa" >> $DIR/$tdir/frename
4505
4506         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4507         local link_new=`stat -c %Y $DIR/$tdir/flink`
4508         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4509         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4510
4511         cat $DIR/$tdir/fopen > /dev/null
4512         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4513         rm -f $DIR/$tdir/funlink2
4514         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4515
4516         for (( i=0; i < 2; i++ )) ; do
4517                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4518                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4519                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4520                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4521
4522                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4523                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4524                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4525                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4526
4527                 cancel_lru_locks $OSC
4528                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4529         done
4530 }
4531 run_test 39b "mtime change on open, link, unlink, rename  ======"
4532
4533 # this should be set to past
4534 TEST_39_MTIME=`date -d "1 year ago" +%s`
4535
4536 # bug 11063
4537 test_39c() {
4538         touch $DIR1/$tfile
4539         sleep 2
4540         local mtime0=`stat -c %Y $DIR1/$tfile`
4541
4542         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4543         local mtime1=`stat -c %Y $DIR1/$tfile`
4544         [ "$mtime1" = $TEST_39_MTIME ] || \
4545                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4546
4547         local d1=`date +%s`
4548         echo hello >> $DIR1/$tfile
4549         local d2=`date +%s`
4550         local mtime2=`stat -c %Y $DIR1/$tfile`
4551         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4552                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4553
4554         mv $DIR1/$tfile $DIR1/$tfile-1
4555
4556         for (( i=0; i < 2; i++ )) ; do
4557                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4558                 [ "$mtime2" = "$mtime3" ] || \
4559                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4560
4561                 cancel_lru_locks $OSC
4562                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4563         done
4564 }
4565 run_test 39c "mtime change on rename ==========================="
4566
4567 # bug 21114
4568 test_39d() {
4569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4570
4571         touch $DIR1/$tfile
4572         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4573
4574         for (( i=0; i < 2; i++ )) ; do
4575                 local mtime=`stat -c %Y $DIR1/$tfile`
4576                 [ $mtime = $TEST_39_MTIME ] || \
4577                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4578
4579                 cancel_lru_locks $OSC
4580                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4581         done
4582 }
4583 run_test 39d "create, utime, stat =============================="
4584
4585 # bug 21114
4586 test_39e() {
4587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4588
4589         touch $DIR1/$tfile
4590         local mtime1=`stat -c %Y $DIR1/$tfile`
4591
4592         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4593
4594         for (( i=0; i < 2; i++ )) ; do
4595                 local mtime2=`stat -c %Y $DIR1/$tfile`
4596                 [ $mtime2 = $TEST_39_MTIME ] || \
4597                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4598
4599                 cancel_lru_locks $OSC
4600                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4601         done
4602 }
4603 run_test 39e "create, stat, utime, stat ========================"
4604
4605 # bug 21114
4606 test_39f() {
4607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4608
4609         touch $DIR1/$tfile
4610         mtime1=`stat -c %Y $DIR1/$tfile`
4611
4612         sleep 2
4613         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4614
4615         for (( i=0; i < 2; i++ )) ; do
4616                 local mtime2=`stat -c %Y $DIR1/$tfile`
4617                 [ $mtime2 = $TEST_39_MTIME ] || \
4618                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4619
4620                 cancel_lru_locks $OSC
4621                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4622         done
4623 }
4624 run_test 39f "create, stat, sleep, utime, stat ================="
4625
4626 # bug 11063
4627 test_39g() {
4628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4629
4630         echo hello >> $DIR1/$tfile
4631         local mtime1=`stat -c %Y $DIR1/$tfile`
4632
4633         sleep 2
4634         chmod o+r $DIR1/$tfile
4635
4636         for (( i=0; i < 2; i++ )) ; do
4637                 local mtime2=`stat -c %Y $DIR1/$tfile`
4638                 [ "$mtime1" = "$mtime2" ] || \
4639                         error "lost mtime: $mtime2, should be $mtime1"
4640
4641                 cancel_lru_locks $OSC
4642                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4643         done
4644 }
4645 run_test 39g "write, chmod, stat ==============================="
4646
4647 # bug 11063
4648 test_39h() {
4649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4650
4651         touch $DIR1/$tfile
4652         sleep 1
4653
4654         local d1=`date`
4655         echo hello >> $DIR1/$tfile
4656         local mtime1=`stat -c %Y $DIR1/$tfile`
4657
4658         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4659         local d2=`date`
4660         if [ "$d1" != "$d2" ]; then
4661                 echo "write and touch not within one second"
4662         else
4663                 for (( i=0; i < 2; i++ )) ; do
4664                         local mtime2=`stat -c %Y $DIR1/$tfile`
4665                         [ "$mtime2" = $TEST_39_MTIME ] || \
4666                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4667
4668                         cancel_lru_locks $OSC
4669                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4670                 done
4671         fi
4672 }
4673 run_test 39h "write, utime within one second, stat ============="
4674
4675 test_39i() {
4676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4677
4678         touch $DIR1/$tfile
4679         sleep 1
4680
4681         echo hello >> $DIR1/$tfile
4682         local mtime1=`stat -c %Y $DIR1/$tfile`
4683
4684         mv $DIR1/$tfile $DIR1/$tfile-1
4685
4686         for (( i=0; i < 2; i++ )) ; do
4687                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4688
4689                 [ "$mtime1" = "$mtime2" ] || \
4690                         error "lost mtime: $mtime2, should be $mtime1"
4691
4692                 cancel_lru_locks $OSC
4693                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4694         done
4695 }
4696 run_test 39i "write, rename, stat =============================="
4697
4698 test_39j() {
4699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4700
4701         start_full_debug_logging
4702         touch $DIR1/$tfile
4703         sleep 1
4704
4705         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4706         lctl set_param fail_loc=0x80000412
4707         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4708                 error "multiop failed"
4709         local multipid=$!
4710         local mtime1=`stat -c %Y $DIR1/$tfile`
4711
4712         mv $DIR1/$tfile $DIR1/$tfile-1
4713
4714         kill -USR1 $multipid
4715         wait $multipid || error "multiop close failed"
4716
4717         for (( i=0; i < 2; i++ )) ; do
4718                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4719                 [ "$mtime1" = "$mtime2" ] ||
4720                         error "mtime is lost on close: $mtime2, " \
4721                               "should be $mtime1"
4722
4723                 cancel_lru_locks
4724                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4725         done
4726         lctl set_param fail_loc=0
4727         stop_full_debug_logging
4728 }
4729 run_test 39j "write, rename, close, stat ======================="
4730
4731 test_39k() {
4732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4733
4734         touch $DIR1/$tfile
4735         sleep 1
4736
4737         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4738         local multipid=$!
4739         local mtime1=`stat -c %Y $DIR1/$tfile`
4740
4741         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4742
4743         kill -USR1 $multipid
4744         wait $multipid || error "multiop close failed"
4745
4746         for (( i=0; i < 2; i++ )) ; do
4747                 local mtime2=`stat -c %Y $DIR1/$tfile`
4748
4749                 [ "$mtime2" = $TEST_39_MTIME ] || \
4750                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4751
4752                 cancel_lru_locks
4753                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4754         done
4755 }
4756 run_test 39k "write, utime, close, stat ========================"
4757
4758 # this should be set to future
4759 TEST_39_ATIME=`date -d "1 year" +%s`
4760
4761 test_39l() {
4762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4763         remote_mds_nodsh && skip "remote MDS with nodsh"
4764
4765         local atime_diff=$(do_facet $SINGLEMDS \
4766                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4767         rm -rf $DIR/$tdir
4768         mkdir -p $DIR/$tdir
4769
4770         # test setting directory atime to future
4771         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4772         local atime=$(stat -c %X $DIR/$tdir)
4773         [ "$atime" = $TEST_39_ATIME ] ||
4774                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4775
4776         # test setting directory atime from future to now
4777         local now=$(date +%s)
4778         touch -a -d @$now $DIR/$tdir
4779
4780         atime=$(stat -c %X $DIR/$tdir)
4781         [ "$atime" -eq "$now"  ] ||
4782                 error "atime is not updated from future: $atime, $now"
4783
4784         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4785         sleep 3
4786
4787         # test setting directory atime when now > dir atime + atime_diff
4788         local d1=$(date +%s)
4789         ls $DIR/$tdir
4790         local d2=$(date +%s)
4791         cancel_lru_locks mdc
4792         atime=$(stat -c %X $DIR/$tdir)
4793         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4794                 error "atime is not updated  : $atime, should be $d2"
4795
4796         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4797         sleep 3
4798
4799         # test not setting directory atime when now < dir atime + atime_diff
4800         ls $DIR/$tdir
4801         cancel_lru_locks mdc
4802         atime=$(stat -c %X $DIR/$tdir)
4803         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4804                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4805
4806         do_facet $SINGLEMDS \
4807                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4808 }
4809 run_test 39l "directory atime update ==========================="
4810
4811 test_39m() {
4812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4813
4814         touch $DIR1/$tfile
4815         sleep 2
4816         local far_past_mtime=$(date -d "May 29 1953" +%s)
4817         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4818
4819         touch -m -d @$far_past_mtime $DIR1/$tfile
4820         touch -a -d @$far_past_atime $DIR1/$tfile
4821
4822         for (( i=0; i < 2; i++ )) ; do
4823                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4824                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4825                         error "atime or mtime set incorrectly"
4826
4827                 cancel_lru_locks $OSC
4828                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4829         done
4830 }
4831 run_test 39m "test atime and mtime before 1970"
4832
4833 test_39n() { # LU-3832
4834         remote_mds_nodsh && skip "remote MDS with nodsh"
4835
4836         local atime_diff=$(do_facet $SINGLEMDS \
4837                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4838         local atime0
4839         local atime1
4840         local atime2
4841
4842         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4843
4844         rm -rf $DIR/$tfile
4845         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4846         atime0=$(stat -c %X $DIR/$tfile)
4847
4848         sleep 5
4849         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4850         atime1=$(stat -c %X $DIR/$tfile)
4851
4852         sleep 5
4853         cancel_lru_locks mdc
4854         cancel_lru_locks osc
4855         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4856         atime2=$(stat -c %X $DIR/$tfile)
4857
4858         do_facet $SINGLEMDS \
4859                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4860
4861         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4862         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4863 }
4864 run_test 39n "check that O_NOATIME is honored"
4865
4866 test_39o() {
4867         TESTDIR=$DIR/$tdir/$tfile
4868         [ -e $TESTDIR ] && rm -rf $TESTDIR
4869         mkdir -p $TESTDIR
4870         cd $TESTDIR
4871         links1=2
4872         ls
4873         mkdir a b
4874         ls
4875         links2=$(stat -c %h .)
4876         [ $(($links1 + 2)) != $links2 ] &&
4877                 error "wrong links count $(($links1 + 2)) != $links2"
4878         rmdir b
4879         links3=$(stat -c %h .)
4880         [ $(($links1 + 1)) != $links3 ] &&
4881                 error "wrong links count $links1 != $links3"
4882         return 0
4883 }
4884 run_test 39o "directory cached attributes updated after create"
4885
4886 test_39p() {
4887         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4888
4889         local MDTIDX=1
4890         TESTDIR=$DIR/$tdir/$tdir
4891         [ -e $TESTDIR ] && rm -rf $TESTDIR
4892         test_mkdir -p $TESTDIR
4893         cd $TESTDIR
4894         links1=2
4895         ls
4896         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4897         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4898         ls
4899         links2=$(stat -c %h .)
4900         [ $(($links1 + 2)) != $links2 ] &&
4901                 error "wrong links count $(($links1 + 2)) != $links2"
4902         rmdir remote_dir2
4903         links3=$(stat -c %h .)
4904         [ $(($links1 + 1)) != $links3 ] &&
4905                 error "wrong links count $links1 != $links3"
4906         return 0
4907 }
4908 run_test 39p "remote directory cached attributes updated after create ========"
4909
4910 test_39r() {
4911         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4912                 skip "no atime update on old OST"
4913         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4914                 skip_env "ldiskfs only test"
4915         fi
4916
4917         local saved_adiff
4918         saved_adiff=$(do_facet ost1 \
4919                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4920         stack_trap "do_facet ost1 \
4921                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4922
4923         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4924
4925         $LFS setstripe -i 0 $DIR/$tfile
4926         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4927                 error "can't write initial file"
4928         cancel_lru_locks osc
4929
4930         # exceed atime_diff and access file
4931         sleep 6
4932         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4933                 error "can't udpate atime"
4934
4935         local atime_cli=$(stat -c %X $DIR/$tfile)
4936         echo "client atime: $atime_cli"
4937         # allow atime update to be written to device
4938         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4939         sleep 5
4940
4941         local ostdev=$(ostdevname 1)
4942         local fid=($(lfs getstripe -y $DIR/$tfile |
4943                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4944         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4945         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4946
4947         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4948         local atime_ost=$(do_facet ost1 "$cmd" |&
4949                           awk -F'[: ]' '/atime:/ { print $4 }')
4950         (( atime_cli == atime_ost )) ||
4951                 error "atime on client $atime_cli != ost $atime_ost"
4952 }
4953 run_test 39r "lazy atime update on OST"
4954
4955 test_39q() { # LU-8041
4956         local testdir=$DIR/$tdir
4957         mkdir -p $testdir
4958         multiop_bg_pause $testdir D_c || error "multiop failed"
4959         local multipid=$!
4960         cancel_lru_locks mdc
4961         kill -USR1 $multipid
4962         local atime=$(stat -c %X $testdir)
4963         [ "$atime" -ne 0 ] || error "atime is zero"
4964 }
4965 run_test 39q "close won't zero out atime"
4966
4967 test_40() {
4968         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4969         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4970                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4971         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4972                 error "$tfile is not 4096 bytes in size"
4973 }
4974 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4975
4976 test_41() {
4977         # bug 1553
4978         small_write $DIR/f41 18
4979 }
4980 run_test 41 "test small file write + fstat ====================="
4981
4982 count_ost_writes() {
4983         lctl get_param -n ${OSC}.*.stats |
4984                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4985                         END { printf("%0.0f", writes) }'
4986 }
4987
4988 # decent default
4989 WRITEBACK_SAVE=500
4990 DIRTY_RATIO_SAVE=40
4991 MAX_DIRTY_RATIO=50
4992 BG_DIRTY_RATIO_SAVE=10
4993 MAX_BG_DIRTY_RATIO=25
4994
4995 start_writeback() {
4996         trap 0
4997         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4998         # dirty_ratio, dirty_background_ratio
4999         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5000                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5001                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5002                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5003         else
5004                 # if file not here, we are a 2.4 kernel
5005                 kill -CONT `pidof kupdated`
5006         fi
5007 }
5008
5009 stop_writeback() {
5010         # setup the trap first, so someone cannot exit the test at the
5011         # exact wrong time and mess up a machine
5012         trap start_writeback EXIT
5013         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5014         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5015                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5016                 sysctl -w vm.dirty_writeback_centisecs=0
5017                 sysctl -w vm.dirty_writeback_centisecs=0
5018                 # save and increase /proc/sys/vm/dirty_ratio
5019                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5020                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5021                 # save and increase /proc/sys/vm/dirty_background_ratio
5022                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5023                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5024         else
5025                 # if file not here, we are a 2.4 kernel
5026                 kill -STOP `pidof kupdated`
5027         fi
5028 }
5029
5030 # ensure that all stripes have some grant before we test client-side cache
5031 setup_test42() {
5032         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5033                 dd if=/dev/zero of=$i bs=4k count=1
5034                 rm $i
5035         done
5036 }
5037
5038 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5039 # file truncation, and file removal.
5040 test_42a() {
5041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5042
5043         setup_test42
5044         cancel_lru_locks $OSC
5045         stop_writeback
5046         sync; sleep 1; sync # just to be safe
5047         BEFOREWRITES=`count_ost_writes`
5048         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5049         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5050         AFTERWRITES=`count_ost_writes`
5051         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5052                 error "$BEFOREWRITES < $AFTERWRITES"
5053         start_writeback
5054 }
5055 run_test 42a "ensure that we don't flush on close"
5056
5057 test_42b() {
5058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5059
5060         setup_test42
5061         cancel_lru_locks $OSC
5062         stop_writeback
5063         sync
5064         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5065         BEFOREWRITES=$(count_ost_writes)
5066         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5067         AFTERWRITES=$(count_ost_writes)
5068         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5069                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5070         fi
5071         BEFOREWRITES=$(count_ost_writes)
5072         sync || error "sync: $?"
5073         AFTERWRITES=$(count_ost_writes)
5074         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5075                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5076         fi
5077         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5078         start_writeback
5079         return 0
5080 }
5081 run_test 42b "test destroy of file with cached dirty data ======"
5082
5083 # if these tests just want to test the effect of truncation,
5084 # they have to be very careful.  consider:
5085 # - the first open gets a {0,EOF}PR lock
5086 # - the first write conflicts and gets a {0, count-1}PW
5087 # - the rest of the writes are under {count,EOF}PW
5088 # - the open for truncate tries to match a {0,EOF}PR
5089 #   for the filesize and cancels the PWs.
5090 # any number of fixes (don't get {0,EOF} on open, match
5091 # composite locks, do smarter file size management) fix
5092 # this, but for now we want these tests to verify that
5093 # the cancellation with truncate intent works, so we
5094 # start the file with a full-file pw lock to match against
5095 # until the truncate.
5096 trunc_test() {
5097         test=$1
5098         file=$DIR/$test
5099         offset=$2
5100         cancel_lru_locks $OSC
5101         stop_writeback
5102         # prime the file with 0,EOF PW to match
5103         touch $file
5104         $TRUNCATE $file 0
5105         sync; sync
5106         # now the real test..
5107         dd if=/dev/zero of=$file bs=1024 count=100
5108         BEFOREWRITES=`count_ost_writes`
5109         $TRUNCATE $file $offset
5110         cancel_lru_locks $OSC
5111         AFTERWRITES=`count_ost_writes`
5112         start_writeback
5113 }
5114
5115 test_42c() {
5116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5117
5118         trunc_test 42c 1024
5119         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5120                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5121         rm $file
5122 }
5123 run_test 42c "test partial truncate of file with cached dirty data"
5124
5125 test_42d() {
5126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5127
5128         trunc_test 42d 0
5129         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5130                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5131         rm $file
5132 }
5133 run_test 42d "test complete truncate of file with cached dirty data"
5134
5135 test_42e() { # bug22074
5136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5137
5138         local TDIR=$DIR/${tdir}e
5139         local pages=16 # hardcoded 16 pages, don't change it.
5140         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5141         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5142         local max_dirty_mb
5143         local warmup_files
5144
5145         test_mkdir $DIR/${tdir}e
5146         $LFS setstripe -c 1 $TDIR
5147         createmany -o $TDIR/f $files
5148
5149         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5150
5151         # we assume that with $OSTCOUNT files, at least one of them will
5152         # be allocated on OST0.
5153         warmup_files=$((OSTCOUNT * max_dirty_mb))
5154         createmany -o $TDIR/w $warmup_files
5155
5156         # write a large amount of data into one file and sync, to get good
5157         # avail_grant number from OST.
5158         for ((i=0; i<$warmup_files; i++)); do
5159                 idx=$($LFS getstripe -i $TDIR/w$i)
5160                 [ $idx -ne 0 ] && continue
5161                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5162                 break
5163         done
5164         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5165         sync
5166         $LCTL get_param $proc_osc0/cur_dirty_bytes
5167         $LCTL get_param $proc_osc0/cur_grant_bytes
5168
5169         # create as much dirty pages as we can while not to trigger the actual
5170         # RPCs directly. but depends on the env, VFS may trigger flush during this
5171         # period, hopefully we are good.
5172         for ((i=0; i<$warmup_files; i++)); do
5173                 idx=$($LFS getstripe -i $TDIR/w$i)
5174                 [ $idx -ne 0 ] && continue
5175                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5176         done
5177         $LCTL get_param $proc_osc0/cur_dirty_bytes
5178         $LCTL get_param $proc_osc0/cur_grant_bytes
5179
5180         # perform the real test
5181         $LCTL set_param $proc_osc0/rpc_stats 0
5182         for ((;i<$files; i++)); do
5183                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5184                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5185         done
5186         sync
5187         $LCTL get_param $proc_osc0/rpc_stats
5188
5189         local percent=0
5190         local have_ppr=false
5191         $LCTL get_param $proc_osc0/rpc_stats |
5192                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5193                         # skip lines until we are at the RPC histogram data
5194                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5195                         $have_ppr || continue
5196
5197                         # we only want the percent stat for < 16 pages
5198                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5199
5200                         percent=$((percent + WPCT))
5201                         if [[ $percent -gt 15 ]]; then
5202                                 error "less than 16-pages write RPCs" \
5203                                       "$percent% > 15%"
5204                                 break
5205                         fi
5206                 done
5207         rm -rf $TDIR
5208 }
5209 run_test 42e "verify sub-RPC writes are not done synchronously"
5210
5211 test_43A() { # was test_43
5212         test_mkdir $DIR/$tdir
5213         cp -p /bin/ls $DIR/$tdir/$tfile
5214         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5215         pid=$!
5216         # give multiop a chance to open
5217         sleep 1
5218
5219         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5220         kill -USR1 $pid
5221         # Wait for multiop to exit
5222         wait $pid
5223 }
5224 run_test 43A "execution of file opened for write should return -ETXTBSY"
5225
5226 test_43a() {
5227         test_mkdir $DIR/$tdir
5228         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5229         $DIR/$tdir/sleep 60 &
5230         SLEEP_PID=$!
5231         # Make sure exec of $tdir/sleep wins race with truncate
5232         sleep 1
5233         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5234         kill $SLEEP_PID
5235 }
5236 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5237
5238 test_43b() {
5239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5240
5241         test_mkdir $DIR/$tdir
5242         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5243         $DIR/$tdir/sleep 60 &
5244         SLEEP_PID=$!
5245         # Make sure exec of $tdir/sleep wins race with truncate
5246         sleep 1
5247         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5248         kill $SLEEP_PID
5249 }
5250 run_test 43b "truncate of file being executed should return -ETXTBSY"
5251
5252 test_43c() {
5253         local testdir="$DIR/$tdir"
5254         test_mkdir $testdir
5255         cp $SHELL $testdir/
5256         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5257                 ( cd $testdir && md5sum -c )
5258 }
5259 run_test 43c "md5sum of copy into lustre"
5260
5261 test_44A() { # was test_44
5262         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5263
5264         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5265         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5266 }
5267 run_test 44A "zero length read from a sparse stripe"
5268
5269 test_44a() {
5270         local nstripe=$($LFS getstripe -c -d $DIR)
5271         [ -z "$nstripe" ] && skip "can't get stripe info"
5272         [[ $nstripe -gt $OSTCOUNT ]] &&
5273                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5274
5275         local stride=$($LFS getstripe -S -d $DIR)
5276         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5277                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5278         fi
5279
5280         OFFSETS="0 $((stride/2)) $((stride-1))"
5281         for offset in $OFFSETS; do
5282                 for i in $(seq 0 $((nstripe-1))); do
5283                         local GLOBALOFFSETS=""
5284                         # size in Bytes
5285                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5286                         local myfn=$DIR/d44a-$size
5287                         echo "--------writing $myfn at $size"
5288                         ll_sparseness_write $myfn $size ||
5289                                 error "ll_sparseness_write"
5290                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5291                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5292                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5293
5294                         for j in $(seq 0 $((nstripe-1))); do
5295                                 # size in Bytes
5296                                 size=$((((j + $nstripe )*$stride + $offset)))
5297                                 ll_sparseness_write $myfn $size ||
5298                                         error "ll_sparseness_write"
5299                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5300                         done
5301                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5302                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5303                         rm -f $myfn
5304                 done
5305         done
5306 }
5307 run_test 44a "test sparse pwrite ==============================="
5308
5309 dirty_osc_total() {
5310         tot=0
5311         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5312                 tot=$(($tot + $d))
5313         done
5314         echo $tot
5315 }
5316 do_dirty_record() {
5317         before=`dirty_osc_total`
5318         echo executing "\"$*\""
5319         eval $*
5320         after=`dirty_osc_total`
5321         echo before $before, after $after
5322 }
5323 test_45() {
5324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5325
5326         f="$DIR/f45"
5327         # Obtain grants from OST if it supports it
5328         echo blah > ${f}_grant
5329         stop_writeback
5330         sync
5331         do_dirty_record "echo blah > $f"
5332         [[ $before -eq $after ]] && error "write wasn't cached"
5333         do_dirty_record "> $f"
5334         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5335         do_dirty_record "echo blah > $f"
5336         [[ $before -eq $after ]] && error "write wasn't cached"
5337         do_dirty_record "sync"
5338         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5339         do_dirty_record "echo blah > $f"
5340         [[ $before -eq $after ]] && error "write wasn't cached"
5341         do_dirty_record "cancel_lru_locks osc"
5342         [[ $before -gt $after ]] ||
5343                 error "lock cancellation didn't lower dirty count"
5344         start_writeback
5345 }
5346 run_test 45 "osc io page accounting ============================"
5347
5348 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5349 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5350 # objects offset and an assert hit when an rpc was built with 1023's mapped
5351 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5352 test_46() {
5353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5354
5355         f="$DIR/f46"
5356         stop_writeback
5357         sync
5358         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5359         sync
5360         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5361         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5362         sync
5363         start_writeback
5364 }
5365 run_test 46 "dirtying a previously written page ================"
5366
5367 # test_47 is removed "Device nodes check" is moved to test_28
5368
5369 test_48a() { # bug 2399
5370         [ "$mds1_FSTYPE" = "zfs" ] &&
5371         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5372                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5373
5374         test_mkdir $DIR/$tdir
5375         cd $DIR/$tdir
5376         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5377         test_mkdir $DIR/$tdir
5378         touch foo || error "'touch foo' failed after recreating cwd"
5379         test_mkdir bar
5380         touch .foo || error "'touch .foo' failed after recreating cwd"
5381         test_mkdir .bar
5382         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5383         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5384         cd . || error "'cd .' failed after recreating cwd"
5385         mkdir . && error "'mkdir .' worked after recreating cwd"
5386         rmdir . && error "'rmdir .' worked after recreating cwd"
5387         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5388         cd .. || error "'cd ..' failed after recreating cwd"
5389 }
5390 run_test 48a "Access renamed working dir (should return errors)="
5391
5392 test_48b() { # bug 2399
5393         rm -rf $DIR/$tdir
5394         test_mkdir $DIR/$tdir
5395         cd $DIR/$tdir
5396         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5397         touch foo && error "'touch foo' worked after removing cwd"
5398         mkdir foo && error "'mkdir foo' worked after removing cwd"
5399         touch .foo && error "'touch .foo' worked after removing cwd"
5400         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5401         ls . > /dev/null && error "'ls .' worked after removing cwd"
5402         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5403         mkdir . && error "'mkdir .' worked after removing cwd"
5404         rmdir . && error "'rmdir .' worked after removing cwd"
5405         ln -s . foo && error "'ln -s .' worked after removing cwd"
5406         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5407 }
5408 run_test 48b "Access removed working dir (should return errors)="
5409
5410 test_48c() { # bug 2350
5411         #lctl set_param debug=-1
5412         #set -vx
5413         rm -rf $DIR/$tdir
5414         test_mkdir -p $DIR/$tdir/dir
5415         cd $DIR/$tdir/dir
5416         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5417         $TRACE touch foo && error "touch foo worked after removing cwd"
5418         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5419         touch .foo && error "touch .foo worked after removing cwd"
5420         mkdir .foo && error "mkdir .foo worked after removing cwd"
5421         $TRACE ls . && error "'ls .' worked after removing cwd"
5422         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5423         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5424         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5425         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5426         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5427 }
5428 run_test 48c "Access removed working subdir (should return errors)"
5429
5430 test_48d() { # bug 2350
5431         #lctl set_param debug=-1
5432         #set -vx
5433         rm -rf $DIR/$tdir
5434         test_mkdir -p $DIR/$tdir/dir
5435         cd $DIR/$tdir/dir
5436         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5437         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5438         $TRACE touch foo && error "'touch foo' worked after removing parent"
5439         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5440         touch .foo && error "'touch .foo' worked after removing parent"
5441         mkdir .foo && error "mkdir .foo worked after removing parent"
5442         $TRACE ls . && error "'ls .' worked after removing parent"
5443         $TRACE ls .. && error "'ls ..' worked after removing parent"
5444         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5445         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5446         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5447         true
5448 }
5449 run_test 48d "Access removed parent subdir (should return errors)"
5450
5451 test_48e() { # bug 4134
5452         #lctl set_param debug=-1
5453         #set -vx
5454         rm -rf $DIR/$tdir
5455         test_mkdir -p $DIR/$tdir/dir
5456         cd $DIR/$tdir/dir
5457         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5458         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5459         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5460         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5461         # On a buggy kernel addition of "touch foo" after cd .. will
5462         # produce kernel oops in lookup_hash_it
5463         touch ../foo && error "'cd ..' worked after recreate parent"
5464         cd $DIR
5465         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5466 }
5467 run_test 48e "Access to recreated parent subdir (should return errors)"
5468
5469 test_48f() {
5470         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5471                 skip "need MDS >= 2.13.55"
5472         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5473         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5474                 skip "needs different host for mdt1 mdt2"
5475         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5476
5477         $LFS mkdir -i0 $DIR/$tdir
5478         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5479
5480         for d in sub1 sub2 sub3; do
5481                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5482                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5483                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5484         done
5485
5486         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5487 }
5488 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5489
5490 test_49() { # LU-1030
5491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5492         remote_ost_nodsh && skip "remote OST with nodsh"
5493
5494         # get ost1 size - $FSNAME-OST0000
5495         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5496                 awk '{ print $4 }')
5497         # write 800M at maximum
5498         [[ $ost1_size -lt 2 ]] && ost1_size=2
5499         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5500
5501         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5502         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5503         local dd_pid=$!
5504
5505         # change max_pages_per_rpc while writing the file
5506         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5507         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5508         # loop until dd process exits
5509         while ps ax -opid | grep -wq $dd_pid; do
5510                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5511                 sleep $((RANDOM % 5 + 1))
5512         done
5513         # restore original max_pages_per_rpc
5514         $LCTL set_param $osc1_mppc=$orig_mppc
5515         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5516 }
5517 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5518
5519 test_50() {
5520         # bug 1485
5521         test_mkdir $DIR/$tdir
5522         cd $DIR/$tdir
5523         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5524 }
5525 run_test 50 "special situations: /proc symlinks  ==============="
5526
5527 test_51a() {    # was test_51
5528         # bug 1516 - create an empty entry right after ".." then split dir
5529         test_mkdir -c1 $DIR/$tdir
5530         touch $DIR/$tdir/foo
5531         $MCREATE $DIR/$tdir/bar
5532         rm $DIR/$tdir/foo
5533         createmany -m $DIR/$tdir/longfile 201
5534         FNUM=202
5535         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5536                 $MCREATE $DIR/$tdir/longfile$FNUM
5537                 FNUM=$(($FNUM + 1))
5538                 echo -n "+"
5539         done
5540         echo
5541         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5542 }
5543 run_test 51a "special situations: split htree with empty entry =="
5544
5545 cleanup_print_lfs_df () {
5546         trap 0
5547         $LFS df
5548         $LFS df -i
5549 }
5550
5551 test_51b() {
5552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5553
5554         local dir=$DIR/$tdir
5555         local nrdirs=$((65536 + 100))
5556
5557         # cleanup the directory
5558         rm -fr $dir
5559
5560         test_mkdir -c1 $dir
5561
5562         $LFS df
5563         $LFS df -i
5564         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5565         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5566         [[ $numfree -lt $nrdirs ]] &&
5567                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5568
5569         # need to check free space for the directories as well
5570         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5571         numfree=$(( blkfree / $(fs_inode_ksize) ))
5572         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5573
5574         trap cleanup_print_lfs_df EXIT
5575
5576         # create files
5577         createmany -d $dir/d $nrdirs || {
5578                 unlinkmany $dir/d $nrdirs
5579                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5580         }
5581
5582         # really created :
5583         nrdirs=$(ls -U $dir | wc -l)
5584
5585         # unlink all but 100 subdirectories, then check it still works
5586         local left=100
5587         local delete=$((nrdirs - left))
5588
5589         $LFS df
5590         $LFS df -i
5591
5592         # for ldiskfs the nlink count should be 1, but this is OSD specific
5593         # and so this is listed for informational purposes only
5594         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5595         unlinkmany -d $dir/d $delete ||
5596                 error "unlink of first $delete subdirs failed"
5597
5598         echo "nlink between: $(stat -c %h $dir)"
5599         local found=$(ls -U $dir | wc -l)
5600         [ $found -ne $left ] &&
5601                 error "can't find subdirs: found only $found, expected $left"
5602
5603         unlinkmany -d $dir/d $delete $left ||
5604                 error "unlink of second $left subdirs failed"
5605         # regardless of whether the backing filesystem tracks nlink accurately
5606         # or not, the nlink count shouldn't be more than "." and ".." here
5607         local after=$(stat -c %h $dir)
5608         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5609                 echo "nlink after: $after"
5610
5611         cleanup_print_lfs_df
5612 }
5613 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5614
5615 test_51d() {
5616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5617         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5618
5619         test_mkdir $DIR/$tdir
5620         createmany -o $DIR/$tdir/t- 1000
5621         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5622         for N in $(seq 0 $((OSTCOUNT - 1))); do
5623                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5624                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5625                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5626                         '($1 == '$N') { objs += 1 } \
5627                         END { printf("%0.0f", objs) }')
5628                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5629         done
5630         unlinkmany $DIR/$tdir/t- 1000
5631
5632         NLAST=0
5633         for N in $(seq 1 $((OSTCOUNT - 1))); do
5634                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5635                         error "OST $N has less objects vs OST $NLAST" \
5636                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5637                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5638                         error "OST $N has less objects vs OST $NLAST" \
5639                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5640
5641                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5642                         error "OST $N has less #0 objects vs OST $NLAST" \
5643                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5644                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5645                         error "OST $N has less #0 objects vs OST $NLAST" \
5646                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5647                 NLAST=$N
5648         done
5649         rm -f $TMP/$tfile
5650 }
5651 run_test 51d "check object distribution"
5652
5653 test_51e() {
5654         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5655                 skip_env "ldiskfs only test"
5656         fi
5657
5658         test_mkdir -c1 $DIR/$tdir
5659         test_mkdir -c1 $DIR/$tdir/d0
5660
5661         touch $DIR/$tdir/d0/foo
5662         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5663                 error "file exceed 65000 nlink limit!"
5664         unlinkmany $DIR/$tdir/d0/f- 65001
5665         return 0
5666 }
5667 run_test 51e "check file nlink limit"
5668
5669 test_51f() {
5670         test_mkdir $DIR/$tdir
5671
5672         local max=100000
5673         local ulimit_old=$(ulimit -n)
5674         local spare=20 # number of spare fd's for scripts/libraries, etc.
5675         local mdt=$($LFS getstripe -m $DIR/$tdir)
5676         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5677
5678         echo "MDT$mdt numfree=$numfree, max=$max"
5679         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5680         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5681                 while ! ulimit -n $((numfree + spare)); do
5682                         numfree=$((numfree * 3 / 4))
5683                 done
5684                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5685         else
5686                 echo "left ulimit at $ulimit_old"
5687         fi
5688
5689         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5690                 unlinkmany $DIR/$tdir/f $numfree
5691                 error "create+open $numfree files in $DIR/$tdir failed"
5692         }
5693         ulimit -n $ulimit_old
5694
5695         # if createmany exits at 120s there will be fewer than $numfree files
5696         unlinkmany $DIR/$tdir/f $numfree || true
5697 }
5698 run_test 51f "check many open files limit"
5699
5700 test_52a() {
5701         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5702         test_mkdir $DIR/$tdir
5703         touch $DIR/$tdir/foo
5704         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5705         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5706         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5707         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5708         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5709                                         error "link worked"
5710         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5711         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5712         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5713                                                      error "lsattr"
5714         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5715         cp -r $DIR/$tdir $TMP/
5716         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5717 }
5718 run_test 52a "append-only flag test (should return errors)"
5719
5720 test_52b() {
5721         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5722         test_mkdir $DIR/$tdir
5723         touch $DIR/$tdir/foo
5724         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5725         cat test > $DIR/$tdir/foo && error "cat test worked"
5726         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5727         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5728         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5729                                         error "link worked"
5730         echo foo >> $DIR/$tdir/foo && error "echo worked"
5731         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5732         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5733         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5734         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5735                                                         error "lsattr"
5736         chattr -i $DIR/$tdir/foo || error "chattr failed"
5737
5738         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5739 }
5740 run_test 52b "immutable flag test (should return errors) ======="
5741
5742 test_53() {
5743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5744         remote_mds_nodsh && skip "remote MDS with nodsh"
5745         remote_ost_nodsh && skip "remote OST with nodsh"
5746
5747         local param
5748         local param_seq
5749         local ostname
5750         local mds_last
5751         local mds_last_seq
5752         local ost_last
5753         local ost_last_seq
5754         local ost_last_id
5755         local ostnum
5756         local node
5757         local found=false
5758         local support_last_seq=true
5759
5760         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5761                 support_last_seq=false
5762
5763         # only test MDT0000
5764         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5765         local value
5766         for value in $(do_facet $SINGLEMDS \
5767                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5768                 param=$(echo ${value[0]} | cut -d "=" -f1)
5769                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5770
5771                 if $support_last_seq; then
5772                         param_seq=$(echo $param |
5773                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5774                         mds_last_seq=$(do_facet $SINGLEMDS \
5775                                        $LCTL get_param -n $param_seq)
5776                 fi
5777                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5778
5779                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5780                 node=$(facet_active_host ost$((ostnum+1)))
5781                 param="obdfilter.$ostname.last_id"
5782                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5783                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5784                         ost_last_id=$ost_last
5785
5786                         if $support_last_seq; then
5787                                 ost_last_id=$(echo $ost_last |
5788                                               awk -F':' '{print $2}' |
5789                                               sed -e "s/^0x//g")
5790                                 ost_last_seq=$(echo $ost_last |
5791                                                awk -F':' '{print $1}')
5792                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5793                         fi
5794
5795                         if [[ $ost_last_id != $mds_last ]]; then
5796                                 error "$ost_last_id != $mds_last"
5797                         else
5798                                 found=true
5799                                 break
5800                         fi
5801                 done
5802         done
5803         $found || error "can not match last_seq/last_id for $mdtosc"
5804         return 0
5805 }
5806 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5807
5808 test_54a() {
5809         perl -MSocket -e ';' || skip "no Socket perl module installed"
5810
5811         $SOCKETSERVER $DIR/socket ||
5812                 error "$SOCKETSERVER $DIR/socket failed: $?"
5813         $SOCKETCLIENT $DIR/socket ||
5814                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5815         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5816 }
5817 run_test 54a "unix domain socket test =========================="
5818
5819 test_54b() {
5820         f="$DIR/f54b"
5821         mknod $f c 1 3
5822         chmod 0666 $f
5823         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5824 }
5825 run_test 54b "char device works in lustre ======================"
5826
5827 find_loop_dev() {
5828         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5829         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5830         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5831
5832         for i in $(seq 3 7); do
5833                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5834                 LOOPDEV=$LOOPBASE$i
5835                 LOOPNUM=$i
5836                 break
5837         done
5838 }
5839
5840 cleanup_54c() {
5841         local rc=0
5842         loopdev="$DIR/loop54c"
5843
5844         trap 0
5845         $UMOUNT $DIR/$tdir || rc=$?
5846         losetup -d $loopdev || true
5847         losetup -d $LOOPDEV || true
5848         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5849         return $rc
5850 }
5851
5852 test_54c() {
5853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5854
5855         loopdev="$DIR/loop54c"
5856
5857         find_loop_dev
5858         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5859         trap cleanup_54c EXIT
5860         mknod $loopdev b 7 $LOOPNUM
5861         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5862         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5863         losetup $loopdev $DIR/$tfile ||
5864                 error "can't set up $loopdev for $DIR/$tfile"
5865         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5866         test_mkdir $DIR/$tdir
5867         mount -t ext2 $loopdev $DIR/$tdir ||
5868                 error "error mounting $loopdev on $DIR/$tdir"
5869         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5870                 error "dd write"
5871         df $DIR/$tdir
5872         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5873                 error "dd read"
5874         cleanup_54c
5875 }
5876 run_test 54c "block device works in lustre ====================="
5877
5878 test_54d() {
5879         f="$DIR/f54d"
5880         string="aaaaaa"
5881         mknod $f p
5882         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5883 }
5884 run_test 54d "fifo device works in lustre ======================"
5885
5886 test_54e() {
5887         f="$DIR/f54e"
5888         string="aaaaaa"
5889         cp -aL /dev/console $f
5890         echo $string > $f || error "echo $string to $f failed"
5891 }
5892 run_test 54e "console/tty device works in lustre ======================"
5893
5894 test_56a() {
5895         local numfiles=3
5896         local dir=$DIR/$tdir
5897
5898         rm -rf $dir
5899         test_mkdir -p $dir/dir
5900         for i in $(seq $numfiles); do
5901                 touch $dir/file$i
5902                 touch $dir/dir/file$i
5903         done
5904
5905         local numcomp=$($LFS getstripe --component-count $dir)
5906
5907         [[ $numcomp == 0 ]] && numcomp=1
5908
5909         # test lfs getstripe with --recursive
5910         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5911
5912         [[ $filenum -eq $((numfiles * 2)) ]] ||
5913                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5914         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5915         [[ $filenum -eq $numfiles ]] ||
5916                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5917         echo "$LFS getstripe showed obdidx or l_ost_idx"
5918
5919         # test lfs getstripe with file instead of dir
5920         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5921         [[ $filenum -eq 1 ]] ||
5922                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5923         echo "$LFS getstripe file1 passed"
5924
5925         #test lfs getstripe with --verbose
5926         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5927         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5928                 error "$LFS getstripe --verbose $dir: "\
5929                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5930         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5931                 error "$LFS getstripe $dir: showed lmm_magic"
5932
5933         #test lfs getstripe with -v prints lmm_fid
5934         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5935         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5936                 error "$LFS getstripe -v $dir: "\
5937                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5938         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5939                 error "$LFS getstripe $dir: showed lmm_fid by default"
5940         echo "$LFS getstripe --verbose passed"
5941
5942         #check for FID information
5943         local fid1=$($LFS getstripe --fid $dir/file1)
5944         local fid2=$($LFS getstripe --verbose $dir/file1 |
5945                      awk '/lmm_fid: / { print $2; exit; }')
5946         local fid3=$($LFS path2fid $dir/file1)
5947
5948         [ "$fid1" != "$fid2" ] &&
5949                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5950         [ "$fid1" != "$fid3" ] &&
5951                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5952         echo "$LFS getstripe --fid passed"
5953
5954         #test lfs getstripe with --obd
5955         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5956                 error "$LFS getstripe --obd wrong_uuid: should return error"
5957
5958         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5959
5960         local ostidx=1
5961         local obduuid=$(ostuuid_from_index $ostidx)
5962         local found=$($LFS getstripe -r --obd $obduuid $dir |
5963                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5964
5965         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5966         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5967                 ((filenum--))
5968         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5969                 ((filenum--))
5970
5971         [[ $found -eq $filenum ]] ||
5972                 error "$LFS getstripe --obd: found $found expect $filenum"
5973         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5974                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5975                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5976                 error "$LFS getstripe --obd: should not show file on other obd"
5977         echo "$LFS getstripe --obd passed"
5978 }
5979 run_test 56a "check $LFS getstripe"
5980
5981 test_56b() {
5982         local dir=$DIR/$tdir
5983         local numdirs=3
5984
5985         test_mkdir $dir
5986         for i in $(seq $numdirs); do
5987                 test_mkdir $dir/dir$i
5988         done
5989
5990         # test lfs getdirstripe default mode is non-recursion, which is
5991         # different from lfs getstripe
5992         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5993
5994         [[ $dircnt -eq 1 ]] ||
5995                 error "$LFS getdirstripe: found $dircnt, not 1"
5996         dircnt=$($LFS getdirstripe --recursive $dir |
5997                 grep -c lmv_stripe_count)
5998         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5999                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6000 }
6001 run_test 56b "check $LFS getdirstripe"
6002
6003 test_56c() {
6004         remote_ost_nodsh && skip "remote OST with nodsh"
6005
6006         local ost_idx=0
6007         local ost_name=$(ostname_from_index $ost_idx)
6008         local old_status=$(ost_dev_status $ost_idx)
6009         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6010
6011         [[ -z "$old_status" ]] ||
6012                 skip_env "OST $ost_name is in $old_status status"
6013
6014         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6015         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6016                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6017         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6018                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6019                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6020         fi
6021
6022         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6023                 error "$LFS df -v showing inactive devices"
6024         sleep_maxage
6025
6026         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6027
6028         [[ "$new_status" =~ "D" ]] ||
6029                 error "$ost_name status is '$new_status', missing 'D'"
6030         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6031                 [[ "$new_status" =~ "N" ]] ||
6032                         error "$ost_name status is '$new_status', missing 'N'"
6033         fi
6034         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6035                 [[ "$new_status" =~ "f" ]] ||
6036                         error "$ost_name status is '$new_status', missing 'f'"
6037         fi
6038
6039         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6040         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6041                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6042         [[ -z "$p" ]] && restore_lustre_params < $p || true
6043         sleep_maxage
6044
6045         new_status=$(ost_dev_status $ost_idx)
6046         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6047                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6048         # can't check 'f' as devices may actually be on flash
6049 }
6050 run_test 56c "check 'lfs df' showing device status"
6051
6052 test_56d() {
6053         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6054         local osts=$($LFS df -v $MOUNT | grep -c OST)
6055
6056         $LFS df $MOUNT
6057
6058         (( mdts == MDSCOUNT )) ||
6059                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6060         (( osts == OSTCOUNT )) ||
6061                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6062 }
6063 run_test 56d "'lfs df -v' prints only configured devices"
6064
6065 NUMFILES=3
6066 NUMDIRS=3
6067 setup_56() {
6068         local local_tdir="$1"
6069         local local_numfiles="$2"
6070         local local_numdirs="$3"
6071         local dir_params="$4"
6072         local dir_stripe_params="$5"
6073
6074         if [ ! -d "$local_tdir" ] ; then
6075                 test_mkdir -p $dir_stripe_params $local_tdir
6076                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6077                 for i in $(seq $local_numfiles) ; do
6078                         touch $local_tdir/file$i
6079                 done
6080                 for i in $(seq $local_numdirs) ; do
6081                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6082                         for j in $(seq $local_numfiles) ; do
6083                                 touch $local_tdir/dir$i/file$j
6084                         done
6085                 done
6086         fi
6087 }
6088
6089 setup_56_special() {
6090         local local_tdir=$1
6091         local local_numfiles=$2
6092         local local_numdirs=$3
6093
6094         setup_56 $local_tdir $local_numfiles $local_numdirs
6095
6096         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6097                 for i in $(seq $local_numfiles) ; do
6098                         mknod $local_tdir/loop${i}b b 7 $i
6099                         mknod $local_tdir/null${i}c c 1 3
6100                         ln -s $local_tdir/file1 $local_tdir/link${i}
6101                 done
6102                 for i in $(seq $local_numdirs) ; do
6103                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6104                         mknod $local_tdir/dir$i/null${i}c c 1 3
6105                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6106                 done
6107         fi
6108 }
6109
6110 test_56g() {
6111         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6112         local expected=$(($NUMDIRS + 2))
6113
6114         setup_56 $dir $NUMFILES $NUMDIRS
6115
6116         # test lfs find with -name
6117         for i in $(seq $NUMFILES) ; do
6118                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6119
6120                 [ $nums -eq $expected ] ||
6121                         error "lfs find -name '*$i' $dir wrong: "\
6122                               "found $nums, expected $expected"
6123         done
6124 }
6125 run_test 56g "check lfs find -name"
6126
6127 test_56h() {
6128         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6129         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6130
6131         setup_56 $dir $NUMFILES $NUMDIRS
6132
6133         # test lfs find with ! -name
6134         for i in $(seq $NUMFILES) ; do
6135                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6136
6137                 [ $nums -eq $expected ] ||
6138                         error "lfs find ! -name '*$i' $dir wrong: "\
6139                               "found $nums, expected $expected"
6140         done
6141 }
6142 run_test 56h "check lfs find ! -name"
6143
6144 test_56i() {
6145         local dir=$DIR/$tdir
6146
6147         test_mkdir $dir
6148
6149         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6150         local out=$($cmd)
6151
6152         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6153 }
6154 run_test 56i "check 'lfs find -ost UUID' skips directories"
6155
6156 test_56j() {
6157         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6158
6159         setup_56_special $dir $NUMFILES $NUMDIRS
6160
6161         local expected=$((NUMDIRS + 1))
6162         local cmd="$LFS find -type d $dir"
6163         local nums=$($cmd | wc -l)
6164
6165         [ $nums -eq $expected ] ||
6166                 error "'$cmd' wrong: found $nums, expected $expected"
6167 }
6168 run_test 56j "check lfs find -type d"
6169
6170 test_56k() {
6171         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6172
6173         setup_56_special $dir $NUMFILES $NUMDIRS
6174
6175         local expected=$(((NUMDIRS + 1) * NUMFILES))
6176         local cmd="$LFS find -type f $dir"
6177         local nums=$($cmd | wc -l)
6178
6179         [ $nums -eq $expected ] ||
6180                 error "'$cmd' wrong: found $nums, expected $expected"
6181 }
6182 run_test 56k "check lfs find -type f"
6183
6184 test_56l() {
6185         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6186
6187         setup_56_special $dir $NUMFILES $NUMDIRS
6188
6189         local expected=$((NUMDIRS + NUMFILES))
6190         local cmd="$LFS find -type b $dir"
6191         local nums=$($cmd | wc -l)
6192
6193         [ $nums -eq $expected ] ||
6194                 error "'$cmd' wrong: found $nums, expected $expected"
6195 }
6196 run_test 56l "check lfs find -type b"
6197
6198 test_56m() {
6199         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6200
6201         setup_56_special $dir $NUMFILES $NUMDIRS
6202
6203         local expected=$((NUMDIRS + NUMFILES))
6204         local cmd="$LFS find -type c $dir"
6205         local nums=$($cmd | wc -l)
6206         [ $nums -eq $expected ] ||
6207                 error "'$cmd' wrong: found $nums, expected $expected"
6208 }
6209 run_test 56m "check lfs find -type c"
6210
6211 test_56n() {
6212         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6213         setup_56_special $dir $NUMFILES $NUMDIRS
6214
6215         local expected=$((NUMDIRS + NUMFILES))
6216         local cmd="$LFS find -type l $dir"
6217         local nums=$($cmd | wc -l)
6218
6219         [ $nums -eq $expected ] ||
6220                 error "'$cmd' wrong: found $nums, expected $expected"
6221 }
6222 run_test 56n "check lfs find -type l"
6223
6224 test_56o() {
6225         local dir=$DIR/$tdir
6226
6227         setup_56 $dir $NUMFILES $NUMDIRS
6228         utime $dir/file1 > /dev/null || error "utime (1)"
6229         utime $dir/file2 > /dev/null || error "utime (2)"
6230         utime $dir/dir1 > /dev/null || error "utime (3)"
6231         utime $dir/dir2 > /dev/null || error "utime (4)"
6232         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6233         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6234
6235         local expected=4
6236         local nums=$($LFS find -mtime +0 $dir | wc -l)
6237
6238         [ $nums -eq $expected ] ||
6239                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6240
6241         expected=12
6242         cmd="$LFS find -mtime 0 $dir"
6243         nums=$($cmd | wc -l)
6244         [ $nums -eq $expected ] ||
6245                 error "'$cmd' wrong: found $nums, expected $expected"
6246 }
6247 run_test 56o "check lfs find -mtime for old files"
6248
6249 test_56ob() {
6250         local dir=$DIR/$tdir
6251         local expected=1
6252         local count=0
6253
6254         # just to make sure there is something that won't be found
6255         test_mkdir $dir
6256         touch $dir/$tfile.now
6257
6258         for age in year week day hour min; do
6259                 count=$((count + 1))
6260
6261                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6262                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6263                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6264
6265                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6266                 local nums=$($cmd | wc -l)
6267                 [ $nums -eq $expected ] ||
6268                         error "'$cmd' wrong: found $nums, expected $expected"
6269
6270                 cmd="$LFS find $dir -atime $count${age:0:1}"
6271                 nums=$($cmd | wc -l)
6272                 [ $nums -eq $expected ] ||
6273                         error "'$cmd' wrong: found $nums, expected $expected"
6274         done
6275
6276         sleep 2
6277         cmd="$LFS find $dir -ctime +1s -type f"
6278         nums=$($cmd | wc -l)
6279         (( $nums == $count * 2 + 1)) ||
6280                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6281 }
6282 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6283
6284 test_newerXY_base() {
6285         local x=$1
6286         local y=$2
6287         local dir=$DIR/$tdir
6288         local ref
6289         local negref
6290
6291         if [ $y == "t" ]; then
6292                 if [ $x == "b" ]; then
6293                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6294                 else
6295                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6296                 fi
6297         else
6298                 ref=$DIR/$tfile.newer.$x$y
6299                 touch $ref || error "touch $ref failed"
6300         fi
6301
6302         echo "before = $ref"
6303         sleep 2
6304         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6305         sleep 2
6306         if [ $y == "t" ]; then
6307                 if [ $x == "b" ]; then
6308                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6309                 else
6310                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6311                 fi
6312         else
6313                 negref=$DIR/$tfile.negnewer.$x$y
6314                 touch $negref || error "touch $negref failed"
6315         fi
6316
6317         echo "after = $negref"
6318         local cmd="$LFS find $dir -newer$x$y $ref"
6319         local nums=$(eval $cmd | wc -l)
6320         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6321
6322         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6323                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6324
6325         cmd="$LFS find $dir ! -newer$x$y $negref"
6326         nums=$(eval $cmd | wc -l)
6327         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6328                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6329
6330         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6331         nums=$(eval $cmd | wc -l)
6332         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6333                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6334
6335         rm -rf $DIR/*
6336 }
6337
6338 test_56oc() {
6339         test_newerXY_base "a" "a"
6340         test_newerXY_base "a" "m"
6341         test_newerXY_base "a" "c"
6342         test_newerXY_base "m" "a"
6343         test_newerXY_base "m" "m"
6344         test_newerXY_base "m" "c"
6345         test_newerXY_base "c" "a"
6346         test_newerXY_base "c" "m"
6347         test_newerXY_base "c" "c"
6348
6349         [[ -n "$sles_version" ]] &&
6350                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6351
6352         test_newerXY_base "a" "t"
6353         test_newerXY_base "m" "t"
6354         test_newerXY_base "c" "t"
6355
6356         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6357            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6358                 ! btime_supported && echo "btime unsupported" && return 0
6359
6360         test_newerXY_base "b" "b"
6361         test_newerXY_base "b" "t"
6362 }
6363 run_test 56oc "check lfs find -newerXY work"
6364
6365 btime_supported() {
6366         local dir=$DIR/$tdir
6367         local rc
6368
6369         mkdir -p $dir
6370         touch $dir/$tfile
6371         $LFS find $dir -btime -1d -type f
6372         rc=$?
6373         rm -rf $dir
6374         return $rc
6375 }
6376
6377 test_56od() {
6378         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6379                 ! btime_supported && skip "btime unsupported on MDS"
6380
6381         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6382                 ! btime_supported && skip "btime unsupported on clients"
6383
6384         local dir=$DIR/$tdir
6385         local ref=$DIR/$tfile.ref
6386         local negref=$DIR/$tfile.negref
6387
6388         mkdir $dir || error "mkdir $dir failed"
6389         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6390         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6391         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6392         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6393         touch $ref || error "touch $ref failed"
6394         # sleep 3 seconds at least
6395         sleep 3
6396
6397         local before=$(do_facet mds1 date +%s)
6398         local skew=$(($(date +%s) - before + 1))
6399
6400         if (( skew < 0 && skew > -5 )); then
6401                 sleep $((0 - skew + 1))
6402                 skew=0
6403         fi
6404
6405         # Set the dir stripe params to limit files all on MDT0,
6406         # otherwise we need to calc the max clock skew between
6407         # the client and MDTs.
6408         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6409         sleep 2
6410         touch $negref || error "touch $negref failed"
6411
6412         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6413         local nums=$($cmd | wc -l)
6414         local expected=$(((NUMFILES + 1) * NUMDIRS))
6415
6416         [ $nums -eq $expected ] ||
6417                 error "'$cmd' wrong: found $nums, expected $expected"
6418
6419         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6420         nums=$($cmd | wc -l)
6421         expected=$((NUMFILES + 1))
6422         [ $nums -eq $expected ] ||
6423                 error "'$cmd' wrong: found $nums, expected $expected"
6424
6425         [ $skew -lt 0 ] && return
6426
6427         local after=$(do_facet mds1 date +%s)
6428         local age=$((after - before + 1 + skew))
6429
6430         cmd="$LFS find $dir -btime -${age}s -type f"
6431         nums=$($cmd | wc -l)
6432         expected=$(((NUMFILES + 1) * NUMDIRS))
6433
6434         echo "Clock skew between client and server: $skew, age:$age"
6435         [ $nums -eq $expected ] ||
6436                 error "'$cmd' wrong: found $nums, expected $expected"
6437
6438         expected=$(($NUMDIRS + 1))
6439         cmd="$LFS find $dir -btime -${age}s -type d"
6440         nums=$($cmd | wc -l)
6441         [ $nums -eq $expected ] ||
6442                 error "'$cmd' wrong: found $nums, expected $expected"
6443         rm -f $ref $negref || error "Failed to remove $ref $negref"
6444 }
6445 run_test 56od "check lfs find -btime with units"
6446
6447 test_56p() {
6448         [ $RUNAS_ID -eq $UID ] &&
6449                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6450
6451         local dir=$DIR/$tdir
6452
6453         setup_56 $dir $NUMFILES $NUMDIRS
6454         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6455
6456         local expected=$NUMFILES
6457         local cmd="$LFS find -uid $RUNAS_ID $dir"
6458         local nums=$($cmd | wc -l)
6459
6460         [ $nums -eq $expected ] ||
6461                 error "'$cmd' wrong: found $nums, expected $expected"
6462
6463         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6464         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6465         nums=$($cmd | wc -l)
6466         [ $nums -eq $expected ] ||
6467                 error "'$cmd' wrong: found $nums, expected $expected"
6468 }
6469 run_test 56p "check lfs find -uid and ! -uid"
6470
6471 test_56q() {
6472         [ $RUNAS_ID -eq $UID ] &&
6473                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6474
6475         local dir=$DIR/$tdir
6476
6477         setup_56 $dir $NUMFILES $NUMDIRS
6478         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6479
6480         local expected=$NUMFILES
6481         local cmd="$LFS find -gid $RUNAS_GID $dir"
6482         local nums=$($cmd | wc -l)
6483
6484         [ $nums -eq $expected ] ||
6485                 error "'$cmd' wrong: found $nums, expected $expected"
6486
6487         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6488         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6489         nums=$($cmd | wc -l)
6490         [ $nums -eq $expected ] ||
6491                 error "'$cmd' wrong: found $nums, expected $expected"
6492 }
6493 run_test 56q "check lfs find -gid and ! -gid"
6494
6495 test_56r() {
6496         local dir=$DIR/$tdir
6497
6498         setup_56 $dir $NUMFILES $NUMDIRS
6499
6500         local expected=12
6501         local cmd="$LFS find -size 0 -type f -lazy $dir"
6502         local nums=$($cmd | wc -l)
6503
6504         [ $nums -eq $expected ] ||
6505                 error "'$cmd' wrong: found $nums, expected $expected"
6506         cmd="$LFS find -size 0 -type f $dir"
6507         nums=$($cmd | wc -l)
6508         [ $nums -eq $expected ] ||
6509                 error "'$cmd' wrong: found $nums, expected $expected"
6510
6511         expected=0
6512         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6513         nums=$($cmd | wc -l)
6514         [ $nums -eq $expected ] ||
6515                 error "'$cmd' wrong: found $nums, expected $expected"
6516         cmd="$LFS find ! -size 0 -type f $dir"
6517         nums=$($cmd | wc -l)
6518         [ $nums -eq $expected ] ||
6519                 error "'$cmd' wrong: found $nums, expected $expected"
6520
6521         echo "test" > $dir/$tfile
6522         echo "test2" > $dir/$tfile.2 && sync
6523         expected=1
6524         cmd="$LFS find -size 5 -type f -lazy $dir"
6525         nums=$($cmd | wc -l)
6526         [ $nums -eq $expected ] ||
6527                 error "'$cmd' wrong: found $nums, expected $expected"
6528         cmd="$LFS find -size 5 -type f $dir"
6529         nums=$($cmd | wc -l)
6530         [ $nums -eq $expected ] ||
6531                 error "'$cmd' wrong: found $nums, expected $expected"
6532
6533         expected=1
6534         cmd="$LFS find -size +5 -type f -lazy $dir"
6535         nums=$($cmd | wc -l)
6536         [ $nums -eq $expected ] ||
6537                 error "'$cmd' wrong: found $nums, expected $expected"
6538         cmd="$LFS find -size +5 -type f $dir"
6539         nums=$($cmd | wc -l)
6540         [ $nums -eq $expected ] ||
6541                 error "'$cmd' wrong: found $nums, expected $expected"
6542
6543         expected=2
6544         cmd="$LFS find -size +0 -type f -lazy $dir"
6545         nums=$($cmd | wc -l)
6546         [ $nums -eq $expected ] ||
6547                 error "'$cmd' wrong: found $nums, expected $expected"
6548         cmd="$LFS find -size +0 -type f $dir"
6549         nums=$($cmd | wc -l)
6550         [ $nums -eq $expected ] ||
6551                 error "'$cmd' wrong: found $nums, expected $expected"
6552
6553         expected=2
6554         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6555         nums=$($cmd | wc -l)
6556         [ $nums -eq $expected ] ||
6557                 error "'$cmd' wrong: found $nums, expected $expected"
6558         cmd="$LFS find ! -size -5 -type f $dir"
6559         nums=$($cmd | wc -l)
6560         [ $nums -eq $expected ] ||
6561                 error "'$cmd' wrong: found $nums, expected $expected"
6562
6563         expected=12
6564         cmd="$LFS find -size -5 -type f -lazy $dir"
6565         nums=$($cmd | wc -l)
6566         [ $nums -eq $expected ] ||
6567                 error "'$cmd' wrong: found $nums, expected $expected"
6568         cmd="$LFS find -size -5 -type f $dir"
6569         nums=$($cmd | wc -l)
6570         [ $nums -eq $expected ] ||
6571                 error "'$cmd' wrong: found $nums, expected $expected"
6572 }
6573 run_test 56r "check lfs find -size works"
6574
6575 test_56ra_sub() {
6576         local expected=$1
6577         local glimpses=$2
6578         local cmd="$3"
6579
6580         cancel_lru_locks $OSC
6581
6582         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6583         local nums=$($cmd | wc -l)
6584
6585         [ $nums -eq $expected ] ||
6586                 error "'$cmd' wrong: found $nums, expected $expected"
6587
6588         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6589
6590         if (( rpcs_before + glimpses != rpcs_after )); then
6591                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6592                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6593
6594                 if [[ $glimpses == 0 ]]; then
6595                         error "'$cmd' should not send glimpse RPCs to OST"
6596                 else
6597                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6598                 fi
6599         fi
6600 }
6601
6602 test_56ra() {
6603         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6604                 skip "MDS < 2.12.58 doesn't return LSOM data"
6605         local dir=$DIR/$tdir
6606         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6607
6608         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6609
6610         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6611         $LCTL set_param -n llite.*.statahead_agl=0
6612         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6613
6614         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6615         # open and close all files to ensure LSOM is updated
6616         cancel_lru_locks $OSC
6617         find $dir -type f | xargs cat > /dev/null
6618
6619         #   expect_found  glimpse_rpcs  command_to_run
6620         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6621         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6622         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6623         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6624
6625         echo "test" > $dir/$tfile
6626         echo "test2" > $dir/$tfile.2 && sync
6627         cancel_lru_locks $OSC
6628         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6629
6630         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6631         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6632         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6633         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6634
6635         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6636         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6637         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6638         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6639         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6640         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6641 }
6642 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6643
6644 test_56rb() {
6645         local dir=$DIR/$tdir
6646         local tmp=$TMP/$tfile.log
6647         local mdt_idx;
6648
6649         test_mkdir -p $dir || error "failed to mkdir $dir"
6650         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6651                 error "failed to setstripe $dir/$tfile"
6652         mdt_idx=$($LFS getdirstripe -i $dir)
6653         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6654
6655         stack_trap "rm -f $tmp" EXIT
6656         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6657         ! grep -q obd_uuid $tmp ||
6658                 error "failed to find --size +100K --ost 0 $dir"
6659         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6660         ! grep -q obd_uuid $tmp ||
6661                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6662 }
6663 run_test 56rb "check lfs find --size --ost/--mdt works"
6664
6665 test_56s() { # LU-611 #LU-9369
6666         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6667
6668         local dir=$DIR/$tdir
6669         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6670
6671         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6672         for i in $(seq $NUMDIRS); do
6673                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6674         done
6675
6676         local expected=$NUMDIRS
6677         local cmd="$LFS find -c $OSTCOUNT $dir"
6678         local nums=$($cmd | wc -l)
6679
6680         [ $nums -eq $expected ] || {
6681                 $LFS getstripe -R $dir
6682                 error "'$cmd' wrong: found $nums, expected $expected"
6683         }
6684
6685         expected=$((NUMDIRS + onestripe))
6686         cmd="$LFS find -stripe-count +0 -type f $dir"
6687         nums=$($cmd | wc -l)
6688         [ $nums -eq $expected ] || {
6689                 $LFS getstripe -R $dir
6690                 error "'$cmd' wrong: found $nums, expected $expected"
6691         }
6692
6693         expected=$onestripe
6694         cmd="$LFS find -stripe-count 1 -type f $dir"
6695         nums=$($cmd | wc -l)
6696         [ $nums -eq $expected ] || {
6697                 $LFS getstripe -R $dir
6698                 error "'$cmd' wrong: found $nums, expected $expected"
6699         }
6700
6701         cmd="$LFS find -stripe-count -2 -type f $dir"
6702         nums=$($cmd | wc -l)
6703         [ $nums -eq $expected ] || {
6704                 $LFS getstripe -R $dir
6705                 error "'$cmd' wrong: found $nums, expected $expected"
6706         }
6707
6708         expected=0
6709         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6710         nums=$($cmd | wc -l)
6711         [ $nums -eq $expected ] || {
6712                 $LFS getstripe -R $dir
6713                 error "'$cmd' wrong: found $nums, expected $expected"
6714         }
6715 }
6716 run_test 56s "check lfs find -stripe-count works"
6717
6718 test_56t() { # LU-611 #LU-9369
6719         local dir=$DIR/$tdir
6720
6721         setup_56 $dir 0 $NUMDIRS
6722         for i in $(seq $NUMDIRS); do
6723                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6724         done
6725
6726         local expected=$NUMDIRS
6727         local cmd="$LFS find -S 8M $dir"
6728         local nums=$($cmd | wc -l)
6729
6730         [ $nums -eq $expected ] || {
6731                 $LFS getstripe -R $dir
6732                 error "'$cmd' wrong: found $nums, expected $expected"
6733         }
6734         rm -rf $dir
6735
6736         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6737
6738         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6739
6740         expected=$(((NUMDIRS + 1) * NUMFILES))
6741         cmd="$LFS find -stripe-size 512k -type f $dir"
6742         nums=$($cmd | wc -l)
6743         [ $nums -eq $expected ] ||
6744                 error "'$cmd' wrong: found $nums, expected $expected"
6745
6746         cmd="$LFS find -stripe-size +320k -type f $dir"
6747         nums=$($cmd | wc -l)
6748         [ $nums -eq $expected ] ||
6749                 error "'$cmd' wrong: found $nums, expected $expected"
6750
6751         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6752         cmd="$LFS find -stripe-size +200k -type f $dir"
6753         nums=$($cmd | wc -l)
6754         [ $nums -eq $expected ] ||
6755                 error "'$cmd' wrong: found $nums, expected $expected"
6756
6757         cmd="$LFS find -stripe-size -640k -type f $dir"
6758         nums=$($cmd | wc -l)
6759         [ $nums -eq $expected ] ||
6760                 error "'$cmd' wrong: found $nums, expected $expected"
6761
6762         expected=4
6763         cmd="$LFS find -stripe-size 256k -type f $dir"
6764         nums=$($cmd | wc -l)
6765         [ $nums -eq $expected ] ||
6766                 error "'$cmd' wrong: found $nums, expected $expected"
6767
6768         cmd="$LFS find -stripe-size -320k -type f $dir"
6769         nums=$($cmd | wc -l)
6770         [ $nums -eq $expected ] ||
6771                 error "'$cmd' wrong: found $nums, expected $expected"
6772
6773         expected=0
6774         cmd="$LFS find -stripe-size 1024k -type f $dir"
6775         nums=$($cmd | wc -l)
6776         [ $nums -eq $expected ] ||
6777                 error "'$cmd' wrong: found $nums, expected $expected"
6778 }
6779 run_test 56t "check lfs find -stripe-size works"
6780
6781 test_56u() { # LU-611
6782         local dir=$DIR/$tdir
6783
6784         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6785
6786         if [[ $OSTCOUNT -gt 1 ]]; then
6787                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6788                 onestripe=4
6789         else
6790                 onestripe=0
6791         fi
6792
6793         local expected=$(((NUMDIRS + 1) * NUMFILES))
6794         local cmd="$LFS find -stripe-index 0 -type f $dir"
6795         local nums=$($cmd | wc -l)
6796
6797         [ $nums -eq $expected ] ||
6798                 error "'$cmd' wrong: found $nums, expected $expected"
6799
6800         expected=$onestripe
6801         cmd="$LFS find -stripe-index 1 -type f $dir"
6802         nums=$($cmd | wc -l)
6803         [ $nums -eq $expected ] ||
6804                 error "'$cmd' wrong: found $nums, expected $expected"
6805
6806         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6807         nums=$($cmd | wc -l)
6808         [ $nums -eq $expected ] ||
6809                 error "'$cmd' wrong: found $nums, expected $expected"
6810
6811         expected=0
6812         # This should produce an error and not return any files
6813         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6814         nums=$($cmd 2>/dev/null | wc -l)
6815         [ $nums -eq $expected ] ||
6816                 error "'$cmd' wrong: found $nums, expected $expected"
6817
6818         if [[ $OSTCOUNT -gt 1 ]]; then
6819                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6820                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6821                 nums=$($cmd | wc -l)
6822                 [ $nums -eq $expected ] ||
6823                         error "'$cmd' wrong: found $nums, expected $expected"
6824         fi
6825 }
6826 run_test 56u "check lfs find -stripe-index works"
6827
6828 test_56v() {
6829         local mdt_idx=0
6830         local dir=$DIR/$tdir
6831
6832         setup_56 $dir $NUMFILES $NUMDIRS
6833
6834         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6835         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6836
6837         for file in $($LFS find -m $UUID $dir); do
6838                 file_midx=$($LFS getstripe -m $file)
6839                 [ $file_midx -eq $mdt_idx ] ||
6840                         error "lfs find -m $UUID != getstripe -m $file_midx"
6841         done
6842 }
6843 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6844
6845 test_56w() {
6846         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6848
6849         local dir=$DIR/$tdir
6850
6851         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6852
6853         local stripe_size=$($LFS getstripe -S -d $dir) ||
6854                 error "$LFS getstripe -S -d $dir failed"
6855         stripe_size=${stripe_size%% *}
6856
6857         local file_size=$((stripe_size * OSTCOUNT))
6858         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6859         local required_space=$((file_num * file_size))
6860         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6861                            head -n1)
6862         [[ $free_space -le $((required_space / 1024)) ]] &&
6863                 skip_env "need $required_space, have $free_space kbytes"
6864
6865         local dd_bs=65536
6866         local dd_count=$((file_size / dd_bs))
6867
6868         # write data into the files
6869         local i
6870         local j
6871         local file
6872
6873         for i in $(seq $NUMFILES); do
6874                 file=$dir/file$i
6875                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6876                         error "write data into $file failed"
6877         done
6878         for i in $(seq $NUMDIRS); do
6879                 for j in $(seq $NUMFILES); do
6880                         file=$dir/dir$i/file$j
6881                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6882                                 error "write data into $file failed"
6883                 done
6884         done
6885
6886         # $LFS_MIGRATE will fail if hard link migration is unsupported
6887         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6888                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6889                         error "creating links to $dir/dir1/file1 failed"
6890         fi
6891
6892         local expected=-1
6893
6894         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6895
6896         # lfs_migrate file
6897         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6898
6899         echo "$cmd"
6900         eval $cmd || error "$cmd failed"
6901
6902         check_stripe_count $dir/file1 $expected
6903
6904         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6905         then
6906                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6907                 # OST 1 if it is on OST 0. This file is small enough to
6908                 # be on only one stripe.
6909                 file=$dir/migr_1_ost
6910                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6911                         error "write data into $file failed"
6912                 local obdidx=$($LFS getstripe -i $file)
6913                 local oldmd5=$(md5sum $file)
6914                 local newobdidx=0
6915
6916                 [[ $obdidx -eq 0 ]] && newobdidx=1
6917                 cmd="$LFS migrate -i $newobdidx $file"
6918                 echo $cmd
6919                 eval $cmd || error "$cmd failed"
6920
6921                 local realobdix=$($LFS getstripe -i $file)
6922                 local newmd5=$(md5sum $file)
6923
6924                 [[ $newobdidx -ne $realobdix ]] &&
6925                         error "new OST is different (was=$obdidx, "\
6926                               "wanted=$newobdidx, got=$realobdix)"
6927                 [[ "$oldmd5" != "$newmd5" ]] &&
6928                         error "md5sum differ: $oldmd5, $newmd5"
6929         fi
6930
6931         # lfs_migrate dir
6932         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6933         echo "$cmd"
6934         eval $cmd || error "$cmd failed"
6935
6936         for j in $(seq $NUMFILES); do
6937                 check_stripe_count $dir/dir1/file$j $expected
6938         done
6939
6940         # lfs_migrate works with lfs find
6941         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6942              $LFS_MIGRATE -y -c $expected"
6943         echo "$cmd"
6944         eval $cmd || error "$cmd failed"
6945
6946         for i in $(seq 2 $NUMFILES); do
6947                 check_stripe_count $dir/file$i $expected
6948         done
6949         for i in $(seq 2 $NUMDIRS); do
6950                 for j in $(seq $NUMFILES); do
6951                 check_stripe_count $dir/dir$i/file$j $expected
6952                 done
6953         done
6954 }
6955 run_test 56w "check lfs_migrate -c stripe_count works"
6956
6957 test_56wb() {
6958         local file1=$DIR/$tdir/file1
6959         local create_pool=false
6960         local initial_pool=$($LFS getstripe -p $DIR)
6961         local pool_list=()
6962         local pool=""
6963
6964         echo -n "Creating test dir..."
6965         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6966         echo "done."
6967
6968         echo -n "Creating test file..."
6969         touch $file1 || error "cannot create file"
6970         echo "done."
6971
6972         echo -n "Detecting existing pools..."
6973         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6974
6975         if [ ${#pool_list[@]} -gt 0 ]; then
6976                 echo "${pool_list[@]}"
6977                 for thispool in "${pool_list[@]}"; do
6978                         if [[ -z "$initial_pool" ||
6979                               "$initial_pool" != "$thispool" ]]; then
6980                                 pool="$thispool"
6981                                 echo "Using existing pool '$pool'"
6982                                 break
6983                         fi
6984                 done
6985         else
6986                 echo "none detected."
6987         fi
6988         if [ -z "$pool" ]; then
6989                 pool=${POOL:-testpool}
6990                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6991                 echo -n "Creating pool '$pool'..."
6992                 create_pool=true
6993                 pool_add $pool &> /dev/null ||
6994                         error "pool_add failed"
6995                 echo "done."
6996
6997                 echo -n "Adding target to pool..."
6998                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6999                         error "pool_add_targets failed"
7000                 echo "done."
7001         fi
7002
7003         echo -n "Setting pool using -p option..."
7004         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7005                 error "migrate failed rc = $?"
7006         echo "done."
7007
7008         echo -n "Verifying test file is in pool after migrating..."
7009         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7010                 error "file was not migrated to pool $pool"
7011         echo "done."
7012
7013         echo -n "Removing test file from pool '$pool'..."
7014         # "lfs migrate $file" won't remove the file from the pool
7015         # until some striping information is changed.
7016         $LFS migrate -c 1 $file1 &> /dev/null ||
7017                 error "cannot remove from pool"
7018         [ "$($LFS getstripe -p $file1)" ] &&
7019                 error "pool still set"
7020         echo "done."
7021
7022         echo -n "Setting pool using --pool option..."
7023         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7024                 error "migrate failed rc = $?"
7025         echo "done."
7026
7027         # Clean up
7028         rm -f $file1
7029         if $create_pool; then
7030                 destroy_test_pools 2> /dev/null ||
7031                         error "destroy test pools failed"
7032         fi
7033 }
7034 run_test 56wb "check lfs_migrate pool support"
7035
7036 test_56wc() {
7037         local file1="$DIR/$tdir/file1"
7038         local parent_ssize
7039         local parent_scount
7040         local cur_ssize
7041         local cur_scount
7042         local orig_ssize
7043
7044         echo -n "Creating test dir..."
7045         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7046         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7047                 error "cannot set stripe by '-S 1M -c 1'"
7048         echo "done"
7049
7050         echo -n "Setting initial stripe for test file..."
7051         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7052                 error "cannot set stripe"
7053         cur_ssize=$($LFS getstripe -S "$file1")
7054         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7055         echo "done."
7056
7057         # File currently set to -S 512K -c 1
7058
7059         # Ensure -c and -S options are rejected when -R is set
7060         echo -n "Verifying incompatible options are detected..."
7061         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7062                 error "incompatible -c and -R options not detected"
7063         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7064                 error "incompatible -S and -R options not detected"
7065         echo "done."
7066
7067         # Ensure unrecognized options are passed through to 'lfs migrate'
7068         echo -n "Verifying -S option is passed through to lfs migrate..."
7069         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7070                 error "migration failed"
7071         cur_ssize=$($LFS getstripe -S "$file1")
7072         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7073         echo "done."
7074
7075         # File currently set to -S 1M -c 1
7076
7077         # Ensure long options are supported
7078         echo -n "Verifying long options supported..."
7079         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7080                 error "long option without argument not supported"
7081         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7082                 error "long option with argument not supported"
7083         cur_ssize=$($LFS getstripe -S "$file1")
7084         [ $cur_ssize -eq 524288 ] ||
7085                 error "migrate --stripe-size $cur_ssize != 524288"
7086         echo "done."
7087
7088         # File currently set to -S 512K -c 1
7089
7090         if [ "$OSTCOUNT" -gt 1 ]; then
7091                 echo -n "Verifying explicit stripe count can be set..."
7092                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7093                         error "migrate failed"
7094                 cur_scount=$($LFS getstripe -c "$file1")
7095                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7096                 echo "done."
7097         fi
7098
7099         # File currently set to -S 512K -c 1 or -S 512K -c 2
7100
7101         # Ensure parent striping is used if -R is set, and no stripe
7102         # count or size is specified
7103         echo -n "Setting stripe for parent directory..."
7104         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7105                 error "cannot set stripe '-S 2M -c 1'"
7106         echo "done."
7107
7108         echo -n "Verifying restripe option uses parent stripe settings..."
7109         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7110         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7111         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7112                 error "migrate failed"
7113         cur_ssize=$($LFS getstripe -S "$file1")
7114         [ $cur_ssize -eq $parent_ssize ] ||
7115                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7116         cur_scount=$($LFS getstripe -c "$file1")
7117         [ $cur_scount -eq $parent_scount ] ||
7118                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7119         echo "done."
7120
7121         # File currently set to -S 1M -c 1
7122
7123         # Ensure striping is preserved if -R is not set, and no stripe
7124         # count or size is specified
7125         echo -n "Verifying striping size preserved when not specified..."
7126         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7127         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7128                 error "cannot set stripe on parent directory"
7129         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7130                 error "migrate failed"
7131         cur_ssize=$($LFS getstripe -S "$file1")
7132         [ $cur_ssize -eq $orig_ssize ] ||
7133                 error "migrate by default $cur_ssize != $orig_ssize"
7134         echo "done."
7135
7136         # Ensure file name properly detected when final option has no argument
7137         echo -n "Verifying file name properly detected..."
7138         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7139                 error "file name interpreted as option argument"
7140         echo "done."
7141
7142         # Clean up
7143         rm -f "$file1"
7144 }
7145 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7146
7147 test_56wd() {
7148         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7149
7150         local file1=$DIR/$tdir/file1
7151
7152         echo -n "Creating test dir..."
7153         test_mkdir $DIR/$tdir || error "cannot create dir"
7154         echo "done."
7155
7156         echo -n "Creating test file..."
7157         touch $file1
7158         echo "done."
7159
7160         # Ensure 'lfs migrate' will fail by using a non-existent option,
7161         # and make sure rsync is not called to recover
7162         echo -n "Make sure --no-rsync option works..."
7163         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7164                 grep -q 'refusing to fall back to rsync' ||
7165                 error "rsync was called with --no-rsync set"
7166         echo "done."
7167
7168         # Ensure rsync is called without trying 'lfs migrate' first
7169         echo -n "Make sure --rsync option works..."
7170         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7171                 grep -q 'falling back to rsync' &&
7172                 error "lfs migrate was called with --rsync set"
7173         echo "done."
7174
7175         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7176         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7177                 grep -q 'at the same time' ||
7178                 error "--rsync and --no-rsync accepted concurrently"
7179         echo "done."
7180
7181         # Clean up
7182         rm -f $file1
7183 }
7184 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7185
7186 test_56we() {
7187         local td=$DIR/$tdir
7188         local tf=$td/$tfile
7189
7190         test_mkdir $td || error "cannot create $td"
7191         touch $tf || error "cannot touch $tf"
7192
7193         echo -n "Make sure --non-direct|-D works..."
7194         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7195                 grep -q "lfs migrate --non-direct" ||
7196                 error "--non-direct option cannot work correctly"
7197         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7198                 grep -q "lfs migrate -D" ||
7199                 error "-D option cannot work correctly"
7200         echo "done."
7201 }
7202 run_test 56we "check lfs_migrate --non-direct|-D support"
7203
7204 test_56x() {
7205         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7206         check_swap_layouts_support
7207
7208         local dir=$DIR/$tdir
7209         local ref1=/etc/passwd
7210         local file1=$dir/file1
7211
7212         test_mkdir $dir || error "creating dir $dir"
7213         $LFS setstripe -c 2 $file1
7214         cp $ref1 $file1
7215         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7216         stripe=$($LFS getstripe -c $file1)
7217         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7218         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7219
7220         # clean up
7221         rm -f $file1
7222 }
7223 run_test 56x "lfs migration support"
7224
7225 test_56xa() {
7226         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7227         check_swap_layouts_support
7228
7229         local dir=$DIR/$tdir/$testnum
7230
7231         test_mkdir -p $dir
7232
7233         local ref1=/etc/passwd
7234         local file1=$dir/file1
7235
7236         $LFS setstripe -c 2 $file1
7237         cp $ref1 $file1
7238         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7239
7240         local stripe=$($LFS getstripe -c $file1)
7241
7242         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7243         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7244
7245         # clean up
7246         rm -f $file1
7247 }
7248 run_test 56xa "lfs migration --block support"
7249
7250 check_migrate_links() {
7251         local dir="$1"
7252         local file1="$dir/file1"
7253         local begin="$2"
7254         local count="$3"
7255         local runas="$4"
7256         local total_count=$(($begin + $count - 1))
7257         local symlink_count=10
7258         local uniq_count=10
7259
7260         if [ ! -f "$file1" ]; then
7261                 echo -n "creating initial file..."
7262                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7263                         error "cannot setstripe initial file"
7264                 echo "done"
7265
7266                 echo -n "creating symlinks..."
7267                 for s in $(seq 1 $symlink_count); do
7268                         ln -s "$file1" "$dir/slink$s" ||
7269                                 error "cannot create symlinks"
7270                 done
7271                 echo "done"
7272
7273                 echo -n "creating nonlinked files..."
7274                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7275                         error "cannot create nonlinked files"
7276                 echo "done"
7277         fi
7278
7279         # create hard links
7280         if [ ! -f "$dir/file$total_count" ]; then
7281                 echo -n "creating hard links $begin:$total_count..."
7282                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7283                         /dev/null || error "cannot create hard links"
7284                 echo "done"
7285         fi
7286
7287         echo -n "checking number of hard links listed in xattrs..."
7288         local fid=$($LFS getstripe -F "$file1")
7289         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7290
7291         echo "${#paths[*]}"
7292         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7293                         skip "hard link list has unexpected size, skipping test"
7294         fi
7295         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7296                         error "link names should exceed xattrs size"
7297         fi
7298
7299         echo -n "migrating files..."
7300         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7301         local rc=$?
7302         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7303         echo "done"
7304
7305         # make sure all links have been properly migrated
7306         echo -n "verifying files..."
7307         fid=$($LFS getstripe -F "$file1") ||
7308                 error "cannot get fid for file $file1"
7309         for i in $(seq 2 $total_count); do
7310                 local fid2=$($LFS getstripe -F $dir/file$i)
7311
7312                 [ "$fid2" == "$fid" ] ||
7313                         error "migrated hard link has mismatched FID"
7314         done
7315
7316         # make sure hard links were properly detected, and migration was
7317         # performed only once for the entire link set; nonlinked files should
7318         # also be migrated
7319         local actual=$(grep -c 'done' <<< "$migrate_out")
7320         local expected=$(($uniq_count + 1))
7321
7322         [ "$actual" -eq  "$expected" ] ||
7323                 error "hard links individually migrated ($actual != $expected)"
7324
7325         # make sure the correct number of hard links are present
7326         local hardlinks=$(stat -c '%h' "$file1")
7327
7328         [ $hardlinks -eq $total_count ] ||
7329                 error "num hard links $hardlinks != $total_count"
7330         echo "done"
7331
7332         return 0
7333 }
7334
7335 test_56xb() {
7336         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7337                 skip "Need MDS version at least 2.10.55"
7338
7339         local dir="$DIR/$tdir"
7340
7341         test_mkdir "$dir" || error "cannot create dir $dir"
7342
7343         echo "testing lfs migrate mode when all links fit within xattrs"
7344         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7345
7346         echo "testing rsync mode when all links fit within xattrs"
7347         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7348
7349         echo "testing lfs migrate mode when all links do not fit within xattrs"
7350         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7351
7352         echo "testing rsync mode when all links do not fit within xattrs"
7353         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7354
7355         chown -R $RUNAS_ID $dir
7356         echo "testing non-root lfs migrate mode when not all links are in xattr"
7357         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7358
7359         # clean up
7360         rm -rf $dir
7361 }
7362 run_test 56xb "lfs migration hard link support"
7363
7364 test_56xc() {
7365         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7366
7367         local dir="$DIR/$tdir"
7368
7369         test_mkdir "$dir" || error "cannot create dir $dir"
7370
7371         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7372         echo -n "Setting initial stripe for 20MB test file..."
7373         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7374                 error "cannot setstripe 20MB file"
7375         echo "done"
7376         echo -n "Sizing 20MB test file..."
7377         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7378         echo "done"
7379         echo -n "Verifying small file autostripe count is 1..."
7380         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7381                 error "cannot migrate 20MB file"
7382         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7383                 error "cannot get stripe for $dir/20mb"
7384         [ $stripe_count -eq 1 ] ||
7385                 error "unexpected stripe count $stripe_count for 20MB file"
7386         rm -f "$dir/20mb"
7387         echo "done"
7388
7389         # Test 2: File is small enough to fit within the available space on
7390         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7391         # have at least an additional 1KB for each desired stripe for test 3
7392         echo -n "Setting stripe for 1GB test file..."
7393         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7394         echo "done"
7395         echo -n "Sizing 1GB test file..."
7396         # File size is 1GB + 3KB
7397         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7398         echo "done"
7399
7400         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7401         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7402         if (( avail > 524288 * OSTCOUNT )); then
7403                 echo -n "Migrating 1GB file..."
7404                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7405                         error "cannot migrate 1GB file"
7406                 echo "done"
7407                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7408                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7409                         error "cannot getstripe for 1GB file"
7410                 [ $stripe_count -eq 2 ] ||
7411                         error "unexpected stripe count $stripe_count != 2"
7412                 echo "done"
7413         fi
7414
7415         # Test 3: File is too large to fit within the available space on
7416         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7417         if [ $OSTCOUNT -ge 3 ]; then
7418                 # The required available space is calculated as
7419                 # file size (1GB + 3KB) / OST count (3).
7420                 local kb_per_ost=349526
7421
7422                 echo -n "Migrating 1GB file with limit..."
7423                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7424                         error "cannot migrate 1GB file with limit"
7425                 echo "done"
7426
7427                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7428                 echo -n "Verifying 1GB autostripe count with limited space..."
7429                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7430                         error "unexpected stripe count $stripe_count (min 3)"
7431                 echo "done"
7432         fi
7433
7434         # clean up
7435         rm -rf $dir
7436 }
7437 run_test 56xc "lfs migration autostripe"
7438
7439 test_56xd() {
7440         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7441
7442         local dir=$DIR/$tdir
7443         local f_mgrt=$dir/$tfile.mgrt
7444         local f_yaml=$dir/$tfile.yaml
7445         local f_copy=$dir/$tfile.copy
7446         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7447         local layout_copy="-c 2 -S 2M -i 1"
7448         local yamlfile=$dir/yamlfile
7449         local layout_before;
7450         local layout_after;
7451
7452         test_mkdir "$dir" || error "cannot create dir $dir"
7453         $LFS setstripe $layout_yaml $f_yaml ||
7454                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7455         $LFS getstripe --yaml $f_yaml > $yamlfile
7456         $LFS setstripe $layout_copy $f_copy ||
7457                 error "cannot setstripe $f_copy with layout $layout_copy"
7458         touch $f_mgrt
7459         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7460
7461         # 1. test option --yaml
7462         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7463                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7464         layout_before=$(get_layout_param $f_yaml)
7465         layout_after=$(get_layout_param $f_mgrt)
7466         [ "$layout_after" == "$layout_before" ] ||
7467                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7468
7469         # 2. test option --copy
7470         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7471                 error "cannot migrate $f_mgrt with --copy $f_copy"
7472         layout_before=$(get_layout_param $f_copy)
7473         layout_after=$(get_layout_param $f_mgrt)
7474         [ "$layout_after" == "$layout_before" ] ||
7475                 error "lfs_migrate --copy: $layout_after != $layout_before"
7476 }
7477 run_test 56xd "check lfs_migrate --yaml and --copy support"
7478
7479 test_56xe() {
7480         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7481
7482         local dir=$DIR/$tdir
7483         local f_comp=$dir/$tfile
7484         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7485         local layout_before=""
7486         local layout_after=""
7487
7488         test_mkdir "$dir" || error "cannot create dir $dir"
7489         $LFS setstripe $layout $f_comp ||
7490                 error "cannot setstripe $f_comp with layout $layout"
7491         layout_before=$(get_layout_param $f_comp)
7492         dd if=/dev/zero of=$f_comp bs=1M count=4
7493
7494         # 1. migrate a comp layout file by lfs_migrate
7495         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7496         layout_after=$(get_layout_param $f_comp)
7497         [ "$layout_before" == "$layout_after" ] ||
7498                 error "lfs_migrate: $layout_before != $layout_after"
7499
7500         # 2. migrate a comp layout file by lfs migrate
7501         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7502         layout_after=$(get_layout_param $f_comp)
7503         [ "$layout_before" == "$layout_after" ] ||
7504                 error "lfs migrate: $layout_before != $layout_after"
7505 }
7506 run_test 56xe "migrate a composite layout file"
7507
7508 test_56xf() {
7509         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7510
7511         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7512                 skip "Need server version at least 2.13.53"
7513
7514         local dir=$DIR/$tdir
7515         local f_comp=$dir/$tfile
7516         local layout="-E 1M -c1 -E -1 -c2"
7517         local fid_before=""
7518         local fid_after=""
7519
7520         test_mkdir "$dir" || error "cannot create dir $dir"
7521         $LFS setstripe $layout $f_comp ||
7522                 error "cannot setstripe $f_comp with layout $layout"
7523         fid_before=$($LFS getstripe --fid $f_comp)
7524         dd if=/dev/zero of=$f_comp bs=1M count=4
7525
7526         # 1. migrate a comp layout file to a comp layout
7527         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7528         fid_after=$($LFS getstripe --fid $f_comp)
7529         [ "$fid_before" == "$fid_after" ] ||
7530                 error "comp-to-comp migrate: $fid_before != $fid_after"
7531
7532         # 2. migrate a comp layout file to a plain layout
7533         $LFS migrate -c2 $f_comp ||
7534                 error "cannot migrate $f_comp by lfs migrate"
7535         fid_after=$($LFS getstripe --fid $f_comp)
7536         [ "$fid_before" == "$fid_after" ] ||
7537                 error "comp-to-plain migrate: $fid_before != $fid_after"
7538
7539         # 3. migrate a plain layout file to a comp layout
7540         $LFS migrate $layout $f_comp ||
7541                 error "cannot migrate $f_comp by lfs migrate"
7542         fid_after=$($LFS getstripe --fid $f_comp)
7543         [ "$fid_before" == "$fid_after" ] ||
7544                 error "plain-to-comp migrate: $fid_before != $fid_after"
7545 }
7546 run_test 56xf "FID is not lost during migration of a composite layout file"
7547
7548 test_56y() {
7549         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7550                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7551
7552         local res=""
7553         local dir=$DIR/$tdir
7554         local f1=$dir/file1
7555         local f2=$dir/file2
7556
7557         test_mkdir -p $dir || error "creating dir $dir"
7558         touch $f1 || error "creating std file $f1"
7559         $MULTIOP $f2 H2c || error "creating released file $f2"
7560
7561         # a directory can be raid0, so ask only for files
7562         res=$($LFS find $dir -L raid0 -type f | wc -l)
7563         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7564
7565         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7566         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7567
7568         # only files can be released, so no need to force file search
7569         res=$($LFS find $dir -L released)
7570         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7571
7572         res=$($LFS find $dir -type f \! -L released)
7573         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7574 }
7575 run_test 56y "lfs find -L raid0|released"
7576
7577 test_56z() { # LU-4824
7578         # This checks to make sure 'lfs find' continues after errors
7579         # There are two classes of errors that should be caught:
7580         # - If multiple paths are provided, all should be searched even if one
7581         #   errors out
7582         # - If errors are encountered during the search, it should not terminate
7583         #   early
7584         local dir=$DIR/$tdir
7585         local i
7586
7587         test_mkdir $dir
7588         for i in d{0..9}; do
7589                 test_mkdir $dir/$i
7590                 touch $dir/$i/$tfile
7591         done
7592         $LFS find $DIR/non_existent_dir $dir &&
7593                 error "$LFS find did not return an error"
7594         # Make a directory unsearchable. This should NOT be the last entry in
7595         # directory order.  Arbitrarily pick the 6th entry
7596         chmod 700 $($LFS find $dir -type d | sed '6!d')
7597
7598         $RUNAS $LFS find $DIR/non_existent $dir
7599         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7600
7601         # The user should be able to see 10 directories and 9 files
7602         (( count == 19 )) ||
7603                 error "$LFS find found $count != 19 entries after error"
7604 }
7605 run_test 56z "lfs find should continue after an error"
7606
7607 test_56aa() { # LU-5937
7608         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7609
7610         local dir=$DIR/$tdir
7611
7612         mkdir $dir
7613         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7614
7615         createmany -o $dir/striped_dir/${tfile}- 1024
7616         local dirs=$($LFS find --size +8k $dir/)
7617
7618         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7619 }
7620 run_test 56aa "lfs find --size under striped dir"
7621
7622 test_56ab() { # LU-10705
7623         test_mkdir $DIR/$tdir
7624         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7625         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7626         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7627         # Flush writes to ensure valid blocks.  Need to be more thorough for
7628         # ZFS, since blocks are not allocated/returned to client immediately.
7629         sync_all_data
7630         wait_zfs_commit ost1 2
7631         cancel_lru_locks osc
7632         ls -ls $DIR/$tdir
7633
7634         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7635
7636         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7637
7638         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7639         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7640
7641         rm -f $DIR/$tdir/$tfile.[123]
7642 }
7643 run_test 56ab "lfs find --blocks"
7644
7645 test_56ba() {
7646         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7647                 skip "Need MDS version at least 2.10.50"
7648
7649         # Create composite files with one component
7650         local dir=$DIR/$tdir
7651
7652         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7653         # Create composite files with three components
7654         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7655         # Create non-composite files
7656         createmany -o $dir/${tfile}- 10
7657
7658         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7659
7660         [[ $nfiles == 10 ]] ||
7661                 error "lfs find -E 1M found $nfiles != 10 files"
7662
7663         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7664         [[ $nfiles == 25 ]] ||
7665                 error "lfs find ! -E 1M found $nfiles != 25 files"
7666
7667         # All files have a component that starts at 0
7668         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7669         [[ $nfiles == 35 ]] ||
7670                 error "lfs find --component-start 0 - $nfiles != 35 files"
7671
7672         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7673         [[ $nfiles == 15 ]] ||
7674                 error "lfs find --component-start 2M - $nfiles != 15 files"
7675
7676         # All files created here have a componenet that does not starts at 2M
7677         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7678         [[ $nfiles == 35 ]] ||
7679                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7680
7681         # Find files with a specified number of components
7682         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7683         [[ $nfiles == 15 ]] ||
7684                 error "lfs find --component-count 3 - $nfiles != 15 files"
7685
7686         # Remember non-composite files have a component count of zero
7687         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7688         [[ $nfiles == 10 ]] ||
7689                 error "lfs find --component-count 0 - $nfiles != 10 files"
7690
7691         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7692         [[ $nfiles == 20 ]] ||
7693                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7694
7695         # All files have a flag called "init"
7696         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7697         [[ $nfiles == 35 ]] ||
7698                 error "lfs find --component-flags init - $nfiles != 35 files"
7699
7700         # Multi-component files will have a component not initialized
7701         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7702         [[ $nfiles == 15 ]] ||
7703                 error "lfs find !--component-flags init - $nfiles != 15 files"
7704
7705         rm -rf $dir
7706
7707 }
7708 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7709
7710 test_56ca() {
7711         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7712                 skip "Need MDS version at least 2.10.57"
7713
7714         local td=$DIR/$tdir
7715         local tf=$td/$tfile
7716         local dir
7717         local nfiles
7718         local cmd
7719         local i
7720         local j
7721
7722         # create mirrored directories and mirrored files
7723         mkdir $td || error "mkdir $td failed"
7724         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7725         createmany -o $tf- 10 || error "create $tf- failed"
7726
7727         for i in $(seq 2); do
7728                 dir=$td/dir$i
7729                 mkdir $dir || error "mkdir $dir failed"
7730                 $LFS mirror create -N$((3 + i)) $dir ||
7731                         error "create mirrored dir $dir failed"
7732                 createmany -o $dir/$tfile- 10 ||
7733                         error "create $dir/$tfile- failed"
7734         done
7735
7736         # change the states of some mirrored files
7737         echo foo > $tf-6
7738         for i in $(seq 2); do
7739                 dir=$td/dir$i
7740                 for j in $(seq 4 9); do
7741                         echo foo > $dir/$tfile-$j
7742                 done
7743         done
7744
7745         # find mirrored files with specific mirror count
7746         cmd="$LFS find --mirror-count 3 --type f $td"
7747         nfiles=$($cmd | wc -l)
7748         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7749
7750         cmd="$LFS find ! --mirror-count 3 --type f $td"
7751         nfiles=$($cmd | wc -l)
7752         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7753
7754         cmd="$LFS find --mirror-count +2 --type f $td"
7755         nfiles=$($cmd | wc -l)
7756         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7757
7758         cmd="$LFS find --mirror-count -6 --type f $td"
7759         nfiles=$($cmd | wc -l)
7760         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7761
7762         # find mirrored files with specific file state
7763         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7764         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7765
7766         cmd="$LFS find --mirror-state=ro --type f $td"
7767         nfiles=$($cmd | wc -l)
7768         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7769
7770         cmd="$LFS find ! --mirror-state=ro --type f $td"
7771         nfiles=$($cmd | wc -l)
7772         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7773
7774         cmd="$LFS find --mirror-state=wp --type f $td"
7775         nfiles=$($cmd | wc -l)
7776         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7777
7778         cmd="$LFS find ! --mirror-state=sp --type f $td"
7779         nfiles=$($cmd | wc -l)
7780         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7781 }
7782 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7783
7784 test_56da() { # LU-14179
7785         local path=$DIR/$tdir
7786
7787         test_mkdir $path
7788         cd $path
7789
7790         local longdir=$(str_repeat 'a' 255)
7791
7792         for i in {1..15}; do
7793                 path=$path/$longdir
7794                 test_mkdir $longdir
7795                 cd $longdir
7796         done
7797
7798         local len=${#path}
7799         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7800
7801         test_mkdir $lastdir
7802         cd $lastdir
7803         # PATH_MAX-1
7804         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7805
7806         # NAME_MAX
7807         touch $(str_repeat 'f' 255)
7808
7809         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7810                 error "lfs find reported an error"
7811
7812         rm -rf $DIR/$tdir
7813 }
7814 run_test 56da "test lfs find with long paths"
7815
7816 test_57a() {
7817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7818         # note test will not do anything if MDS is not local
7819         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7820                 skip_env "ldiskfs only test"
7821         fi
7822         remote_mds_nodsh && skip "remote MDS with nodsh"
7823
7824         local MNTDEV="osd*.*MDT*.mntdev"
7825         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7826         [ -z "$DEV" ] && error "can't access $MNTDEV"
7827         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7828                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7829                         error "can't access $DEV"
7830                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7831                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7832                 rm $TMP/t57a.dump
7833         done
7834 }
7835 run_test 57a "verify MDS filesystem created with large inodes =="
7836
7837 test_57b() {
7838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7839         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7840                 skip_env "ldiskfs only test"
7841         fi
7842         remote_mds_nodsh && skip "remote MDS with nodsh"
7843
7844         local dir=$DIR/$tdir
7845         local filecount=100
7846         local file1=$dir/f1
7847         local fileN=$dir/f$filecount
7848
7849         rm -rf $dir || error "removing $dir"
7850         test_mkdir -c1 $dir
7851         local mdtidx=$($LFS getstripe -m $dir)
7852         local mdtname=MDT$(printf %04x $mdtidx)
7853         local facet=mds$((mdtidx + 1))
7854
7855         echo "mcreating $filecount files"
7856         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7857
7858         # verify that files do not have EAs yet
7859         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7860                 error "$file1 has an EA"
7861         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7862                 error "$fileN has an EA"
7863
7864         sync
7865         sleep 1
7866         df $dir  #make sure we get new statfs data
7867         local mdsfree=$(do_facet $facet \
7868                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7869         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7870         local file
7871
7872         echo "opening files to create objects/EAs"
7873         for file in $(seq -f $dir/f%g 1 $filecount); do
7874                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7875                         error "opening $file"
7876         done
7877
7878         # verify that files have EAs now
7879         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7880         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7881
7882         sleep 1  #make sure we get new statfs data
7883         df $dir
7884         local mdsfree2=$(do_facet $facet \
7885                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7886         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7887
7888         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7889                 if [ "$mdsfree" != "$mdsfree2" ]; then
7890                         error "MDC before $mdcfree != after $mdcfree2"
7891                 else
7892                         echo "MDC before $mdcfree != after $mdcfree2"
7893                         echo "unable to confirm if MDS has large inodes"
7894                 fi
7895         fi
7896         rm -rf $dir
7897 }
7898 run_test 57b "default LOV EAs are stored inside large inodes ==="
7899
7900 test_58() {
7901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7902         [ -z "$(which wiretest 2>/dev/null)" ] &&
7903                         skip_env "could not find wiretest"
7904
7905         wiretest
7906 }
7907 run_test 58 "verify cross-platform wire constants =============="
7908
7909 test_59() {
7910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7911
7912         echo "touch 130 files"
7913         createmany -o $DIR/f59- 130
7914         echo "rm 130 files"
7915         unlinkmany $DIR/f59- 130
7916         sync
7917         # wait for commitment of removal
7918         wait_delete_completed
7919 }
7920 run_test 59 "verify cancellation of llog records async ========="
7921
7922 TEST60_HEAD="test_60 run $RANDOM"
7923 test_60a() {
7924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7925         remote_mgs_nodsh && skip "remote MGS with nodsh"
7926         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7927                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7928                         skip_env "missing subtest run-llog.sh"
7929
7930         log "$TEST60_HEAD - from kernel mode"
7931         do_facet mgs "$LCTL dk > /dev/null"
7932         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7933         do_facet mgs $LCTL dk > $TMP/$tfile
7934
7935         # LU-6388: test llog_reader
7936         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7937         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7938         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7939                         skip_env "missing llog_reader"
7940         local fstype=$(facet_fstype mgs)
7941         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7942                 skip_env "Only for ldiskfs or zfs type mgs"
7943
7944         local mntpt=$(facet_mntpt mgs)
7945         local mgsdev=$(mgsdevname 1)
7946         local fid_list
7947         local fid
7948         local rec_list
7949         local rec
7950         local rec_type
7951         local obj_file
7952         local path
7953         local seq
7954         local oid
7955         local pass=true
7956
7957         #get fid and record list
7958         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7959                 tail -n 4))
7960         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7961                 tail -n 4))
7962         #remount mgs as ldiskfs or zfs type
7963         stop mgs || error "stop mgs failed"
7964         mount_fstype mgs || error "remount mgs failed"
7965         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7966                 fid=${fid_list[i]}
7967                 rec=${rec_list[i]}
7968                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7969                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7970                 oid=$((16#$oid))
7971
7972                 case $fstype in
7973                         ldiskfs )
7974                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7975                         zfs )
7976                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7977                 esac
7978                 echo "obj_file is $obj_file"
7979                 do_facet mgs $llog_reader $obj_file
7980
7981                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7982                         awk '{ print $3 }' | sed -e "s/^type=//g")
7983                 if [ $rec_type != $rec ]; then
7984                         echo "FAILED test_60a wrong record type $rec_type," \
7985                               "should be $rec"
7986                         pass=false
7987                         break
7988                 fi
7989
7990                 #check obj path if record type is LLOG_LOGID_MAGIC
7991                 if [ "$rec" == "1064553b" ]; then
7992                         path=$(do_facet mgs $llog_reader $obj_file |
7993                                 grep "path=" | awk '{ print $NF }' |
7994                                 sed -e "s/^path=//g")
7995                         if [ $obj_file != $mntpt/$path ]; then
7996                                 echo "FAILED test_60a wrong obj path" \
7997                                       "$montpt/$path, should be $obj_file"
7998                                 pass=false
7999                                 break
8000                         fi
8001                 fi
8002         done
8003         rm -f $TMP/$tfile
8004         #restart mgs before "error", otherwise it will block the next test
8005         stop mgs || error "stop mgs failed"
8006         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8007         $pass || error "test failed, see FAILED test_60a messages for specifics"
8008 }
8009 run_test 60a "llog_test run from kernel module and test llog_reader"
8010
8011 test_60b() { # bug 6411
8012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8013
8014         dmesg > $DIR/$tfile
8015         LLOG_COUNT=$(do_facet mgs dmesg |
8016                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8017                           /llog_[a-z]*.c:[0-9]/ {
8018                                 if (marker)
8019                                         from_marker++
8020                                 from_begin++
8021                           }
8022                           END {
8023                                 if (marker)
8024                                         print from_marker
8025                                 else
8026                                         print from_begin
8027                           }")
8028
8029         [[ $LLOG_COUNT -gt 120 ]] &&
8030                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8031 }
8032 run_test 60b "limit repeated messages from CERROR/CWARN"
8033
8034 test_60c() {
8035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8036
8037         echo "create 5000 files"
8038         createmany -o $DIR/f60c- 5000
8039 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8040         lctl set_param fail_loc=0x80000137
8041         unlinkmany $DIR/f60c- 5000
8042         lctl set_param fail_loc=0
8043 }
8044 run_test 60c "unlink file when mds full"
8045
8046 test_60d() {
8047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8048
8049         SAVEPRINTK=$(lctl get_param -n printk)
8050         # verify "lctl mark" is even working"
8051         MESSAGE="test message ID $RANDOM $$"
8052         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8053         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8054
8055         lctl set_param printk=0 || error "set lnet.printk failed"
8056         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8057         MESSAGE="new test message ID $RANDOM $$"
8058         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8059         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8060         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8061
8062         lctl set_param -n printk="$SAVEPRINTK"
8063 }
8064 run_test 60d "test printk console message masking"
8065
8066 test_60e() {
8067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8068         remote_mds_nodsh && skip "remote MDS with nodsh"
8069
8070         touch $DIR/$tfile
8071 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8072         do_facet mds1 lctl set_param fail_loc=0x15b
8073         rm $DIR/$tfile
8074 }
8075 run_test 60e "no space while new llog is being created"
8076
8077 test_60f() {
8078         local old_path=$($LCTL get_param -n debug_path)
8079
8080         stack_trap "$LCTL set_param debug_path=$old_path"
8081         stack_trap "rm -f $TMP/$tfile*"
8082         rm -f $TMP/$tfile* 2> /dev/null
8083         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8084         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8085         test_mkdir $DIR/$tdir
8086         # retry in case the open is cached and not released
8087         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8088                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8089                 sleep 0.1
8090         done
8091         ls $TMP/$tfile*
8092         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8093 }
8094 run_test 60f "change debug_path works"
8095
8096 test_60g() {
8097         local pid
8098         local i
8099
8100         test_mkdir -c $MDSCOUNT $DIR/$tdir
8101
8102         (
8103                 local index=0
8104                 while true; do
8105                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8106                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8107                                 2>/dev/null
8108                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8109                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8110                         index=$((index + 1))
8111                 done
8112         ) &
8113
8114         pid=$!
8115
8116         for i in {0..100}; do
8117                 # define OBD_FAIL_OSD_TXN_START    0x19a
8118                 local index=$((i % MDSCOUNT + 1))
8119
8120                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8121                         > /dev/null
8122                 sleep 0.01
8123         done
8124
8125         kill -9 $pid
8126
8127         for i in $(seq $MDSCOUNT); do
8128                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8129         done
8130
8131         mkdir $DIR/$tdir/new || error "mkdir failed"
8132         rmdir $DIR/$tdir/new || error "rmdir failed"
8133
8134         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8135                 -t namespace
8136         for i in $(seq $MDSCOUNT); do
8137                 wait_update_facet mds$i "$LCTL get_param -n \
8138                         mdd.$(facet_svc mds$i).lfsck_namespace |
8139                         awk '/^status/ { print \\\$2 }'" "completed"
8140         done
8141
8142         ls -R $DIR/$tdir || error "ls failed"
8143         rm -rf $DIR/$tdir || error "rmdir failed"
8144 }
8145 run_test 60g "transaction abort won't cause MDT hung"
8146
8147 test_60h() {
8148         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8149                 skip "Need MDS version at least 2.12.52"
8150         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8151
8152         local f
8153
8154         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8155         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8156         for fail_loc in 0x80000188 0x80000189; do
8157                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8158                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8159                         error "mkdir $dir-$fail_loc failed"
8160                 for i in {0..10}; do
8161                         # create may fail on missing stripe
8162                         echo $i > $DIR/$tdir-$fail_loc/$i
8163                 done
8164                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8165                         error "getdirstripe $tdir-$fail_loc failed"
8166                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8167                         error "migrate $tdir-$fail_loc failed"
8168                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8169                         error "getdirstripe $tdir-$fail_loc failed"
8170                 pushd $DIR/$tdir-$fail_loc
8171                 for f in *; do
8172                         echo $f | cmp $f - || error "$f data mismatch"
8173                 done
8174                 popd
8175                 rm -rf $DIR/$tdir-$fail_loc
8176         done
8177 }
8178 run_test 60h "striped directory with missing stripes can be accessed"
8179
8180 test_61a() {
8181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8182
8183         f="$DIR/f61"
8184         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8185         cancel_lru_locks osc
8186         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8187         sync
8188 }
8189 run_test 61a "mmap() writes don't make sync hang ================"
8190
8191 test_61b() {
8192         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8193 }
8194 run_test 61b "mmap() of unstriped file is successful"
8195
8196 # bug 2330 - insufficient obd_match error checking causes LBUG
8197 test_62() {
8198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8199
8200         f="$DIR/f62"
8201         echo foo > $f
8202         cancel_lru_locks osc
8203         lctl set_param fail_loc=0x405
8204         cat $f && error "cat succeeded, expect -EIO"
8205         lctl set_param fail_loc=0
8206 }
8207 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8208 # match every page all of the time.
8209 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8210
8211 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8212 # Though this test is irrelevant anymore, it helped to reveal some
8213 # other grant bugs (LU-4482), let's keep it.
8214 test_63a() {   # was test_63
8215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8216
8217         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8218
8219         for i in `seq 10` ; do
8220                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8221                 sleep 5
8222                 kill $!
8223                 sleep 1
8224         done
8225
8226         rm -f $DIR/f63 || true
8227 }
8228 run_test 63a "Verify oig_wait interruption does not crash ======="
8229
8230 # bug 2248 - async write errors didn't return to application on sync
8231 # bug 3677 - async write errors left page locked
8232 test_63b() {
8233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8234
8235         debugsave
8236         lctl set_param debug=-1
8237
8238         # ensure we have a grant to do async writes
8239         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8240         rm $DIR/$tfile
8241
8242         sync    # sync lest earlier test intercept the fail_loc
8243
8244         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8245         lctl set_param fail_loc=0x80000406
8246         $MULTIOP $DIR/$tfile Owy && \
8247                 error "sync didn't return ENOMEM"
8248         sync; sleep 2; sync     # do a real sync this time to flush page
8249         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8250                 error "locked page left in cache after async error" || true
8251         debugrestore
8252 }
8253 run_test 63b "async write errors should be returned to fsync ==="
8254
8255 test_64a () {
8256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8257
8258         lfs df $DIR
8259         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8260 }
8261 run_test 64a "verify filter grant calculations (in kernel) ====="
8262
8263 test_64b () {
8264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8265
8266         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8267 }
8268 run_test 64b "check out-of-space detection on client"
8269
8270 test_64c() {
8271         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8272 }
8273 run_test 64c "verify grant shrink"
8274
8275 import_param() {
8276         local tgt=$1
8277         local param=$2
8278
8279         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8280 }
8281
8282 # this does exactly what osc_request.c:osc_announce_cached() does in
8283 # order to calculate max amount of grants to ask from server
8284 want_grant() {
8285         local tgt=$1
8286
8287         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8288         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8289
8290         ((rpc_in_flight++));
8291         nrpages=$((nrpages * rpc_in_flight))
8292
8293         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8294
8295         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8296
8297         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8298         local undirty=$((nrpages * PAGE_SIZE))
8299
8300         local max_extent_pages
8301         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8302         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8303         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8304         local grant_extent_tax
8305         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8306
8307         undirty=$((undirty + nrextents * grant_extent_tax))
8308
8309         echo $undirty
8310 }
8311
8312 # this is size of unit for grant allocation. It should be equal to
8313 # what tgt_grant.c:tgt_grant_chunk() calculates
8314 grant_chunk() {
8315         local tgt=$1
8316         local max_brw_size
8317         local grant_extent_tax
8318
8319         max_brw_size=$(import_param $tgt max_brw_size)
8320
8321         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8322
8323         echo $(((max_brw_size + grant_extent_tax) * 2))
8324 }
8325
8326 test_64d() {
8327         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8328                 skip "OST < 2.10.55 doesn't limit grants enough"
8329
8330         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8331
8332         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8333                 skip "no grant_param connect flag"
8334
8335         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8336
8337         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8338         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8339
8340
8341         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8342         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8343
8344         $LFS setstripe $DIR/$tfile -i 0 -c 1
8345         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8346         ddpid=$!
8347
8348         while kill -0 $ddpid; do
8349                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8350
8351                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8352                         kill $ddpid
8353                         error "cur_grant $cur_grant > $max_cur_granted"
8354                 fi
8355
8356                 sleep 1
8357         done
8358 }
8359 run_test 64d "check grant limit exceed"
8360
8361 check_grants() {
8362         local tgt=$1
8363         local expected=$2
8364         local msg=$3
8365         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8366
8367         ((cur_grants == expected)) ||
8368                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8369 }
8370
8371 round_up_p2() {
8372         echo $((($1 + $2 - 1) & ~($2 - 1)))
8373 }
8374
8375 test_64e() {
8376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8377         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8378                 skip "Need OSS version at least 2.11.56"
8379
8380         # Remount client to reset grant
8381         remount_client $MOUNT || error "failed to remount client"
8382         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8383
8384         local init_grants=$(import_param $osc_tgt initial_grant)
8385
8386         check_grants $osc_tgt $init_grants "init grants"
8387
8388         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8389         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8390         local gbs=$(import_param $osc_tgt grant_block_size)
8391
8392         # write random number of bytes from max_brw_size / 4 to max_brw_size
8393         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8394         # align for direct io
8395         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8396         # round to grant consumption unit
8397         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8398
8399         local grants=$((wb_round_up + extent_tax))
8400
8401         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8402
8403         # define OBD_FAIL_TGT_NO_GRANT 0x725
8404         # make the server not grant more back
8405         do_facet ost1 $LCTL set_param fail_loc=0x725
8406         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8407
8408         do_facet ost1 $LCTL set_param fail_loc=0
8409
8410         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8411
8412         rm -f $DIR/$tfile || error "rm failed"
8413
8414         # Remount client to reset grant
8415         remount_client $MOUNT || error "failed to remount client"
8416         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8417
8418         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8419
8420         # define OBD_FAIL_TGT_NO_GRANT 0x725
8421         # make the server not grant more back
8422         do_facet ost1 $LCTL set_param fail_loc=0x725
8423         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8424         do_facet ost1 $LCTL set_param fail_loc=0
8425
8426         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8427 }
8428 run_test 64e "check grant consumption (no grant allocation)"
8429
8430 test_64f() {
8431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8432
8433         # Remount client to reset grant
8434         remount_client $MOUNT || error "failed to remount client"
8435         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8436
8437         local init_grants=$(import_param $osc_tgt initial_grant)
8438         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8439         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8440         local gbs=$(import_param $osc_tgt grant_block_size)
8441         local chunk=$(grant_chunk $osc_tgt)
8442
8443         # write random number of bytes from max_brw_size / 4 to max_brw_size
8444         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8445         # align for direct io
8446         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8447         # round to grant consumption unit
8448         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8449
8450         local grants=$((wb_round_up + extent_tax))
8451
8452         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8453         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8454                 error "error writing to $DIR/$tfile"
8455
8456         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8457                 "direct io with grant allocation"
8458
8459         rm -f $DIR/$tfile || error "rm failed"
8460
8461         # Remount client to reset grant
8462         remount_client $MOUNT || error "failed to remount client"
8463         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8464
8465         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8466
8467         local cmd="oO_WRONLY:w${write_bytes}_yc"
8468
8469         $MULTIOP $DIR/$tfile $cmd &
8470         MULTIPID=$!
8471         sleep 1
8472
8473         check_grants $osc_tgt $((init_grants - grants)) \
8474                 "buffered io, not write rpc"
8475
8476         kill -USR1 $MULTIPID
8477         wait
8478
8479         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8480                 "buffered io, one RPC"
8481 }
8482 run_test 64f "check grant consumption (with grant allocation)"
8483
8484 # bug 1414 - set/get directories' stripe info
8485 test_65a() {
8486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8487
8488         test_mkdir $DIR/$tdir
8489         touch $DIR/$tdir/f1
8490         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8491 }
8492 run_test 65a "directory with no stripe info"
8493
8494 test_65b() {
8495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8496
8497         test_mkdir $DIR/$tdir
8498         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8499
8500         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8501                                                 error "setstripe"
8502         touch $DIR/$tdir/f2
8503         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8504 }
8505 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8506
8507 test_65c() {
8508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8509         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8510
8511         test_mkdir $DIR/$tdir
8512         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8513
8514         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8515                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8516         touch $DIR/$tdir/f3
8517         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8518 }
8519 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8520
8521 test_65d() {
8522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8523
8524         test_mkdir $DIR/$tdir
8525         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8526         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8527
8528         if [[ $STRIPECOUNT -le 0 ]]; then
8529                 sc=1
8530         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8531                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8532                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8533         else
8534                 sc=$(($STRIPECOUNT - 1))
8535         fi
8536         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8537         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8538         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8539                 error "lverify failed"
8540 }
8541 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8542
8543 test_65e() {
8544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8545
8546         test_mkdir $DIR/$tdir
8547
8548         $LFS setstripe $DIR/$tdir || error "setstripe"
8549         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8550                                         error "no stripe info failed"
8551         touch $DIR/$tdir/f6
8552         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8553 }
8554 run_test 65e "directory setstripe defaults"
8555
8556 test_65f() {
8557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8558
8559         test_mkdir $DIR/${tdir}f
8560         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8561                 error "setstripe succeeded" || true
8562 }
8563 run_test 65f "dir setstripe permission (should return error) ==="
8564
8565 test_65g() {
8566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8567
8568         test_mkdir $DIR/$tdir
8569         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8570
8571         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8572                 error "setstripe -S failed"
8573         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8574         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8575                 error "delete default stripe failed"
8576 }
8577 run_test 65g "directory setstripe -d"
8578
8579 test_65h() {
8580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8581
8582         test_mkdir $DIR/$tdir
8583         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8584
8585         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8586                 error "setstripe -S failed"
8587         test_mkdir $DIR/$tdir/dd1
8588         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8589                 error "stripe info inherit failed"
8590 }
8591 run_test 65h "directory stripe info inherit ===================="
8592
8593 test_65i() {
8594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8595
8596         save_layout_restore_at_exit $MOUNT
8597
8598         # bug6367: set non-default striping on root directory
8599         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8600
8601         # bug12836: getstripe on -1 default directory striping
8602         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8603
8604         # bug12836: getstripe -v on -1 default directory striping
8605         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8606
8607         # bug12836: new find on -1 default directory striping
8608         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8609 }
8610 run_test 65i "various tests to set root directory striping"
8611
8612 test_65j() { # bug6367
8613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8614
8615         sync; sleep 1
8616
8617         # if we aren't already remounting for each test, do so for this test
8618         if [ "$I_MOUNTED" = "yes" ]; then
8619                 cleanup || error "failed to unmount"
8620                 setup
8621         fi
8622
8623         save_layout_restore_at_exit $MOUNT
8624
8625         $LFS setstripe -d $MOUNT || error "setstripe failed"
8626 }
8627 run_test 65j "set default striping on root directory (bug 6367)="
8628
8629 cleanup_65k() {
8630         rm -rf $DIR/$tdir
8631         wait_delete_completed
8632         do_facet $SINGLEMDS "lctl set_param -n \
8633                 osp.$ost*MDT0000.max_create_count=$max_count"
8634         do_facet $SINGLEMDS "lctl set_param -n \
8635                 osp.$ost*MDT0000.create_count=$count"
8636         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8637         echo $INACTIVE_OSC "is Activate"
8638
8639         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8640 }
8641
8642 test_65k() { # bug11679
8643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8644         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8645         remote_mds_nodsh && skip "remote MDS with nodsh"
8646
8647         local disable_precreate=true
8648         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8649                 disable_precreate=false
8650
8651         echo "Check OST status: "
8652         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8653                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8654
8655         for OSC in $MDS_OSCS; do
8656                 echo $OSC "is active"
8657                 do_facet $SINGLEMDS lctl --device %$OSC activate
8658         done
8659
8660         for INACTIVE_OSC in $MDS_OSCS; do
8661                 local ost=$(osc_to_ost $INACTIVE_OSC)
8662                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8663                                lov.*md*.target_obd |
8664                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8665
8666                 mkdir -p $DIR/$tdir
8667                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8668                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8669
8670                 echo "Deactivate: " $INACTIVE_OSC
8671                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8672
8673                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8674                               osp.$ost*MDT0000.create_count")
8675                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8676                                   osp.$ost*MDT0000.max_create_count")
8677                 $disable_precreate &&
8678                         do_facet $SINGLEMDS "lctl set_param -n \
8679                                 osp.$ost*MDT0000.max_create_count=0"
8680
8681                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8682                         [ -f $DIR/$tdir/$idx ] && continue
8683                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8684                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8685                                 { cleanup_65k;
8686                                   error "setstripe $idx should succeed"; }
8687                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8688                 done
8689                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8690                 rmdir $DIR/$tdir
8691
8692                 do_facet $SINGLEMDS "lctl set_param -n \
8693                         osp.$ost*MDT0000.max_create_count=$max_count"
8694                 do_facet $SINGLEMDS "lctl set_param -n \
8695                         osp.$ost*MDT0000.create_count=$count"
8696                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8697                 echo $INACTIVE_OSC "is Activate"
8698
8699                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8700         done
8701 }
8702 run_test 65k "validate manual striping works properly with deactivated OSCs"
8703
8704 test_65l() { # bug 12836
8705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8706
8707         test_mkdir -p $DIR/$tdir/test_dir
8708         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8709         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8710 }
8711 run_test 65l "lfs find on -1 stripe dir ========================"
8712
8713 test_65m() {
8714         local layout=$(save_layout $MOUNT)
8715         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8716                 restore_layout $MOUNT $layout
8717                 error "setstripe should fail by non-root users"
8718         }
8719         true
8720 }
8721 run_test 65m "normal user can't set filesystem default stripe"
8722
8723 test_65n() {
8724         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8725         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8726                 skip "Need MDS version at least 2.12.50"
8727         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8728
8729         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8730         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8731         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8732
8733         local root_layout=$(save_layout $MOUNT)
8734         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8735
8736         # new subdirectory under root directory should not inherit
8737         # the default layout from root
8738         local dir1=$MOUNT/$tdir-1
8739         mkdir $dir1 || error "mkdir $dir1 failed"
8740         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8741                 error "$dir1 shouldn't have LOV EA"
8742
8743         # delete the default layout on root directory
8744         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8745
8746         local dir2=$MOUNT/$tdir-2
8747         mkdir $dir2 || error "mkdir $dir2 failed"
8748         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8749                 error "$dir2 shouldn't have LOV EA"
8750
8751         # set a new striping pattern on root directory
8752         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8753         local new_def_stripe_size=$((def_stripe_size * 2))
8754         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8755                 error "set stripe size on $MOUNT failed"
8756
8757         # new file created in $dir2 should inherit the new stripe size from
8758         # the filesystem default
8759         local file2=$dir2/$tfile-2
8760         touch $file2 || error "touch $file2 failed"
8761
8762         local file2_stripe_size=$($LFS getstripe -S $file2)
8763         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8764         {
8765                 echo "file2_stripe_size: '$file2_stripe_size'"
8766                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8767                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8768         }
8769
8770         local dir3=$MOUNT/$tdir-3
8771         mkdir $dir3 || error "mkdir $dir3 failed"
8772         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8773         # the root layout, which is the actual default layout that will be used
8774         # when new files are created in $dir3.
8775         local dir3_layout=$(get_layout_param $dir3)
8776         local root_dir_layout=$(get_layout_param $MOUNT)
8777         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8778         {
8779                 echo "dir3_layout: '$dir3_layout'"
8780                 echo "root_dir_layout: '$root_dir_layout'"
8781                 error "$dir3 should show the default layout from $MOUNT"
8782         }
8783
8784         # set OST pool on root directory
8785         local pool=$TESTNAME
8786         pool_add $pool || error "add $pool failed"
8787         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8788                 error "add targets to $pool failed"
8789
8790         $LFS setstripe -p $pool $MOUNT ||
8791                 error "set OST pool on $MOUNT failed"
8792
8793         # new file created in $dir3 should inherit the pool from
8794         # the filesystem default
8795         local file3=$dir3/$tfile-3
8796         touch $file3 || error "touch $file3 failed"
8797
8798         local file3_pool=$($LFS getstripe -p $file3)
8799         [[ "$file3_pool" = "$pool" ]] ||
8800                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8801
8802         local dir4=$MOUNT/$tdir-4
8803         mkdir $dir4 || error "mkdir $dir4 failed"
8804         local dir4_layout=$(get_layout_param $dir4)
8805         root_dir_layout=$(get_layout_param $MOUNT)
8806         echo "$LFS getstripe -d $dir4"
8807         $LFS getstripe -d $dir4
8808         echo "$LFS getstripe -d $MOUNT"
8809         $LFS getstripe -d $MOUNT
8810         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8811         {
8812                 echo "dir4_layout: '$dir4_layout'"
8813                 echo "root_dir_layout: '$root_dir_layout'"
8814                 error "$dir4 should show the default layout from $MOUNT"
8815         }
8816
8817         # new file created in $dir4 should inherit the pool from
8818         # the filesystem default
8819         local file4=$dir4/$tfile-4
8820         touch $file4 || error "touch $file4 failed"
8821
8822         local file4_pool=$($LFS getstripe -p $file4)
8823         [[ "$file4_pool" = "$pool" ]] ||
8824                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8825
8826         # new subdirectory under non-root directory should inherit
8827         # the default layout from its parent directory
8828         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8829                 error "set directory layout on $dir4 failed"
8830
8831         local dir5=$dir4/$tdir-5
8832         mkdir $dir5 || error "mkdir $dir5 failed"
8833
8834         dir4_layout=$(get_layout_param $dir4)
8835         local dir5_layout=$(get_layout_param $dir5)
8836         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8837         {
8838                 echo "dir4_layout: '$dir4_layout'"
8839                 echo "dir5_layout: '$dir5_layout'"
8840                 error "$dir5 should inherit the default layout from $dir4"
8841         }
8842
8843         # though subdir under ROOT doesn't inherit default layout, but
8844         # its sub dir/file should be created with default layout.
8845         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8846         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8847                 skip "Need MDS version at least 2.12.59"
8848
8849         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8850         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8851         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8852
8853         if [ $default_lmv_hash == "none" ]; then
8854                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8855         else
8856                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8857                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8858         fi
8859
8860         $LFS setdirstripe -D -c 2 $MOUNT ||
8861                 error "setdirstripe -D -c 2 failed"
8862         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8863         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8864         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8865 }
8866 run_test 65n "don't inherit default layout from root for new subdirectories"
8867
8868 # bug 2543 - update blocks count on client
8869 test_66() {
8870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8871
8872         COUNT=${COUNT:-8}
8873         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8874         sync; sync_all_data; sync; sync_all_data
8875         cancel_lru_locks osc
8876         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8877         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8878 }
8879 run_test 66 "update inode blocks count on client ==============="
8880
8881 meminfo() {
8882         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8883 }
8884
8885 swap_used() {
8886         swapon -s | awk '($1 == "'$1'") { print $4 }'
8887 }
8888
8889 # bug5265, obdfilter oa2dentry return -ENOENT
8890 # #define OBD_FAIL_SRV_ENOENT 0x217
8891 test_69() {
8892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8893         remote_ost_nodsh && skip "remote OST with nodsh"
8894
8895         f="$DIR/$tfile"
8896         $LFS setstripe -c 1 -i 0 $f
8897
8898         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8899
8900         do_facet ost1 lctl set_param fail_loc=0x217
8901         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8902         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8903
8904         do_facet ost1 lctl set_param fail_loc=0
8905         $DIRECTIO write $f 0 2 || error "write error"
8906
8907         cancel_lru_locks osc
8908         $DIRECTIO read $f 0 1 || error "read error"
8909
8910         do_facet ost1 lctl set_param fail_loc=0x217
8911         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8912
8913         do_facet ost1 lctl set_param fail_loc=0
8914         rm -f $f
8915 }
8916 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8917
8918 test_71() {
8919         test_mkdir $DIR/$tdir
8920         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8921         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8922 }
8923 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8924
8925 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8927         [ "$RUNAS_ID" = "$UID" ] &&
8928                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8929         # Check that testing environment is properly set up. Skip if not
8930         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8931                 skip_env "User $RUNAS_ID does not exist - skipping"
8932
8933         touch $DIR/$tfile
8934         chmod 777 $DIR/$tfile
8935         chmod ug+s $DIR/$tfile
8936         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8937                 error "$RUNAS dd $DIR/$tfile failed"
8938         # See if we are still setuid/sgid
8939         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8940                 error "S/gid is not dropped on write"
8941         # Now test that MDS is updated too
8942         cancel_lru_locks mdc
8943         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8944                 error "S/gid is not dropped on MDS"
8945         rm -f $DIR/$tfile
8946 }
8947 run_test 72a "Test that remove suid works properly (bug5695) ===="
8948
8949 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8950         local perm
8951
8952         [ "$RUNAS_ID" = "$UID" ] &&
8953                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8954         [ "$RUNAS_ID" -eq 0 ] &&
8955                 skip_env "RUNAS_ID = 0 -- skipping"
8956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8957         # Check that testing environment is properly set up. Skip if not
8958         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8959                 skip_env "User $RUNAS_ID does not exist - skipping"
8960
8961         touch $DIR/${tfile}-f{g,u}
8962         test_mkdir $DIR/${tfile}-dg
8963         test_mkdir $DIR/${tfile}-du
8964         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8965         chmod g+s $DIR/${tfile}-{f,d}g
8966         chmod u+s $DIR/${tfile}-{f,d}u
8967         for perm in 777 2777 4777; do
8968                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8969                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8970                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8971                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8972         done
8973         true
8974 }
8975 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8976
8977 # bug 3462 - multiple simultaneous MDC requests
8978 test_73() {
8979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8980
8981         test_mkdir $DIR/d73-1
8982         test_mkdir $DIR/d73-2
8983         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8984         pid1=$!
8985
8986         lctl set_param fail_loc=0x80000129
8987         $MULTIOP $DIR/d73-1/f73-2 Oc &
8988         sleep 1
8989         lctl set_param fail_loc=0
8990
8991         $MULTIOP $DIR/d73-2/f73-3 Oc &
8992         pid3=$!
8993
8994         kill -USR1 $pid1
8995         wait $pid1 || return 1
8996
8997         sleep 25
8998
8999         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9000         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9001         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9002
9003         rm -rf $DIR/d73-*
9004 }
9005 run_test 73 "multiple MDC requests (should not deadlock)"
9006
9007 test_74a() { # bug 6149, 6184
9008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9009
9010         touch $DIR/f74a
9011         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9012         #
9013         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9014         # will spin in a tight reconnection loop
9015         $LCTL set_param fail_loc=0x8000030e
9016         # get any lock that won't be difficult - lookup works.
9017         ls $DIR/f74a
9018         $LCTL set_param fail_loc=0
9019         rm -f $DIR/f74a
9020         true
9021 }
9022 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9023
9024 test_74b() { # bug 13310
9025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9026
9027         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9028         #
9029         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9030         # will spin in a tight reconnection loop
9031         $LCTL set_param fail_loc=0x8000030e
9032         # get a "difficult" lock
9033         touch $DIR/f74b
9034         $LCTL set_param fail_loc=0
9035         rm -f $DIR/f74b
9036         true
9037 }
9038 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9039
9040 test_74c() {
9041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9042
9043         #define OBD_FAIL_LDLM_NEW_LOCK
9044         $LCTL set_param fail_loc=0x319
9045         touch $DIR/$tfile && error "touch successful"
9046         $LCTL set_param fail_loc=0
9047         true
9048 }
9049 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9050
9051 slab_lic=/sys/kernel/slab/lustre_inode_cache
9052 num_objects() {
9053         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9054         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9055                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9056 }
9057
9058 test_76a() { # Now for b=20433, added originally in b=1443
9059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9060
9061         cancel_lru_locks osc
9062         # there may be some slab objects cached per core
9063         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9064         local before=$(num_objects)
9065         local count=$((512 * cpus))
9066         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9067         local margin=$((count / 10))
9068         if [[ -f $slab_lic/aliases ]]; then
9069                 local aliases=$(cat $slab_lic/aliases)
9070                 (( aliases > 0 )) && margin=$((margin * aliases))
9071         fi
9072
9073         echo "before slab objects: $before"
9074         for i in $(seq $count); do
9075                 touch $DIR/$tfile
9076                 rm -f $DIR/$tfile
9077         done
9078         cancel_lru_locks osc
9079         local after=$(num_objects)
9080         echo "created: $count, after slab objects: $after"
9081         # shared slab counts are not very accurate, allow significant margin
9082         # the main goal is that the cache growth is not permanently > $count
9083         while (( after > before + margin )); do
9084                 sleep 1
9085                 after=$(num_objects)
9086                 wait=$((wait + 1))
9087                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9088                 if (( wait > 60 )); then
9089                         error "inode slab grew from $before+$margin to $after"
9090                 fi
9091         done
9092 }
9093 run_test 76a "confirm clients recycle inodes properly ===="
9094
9095 test_76b() {
9096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9097         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9098
9099         local count=512
9100         local before=$(num_objects)
9101
9102         for i in $(seq $count); do
9103                 mkdir $DIR/$tdir
9104                 rmdir $DIR/$tdir
9105         done
9106
9107         local after=$(num_objects)
9108         local wait=0
9109
9110         while (( after > before )); do
9111                 sleep 1
9112                 after=$(num_objects)
9113                 wait=$((wait + 1))
9114                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9115                 if (( wait > 60 )); then
9116                         error "inode slab grew from $before to $after"
9117                 fi
9118         done
9119
9120         echo "slab objects before: $before, after: $after"
9121 }
9122 run_test 76b "confirm clients recycle directory inodes properly ===="
9123
9124 export ORIG_CSUM=""
9125 set_checksums()
9126 {
9127         # Note: in sptlrpc modes which enable its own bulk checksum, the
9128         # original crc32_le bulk checksum will be automatically disabled,
9129         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9130         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9131         # In this case set_checksums() will not be no-op, because sptlrpc
9132         # bulk checksum will be enabled all through the test.
9133
9134         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9135         lctl set_param -n osc.*.checksums $1
9136         return 0
9137 }
9138
9139 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9140                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9141 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9142                              tr -d [] | head -n1)}
9143 set_checksum_type()
9144 {
9145         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9146         rc=$?
9147         log "set checksum type to $1, rc = $rc"
9148         return $rc
9149 }
9150
9151 get_osc_checksum_type()
9152 {
9153         # arugment 1: OST name, like OST0000
9154         ost=$1
9155         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9156                         sed 's/.*\[\(.*\)\].*/\1/g')
9157         rc=$?
9158         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9159         echo $checksum_type
9160 }
9161
9162 F77_TMP=$TMP/f77-temp
9163 F77SZ=8
9164 setup_f77() {
9165         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9166                 error "error writing to $F77_TMP"
9167 }
9168
9169 test_77a() { # bug 10889
9170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9171         $GSS && skip_env "could not run with gss"
9172
9173         [ ! -f $F77_TMP ] && setup_f77
9174         set_checksums 1
9175         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9176         set_checksums 0
9177         rm -f $DIR/$tfile
9178 }
9179 run_test 77a "normal checksum read/write operation"
9180
9181 test_77b() { # bug 10889
9182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9183         $GSS && skip_env "could not run with gss"
9184
9185         [ ! -f $F77_TMP ] && setup_f77
9186         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9187         $LCTL set_param fail_loc=0x80000409
9188         set_checksums 1
9189
9190         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9191                 error "dd error: $?"
9192         $LCTL set_param fail_loc=0
9193
9194         for algo in $CKSUM_TYPES; do
9195                 cancel_lru_locks osc
9196                 set_checksum_type $algo
9197                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9198                 $LCTL set_param fail_loc=0x80000408
9199                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9200                 $LCTL set_param fail_loc=0
9201         done
9202         set_checksums 0
9203         set_checksum_type $ORIG_CSUM_TYPE
9204         rm -f $DIR/$tfile
9205 }
9206 run_test 77b "checksum error on client write, read"
9207
9208 cleanup_77c() {
9209         trap 0
9210         set_checksums 0
9211         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9212         $check_ost &&
9213                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9214         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9215         $check_ost && [ -n "$ost_file_prefix" ] &&
9216                 do_facet ost1 rm -f ${ost_file_prefix}\*
9217 }
9218
9219 test_77c() {
9220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9221         $GSS && skip_env "could not run with gss"
9222         remote_ost_nodsh && skip "remote OST with nodsh"
9223
9224         local bad1
9225         local osc_file_prefix
9226         local osc_file
9227         local check_ost=false
9228         local ost_file_prefix
9229         local ost_file
9230         local orig_cksum
9231         local dump_cksum
9232         local fid
9233
9234         # ensure corruption will occur on first OSS/OST
9235         $LFS setstripe -i 0 $DIR/$tfile
9236
9237         [ ! -f $F77_TMP ] && setup_f77
9238         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9239                 error "dd write error: $?"
9240         fid=$($LFS path2fid $DIR/$tfile)
9241
9242         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9243         then
9244                 check_ost=true
9245                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9246                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9247         else
9248                 echo "OSS do not support bulk pages dump upon error"
9249         fi
9250
9251         osc_file_prefix=$($LCTL get_param -n debug_path)
9252         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9253
9254         trap cleanup_77c EXIT
9255
9256         set_checksums 1
9257         # enable bulk pages dump upon error on Client
9258         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9259         # enable bulk pages dump upon error on OSS
9260         $check_ost &&
9261                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9262
9263         # flush Client cache to allow next read to reach OSS
9264         cancel_lru_locks osc
9265
9266         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9267         $LCTL set_param fail_loc=0x80000408
9268         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9269         $LCTL set_param fail_loc=0
9270
9271         rm -f $DIR/$tfile
9272
9273         # check cksum dump on Client
9274         osc_file=$(ls ${osc_file_prefix}*)
9275         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9276         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9277         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9278         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9279         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9280                      cksum)
9281         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9282         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9283                 error "dump content does not match on Client"
9284
9285         $check_ost || skip "No need to check cksum dump on OSS"
9286
9287         # check cksum dump on OSS
9288         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9289         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9290         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9291         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9292         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9293                 error "dump content does not match on OSS"
9294
9295         cleanup_77c
9296 }
9297 run_test 77c "checksum error on client read with debug"
9298
9299 test_77d() { # bug 10889
9300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9301         $GSS && skip_env "could not run with gss"
9302
9303         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9304         $LCTL set_param fail_loc=0x80000409
9305         set_checksums 1
9306         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9307                 error "direct write: rc=$?"
9308         $LCTL set_param fail_loc=0
9309         set_checksums 0
9310
9311         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9312         $LCTL set_param fail_loc=0x80000408
9313         set_checksums 1
9314         cancel_lru_locks osc
9315         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9316                 error "direct read: rc=$?"
9317         $LCTL set_param fail_loc=0
9318         set_checksums 0
9319 }
9320 run_test 77d "checksum error on OST direct write, read"
9321
9322 test_77f() { # bug 10889
9323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9324         $GSS && skip_env "could not run with gss"
9325
9326         set_checksums 1
9327         for algo in $CKSUM_TYPES; do
9328                 cancel_lru_locks osc
9329                 set_checksum_type $algo
9330                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9331                 $LCTL set_param fail_loc=0x409
9332                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9333                         error "direct write succeeded"
9334                 $LCTL set_param fail_loc=0
9335         done
9336         set_checksum_type $ORIG_CSUM_TYPE
9337         set_checksums 0
9338 }
9339 run_test 77f "repeat checksum error on write (expect error)"
9340
9341 test_77g() { # bug 10889
9342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9343         $GSS && skip_env "could not run with gss"
9344         remote_ost_nodsh && skip "remote OST with nodsh"
9345
9346         [ ! -f $F77_TMP ] && setup_f77
9347
9348         local file=$DIR/$tfile
9349         stack_trap "rm -f $file" EXIT
9350
9351         $LFS setstripe -c 1 -i 0 $file
9352         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9353         do_facet ost1 lctl set_param fail_loc=0x8000021a
9354         set_checksums 1
9355         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9356                 error "write error: rc=$?"
9357         do_facet ost1 lctl set_param fail_loc=0
9358         set_checksums 0
9359
9360         cancel_lru_locks osc
9361         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9362         do_facet ost1 lctl set_param fail_loc=0x8000021b
9363         set_checksums 1
9364         cmp $F77_TMP $file || error "file compare failed"
9365         do_facet ost1 lctl set_param fail_loc=0
9366         set_checksums 0
9367 }
9368 run_test 77g "checksum error on OST write, read"
9369
9370 test_77k() { # LU-10906
9371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9372         $GSS && skip_env "could not run with gss"
9373
9374         local cksum_param="osc.$FSNAME*.checksums"
9375         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9376         local checksum
9377         local i
9378
9379         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9380         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9381         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9382
9383         for i in 0 1; do
9384                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9385                         error "failed to set checksum=$i on MGS"
9386                 wait_update $HOSTNAME "$get_checksum" $i
9387                 #remount
9388                 echo "remount client, checksum should be $i"
9389                 remount_client $MOUNT || error "failed to remount client"
9390                 checksum=$(eval $get_checksum)
9391                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9392         done
9393         # remove persistent param to avoid races with checksum mountopt below
9394         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9395                 error "failed to delete checksum on MGS"
9396
9397         for opt in "checksum" "nochecksum"; do
9398                 #remount with mount option
9399                 echo "remount client with option $opt, checksum should be $i"
9400                 umount_client $MOUNT || error "failed to umount client"
9401                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9402                         error "failed to mount client with option '$opt'"
9403                 checksum=$(eval $get_checksum)
9404                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9405                 i=$((i - 1))
9406         done
9407
9408         remount_client $MOUNT || error "failed to remount client"
9409 }
9410 run_test 77k "enable/disable checksum correctly"
9411
9412 test_77l() {
9413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9414         $GSS && skip_env "could not run with gss"
9415
9416         set_checksums 1
9417         stack_trap "set_checksums $ORIG_CSUM" EXIT
9418         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9419
9420         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9421
9422         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9423         for algo in $CKSUM_TYPES; do
9424                 set_checksum_type $algo || error "fail to set checksum type $algo"
9425                 osc_algo=$(get_osc_checksum_type OST0000)
9426                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9427
9428                 # no locks, no reqs to let the connection idle
9429                 cancel_lru_locks osc
9430                 lru_resize_disable osc
9431                 wait_osc_import_state client ost1 IDLE
9432
9433                 # ensure ost1 is connected
9434                 stat $DIR/$tfile >/dev/null || error "can't stat"
9435                 wait_osc_import_state client ost1 FULL
9436
9437                 osc_algo=$(get_osc_checksum_type OST0000)
9438                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9439         done
9440         return 0
9441 }
9442 run_test 77l "preferred checksum type is remembered after reconnected"
9443
9444 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9445 rm -f $F77_TMP
9446 unset F77_TMP
9447
9448 cleanup_test_78() {
9449         trap 0
9450         rm -f $DIR/$tfile
9451 }
9452
9453 test_78() { # bug 10901
9454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9455         remote_ost || skip_env "local OST"
9456
9457         NSEQ=5
9458         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9459         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9460         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9461         echo "MemTotal: $MEMTOTAL"
9462
9463         # reserve 256MB of memory for the kernel and other running processes,
9464         # and then take 1/2 of the remaining memory for the read/write buffers.
9465         if [ $MEMTOTAL -gt 512 ] ;then
9466                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9467         else
9468                 # for those poor memory-starved high-end clusters...
9469                 MEMTOTAL=$((MEMTOTAL / 2))
9470         fi
9471         echo "Mem to use for directio: $MEMTOTAL"
9472
9473         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9474         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9475         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9476         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9477                 head -n1)
9478         echo "Smallest OST: $SMALLESTOST"
9479         [[ $SMALLESTOST -lt 10240 ]] &&
9480                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9481
9482         trap cleanup_test_78 EXIT
9483
9484         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9485                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9486
9487         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9488         echo "File size: $F78SIZE"
9489         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9490         for i in $(seq 1 $NSEQ); do
9491                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9492                 echo directIO rdwr round $i of $NSEQ
9493                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9494         done
9495
9496         cleanup_test_78
9497 }
9498 run_test 78 "handle large O_DIRECT writes correctly ============"
9499
9500 test_79() { # bug 12743
9501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9502
9503         wait_delete_completed
9504
9505         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9506         BKFREE=$(calc_osc_kbytes kbytesfree)
9507         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9508
9509         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9510         DFTOTAL=`echo $STRING | cut -d, -f1`
9511         DFUSED=`echo $STRING  | cut -d, -f2`
9512         DFAVAIL=`echo $STRING | cut -d, -f3`
9513         DFFREE=$(($DFTOTAL - $DFUSED))
9514
9515         ALLOWANCE=$((64 * $OSTCOUNT))
9516
9517         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9518            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9519                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9520         fi
9521         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9522            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9523                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9524         fi
9525         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9526            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9527                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9528         fi
9529 }
9530 run_test 79 "df report consistency check ======================="
9531
9532 test_80() { # bug 10718
9533         remote_ost_nodsh && skip "remote OST with nodsh"
9534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9535
9536         # relax strong synchronous semantics for slow backends like ZFS
9537         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9538                 local soc="obdfilter.*.sync_lock_cancel"
9539                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9540
9541                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9542                 if [ -z "$save" ]; then
9543                         soc="obdfilter.*.sync_on_lock_cancel"
9544                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9545                 fi
9546
9547                 if [ "$save" != "never" ]; then
9548                         local hosts=$(comma_list $(osts_nodes))
9549
9550                         do_nodes $hosts $LCTL set_param $soc=never
9551                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9552                 fi
9553         fi
9554
9555         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9556         sync; sleep 1; sync
9557         local before=$(date +%s)
9558         cancel_lru_locks osc
9559         local after=$(date +%s)
9560         local diff=$((after - before))
9561         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9562
9563         rm -f $DIR/$tfile
9564 }
9565 run_test 80 "Page eviction is equally fast at high offsets too"
9566
9567 test_81a() { # LU-456
9568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9569         remote_ost_nodsh && skip "remote OST with nodsh"
9570
9571         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9572         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9573         do_facet ost1 lctl set_param fail_loc=0x80000228
9574
9575         # write should trigger a retry and success
9576         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9577         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9578         RC=$?
9579         if [ $RC -ne 0 ] ; then
9580                 error "write should success, but failed for $RC"
9581         fi
9582 }
9583 run_test 81a "OST should retry write when get -ENOSPC ==============="
9584
9585 test_81b() { # LU-456
9586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9587         remote_ost_nodsh && skip "remote OST with nodsh"
9588
9589         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9590         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9591         do_facet ost1 lctl set_param fail_loc=0x228
9592
9593         # write should retry several times and return -ENOSPC finally
9594         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9595         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9596         RC=$?
9597         ENOSPC=28
9598         if [ $RC -ne $ENOSPC ] ; then
9599                 error "dd should fail for -ENOSPC, but succeed."
9600         fi
9601 }
9602 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9603
9604 test_99() {
9605         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9606
9607         test_mkdir $DIR/$tdir.cvsroot
9608         chown $RUNAS_ID $DIR/$tdir.cvsroot
9609
9610         cd $TMP
9611         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9612
9613         cd /etc/init.d
9614         # some versions of cvs import exit(1) when asked to import links or
9615         # files they can't read.  ignore those files.
9616         local toignore=$(find . -type l -printf '-I %f\n' -o \
9617                          ! -perm /4 -printf '-I %f\n')
9618         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9619                 $tdir.reposname vtag rtag
9620
9621         cd $DIR
9622         test_mkdir $DIR/$tdir.reposname
9623         chown $RUNAS_ID $DIR/$tdir.reposname
9624         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9625
9626         cd $DIR/$tdir.reposname
9627         $RUNAS touch foo99
9628         $RUNAS cvs add -m 'addmsg' foo99
9629         $RUNAS cvs update
9630         $RUNAS cvs commit -m 'nomsg' foo99
9631         rm -fr $DIR/$tdir.cvsroot
9632 }
9633 run_test 99 "cvs strange file/directory operations"
9634
9635 test_100() {
9636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9637         [[ "$NETTYPE" =~ tcp ]] ||
9638                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9639         remote_ost_nodsh && skip "remote OST with nodsh"
9640         remote_mds_nodsh && skip "remote MDS with nodsh"
9641         remote_servers ||
9642                 skip "useless for local single node setup"
9643
9644         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9645                 [ "$PROT" != "tcp" ] && continue
9646                 RPORT=$(echo $REMOTE | cut -d: -f2)
9647                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9648
9649                 rc=0
9650                 LPORT=`echo $LOCAL | cut -d: -f2`
9651                 if [ $LPORT -ge 1024 ]; then
9652                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9653                         netstat -tna
9654                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9655                 fi
9656         done
9657         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9658 }
9659 run_test 100 "check local port using privileged port ==========="
9660
9661 function get_named_value()
9662 {
9663     local tag=$1
9664
9665     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9666 }
9667
9668 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9669                    awk '/^max_cached_mb/ { print $2 }')
9670
9671 cleanup_101a() {
9672         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9673         trap 0
9674 }
9675
9676 test_101a() {
9677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9678
9679         local s
9680         local discard
9681         local nreads=10000
9682         local cache_limit=32
9683
9684         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9685         trap cleanup_101a EXIT
9686         $LCTL set_param -n llite.*.read_ahead_stats=0
9687         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9688
9689         #
9690         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9691         #
9692         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9693         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9694
9695         discard=0
9696         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9697                    get_named_value 'read.but.discarded'); do
9698                         discard=$(($discard + $s))
9699         done
9700         cleanup_101a
9701
9702         $LCTL get_param osc.*-osc*.rpc_stats
9703         $LCTL get_param llite.*.read_ahead_stats
9704
9705         # Discard is generally zero, but sometimes a few random reads line up
9706         # and trigger larger readahead, which is wasted & leads to discards.
9707         if [[ $(($discard)) -gt $nreads ]]; then
9708                 error "too many ($discard) discarded pages"
9709         fi
9710         rm -f $DIR/$tfile || true
9711 }
9712 run_test 101a "check read-ahead for random reads"
9713
9714 setup_test101bc() {
9715         test_mkdir $DIR/$tdir
9716         local ssize=$1
9717         local FILE_LENGTH=$2
9718         STRIPE_OFFSET=0
9719
9720         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9721
9722         local list=$(comma_list $(osts_nodes))
9723         set_osd_param $list '' read_cache_enable 0
9724         set_osd_param $list '' writethrough_cache_enable 0
9725
9726         trap cleanup_test101bc EXIT
9727         # prepare the read-ahead file
9728         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9729
9730         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9731                                 count=$FILE_SIZE_MB 2> /dev/null
9732
9733 }
9734
9735 cleanup_test101bc() {
9736         trap 0
9737         rm -rf $DIR/$tdir
9738         rm -f $DIR/$tfile
9739
9740         local list=$(comma_list $(osts_nodes))
9741         set_osd_param $list '' read_cache_enable 1
9742         set_osd_param $list '' writethrough_cache_enable 1
9743 }
9744
9745 calc_total() {
9746         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9747 }
9748
9749 ra_check_101() {
9750         local READ_SIZE=$1
9751         local STRIPE_SIZE=$2
9752         local FILE_LENGTH=$3
9753         local RA_INC=1048576
9754         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9755         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9756                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9757         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9758                   get_named_value 'read.but.discarded' | calc_total)
9759         if [[ $DISCARD -gt $discard_limit ]]; then
9760                 $LCTL get_param llite.*.read_ahead_stats
9761                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9762         else
9763                 echo "Read-ahead success for size ${READ_SIZE}"
9764         fi
9765 }
9766
9767 test_101b() {
9768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9769         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9770
9771         local STRIPE_SIZE=1048576
9772         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9773
9774         if [ $SLOW == "yes" ]; then
9775                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9776         else
9777                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9778         fi
9779
9780         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9781
9782         # prepare the read-ahead file
9783         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9784         cancel_lru_locks osc
9785         for BIDX in 2 4 8 16 32 64 128 256
9786         do
9787                 local BSIZE=$((BIDX*4096))
9788                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9789                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9790                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9791                 $LCTL set_param -n llite.*.read_ahead_stats=0
9792                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9793                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9794                 cancel_lru_locks osc
9795                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9796         done
9797         cleanup_test101bc
9798         true
9799 }
9800 run_test 101b "check stride-io mode read-ahead ================="
9801
9802 test_101c() {
9803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9804
9805         local STRIPE_SIZE=1048576
9806         local FILE_LENGTH=$((STRIPE_SIZE*100))
9807         local nreads=10000
9808         local rsize=65536
9809         local osc_rpc_stats
9810
9811         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9812
9813         cancel_lru_locks osc
9814         $LCTL set_param osc.*.rpc_stats=0
9815         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9816         $LCTL get_param osc.*.rpc_stats
9817         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9818                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9819                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9820                 local size
9821
9822                 if [ $lines -le 20 ]; then
9823                         echo "continue debug"
9824                         continue
9825                 fi
9826                 for size in 1 2 4 8; do
9827                         local rpc=$(echo "$stats" |
9828                                     awk '($1 == "'$size':") {print $2; exit; }')
9829                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9830                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9831                 done
9832                 echo "$osc_rpc_stats check passed!"
9833         done
9834         cleanup_test101bc
9835         true
9836 }
9837 run_test 101c "check stripe_size aligned read-ahead"
9838
9839 test_101d() {
9840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9841
9842         local file=$DIR/$tfile
9843         local sz_MB=${FILESIZE_101d:-80}
9844         local ra_MB=${READAHEAD_MB:-40}
9845
9846         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9847         [ $free_MB -lt $sz_MB ] &&
9848                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9849
9850         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9851         $LFS setstripe -c -1 $file || error "setstripe failed"
9852
9853         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9854         echo Cancel LRU locks on lustre client to flush the client cache
9855         cancel_lru_locks osc
9856
9857         echo Disable read-ahead
9858         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9859         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9860         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
9861         $LCTL get_param -n llite.*.max_read_ahead_mb
9862
9863         echo "Reading the test file $file with read-ahead disabled"
9864         local sz_KB=$((sz_MB * 1024 / 4))
9865         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9866         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9867         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9868                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9869
9870         echo "Cancel LRU locks on lustre client to flush the client cache"
9871         cancel_lru_locks osc
9872         echo Enable read-ahead with ${ra_MB}MB
9873         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9874
9875         echo "Reading the test file $file with read-ahead enabled"
9876         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9877                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9878
9879         echo "read-ahead disabled time read $raOFF"
9880         echo "read-ahead enabled time read $raON"
9881
9882         rm -f $file
9883         wait_delete_completed
9884
9885         # use awk for this check instead of bash because it handles decimals
9886         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9887                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9888 }
9889 run_test 101d "file read with and without read-ahead enabled"
9890
9891 test_101e() {
9892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9893
9894         local file=$DIR/$tfile
9895         local size_KB=500  #KB
9896         local count=100
9897         local bsize=1024
9898
9899         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9900         local need_KB=$((count * size_KB))
9901         [[ $free_KB -le $need_KB ]] &&
9902                 skip_env "Need free space $need_KB, have $free_KB"
9903
9904         echo "Creating $count ${size_KB}K test files"
9905         for ((i = 0; i < $count; i++)); do
9906                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9907         done
9908
9909         echo "Cancel LRU locks on lustre client to flush the client cache"
9910         cancel_lru_locks $OSC
9911
9912         echo "Reset readahead stats"
9913         $LCTL set_param -n llite.*.read_ahead_stats=0
9914
9915         for ((i = 0; i < $count; i++)); do
9916                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9917         done
9918
9919         $LCTL get_param llite.*.max_cached_mb
9920         $LCTL get_param llite.*.read_ahead_stats
9921         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9922                      get_named_value 'misses' | calc_total)
9923
9924         for ((i = 0; i < $count; i++)); do
9925                 rm -rf $file.$i 2>/dev/null
9926         done
9927
9928         #10000 means 20% reads are missing in readahead
9929         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9930 }
9931 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9932
9933 test_101f() {
9934         which iozone || skip_env "no iozone installed"
9935
9936         local old_debug=$($LCTL get_param debug)
9937         old_debug=${old_debug#*=}
9938         $LCTL set_param debug="reada mmap"
9939
9940         # create a test file
9941         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9942
9943         echo Cancel LRU locks on lustre client to flush the client cache
9944         cancel_lru_locks osc
9945
9946         echo Reset readahead stats
9947         $LCTL set_param -n llite.*.read_ahead_stats=0
9948
9949         echo mmap read the file with small block size
9950         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9951                 > /dev/null 2>&1
9952
9953         echo checking missing pages
9954         $LCTL get_param llite.*.read_ahead_stats
9955         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9956                         get_named_value 'misses' | calc_total)
9957
9958         $LCTL set_param debug="$old_debug"
9959         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9960         rm -f $DIR/$tfile
9961 }
9962 run_test 101f "check mmap read performance"
9963
9964 test_101g_brw_size_test() {
9965         local mb=$1
9966         local pages=$((mb * 1048576 / PAGE_SIZE))
9967         local file=$DIR/$tfile
9968
9969         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9970                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9971         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9972                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9973                         return 2
9974         done
9975
9976         stack_trap "rm -f $file" EXIT
9977         $LCTL set_param -n osc.*.rpc_stats=0
9978
9979         # 10 RPCs should be enough for the test
9980         local count=10
9981         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9982                 { error "dd write ${mb} MB blocks failed"; return 3; }
9983         cancel_lru_locks osc
9984         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9985                 { error "dd write ${mb} MB blocks failed"; return 4; }
9986
9987         # calculate number of full-sized read and write RPCs
9988         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9989                 sed -n '/pages per rpc/,/^$/p' |
9990                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9991                 END { print reads,writes }'))
9992         # allow one extra full-sized read RPC for async readahead
9993         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9994                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9995         [[ ${rpcs[1]} == $count ]] ||
9996                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9997 }
9998
9999 test_101g() {
10000         remote_ost_nodsh && skip "remote OST with nodsh"
10001
10002         local rpcs
10003         local osts=$(get_facets OST)
10004         local list=$(comma_list $(osts_nodes))
10005         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10006         local brw_size="obdfilter.*.brw_size"
10007
10008         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10009
10010         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10011
10012         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10013                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10014                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10015            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10016                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10017                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10018
10019                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10020                         suffix="M"
10021
10022                 if [[ $orig_mb -lt 16 ]]; then
10023                         save_lustre_params $osts "$brw_size" > $p
10024                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10025                                 error "set 16MB RPC size failed"
10026
10027                         echo "remount client to enable new RPC size"
10028                         remount_client $MOUNT || error "remount_client failed"
10029                 fi
10030
10031                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10032                 # should be able to set brw_size=12, but no rpc_stats for that
10033                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10034         fi
10035
10036         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10037
10038         if [[ $orig_mb -lt 16 ]]; then
10039                 restore_lustre_params < $p
10040                 remount_client $MOUNT || error "remount_client restore failed"
10041         fi
10042
10043         rm -f $p $DIR/$tfile
10044 }
10045 run_test 101g "Big bulk(4/16 MiB) readahead"
10046
10047 test_101h() {
10048         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10049
10050         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10051                 error "dd 70M file failed"
10052         echo Cancel LRU locks on lustre client to flush the client cache
10053         cancel_lru_locks osc
10054
10055         echo "Reset readahead stats"
10056         $LCTL set_param -n llite.*.read_ahead_stats 0
10057
10058         echo "Read 10M of data but cross 64M bundary"
10059         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10060         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10061                      get_named_value 'misses' | calc_total)
10062         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10063         rm -f $p $DIR/$tfile
10064 }
10065 run_test 101h "Readahead should cover current read window"
10066
10067 test_101i() {
10068         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10069                 error "dd 10M file failed"
10070
10071         local max_per_file_mb=$($LCTL get_param -n \
10072                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10073         cancel_lru_locks osc
10074         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10075         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10076                 error "set max_read_ahead_per_file_mb to 1 failed"
10077
10078         echo "Reset readahead stats"
10079         $LCTL set_param llite.*.read_ahead_stats=0
10080
10081         dd if=$DIR/$tfile of=/dev/null bs=2M
10082
10083         $LCTL get_param llite.*.read_ahead_stats
10084         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10085                      awk '/misses/ { print $2 }')
10086         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10087         rm -f $DIR/$tfile
10088 }
10089 run_test 101i "allow current readahead to exceed reservation"
10090
10091 test_101j() {
10092         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10093                 error "setstripe $DIR/$tfile failed"
10094         local file_size=$((1048576 * 16))
10095         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10096         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10097
10098         echo Disable read-ahead
10099         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10100
10101         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10102         for blk in $PAGE_SIZE 1048576 $file_size; do
10103                 cancel_lru_locks osc
10104                 echo "Reset readahead stats"
10105                 $LCTL set_param -n llite.*.read_ahead_stats=0
10106                 local count=$(($file_size / $blk))
10107                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10108                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10109                              get_named_value 'failed.to.fast.read' | calc_total)
10110                 $LCTL get_param -n llite.*.read_ahead_stats
10111                 [ $miss -eq $count ] || error "expected $count got $miss"
10112         done
10113
10114         rm -f $p $DIR/$tfile
10115 }
10116 run_test 101j "A complete read block should be submitted when no RA"
10117
10118 setup_test102() {
10119         test_mkdir $DIR/$tdir
10120         chown $RUNAS_ID $DIR/$tdir
10121         STRIPE_SIZE=65536
10122         STRIPE_OFFSET=1
10123         STRIPE_COUNT=$OSTCOUNT
10124         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10125
10126         trap cleanup_test102 EXIT
10127         cd $DIR
10128         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10129         cd $DIR/$tdir
10130         for num in 1 2 3 4; do
10131                 for count in $(seq 1 $STRIPE_COUNT); do
10132                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10133                                 local size=`expr $STRIPE_SIZE \* $num`
10134                                 local file=file"$num-$idx-$count"
10135                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10136                         done
10137                 done
10138         done
10139
10140         cd $DIR
10141         $1 tar cf $TMP/f102.tar $tdir --xattrs
10142 }
10143
10144 cleanup_test102() {
10145         trap 0
10146         rm -f $TMP/f102.tar
10147         rm -rf $DIR/d0.sanity/d102
10148 }
10149
10150 test_102a() {
10151         [ "$UID" != 0 ] && skip "must run as root"
10152         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10153                 skip_env "must have user_xattr"
10154
10155         [ -z "$(which setfattr 2>/dev/null)" ] &&
10156                 skip_env "could not find setfattr"
10157
10158         local testfile=$DIR/$tfile
10159
10160         touch $testfile
10161         echo "set/get xattr..."
10162         setfattr -n trusted.name1 -v value1 $testfile ||
10163                 error "setfattr -n trusted.name1=value1 $testfile failed"
10164         getfattr -n trusted.name1 $testfile 2> /dev/null |
10165           grep "trusted.name1=.value1" ||
10166                 error "$testfile missing trusted.name1=value1"
10167
10168         setfattr -n user.author1 -v author1 $testfile ||
10169                 error "setfattr -n user.author1=author1 $testfile failed"
10170         getfattr -n user.author1 $testfile 2> /dev/null |
10171           grep "user.author1=.author1" ||
10172                 error "$testfile missing trusted.author1=author1"
10173
10174         echo "listxattr..."
10175         setfattr -n trusted.name2 -v value2 $testfile ||
10176                 error "$testfile unable to set trusted.name2"
10177         setfattr -n trusted.name3 -v value3 $testfile ||
10178                 error "$testfile unable to set trusted.name3"
10179         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10180             grep "trusted.name" | wc -l) -eq 3 ] ||
10181                 error "$testfile missing 3 trusted.name xattrs"
10182
10183         setfattr -n user.author2 -v author2 $testfile ||
10184                 error "$testfile unable to set user.author2"
10185         setfattr -n user.author3 -v author3 $testfile ||
10186                 error "$testfile unable to set user.author3"
10187         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10188             grep "user.author" | wc -l) -eq 3 ] ||
10189                 error "$testfile missing 3 user.author xattrs"
10190
10191         echo "remove xattr..."
10192         setfattr -x trusted.name1 $testfile ||
10193                 error "$testfile error deleting trusted.name1"
10194         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10195                 error "$testfile did not delete trusted.name1 xattr"
10196
10197         setfattr -x user.author1 $testfile ||
10198                 error "$testfile error deleting user.author1"
10199         echo "set lustre special xattr ..."
10200         $LFS setstripe -c1 $testfile
10201         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10202                 awk -F "=" '/trusted.lov/ { print $2 }' )
10203         setfattr -n "trusted.lov" -v $lovea $testfile ||
10204                 error "$testfile doesn't ignore setting trusted.lov again"
10205         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10206                 error "$testfile allow setting invalid trusted.lov"
10207         rm -f $testfile
10208 }
10209 run_test 102a "user xattr test =================================="
10210
10211 check_102b_layout() {
10212         local layout="$*"
10213         local testfile=$DIR/$tfile
10214
10215         echo "test layout '$layout'"
10216         $LFS setstripe $layout $testfile || error "setstripe failed"
10217         $LFS getstripe -y $testfile
10218
10219         echo "get/set/list trusted.lov xattr ..." # b=10930
10220         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10221         [[ "$value" =~ "trusted.lov" ]] ||
10222                 error "can't get trusted.lov from $testfile"
10223         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10224                 error "getstripe failed"
10225
10226         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10227
10228         value=$(cut -d= -f2 <<<$value)
10229         # LU-13168: truncated xattr should fail if short lov_user_md header
10230         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10231                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10232         for len in $lens; do
10233                 echo "setfattr $len $testfile.2"
10234                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10235                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10236         done
10237         local stripe_size=$($LFS getstripe -S $testfile.2)
10238         local stripe_count=$($LFS getstripe -c $testfile.2)
10239         [[ $stripe_size -eq 65536 ]] ||
10240                 error "stripe size $stripe_size != 65536"
10241         [[ $stripe_count -eq $stripe_count_orig ]] ||
10242                 error "stripe count $stripe_count != $stripe_count_orig"
10243         rm $testfile $testfile.2
10244 }
10245
10246 test_102b() {
10247         [ -z "$(which setfattr 2>/dev/null)" ] &&
10248                 skip_env "could not find setfattr"
10249         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10250
10251         # check plain layout
10252         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10253
10254         # and also check composite layout
10255         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10256
10257 }
10258 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10259
10260 test_102c() {
10261         [ -z "$(which setfattr 2>/dev/null)" ] &&
10262                 skip_env "could not find setfattr"
10263         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10264
10265         # b10930: get/set/list lustre.lov xattr
10266         echo "get/set/list lustre.lov xattr ..."
10267         test_mkdir $DIR/$tdir
10268         chown $RUNAS_ID $DIR/$tdir
10269         local testfile=$DIR/$tdir/$tfile
10270         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10271                 error "setstripe failed"
10272         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10273                 error "getstripe failed"
10274         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10275         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10276
10277         local testfile2=${testfile}2
10278         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10279                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10280
10281         $RUNAS $MCREATE $testfile2
10282         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10283         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10284         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10285         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10286         [ $stripe_count -eq $STRIPECOUNT ] ||
10287                 error "stripe count $stripe_count != $STRIPECOUNT"
10288 }
10289 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10290
10291 compare_stripe_info1() {
10292         local stripe_index_all_zero=true
10293
10294         for num in 1 2 3 4; do
10295                 for count in $(seq 1 $STRIPE_COUNT); do
10296                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10297                                 local size=$((STRIPE_SIZE * num))
10298                                 local file=file"$num-$offset-$count"
10299                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10300                                 [[ $stripe_size -ne $size ]] &&
10301                                     error "$file: size $stripe_size != $size"
10302                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10303                                 # allow fewer stripes to be created, ORI-601
10304                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10305                                     error "$file: count $stripe_count != $count"
10306                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10307                                 [[ $stripe_index -ne 0 ]] &&
10308                                         stripe_index_all_zero=false
10309                         done
10310                 done
10311         done
10312         $stripe_index_all_zero &&
10313                 error "all files are being extracted starting from OST index 0"
10314         return 0
10315 }
10316
10317 have_xattrs_include() {
10318         tar --help | grep -q xattrs-include &&
10319                 echo --xattrs-include="lustre.*"
10320 }
10321
10322 test_102d() {
10323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10324         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10325
10326         XINC=$(have_xattrs_include)
10327         setup_test102
10328         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10329         cd $DIR/$tdir/$tdir
10330         compare_stripe_info1
10331 }
10332 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10333
10334 test_102f() {
10335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10336         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10337
10338         XINC=$(have_xattrs_include)
10339         setup_test102
10340         test_mkdir $DIR/$tdir.restore
10341         cd $DIR
10342         tar cf - --xattrs $tdir | tar xf - \
10343                 -C $DIR/$tdir.restore --xattrs $XINC
10344         cd $DIR/$tdir.restore/$tdir
10345         compare_stripe_info1
10346 }
10347 run_test 102f "tar copy files, not keep osts"
10348
10349 grow_xattr() {
10350         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10351                 skip "must have user_xattr"
10352         [ -z "$(which setfattr 2>/dev/null)" ] &&
10353                 skip_env "could not find setfattr"
10354         [ -z "$(which getfattr 2>/dev/null)" ] &&
10355                 skip_env "could not find getfattr"
10356
10357         local xsize=${1:-1024}  # in bytes
10358         local file=$DIR/$tfile
10359         local value="$(generate_string $xsize)"
10360         local xbig=trusted.big
10361         local toobig=$2
10362
10363         touch $file
10364         log "save $xbig on $file"
10365         if [ -z "$toobig" ]
10366         then
10367                 setfattr -n $xbig -v $value $file ||
10368                         error "saving $xbig on $file failed"
10369         else
10370                 setfattr -n $xbig -v $value $file &&
10371                         error "saving $xbig on $file succeeded"
10372                 return 0
10373         fi
10374
10375         local orig=$(get_xattr_value $xbig $file)
10376         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10377
10378         local xsml=trusted.sml
10379         log "save $xsml on $file"
10380         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10381
10382         local new=$(get_xattr_value $xbig $file)
10383         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10384
10385         log "grow $xsml on $file"
10386         setfattr -n $xsml -v "$value" $file ||
10387                 error "growing $xsml on $file failed"
10388
10389         new=$(get_xattr_value $xbig $file)
10390         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10391         log "$xbig still valid after growing $xsml"
10392
10393         rm -f $file
10394 }
10395
10396 test_102h() { # bug 15777
10397         grow_xattr 1024
10398 }
10399 run_test 102h "grow xattr from inside inode to external block"
10400
10401 test_102ha() {
10402         large_xattr_enabled || skip_env "ea_inode feature disabled"
10403
10404         echo "setting xattr of max xattr size: $(max_xattr_size)"
10405         grow_xattr $(max_xattr_size)
10406
10407         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10408         echo "This should fail:"
10409         grow_xattr $(($(max_xattr_size) + 10)) 1
10410 }
10411 run_test 102ha "grow xattr from inside inode to external inode"
10412
10413 test_102i() { # bug 17038
10414         [ -z "$(which getfattr 2>/dev/null)" ] &&
10415                 skip "could not find getfattr"
10416
10417         touch $DIR/$tfile
10418         ln -s $DIR/$tfile $DIR/${tfile}link
10419         getfattr -n trusted.lov $DIR/$tfile ||
10420                 error "lgetxattr on $DIR/$tfile failed"
10421         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10422                 grep -i "no such attr" ||
10423                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10424         rm -f $DIR/$tfile $DIR/${tfile}link
10425 }
10426 run_test 102i "lgetxattr test on symbolic link ============"
10427
10428 test_102j() {
10429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10430         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10431
10432         XINC=$(have_xattrs_include)
10433         setup_test102 "$RUNAS"
10434         chown $RUNAS_ID $DIR/$tdir
10435         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10436         cd $DIR/$tdir/$tdir
10437         compare_stripe_info1 "$RUNAS"
10438 }
10439 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10440
10441 test_102k() {
10442         [ -z "$(which setfattr 2>/dev/null)" ] &&
10443                 skip "could not find setfattr"
10444
10445         touch $DIR/$tfile
10446         # b22187 just check that does not crash for regular file.
10447         setfattr -n trusted.lov $DIR/$tfile
10448         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10449         local test_kdir=$DIR/$tdir
10450         test_mkdir $test_kdir
10451         local default_size=$($LFS getstripe -S $test_kdir)
10452         local default_count=$($LFS getstripe -c $test_kdir)
10453         local default_offset=$($LFS getstripe -i $test_kdir)
10454         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10455                 error 'dir setstripe failed'
10456         setfattr -n trusted.lov $test_kdir
10457         local stripe_size=$($LFS getstripe -S $test_kdir)
10458         local stripe_count=$($LFS getstripe -c $test_kdir)
10459         local stripe_offset=$($LFS getstripe -i $test_kdir)
10460         [ $stripe_size -eq $default_size ] ||
10461                 error "stripe size $stripe_size != $default_size"
10462         [ $stripe_count -eq $default_count ] ||
10463                 error "stripe count $stripe_count != $default_count"
10464         [ $stripe_offset -eq $default_offset ] ||
10465                 error "stripe offset $stripe_offset != $default_offset"
10466         rm -rf $DIR/$tfile $test_kdir
10467 }
10468 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10469
10470 test_102l() {
10471         [ -z "$(which getfattr 2>/dev/null)" ] &&
10472                 skip "could not find getfattr"
10473
10474         # LU-532 trusted. xattr is invisible to non-root
10475         local testfile=$DIR/$tfile
10476
10477         touch $testfile
10478
10479         echo "listxattr as user..."
10480         chown $RUNAS_ID $testfile
10481         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10482             grep -q "trusted" &&
10483                 error "$testfile trusted xattrs are user visible"
10484
10485         return 0;
10486 }
10487 run_test 102l "listxattr size test =================================="
10488
10489 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10490         local path=$DIR/$tfile
10491         touch $path
10492
10493         listxattr_size_check $path || error "listattr_size_check $path failed"
10494 }
10495 run_test 102m "Ensure listxattr fails on small bufffer ========"
10496
10497 cleanup_test102
10498
10499 getxattr() { # getxattr path name
10500         # Return the base64 encoding of the value of xattr name on path.
10501         local path=$1
10502         local name=$2
10503
10504         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10505         # file: $path
10506         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10507         #
10508         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10509
10510         getfattr --absolute-names --encoding=base64 --name=$name $path |
10511                 awk -F= -v name=$name '$1 == name {
10512                         print substr($0, index($0, "=") + 1);
10513         }'
10514 }
10515
10516 test_102n() { # LU-4101 mdt: protect internal xattrs
10517         [ -z "$(which setfattr 2>/dev/null)" ] &&
10518                 skip "could not find setfattr"
10519         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10520         then
10521                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10522         fi
10523
10524         local file0=$DIR/$tfile.0
10525         local file1=$DIR/$tfile.1
10526         local xattr0=$TMP/$tfile.0
10527         local xattr1=$TMP/$tfile.1
10528         local namelist="lov lma lmv link fid version som hsm"
10529         local name
10530         local value
10531
10532         rm -rf $file0 $file1 $xattr0 $xattr1
10533         touch $file0 $file1
10534
10535         # Get 'before' xattrs of $file1.
10536         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10537
10538         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10539                 namelist+=" lfsck_namespace"
10540         for name in $namelist; do
10541                 # Try to copy xattr from $file0 to $file1.
10542                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10543
10544                 setfattr --name=trusted.$name --value="$value" $file1 ||
10545                         error "setxattr 'trusted.$name' failed"
10546
10547                 # Try to set a garbage xattr.
10548                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10549
10550                 if [[ x$name == "xlov" ]]; then
10551                         setfattr --name=trusted.lov --value="$value" $file1 &&
10552                         error "setxattr invalid 'trusted.lov' success"
10553                 else
10554                         setfattr --name=trusted.$name --value="$value" $file1 ||
10555                                 error "setxattr invalid 'trusted.$name' failed"
10556                 fi
10557
10558                 # Try to remove the xattr from $file1. We don't care if this
10559                 # appears to succeed or fail, we just don't want there to be
10560                 # any changes or crashes.
10561                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10562         done
10563
10564         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10565         then
10566                 name="lfsck_ns"
10567                 # Try to copy xattr from $file0 to $file1.
10568                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10569
10570                 setfattr --name=trusted.$name --value="$value" $file1 ||
10571                         error "setxattr 'trusted.$name' failed"
10572
10573                 # Try to set a garbage xattr.
10574                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10575
10576                 setfattr --name=trusted.$name --value="$value" $file1 ||
10577                         error "setxattr 'trusted.$name' failed"
10578
10579                 # Try to remove the xattr from $file1. We don't care if this
10580                 # appears to succeed or fail, we just don't want there to be
10581                 # any changes or crashes.
10582                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10583         fi
10584
10585         # Get 'after' xattrs of file1.
10586         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10587
10588         if ! diff $xattr0 $xattr1; then
10589                 error "before and after xattrs of '$file1' differ"
10590         fi
10591
10592         rm -rf $file0 $file1 $xattr0 $xattr1
10593
10594         return 0
10595 }
10596 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10597
10598 test_102p() { # LU-4703 setxattr did not check ownership
10599         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10600                 skip "MDS needs to be at least 2.5.56"
10601
10602         local testfile=$DIR/$tfile
10603
10604         touch $testfile
10605
10606         echo "setfacl as user..."
10607         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10608         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10609
10610         echo "setfattr as user..."
10611         setfacl -m "u:$RUNAS_ID:---" $testfile
10612         $RUNAS setfattr -x system.posix_acl_access $testfile
10613         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10614 }
10615 run_test 102p "check setxattr(2) correctly fails without permission"
10616
10617 test_102q() {
10618         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10619                 skip "MDS needs to be at least 2.6.92"
10620
10621         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10622 }
10623 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10624
10625 test_102r() {
10626         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10627                 skip "MDS needs to be at least 2.6.93"
10628
10629         touch $DIR/$tfile || error "touch"
10630         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10631         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10632         rm $DIR/$tfile || error "rm"
10633
10634         #normal directory
10635         mkdir -p $DIR/$tdir || error "mkdir"
10636         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10637         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10638         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10639                 error "$testfile error deleting user.author1"
10640         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10641                 grep "user.$(basename $tdir)" &&
10642                 error "$tdir did not delete user.$(basename $tdir)"
10643         rmdir $DIR/$tdir || error "rmdir"
10644
10645         #striped directory
10646         test_mkdir $DIR/$tdir
10647         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10648         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10649         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10650                 error "$testfile error deleting user.author1"
10651         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10652                 grep "user.$(basename $tdir)" &&
10653                 error "$tdir did not delete user.$(basename $tdir)"
10654         rmdir $DIR/$tdir || error "rm striped dir"
10655 }
10656 run_test 102r "set EAs with empty values"
10657
10658 test_102s() {
10659         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10660                 skip "MDS needs to be at least 2.11.52"
10661
10662         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10663
10664         save_lustre_params client "llite.*.xattr_cache" > $save
10665
10666         for cache in 0 1; do
10667                 lctl set_param llite.*.xattr_cache=$cache
10668
10669                 rm -f $DIR/$tfile
10670                 touch $DIR/$tfile || error "touch"
10671                 for prefix in lustre security system trusted user; do
10672                         # Note getxattr() may fail with 'Operation not
10673                         # supported' or 'No such attribute' depending
10674                         # on prefix and cache.
10675                         getfattr -n $prefix.n102s $DIR/$tfile &&
10676                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10677                 done
10678         done
10679
10680         restore_lustre_params < $save
10681 }
10682 run_test 102s "getting nonexistent xattrs should fail"
10683
10684 test_102t() {
10685         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10686                 skip "MDS needs to be at least 2.11.52"
10687
10688         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10689
10690         save_lustre_params client "llite.*.xattr_cache" > $save
10691
10692         for cache in 0 1; do
10693                 lctl set_param llite.*.xattr_cache=$cache
10694
10695                 for buf_size in 0 256; do
10696                         rm -f $DIR/$tfile
10697                         touch $DIR/$tfile || error "touch"
10698                         setfattr -n user.multiop $DIR/$tfile
10699                         $MULTIOP $DIR/$tfile oa$buf_size ||
10700                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10701                 done
10702         done
10703
10704         restore_lustre_params < $save
10705 }
10706 run_test 102t "zero length xattr values handled correctly"
10707
10708 run_acl_subtest()
10709 {
10710     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10711     return $?
10712 }
10713
10714 test_103a() {
10715         [ "$UID" != 0 ] && skip "must run as root"
10716         $GSS && skip_env "could not run under gss"
10717         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10718                 skip_env "must have acl enabled"
10719         [ -z "$(which setfacl 2>/dev/null)" ] &&
10720                 skip_env "could not find setfacl"
10721         remote_mds_nodsh && skip "remote MDS with nodsh"
10722
10723         gpasswd -a daemon bin                           # LU-5641
10724         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10725
10726         declare -a identity_old
10727
10728         for num in $(seq $MDSCOUNT); do
10729                 switch_identity $num true || identity_old[$num]=$?
10730         done
10731
10732         SAVE_UMASK=$(umask)
10733         umask 0022
10734         mkdir -p $DIR/$tdir
10735         cd $DIR/$tdir
10736
10737         echo "performing cp ..."
10738         run_acl_subtest cp || error "run_acl_subtest cp failed"
10739         echo "performing getfacl-noacl..."
10740         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10741         echo "performing misc..."
10742         run_acl_subtest misc || error  "misc test failed"
10743         echo "performing permissions..."
10744         run_acl_subtest permissions || error "permissions failed"
10745         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10746         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10747                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10748                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10749         then
10750                 echo "performing permissions xattr..."
10751                 run_acl_subtest permissions_xattr ||
10752                         error "permissions_xattr failed"
10753         fi
10754         echo "performing setfacl..."
10755         run_acl_subtest setfacl || error  "setfacl test failed"
10756
10757         # inheritance test got from HP
10758         echo "performing inheritance..."
10759         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10760         chmod +x make-tree || error "chmod +x failed"
10761         run_acl_subtest inheritance || error "inheritance test failed"
10762         rm -f make-tree
10763
10764         echo "LU-974 ignore umask when acl is enabled..."
10765         run_acl_subtest 974 || error "LU-974 umask test failed"
10766         if [ $MDSCOUNT -ge 2 ]; then
10767                 run_acl_subtest 974_remote ||
10768                         error "LU-974 umask test failed under remote dir"
10769         fi
10770
10771         echo "LU-2561 newly created file is same size as directory..."
10772         if [ "$mds1_FSTYPE" != "zfs" ]; then
10773                 run_acl_subtest 2561 || error "LU-2561 test failed"
10774         else
10775                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10776         fi
10777
10778         run_acl_subtest 4924 || error "LU-4924 test failed"
10779
10780         cd $SAVE_PWD
10781         umask $SAVE_UMASK
10782
10783         for num in $(seq $MDSCOUNT); do
10784                 if [ "${identity_old[$num]}" = 1 ]; then
10785                         switch_identity $num false || identity_old[$num]=$?
10786                 fi
10787         done
10788 }
10789 run_test 103a "acl test"
10790
10791 test_103b() {
10792         declare -a pids
10793         local U
10794
10795         for U in {0..511}; do
10796                 {
10797                 local O=$(printf "%04o" $U)
10798
10799                 umask $(printf "%04o" $((511 ^ $O)))
10800                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10801                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10802
10803                 (( $S == ($O & 0666) )) ||
10804                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10805
10806                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10807                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10808                 (( $S == ($O & 0666) )) ||
10809                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10810
10811                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10812                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10813                 (( $S == ($O & 0666) )) ||
10814                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10815                 rm -f $DIR/$tfile.[smp]$0
10816                 } &
10817                 local pid=$!
10818
10819                 # limit the concurrently running threads to 64. LU-11878
10820                 local idx=$((U % 64))
10821                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10822                 pids[idx]=$pid
10823         done
10824         wait
10825 }
10826 run_test 103b "umask lfs setstripe"
10827
10828 test_103c() {
10829         mkdir -p $DIR/$tdir
10830         cp -rp $DIR/$tdir $DIR/$tdir.bak
10831
10832         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10833                 error "$DIR/$tdir shouldn't contain default ACL"
10834         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10835                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10836         true
10837 }
10838 run_test 103c "'cp -rp' won't set empty acl"
10839
10840 test_103e() {
10841         local numacl
10842         local fileacl
10843         local saved_debug=$($LCTL get_param -n debug)
10844
10845         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
10846                 skip "MDS needs to be at least 2.14.0"
10847
10848         large_xattr_enabled || skip_env "ea_inode feature disabled"
10849
10850         mkdir -p $DIR/$tdir
10851         # add big LOV EA to cause reply buffer overflow earlier
10852         $LFS setstripe -C 1000 $DIR/$tdir
10853         lctl set_param mdc.*-mdc*.stats=clear
10854
10855         $LCTL set_param debug=0
10856         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
10857         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
10858
10859         # add a large number of default ACLs (expect 8000+ for 2.13+)
10860         for U in {2..7000}; do
10861                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
10862                         error "Able to add just $U default ACLs"
10863         done
10864         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
10865         echo "$numacl default ACLs created"
10866
10867         stat $DIR/$tdir || error "Cannot stat directory"
10868         # check file creation
10869         touch $DIR/$tdir/$tfile ||
10870                 error "failed to create $tfile with $numacl default ACLs"
10871         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
10872         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10873         echo "$fileacl ACLs were inherited"
10874         (( $fileacl == $numacl )) ||
10875                 error "Not all default ACLs were inherited: $numacl != $fileacl"
10876         # check that new ACLs creation adds new ACLs to inherited ACLs
10877         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
10878                 error "Cannot set new ACL"
10879         numacl=$((numacl + 1))
10880         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10881         (( $fileacl == $numacl )) ||
10882                 error "failed to add new ACL: $fileacl != $numacl as expected"
10883         # adds more ACLs to a file to reach their maximum at 8000+
10884         numacl=0
10885         for U in {20000..25000}; do
10886                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
10887                 numacl=$((numacl + 1))
10888         done
10889         echo "Added $numacl more ACLs to the file"
10890         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
10891         echo "Total $fileacl ACLs in file"
10892         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
10893         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
10894         rmdir $DIR/$tdir || error "Cannot remove directory"
10895 }
10896 run_test 103e "inheritance of big amount of default ACLs"
10897
10898 test_103f() {
10899         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
10900                 skip "MDS needs to be at least 2.14.51"
10901
10902         large_xattr_enabled || skip_env "ea_inode feature disabled"
10903
10904         # enable changelog to consume more internal MDD buffers
10905         changelog_register
10906
10907         mkdir -p $DIR/$tdir
10908         # add big LOV EA
10909         $LFS setstripe -C 1000 $DIR/$tdir
10910         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
10911         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
10912         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
10913         rmdir $DIR/$tdir || error "Cannot remove directory"
10914 }
10915 run_test 103f "changelog doesn't interfere with default ACLs buffers"
10916
10917 test_104a() {
10918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10919
10920         touch $DIR/$tfile
10921         lfs df || error "lfs df failed"
10922         lfs df -ih || error "lfs df -ih failed"
10923         lfs df -h $DIR || error "lfs df -h $DIR failed"
10924         lfs df -i $DIR || error "lfs df -i $DIR failed"
10925         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10926         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10927
10928         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10929         lctl --device %$OSC deactivate
10930         lfs df || error "lfs df with deactivated OSC failed"
10931         lctl --device %$OSC activate
10932         # wait the osc back to normal
10933         wait_osc_import_ready client ost
10934
10935         lfs df || error "lfs df with reactivated OSC failed"
10936         rm -f $DIR/$tfile
10937 }
10938 run_test 104a "lfs df [-ih] [path] test ========================="
10939
10940 test_104b() {
10941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10942         [ $RUNAS_ID -eq $UID ] &&
10943                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10944
10945         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10946                         grep "Permission denied" | wc -l)))
10947         if [ $denied_cnt -ne 0 ]; then
10948                 error "lfs check servers test failed"
10949         fi
10950 }
10951 run_test 104b "$RUNAS lfs check servers test ===================="
10952
10953 #
10954 # Verify $1 is within range of $2.
10955 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
10956 # $1 is <= 2% of $2. Else Fail.
10957 #
10958 value_in_range() {
10959         # Strip all units (M, G, T)
10960         actual=$(echo $1 | tr -d A-Z)
10961         expect=$(echo $2 | tr -d A-Z)
10962
10963         expect_lo=$(($expect * 98 / 100)) # 2% below
10964         expect_hi=$(($expect * 102 / 100)) # 2% above
10965
10966         # permit 2% drift above and below
10967         (( $actual >= $expect_lo && $actual <= $expect_hi ))
10968 }
10969
10970 test_104c() {
10971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10972         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
10973
10974         local ost_param="osd-zfs.$FSNAME-OST0000."
10975         local mdt_param="osd-zfs.$FSNAME-MDT0000."
10976         local ofacets=$(get_facets OST)
10977         local mfacets=$(get_facets MDS)
10978         local saved_ost_blocks=
10979         local saved_mdt_blocks=
10980
10981         echo "Before recordsize change"
10982         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
10983         df=($(df -h | grep "/mnt/lustre"$))
10984
10985         # For checking.
10986         echo "lfs output : ${lfs_df[*]}"
10987         echo "df  output : ${df[*]}"
10988
10989         for facet in ${ofacets//,/ }; do
10990                 if [ -z $saved_ost_blocks ]; then
10991                         saved_ost_blocks=$(do_facet $facet \
10992                                 lctl get_param -n $ost_param.blocksize)
10993                         echo "OST Blocksize: $saved_ost_blocks"
10994                 fi
10995                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
10996                 do_facet $facet zfs set recordsize=32768 $ost
10997         done
10998
10999         # BS too small. Sufficient for functional testing.
11000         for facet in ${mfacets//,/ }; do
11001                 if [ -z $saved_mdt_blocks ]; then
11002                         saved_mdt_blocks=$(do_facet $facet \
11003                                 lctl get_param -n $mdt_param.blocksize)
11004                         echo "MDT Blocksize: $saved_mdt_blocks"
11005                 fi
11006                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11007                 do_facet $facet zfs set recordsize=32768 $mdt
11008         done
11009
11010         # Give new values chance to reflect change
11011         sleep 2
11012
11013         echo "After recordsize change"
11014         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11015         df_after=($(df -h | grep "/mnt/lustre"$))
11016
11017         # For checking.
11018         echo "lfs output : ${lfs_df_after[*]}"
11019         echo "df  output : ${df_after[*]}"
11020
11021         # Verify lfs df
11022         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11023                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11024         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11025                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11026         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11027                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11028
11029         # Verify df
11030         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11031                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11032         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11033                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11034         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11035                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11036
11037         # Restore MDT recordize back to original
11038         for facet in ${mfacets//,/ }; do
11039                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11040                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11041         done
11042
11043         # Restore OST recordize back to original
11044         for facet in ${ofacets//,/ }; do
11045                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11046                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11047         done
11048
11049         return 0
11050 }
11051 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11052
11053 test_105a() {
11054         # doesn't work on 2.4 kernels
11055         touch $DIR/$tfile
11056         if $(flock_is_enabled); then
11057                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11058         else
11059                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11060         fi
11061         rm -f $DIR/$tfile
11062 }
11063 run_test 105a "flock when mounted without -o flock test ========"
11064
11065 test_105b() {
11066         touch $DIR/$tfile
11067         if $(flock_is_enabled); then
11068                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11069         else
11070                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11071         fi
11072         rm -f $DIR/$tfile
11073 }
11074 run_test 105b "fcntl when mounted without -o flock test ========"
11075
11076 test_105c() {
11077         touch $DIR/$tfile
11078         if $(flock_is_enabled); then
11079                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11080         else
11081                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11082         fi
11083         rm -f $DIR/$tfile
11084 }
11085 run_test 105c "lockf when mounted without -o flock test"
11086
11087 test_105d() { # bug 15924
11088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11089
11090         test_mkdir $DIR/$tdir
11091         flock_is_enabled || skip_env "mount w/o flock enabled"
11092         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11093         $LCTL set_param fail_loc=0x80000315
11094         flocks_test 2 $DIR/$tdir
11095 }
11096 run_test 105d "flock race (should not freeze) ========"
11097
11098 test_105e() { # bug 22660 && 22040
11099         flock_is_enabled || skip_env "mount w/o flock enabled"
11100
11101         touch $DIR/$tfile
11102         flocks_test 3 $DIR/$tfile
11103 }
11104 run_test 105e "Two conflicting flocks from same process"
11105
11106 test_106() { #bug 10921
11107         test_mkdir $DIR/$tdir
11108         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11109         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11110 }
11111 run_test 106 "attempt exec of dir followed by chown of that dir"
11112
11113 test_107() {
11114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11115
11116         CDIR=`pwd`
11117         local file=core
11118
11119         cd $DIR
11120         rm -f $file
11121
11122         local save_pattern=$(sysctl -n kernel.core_pattern)
11123         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11124         sysctl -w kernel.core_pattern=$file
11125         sysctl -w kernel.core_uses_pid=0
11126
11127         ulimit -c unlimited
11128         sleep 60 &
11129         SLEEPPID=$!
11130
11131         sleep 1
11132
11133         kill -s 11 $SLEEPPID
11134         wait $SLEEPPID
11135         if [ -e $file ]; then
11136                 size=`stat -c%s $file`
11137                 [ $size -eq 0 ] && error "Fail to create core file $file"
11138         else
11139                 error "Fail to create core file $file"
11140         fi
11141         rm -f $file
11142         sysctl -w kernel.core_pattern=$save_pattern
11143         sysctl -w kernel.core_uses_pid=$save_uses_pid
11144         cd $CDIR
11145 }
11146 run_test 107 "Coredump on SIG"
11147
11148 test_110() {
11149         test_mkdir $DIR/$tdir
11150         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11151         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11152                 error "mkdir with 256 char should fail, but did not"
11153         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11154                 error "create with 255 char failed"
11155         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11156                 error "create with 256 char should fail, but did not"
11157
11158         ls -l $DIR/$tdir
11159         rm -rf $DIR/$tdir
11160 }
11161 run_test 110 "filename length checking"
11162
11163 #
11164 # Purpose: To verify dynamic thread (OSS) creation.
11165 #
11166 test_115() {
11167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11168         remote_ost_nodsh && skip "remote OST with nodsh"
11169
11170         # Lustre does not stop service threads once they are started.
11171         # Reset number of running threads to default.
11172         stopall
11173         setupall
11174
11175         local OSTIO_pre
11176         local save_params="$TMP/sanity-$TESTNAME.parameters"
11177
11178         # Get ll_ost_io count before I/O
11179         OSTIO_pre=$(do_facet ost1 \
11180                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11181         # Exit if lustre is not running (ll_ost_io not running).
11182         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11183
11184         echo "Starting with $OSTIO_pre threads"
11185         local thread_max=$((OSTIO_pre * 2))
11186         local rpc_in_flight=$((thread_max * 2))
11187         # Number of I/O Process proposed to be started.
11188         local nfiles
11189         local facets=$(get_facets OST)
11190
11191         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11192         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11193
11194         # Set in_flight to $rpc_in_flight
11195         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11196                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11197         nfiles=${rpc_in_flight}
11198         # Set ost thread_max to $thread_max
11199         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11200
11201         # 5 Minutes should be sufficient for max number of OSS
11202         # threads(thread_max) to be created.
11203         local timeout=300
11204
11205         # Start I/O.
11206         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11207         test_mkdir $DIR/$tdir
11208         for i in $(seq $nfiles); do
11209                 local file=$DIR/$tdir/${tfile}-$i
11210                 $LFS setstripe -c -1 -i 0 $file
11211                 ($WTL $file $timeout)&
11212         done
11213
11214         # I/O Started - Wait for thread_started to reach thread_max or report
11215         # error if thread_started is more than thread_max.
11216         echo "Waiting for thread_started to reach thread_max"
11217         local thread_started=0
11218         local end_time=$((SECONDS + timeout))
11219
11220         while [ $SECONDS -le $end_time ] ; do
11221                 echo -n "."
11222                 # Get ost i/o thread_started count.
11223                 thread_started=$(do_facet ost1 \
11224                         "$LCTL get_param \
11225                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11226                 # Break out if thread_started is equal/greater than thread_max
11227                 if [[ $thread_started -ge $thread_max ]]; then
11228                         echo ll_ost_io thread_started $thread_started, \
11229                                 equal/greater than thread_max $thread_max
11230                         break
11231                 fi
11232                 sleep 1
11233         done
11234
11235         # Cleanup - We have the numbers, Kill i/o jobs if running.
11236         jobcount=($(jobs -p))
11237         for i in $(seq 0 $((${#jobcount[@]}-1)))
11238         do
11239                 kill -9 ${jobcount[$i]}
11240                 if [ $? -ne 0 ] ; then
11241                         echo Warning: \
11242                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11243                 fi
11244         done
11245
11246         # Cleanup files left by WTL binary.
11247         for i in $(seq $nfiles); do
11248                 local file=$DIR/$tdir/${tfile}-$i
11249                 rm -rf $file
11250                 if [ $? -ne 0 ] ; then
11251                         echo "Warning: Failed to delete file $file"
11252                 fi
11253         done
11254
11255         restore_lustre_params <$save_params
11256         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11257
11258         # Error out if no new thread has started or Thread started is greater
11259         # than thread max.
11260         if [[ $thread_started -le $OSTIO_pre ||
11261                         $thread_started -gt $thread_max ]]; then
11262                 error "ll_ost_io: thread_started $thread_started" \
11263                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11264                       "No new thread started or thread started greater " \
11265                       "than thread_max."
11266         fi
11267 }
11268 run_test 115 "verify dynamic thread creation===================="
11269
11270 free_min_max () {
11271         wait_delete_completed
11272         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11273         echo "OST kbytes available: ${AVAIL[@]}"
11274         MAXV=${AVAIL[0]}
11275         MAXI=0
11276         MINV=${AVAIL[0]}
11277         MINI=0
11278         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11279                 #echo OST $i: ${AVAIL[i]}kb
11280                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11281                         MAXV=${AVAIL[i]}
11282                         MAXI=$i
11283                 fi
11284                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11285                         MINV=${AVAIL[i]}
11286                         MINI=$i
11287                 fi
11288         done
11289         echo "Min free space: OST $MINI: $MINV"
11290         echo "Max free space: OST $MAXI: $MAXV"
11291 }
11292
11293 test_116a() { # was previously test_116()
11294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11295         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11296         remote_mds_nodsh && skip "remote MDS with nodsh"
11297
11298         echo -n "Free space priority "
11299         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11300                 head -n1
11301         declare -a AVAIL
11302         free_min_max
11303
11304         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11305         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11306         trap simple_cleanup_common EXIT
11307
11308         # Check if we need to generate uneven OSTs
11309         test_mkdir -p $DIR/$tdir/OST${MINI}
11310         local FILL=$((MINV / 4))
11311         local DIFF=$((MAXV - MINV))
11312         local DIFF2=$((DIFF * 100 / MINV))
11313
11314         local threshold=$(do_facet $SINGLEMDS \
11315                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11316         threshold=${threshold%%%}
11317         echo -n "Check for uneven OSTs: "
11318         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11319
11320         if [[ $DIFF2 -gt $threshold ]]; then
11321                 echo "ok"
11322                 echo "Don't need to fill OST$MINI"
11323         else
11324                 # generate uneven OSTs. Write 2% over the QOS threshold value
11325                 echo "no"
11326                 DIFF=$((threshold - DIFF2 + 2))
11327                 DIFF2=$((MINV * DIFF / 100))
11328                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11329                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11330                         error "setstripe failed"
11331                 DIFF=$((DIFF2 / 2048))
11332                 i=0
11333                 while [ $i -lt $DIFF ]; do
11334                         i=$((i + 1))
11335                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11336                                 bs=2M count=1 2>/dev/null
11337                         echo -n .
11338                 done
11339                 echo .
11340                 sync
11341                 sleep_maxage
11342                 free_min_max
11343         fi
11344
11345         DIFF=$((MAXV - MINV))
11346         DIFF2=$((DIFF * 100 / MINV))
11347         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11348         if [ $DIFF2 -gt $threshold ]; then
11349                 echo "ok"
11350         else
11351                 echo "failed - QOS mode won't be used"
11352                 simple_cleanup_common
11353                 skip "QOS imbalance criteria not met"
11354         fi
11355
11356         MINI1=$MINI
11357         MINV1=$MINV
11358         MAXI1=$MAXI
11359         MAXV1=$MAXV
11360
11361         # now fill using QOS
11362         $LFS setstripe -c 1 $DIR/$tdir
11363         FILL=$((FILL / 200))
11364         if [ $FILL -gt 600 ]; then
11365                 FILL=600
11366         fi
11367         echo "writing $FILL files to QOS-assigned OSTs"
11368         i=0
11369         while [ $i -lt $FILL ]; do
11370                 i=$((i + 1))
11371                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11372                         count=1 2>/dev/null
11373                 echo -n .
11374         done
11375         echo "wrote $i 200k files"
11376         sync
11377         sleep_maxage
11378
11379         echo "Note: free space may not be updated, so measurements might be off"
11380         free_min_max
11381         DIFF2=$((MAXV - MINV))
11382         echo "free space delta: orig $DIFF final $DIFF2"
11383         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11384         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11385         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11386         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11387         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11388         if [[ $DIFF -gt 0 ]]; then
11389                 FILL=$((DIFF2 * 100 / DIFF - 100))
11390                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11391         fi
11392
11393         # Figure out which files were written where
11394         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11395                awk '/'$MINI1': / {print $2; exit}')
11396         echo $UUID
11397         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11398         echo "$MINC files created on smaller OST $MINI1"
11399         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11400                awk '/'$MAXI1': / {print $2; exit}')
11401         echo $UUID
11402         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11403         echo "$MAXC files created on larger OST $MAXI1"
11404         if [[ $MINC -gt 0 ]]; then
11405                 FILL=$((MAXC * 100 / MINC - 100))
11406                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11407         fi
11408         [[ $MAXC -gt $MINC ]] ||
11409                 error_ignore LU-9 "stripe QOS didn't balance free space"
11410         simple_cleanup_common
11411 }
11412 run_test 116a "stripe QOS: free space balance ==================="
11413
11414 test_116b() { # LU-2093
11415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11416         remote_mds_nodsh && skip "remote MDS with nodsh"
11417
11418 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11419         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11420                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11421         [ -z "$old_rr" ] && skip "no QOS"
11422         do_facet $SINGLEMDS lctl set_param \
11423                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11424         mkdir -p $DIR/$tdir
11425         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11426         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11427         do_facet $SINGLEMDS lctl set_param fail_loc=0
11428         rm -rf $DIR/$tdir
11429         do_facet $SINGLEMDS lctl set_param \
11430                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11431 }
11432 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11433
11434 test_117() # bug 10891
11435 {
11436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11437
11438         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11439         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11440         lctl set_param fail_loc=0x21e
11441         > $DIR/$tfile || error "truncate failed"
11442         lctl set_param fail_loc=0
11443         echo "Truncate succeeded."
11444         rm -f $DIR/$tfile
11445 }
11446 run_test 117 "verify osd extend =========="
11447
11448 NO_SLOW_RESENDCOUNT=4
11449 export OLD_RESENDCOUNT=""
11450 set_resend_count () {
11451         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11452         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11453         lctl set_param -n $PROC_RESENDCOUNT $1
11454         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11455 }
11456
11457 # for reduce test_118* time (b=14842)
11458 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11459
11460 # Reset async IO behavior after error case
11461 reset_async() {
11462         FILE=$DIR/reset_async
11463
11464         # Ensure all OSCs are cleared
11465         $LFS setstripe -c -1 $FILE
11466         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11467         sync
11468         rm $FILE
11469 }
11470
11471 test_118a() #bug 11710
11472 {
11473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11474
11475         reset_async
11476
11477         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11478         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11479         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11480
11481         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11482                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11483                 return 1;
11484         fi
11485         rm -f $DIR/$tfile
11486 }
11487 run_test 118a "verify O_SYNC works =========="
11488
11489 test_118b()
11490 {
11491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11492         remote_ost_nodsh && skip "remote OST with nodsh"
11493
11494         reset_async
11495
11496         #define OBD_FAIL_SRV_ENOENT 0x217
11497         set_nodes_failloc "$(osts_nodes)" 0x217
11498         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11499         RC=$?
11500         set_nodes_failloc "$(osts_nodes)" 0
11501         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11502         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11503                     grep -c writeback)
11504
11505         if [[ $RC -eq 0 ]]; then
11506                 error "Must return error due to dropped pages, rc=$RC"
11507                 return 1;
11508         fi
11509
11510         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11511                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11512                 return 1;
11513         fi
11514
11515         echo "Dirty pages not leaked on ENOENT"
11516
11517         # Due to the above error the OSC will issue all RPCs syncronously
11518         # until a subsequent RPC completes successfully without error.
11519         $MULTIOP $DIR/$tfile Ow4096yc
11520         rm -f $DIR/$tfile
11521
11522         return 0
11523 }
11524 run_test 118b "Reclaim dirty pages on fatal error =========="
11525
11526 test_118c()
11527 {
11528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11529
11530         # for 118c, restore the original resend count, LU-1940
11531         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11532                                 set_resend_count $OLD_RESENDCOUNT
11533         remote_ost_nodsh && skip "remote OST with nodsh"
11534
11535         reset_async
11536
11537         #define OBD_FAIL_OST_EROFS               0x216
11538         set_nodes_failloc "$(osts_nodes)" 0x216
11539
11540         # multiop should block due to fsync until pages are written
11541         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11542         MULTIPID=$!
11543         sleep 1
11544
11545         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11546                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11547         fi
11548
11549         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11550                     grep -c writeback)
11551         if [[ $WRITEBACK -eq 0 ]]; then
11552                 error "No page in writeback, writeback=$WRITEBACK"
11553         fi
11554
11555         set_nodes_failloc "$(osts_nodes)" 0
11556         wait $MULTIPID
11557         RC=$?
11558         if [[ $RC -ne 0 ]]; then
11559                 error "Multiop fsync failed, rc=$RC"
11560         fi
11561
11562         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11563         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11564                     grep -c writeback)
11565         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11566                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11567         fi
11568
11569         rm -f $DIR/$tfile
11570         echo "Dirty pages flushed via fsync on EROFS"
11571         return 0
11572 }
11573 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11574
11575 # continue to use small resend count to reduce test_118* time (b=14842)
11576 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11577
11578 test_118d()
11579 {
11580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11581         remote_ost_nodsh && skip "remote OST with nodsh"
11582
11583         reset_async
11584
11585         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11586         set_nodes_failloc "$(osts_nodes)" 0x214
11587         # multiop should block due to fsync until pages are written
11588         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11589         MULTIPID=$!
11590         sleep 1
11591
11592         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11593                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11594         fi
11595
11596         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11597                     grep -c writeback)
11598         if [[ $WRITEBACK -eq 0 ]]; then
11599                 error "No page in writeback, writeback=$WRITEBACK"
11600         fi
11601
11602         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11603         set_nodes_failloc "$(osts_nodes)" 0
11604
11605         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11606         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11607                     grep -c writeback)
11608         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11609                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11610         fi
11611
11612         rm -f $DIR/$tfile
11613         echo "Dirty pages gaurenteed flushed via fsync"
11614         return 0
11615 }
11616 run_test 118d "Fsync validation inject a delay of the bulk =========="
11617
11618 test_118f() {
11619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11620
11621         reset_async
11622
11623         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11624         lctl set_param fail_loc=0x8000040a
11625
11626         # Should simulate EINVAL error which is fatal
11627         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11628         RC=$?
11629         if [[ $RC -eq 0 ]]; then
11630                 error "Must return error due to dropped pages, rc=$RC"
11631         fi
11632
11633         lctl set_param fail_loc=0x0
11634
11635         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11636         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11637         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11638                     grep -c writeback)
11639         if [[ $LOCKED -ne 0 ]]; then
11640                 error "Locked pages remain in cache, locked=$LOCKED"
11641         fi
11642
11643         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11644                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11645         fi
11646
11647         rm -f $DIR/$tfile
11648         echo "No pages locked after fsync"
11649
11650         reset_async
11651         return 0
11652 }
11653 run_test 118f "Simulate unrecoverable OSC side error =========="
11654
11655 test_118g() {
11656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11657
11658         reset_async
11659
11660         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11661         lctl set_param fail_loc=0x406
11662
11663         # simulate local -ENOMEM
11664         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11665         RC=$?
11666
11667         lctl set_param fail_loc=0
11668         if [[ $RC -eq 0 ]]; then
11669                 error "Must return error due to dropped pages, rc=$RC"
11670         fi
11671
11672         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11673         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11674         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11675                         grep -c writeback)
11676         if [[ $LOCKED -ne 0 ]]; then
11677                 error "Locked pages remain in cache, locked=$LOCKED"
11678         fi
11679
11680         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11681                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11682         fi
11683
11684         rm -f $DIR/$tfile
11685         echo "No pages locked after fsync"
11686
11687         reset_async
11688         return 0
11689 }
11690 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11691
11692 test_118h() {
11693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11694         remote_ost_nodsh && skip "remote OST with nodsh"
11695
11696         reset_async
11697
11698         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11699         set_nodes_failloc "$(osts_nodes)" 0x20e
11700         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11701         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11702         RC=$?
11703
11704         set_nodes_failloc "$(osts_nodes)" 0
11705         if [[ $RC -eq 0 ]]; then
11706                 error "Must return error due to dropped pages, rc=$RC"
11707         fi
11708
11709         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11710         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11711         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11712                     grep -c writeback)
11713         if [[ $LOCKED -ne 0 ]]; then
11714                 error "Locked pages remain in cache, locked=$LOCKED"
11715         fi
11716
11717         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11718                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11719         fi
11720
11721         rm -f $DIR/$tfile
11722         echo "No pages locked after fsync"
11723
11724         return 0
11725 }
11726 run_test 118h "Verify timeout in handling recoverables errors  =========="
11727
11728 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11729
11730 test_118i() {
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_WRITE_BULK      0x20e
11737         set_nodes_failloc "$(osts_nodes)" 0x20e
11738
11739         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11740         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11741         PID=$!
11742         sleep 5
11743         set_nodes_failloc "$(osts_nodes)" 0
11744
11745         wait $PID
11746         RC=$?
11747         if [[ $RC -ne 0 ]]; then
11748                 error "got error, but should be not, rc=$RC"
11749         fi
11750
11751         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11752         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11753         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11754         if [[ $LOCKED -ne 0 ]]; then
11755                 error "Locked pages remain in cache, locked=$LOCKED"
11756         fi
11757
11758         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11759                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11760         fi
11761
11762         rm -f $DIR/$tfile
11763         echo "No pages locked after fsync"
11764
11765         return 0
11766 }
11767 run_test 118i "Fix error before timeout in recoverable error  =========="
11768
11769 [ "$SLOW" = "no" ] && set_resend_count 4
11770
11771 test_118j() {
11772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11773         remote_ost_nodsh && skip "remote OST with nodsh"
11774
11775         reset_async
11776
11777         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11778         set_nodes_failloc "$(osts_nodes)" 0x220
11779
11780         # return -EIO from OST
11781         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11782         RC=$?
11783         set_nodes_failloc "$(osts_nodes)" 0x0
11784         if [[ $RC -eq 0 ]]; then
11785                 error "Must return error due to dropped pages, rc=$RC"
11786         fi
11787
11788         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11789         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11790         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11791         if [[ $LOCKED -ne 0 ]]; then
11792                 error "Locked pages remain in cache, locked=$LOCKED"
11793         fi
11794
11795         # in recoverable error on OST we want resend and stay until it finished
11796         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11797                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11798         fi
11799
11800         rm -f $DIR/$tfile
11801         echo "No pages locked after fsync"
11802
11803         return 0
11804 }
11805 run_test 118j "Simulate unrecoverable OST side error =========="
11806
11807 test_118k()
11808 {
11809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11810         remote_ost_nodsh && skip "remote OSTs with nodsh"
11811
11812         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11813         set_nodes_failloc "$(osts_nodes)" 0x20e
11814         test_mkdir $DIR/$tdir
11815
11816         for ((i=0;i<10;i++)); do
11817                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11818                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11819                 SLEEPPID=$!
11820                 sleep 0.500s
11821                 kill $SLEEPPID
11822                 wait $SLEEPPID
11823         done
11824
11825         set_nodes_failloc "$(osts_nodes)" 0
11826         rm -rf $DIR/$tdir
11827 }
11828 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11829
11830 test_118l() # LU-646
11831 {
11832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11833
11834         test_mkdir $DIR/$tdir
11835         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11836         rm -rf $DIR/$tdir
11837 }
11838 run_test 118l "fsync dir"
11839
11840 test_118m() # LU-3066
11841 {
11842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11843
11844         test_mkdir $DIR/$tdir
11845         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11846         rm -rf $DIR/$tdir
11847 }
11848 run_test 118m "fdatasync dir ========="
11849
11850 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11851
11852 test_118n()
11853 {
11854         local begin
11855         local end
11856
11857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11858         remote_ost_nodsh && skip "remote OSTs with nodsh"
11859
11860         # Sleep to avoid a cached response.
11861         #define OBD_STATFS_CACHE_SECONDS 1
11862         sleep 2
11863
11864         # Inject a 10 second delay in the OST_STATFS handler.
11865         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11866         set_nodes_failloc "$(osts_nodes)" 0x242
11867
11868         begin=$SECONDS
11869         stat --file-system $MOUNT > /dev/null
11870         end=$SECONDS
11871
11872         set_nodes_failloc "$(osts_nodes)" 0
11873
11874         if ((end - begin > 20)); then
11875             error "statfs took $((end - begin)) seconds, expected 10"
11876         fi
11877 }
11878 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11879
11880 test_119a() # bug 11737
11881 {
11882         BSIZE=$((512 * 1024))
11883         directio write $DIR/$tfile 0 1 $BSIZE
11884         # We ask to read two blocks, which is more than a file size.
11885         # directio will indicate an error when requested and actual
11886         # sizes aren't equeal (a normal situation in this case) and
11887         # print actual read amount.
11888         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11889         if [ "$NOB" != "$BSIZE" ]; then
11890                 error "read $NOB bytes instead of $BSIZE"
11891         fi
11892         rm -f $DIR/$tfile
11893 }
11894 run_test 119a "Short directIO read must return actual read amount"
11895
11896 test_119b() # bug 11737
11897 {
11898         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11899
11900         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11901         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11902         sync
11903         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11904                 error "direct read failed"
11905         rm -f $DIR/$tfile
11906 }
11907 run_test 119b "Sparse directIO read must return actual read amount"
11908
11909 test_119c() # bug 13099
11910 {
11911         BSIZE=1048576
11912         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11913         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11914         rm -f $DIR/$tfile
11915 }
11916 run_test 119c "Testing for direct read hitting hole"
11917
11918 test_119d() # bug 15950
11919 {
11920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11921
11922         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11923         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11924         BSIZE=1048576
11925         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11926         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11927         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11928         lctl set_param fail_loc=0x40d
11929         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11930         pid_dio=$!
11931         sleep 1
11932         cat $DIR/$tfile > /dev/null &
11933         lctl set_param fail_loc=0
11934         pid_reads=$!
11935         wait $pid_dio
11936         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11937         sleep 2
11938         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11939         error "the read rpcs have not completed in 2s"
11940         rm -f $DIR/$tfile
11941         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11942 }
11943 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11944
11945 test_120a() {
11946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11947         remote_mds_nodsh && skip "remote MDS with nodsh"
11948         test_mkdir -i0 -c1 $DIR/$tdir
11949         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11950                 skip_env "no early lock cancel on server"
11951
11952         lru_resize_disable mdc
11953         lru_resize_disable osc
11954         cancel_lru_locks mdc
11955         # asynchronous object destroy at MDT could cause bl ast to client
11956         cancel_lru_locks osc
11957
11958         stat $DIR/$tdir > /dev/null
11959         can1=$(do_facet mds1 \
11960                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11961                awk '/ldlm_cancel/ {print $2}')
11962         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11963                awk '/ldlm_bl_callback/ {print $2}')
11964         test_mkdir -i0 -c1 $DIR/$tdir/d1
11965         can2=$(do_facet mds1 \
11966                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11967                awk '/ldlm_cancel/ {print $2}')
11968         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11969                awk '/ldlm_bl_callback/ {print $2}')
11970         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11971         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11972         lru_resize_enable mdc
11973         lru_resize_enable osc
11974 }
11975 run_test 120a "Early Lock Cancel: mkdir test"
11976
11977 test_120b() {
11978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11979         remote_mds_nodsh && skip "remote MDS with nodsh"
11980         test_mkdir $DIR/$tdir
11981         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11982                 skip_env "no early lock cancel on server"
11983
11984         lru_resize_disable mdc
11985         lru_resize_disable osc
11986         cancel_lru_locks mdc
11987         stat $DIR/$tdir > /dev/null
11988         can1=$(do_facet $SINGLEMDS \
11989                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11990                awk '/ldlm_cancel/ {print $2}')
11991         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11992                awk '/ldlm_bl_callback/ {print $2}')
11993         touch $DIR/$tdir/f1
11994         can2=$(do_facet $SINGLEMDS \
11995                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11996                awk '/ldlm_cancel/ {print $2}')
11997         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11998                awk '/ldlm_bl_callback/ {print $2}')
11999         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12000         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12001         lru_resize_enable mdc
12002         lru_resize_enable osc
12003 }
12004 run_test 120b "Early Lock Cancel: create test"
12005
12006 test_120c() {
12007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12008         remote_mds_nodsh && skip "remote MDS with nodsh"
12009         test_mkdir -i0 -c1 $DIR/$tdir
12010         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12011                 skip "no early lock cancel on server"
12012
12013         lru_resize_disable mdc
12014         lru_resize_disable osc
12015         test_mkdir -i0 -c1 $DIR/$tdir/d1
12016         test_mkdir -i0 -c1 $DIR/$tdir/d2
12017         touch $DIR/$tdir/d1/f1
12018         cancel_lru_locks mdc
12019         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12020         can1=$(do_facet mds1 \
12021                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12022                awk '/ldlm_cancel/ {print $2}')
12023         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12024                awk '/ldlm_bl_callback/ {print $2}')
12025         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12026         can2=$(do_facet mds1 \
12027                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12028                awk '/ldlm_cancel/ {print $2}')
12029         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12030                awk '/ldlm_bl_callback/ {print $2}')
12031         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12032         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12033         lru_resize_enable mdc
12034         lru_resize_enable osc
12035 }
12036 run_test 120c "Early Lock Cancel: link test"
12037
12038 test_120d() {
12039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12040         remote_mds_nodsh && skip "remote MDS with nodsh"
12041         test_mkdir -i0 -c1 $DIR/$tdir
12042         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12043                 skip_env "no early lock cancel on server"
12044
12045         lru_resize_disable mdc
12046         lru_resize_disable osc
12047         touch $DIR/$tdir
12048         cancel_lru_locks mdc
12049         stat $DIR/$tdir > /dev/null
12050         can1=$(do_facet mds1 \
12051                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12052                awk '/ldlm_cancel/ {print $2}')
12053         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12054                awk '/ldlm_bl_callback/ {print $2}')
12055         chmod a+x $DIR/$tdir
12056         can2=$(do_facet mds1 \
12057                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12058                awk '/ldlm_cancel/ {print $2}')
12059         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12060                awk '/ldlm_bl_callback/ {print $2}')
12061         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12062         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12063         lru_resize_enable mdc
12064         lru_resize_enable osc
12065 }
12066 run_test 120d "Early Lock Cancel: setattr test"
12067
12068 test_120e() {
12069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12070         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12071                 skip_env "no early lock cancel on server"
12072         remote_mds_nodsh && skip "remote MDS with nodsh"
12073
12074         local dlmtrace_set=false
12075
12076         test_mkdir -i0 -c1 $DIR/$tdir
12077         lru_resize_disable mdc
12078         lru_resize_disable osc
12079         ! $LCTL get_param debug | grep -q dlmtrace &&
12080                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12081         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12082         cancel_lru_locks mdc
12083         cancel_lru_locks osc
12084         dd if=$DIR/$tdir/f1 of=/dev/null
12085         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12086         # XXX client can not do early lock cancel of OST lock
12087         # during unlink (LU-4206), so cancel osc lock now.
12088         sleep 2
12089         cancel_lru_locks osc
12090         can1=$(do_facet mds1 \
12091                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12092                awk '/ldlm_cancel/ {print $2}')
12093         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12094                awk '/ldlm_bl_callback/ {print $2}')
12095         unlink $DIR/$tdir/f1
12096         sleep 5
12097         can2=$(do_facet mds1 \
12098                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12099                awk '/ldlm_cancel/ {print $2}')
12100         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12101                awk '/ldlm_bl_callback/ {print $2}')
12102         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12103                 $LCTL dk $TMP/cancel.debug.txt
12104         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12105                 $LCTL dk $TMP/blocking.debug.txt
12106         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12107         lru_resize_enable mdc
12108         lru_resize_enable osc
12109 }
12110 run_test 120e "Early Lock Cancel: unlink test"
12111
12112 test_120f() {
12113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12114         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12115                 skip_env "no early lock cancel on server"
12116         remote_mds_nodsh && skip "remote MDS with nodsh"
12117
12118         test_mkdir -i0 -c1 $DIR/$tdir
12119         lru_resize_disable mdc
12120         lru_resize_disable osc
12121         test_mkdir -i0 -c1 $DIR/$tdir/d1
12122         test_mkdir -i0 -c1 $DIR/$tdir/d2
12123         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12124         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12125         cancel_lru_locks mdc
12126         cancel_lru_locks osc
12127         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12128         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12129         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12130         # XXX client can not do early lock cancel of OST lock
12131         # during rename (LU-4206), so cancel osc lock now.
12132         sleep 2
12133         cancel_lru_locks osc
12134         can1=$(do_facet mds1 \
12135                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12136                awk '/ldlm_cancel/ {print $2}')
12137         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12138                awk '/ldlm_bl_callback/ {print $2}')
12139         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12140         sleep 5
12141         can2=$(do_facet mds1 \
12142                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12143                awk '/ldlm_cancel/ {print $2}')
12144         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12145                awk '/ldlm_bl_callback/ {print $2}')
12146         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12147         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12148         lru_resize_enable mdc
12149         lru_resize_enable osc
12150 }
12151 run_test 120f "Early Lock Cancel: rename test"
12152
12153 test_120g() {
12154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12155         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12156                 skip_env "no early lock cancel on server"
12157         remote_mds_nodsh && skip "remote MDS with nodsh"
12158
12159         lru_resize_disable mdc
12160         lru_resize_disable osc
12161         count=10000
12162         echo create $count files
12163         test_mkdir $DIR/$tdir
12164         cancel_lru_locks mdc
12165         cancel_lru_locks osc
12166         t0=$(date +%s)
12167
12168         can0=$(do_facet $SINGLEMDS \
12169                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12170                awk '/ldlm_cancel/ {print $2}')
12171         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12172                awk '/ldlm_bl_callback/ {print $2}')
12173         createmany -o $DIR/$tdir/f $count
12174         sync
12175         can1=$(do_facet $SINGLEMDS \
12176                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12177                awk '/ldlm_cancel/ {print $2}')
12178         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12179                awk '/ldlm_bl_callback/ {print $2}')
12180         t1=$(date +%s)
12181         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12182         echo rm $count files
12183         rm -r $DIR/$tdir
12184         sync
12185         can2=$(do_facet $SINGLEMDS \
12186                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12187                awk '/ldlm_cancel/ {print $2}')
12188         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12189                awk '/ldlm_bl_callback/ {print $2}')
12190         t2=$(date +%s)
12191         echo total: $count removes in $((t2-t1))
12192         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12193         sleep 2
12194         # wait for commitment of removal
12195         lru_resize_enable mdc
12196         lru_resize_enable osc
12197 }
12198 run_test 120g "Early Lock Cancel: performance test"
12199
12200 test_121() { #bug #10589
12201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12202
12203         rm -rf $DIR/$tfile
12204         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12205 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12206         lctl set_param fail_loc=0x310
12207         cancel_lru_locks osc > /dev/null
12208         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12209         lctl set_param fail_loc=0
12210         [[ $reads -eq $writes ]] ||
12211                 error "read $reads blocks, must be $writes blocks"
12212 }
12213 run_test 121 "read cancel race ========="
12214
12215 test_123a_base() { # was test 123, statahead(bug 11401)
12216         local lsx="$1"
12217
12218         SLOWOK=0
12219         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12220                 log "testing UP system. Performance may be lower than expected."
12221                 SLOWOK=1
12222         fi
12223
12224         rm -rf $DIR/$tdir
12225         test_mkdir $DIR/$tdir
12226         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12227         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12228         MULT=10
12229         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12230                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12231
12232                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12233                 lctl set_param -n llite.*.statahead_max 0
12234                 lctl get_param llite.*.statahead_max
12235                 cancel_lru_locks mdc
12236                 cancel_lru_locks osc
12237                 stime=$(date +%s)
12238                 time $lsx $DIR/$tdir | wc -l
12239                 etime=$(date +%s)
12240                 delta=$((etime - stime))
12241                 log "$lsx $i files without statahead: $delta sec"
12242                 lctl set_param llite.*.statahead_max=$max
12243
12244                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12245                         grep "statahead wrong:" | awk '{print $3}')
12246                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12247                 cancel_lru_locks mdc
12248                 cancel_lru_locks osc
12249                 stime=$(date +%s)
12250                 time $lsx $DIR/$tdir | wc -l
12251                 etime=$(date +%s)
12252                 delta_sa=$((etime - stime))
12253                 log "$lsx $i files with statahead: $delta_sa sec"
12254                 lctl get_param -n llite.*.statahead_stats
12255                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12256                         grep "statahead wrong:" | awk '{print $3}')
12257
12258                 [[ $swrong -lt $ewrong ]] &&
12259                         log "statahead was stopped, maybe too many locks held!"
12260                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12261
12262                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12263                         max=$(lctl get_param -n llite.*.statahead_max |
12264                                 head -n 1)
12265                         lctl set_param -n llite.*.statahead_max 0
12266                         lctl get_param llite.*.statahead_max
12267                         cancel_lru_locks mdc
12268                         cancel_lru_locks osc
12269                         stime=$(date +%s)
12270                         time $lsx $DIR/$tdir | wc -l
12271                         etime=$(date +%s)
12272                         delta=$((etime - stime))
12273                         log "$lsx $i files again without statahead: $delta sec"
12274                         lctl set_param llite.*.statahead_max=$max
12275                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12276                                 if [  $SLOWOK -eq 0 ]; then
12277                                         error "$lsx $i files is slower with statahead!"
12278                                 else
12279                                         log "$lsx $i files is slower with statahead!"
12280                                 fi
12281                                 break
12282                         fi
12283                 fi
12284
12285                 [ $delta -gt 20 ] && break
12286                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12287                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12288         done
12289         log "$lsx done"
12290
12291         stime=$(date +%s)
12292         rm -r $DIR/$tdir
12293         sync
12294         etime=$(date +%s)
12295         delta=$((etime - stime))
12296         log "rm -r $DIR/$tdir/: $delta seconds"
12297         log "rm done"
12298         lctl get_param -n llite.*.statahead_stats
12299 }
12300
12301 test_123aa() {
12302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12303
12304         test_123a_base "ls -l"
12305 }
12306 run_test 123aa "verify statahead work"
12307
12308 test_123ab() {
12309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12310
12311         statx_supported || skip_env "Test must be statx() syscall supported"
12312
12313         test_123a_base "$STATX -l"
12314 }
12315 run_test 123ab "verify statahead work by using statx"
12316
12317 test_123ac() {
12318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12319
12320         statx_supported || skip_env "Test must be statx() syscall supported"
12321
12322         local rpcs_before
12323         local rpcs_after
12324         local agl_before
12325         local agl_after
12326
12327         cancel_lru_locks $OSC
12328         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12329         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12330                 awk '/agl.total:/ {print $3}')
12331         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12332         test_123a_base "$STATX --cached=always -D"
12333         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12334                 awk '/agl.total:/ {print $3}')
12335         [ $agl_before -eq $agl_after ] ||
12336                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12337         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12338         [ $rpcs_after -eq $rpcs_before ] ||
12339                 error "$STATX should not send glimpse RPCs to $OSC"
12340 }
12341 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12342
12343 test_123b () { # statahead(bug 15027)
12344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12345
12346         test_mkdir $DIR/$tdir
12347         createmany -o $DIR/$tdir/$tfile-%d 1000
12348
12349         cancel_lru_locks mdc
12350         cancel_lru_locks osc
12351
12352 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12353         lctl set_param fail_loc=0x80000803
12354         ls -lR $DIR/$tdir > /dev/null
12355         log "ls done"
12356         lctl set_param fail_loc=0x0
12357         lctl get_param -n llite.*.statahead_stats
12358         rm -r $DIR/$tdir
12359         sync
12360
12361 }
12362 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12363
12364 test_123c() {
12365         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12366
12367         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12368         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12369         touch $DIR/$tdir.1/{1..3}
12370         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12371
12372         remount_client $MOUNT
12373
12374         $MULTIOP $DIR/$tdir.0 Q
12375
12376         # let statahead to complete
12377         ls -l $DIR/$tdir.0 > /dev/null
12378
12379         testid=$(echo $TESTNAME | tr '_' ' ')
12380         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12381                 error "statahead warning" || true
12382 }
12383 run_test 123c "Can not initialize inode warning on DNE statahead"
12384
12385 test_124a() {
12386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12387         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12388                 skip_env "no lru resize on server"
12389
12390         local NR=2000
12391
12392         test_mkdir $DIR/$tdir
12393
12394         log "create $NR files at $DIR/$tdir"
12395         createmany -o $DIR/$tdir/f $NR ||
12396                 error "failed to create $NR files in $DIR/$tdir"
12397
12398         cancel_lru_locks mdc
12399         ls -l $DIR/$tdir > /dev/null
12400
12401         local NSDIR=""
12402         local LRU_SIZE=0
12403         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12404                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12405                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12406                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12407                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12408                         log "NSDIR=$NSDIR"
12409                         log "NS=$(basename $NSDIR)"
12410                         break
12411                 fi
12412         done
12413
12414         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12415                 skip "Not enough cached locks created!"
12416         fi
12417         log "LRU=$LRU_SIZE"
12418
12419         local SLEEP=30
12420
12421         # We know that lru resize allows one client to hold $LIMIT locks
12422         # for 10h. After that locks begin to be killed by client.
12423         local MAX_HRS=10
12424         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12425         log "LIMIT=$LIMIT"
12426         if [ $LIMIT -lt $LRU_SIZE ]; then
12427                 skip "Limit is too small $LIMIT"
12428         fi
12429
12430         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12431         # killing locks. Some time was spent for creating locks. This means
12432         # that up to the moment of sleep finish we must have killed some of
12433         # them (10-100 locks). This depends on how fast ther were created.
12434         # Many of them were touched in almost the same moment and thus will
12435         # be killed in groups.
12436         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12437
12438         # Use $LRU_SIZE_B here to take into account real number of locks
12439         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12440         local LRU_SIZE_B=$LRU_SIZE
12441         log "LVF=$LVF"
12442         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12443         log "OLD_LVF=$OLD_LVF"
12444         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12445
12446         # Let's make sure that we really have some margin. Client checks
12447         # cached locks every 10 sec.
12448         SLEEP=$((SLEEP+20))
12449         log "Sleep ${SLEEP} sec"
12450         local SEC=0
12451         while ((SEC<$SLEEP)); do
12452                 echo -n "..."
12453                 sleep 5
12454                 SEC=$((SEC+5))
12455                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12456                 echo -n "$LRU_SIZE"
12457         done
12458         echo ""
12459         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12460         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12461
12462         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12463                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12464                 unlinkmany $DIR/$tdir/f $NR
12465                 return
12466         }
12467
12468         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12469         log "unlink $NR files at $DIR/$tdir"
12470         unlinkmany $DIR/$tdir/f $NR
12471 }
12472 run_test 124a "lru resize ======================================="
12473
12474 get_max_pool_limit()
12475 {
12476         local limit=$($LCTL get_param \
12477                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12478         local max=0
12479         for l in $limit; do
12480                 if [[ $l -gt $max ]]; then
12481                         max=$l
12482                 fi
12483         done
12484         echo $max
12485 }
12486
12487 test_124b() {
12488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12489         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12490                 skip_env "no lru resize on server"
12491
12492         LIMIT=$(get_max_pool_limit)
12493
12494         NR=$(($(default_lru_size)*20))
12495         if [[ $NR -gt $LIMIT ]]; then
12496                 log "Limit lock number by $LIMIT locks"
12497                 NR=$LIMIT
12498         fi
12499
12500         IFree=$(mdsrate_inodes_available)
12501         if [ $IFree -lt $NR ]; then
12502                 log "Limit lock number by $IFree inodes"
12503                 NR=$IFree
12504         fi
12505
12506         lru_resize_disable mdc
12507         test_mkdir -p $DIR/$tdir/disable_lru_resize
12508
12509         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12510         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12511         cancel_lru_locks mdc
12512         stime=`date +%s`
12513         PID=""
12514         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12515         PID="$PID $!"
12516         sleep 2
12517         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12518         PID="$PID $!"
12519         sleep 2
12520         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12521         PID="$PID $!"
12522         wait $PID
12523         etime=`date +%s`
12524         nolruresize_delta=$((etime-stime))
12525         log "ls -la time: $nolruresize_delta seconds"
12526         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12527         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12528
12529         lru_resize_enable mdc
12530         test_mkdir -p $DIR/$tdir/enable_lru_resize
12531
12532         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12533         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12534         cancel_lru_locks mdc
12535         stime=`date +%s`
12536         PID=""
12537         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12538         PID="$PID $!"
12539         sleep 2
12540         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12541         PID="$PID $!"
12542         sleep 2
12543         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12544         PID="$PID $!"
12545         wait $PID
12546         etime=`date +%s`
12547         lruresize_delta=$((etime-stime))
12548         log "ls -la time: $lruresize_delta seconds"
12549         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12550
12551         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12552                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12553         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12554                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12555         else
12556                 log "lru resize performs the same with no lru resize"
12557         fi
12558         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12559 }
12560 run_test 124b "lru resize (performance test) ======================="
12561
12562 test_124c() {
12563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12564         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12565                 skip_env "no lru resize on server"
12566
12567         # cache ununsed locks on client
12568         local nr=100
12569         cancel_lru_locks mdc
12570         test_mkdir $DIR/$tdir
12571         createmany -o $DIR/$tdir/f $nr ||
12572                 error "failed to create $nr files in $DIR/$tdir"
12573         ls -l $DIR/$tdir > /dev/null
12574
12575         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12576         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12577         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12578         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12579         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12580
12581         # set lru_max_age to 1 sec
12582         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12583         echo "sleep $((recalc_p * 2)) seconds..."
12584         sleep $((recalc_p * 2))
12585
12586         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12587         # restore lru_max_age
12588         $LCTL set_param -n $nsdir.lru_max_age $max_age
12589         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12590         unlinkmany $DIR/$tdir/f $nr
12591 }
12592 run_test 124c "LRUR cancel very aged locks"
12593
12594 test_124d() {
12595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12596         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12597                 skip_env "no lru resize on server"
12598
12599         # cache ununsed locks on client
12600         local nr=100
12601
12602         lru_resize_disable mdc
12603         stack_trap "lru_resize_enable mdc" EXIT
12604
12605         cancel_lru_locks mdc
12606
12607         # asynchronous object destroy at MDT could cause bl ast to client
12608         test_mkdir $DIR/$tdir
12609         createmany -o $DIR/$tdir/f $nr ||
12610                 error "failed to create $nr files in $DIR/$tdir"
12611         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12612
12613         ls -l $DIR/$tdir > /dev/null
12614
12615         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12616         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12617         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12618         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12619
12620         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12621
12622         # set lru_max_age to 1 sec
12623         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12624         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12625
12626         echo "sleep $((recalc_p * 2)) seconds..."
12627         sleep $((recalc_p * 2))
12628
12629         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12630
12631         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12632 }
12633 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12634
12635 test_125() { # 13358
12636         $LCTL get_param -n llite.*.client_type | grep -q local ||
12637                 skip "must run as local client"
12638         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12639                 skip_env "must have acl enabled"
12640         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12641
12642         test_mkdir $DIR/$tdir
12643         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12644         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12645         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12646 }
12647 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12648
12649 test_126() { # bug 12829/13455
12650         $GSS && skip_env "must run as gss disabled"
12651         $LCTL get_param -n llite.*.client_type | grep -q local ||
12652                 skip "must run as local client"
12653         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12654
12655         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12656         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12657         rm -f $DIR/$tfile
12658         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12659 }
12660 run_test 126 "check that the fsgid provided by the client is taken into account"
12661
12662 test_127a() { # bug 15521
12663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12664         local name count samp unit min max sum sumsq
12665
12666         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12667         echo "stats before reset"
12668         $LCTL get_param osc.*.stats
12669         $LCTL set_param osc.*.stats=0
12670         local fsize=$((2048 * 1024))
12671
12672         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12673         cancel_lru_locks osc
12674         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12675
12676         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12677         stack_trap "rm -f $TMP/$tfile.tmp"
12678         while read name count samp unit min max sum sumsq; do
12679                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12680                 [ ! $min ] && error "Missing min value for $name proc entry"
12681                 eval $name=$count || error "Wrong proc format"
12682
12683                 case $name in
12684                 read_bytes|write_bytes)
12685                         [[ "$unit" =~ "bytes" ]] ||
12686                                 error "unit is not 'bytes': $unit"
12687                         (( $min >= 4096 )) || error "min is too small: $min"
12688                         (( $min <= $fsize )) || error "min is too big: $min"
12689                         (( $max >= 4096 )) || error "max is too small: $max"
12690                         (( $max <= $fsize )) || error "max is too big: $max"
12691                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12692                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12693                                 error "sumsquare is too small: $sumsq"
12694                         (( $sumsq <= $fsize * $fsize )) ||
12695                                 error "sumsquare is too big: $sumsq"
12696                         ;;
12697                 ost_read|ost_write)
12698                         [[ "$unit" =~ "usec" ]] ||
12699                                 error "unit is not 'usec': $unit"
12700                         ;;
12701                 *)      ;;
12702                 esac
12703         done < $DIR/$tfile.tmp
12704
12705         #check that we actually got some stats
12706         [ "$read_bytes" ] || error "Missing read_bytes stats"
12707         [ "$write_bytes" ] || error "Missing write_bytes stats"
12708         [ "$read_bytes" != 0 ] || error "no read done"
12709         [ "$write_bytes" != 0 ] || error "no write done"
12710 }
12711 run_test 127a "verify the client stats are sane"
12712
12713 test_127b() { # bug LU-333
12714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12715         local name count samp unit min max sum sumsq
12716
12717         echo "stats before reset"
12718         $LCTL get_param llite.*.stats
12719         $LCTL set_param llite.*.stats=0
12720
12721         # perform 2 reads and writes so MAX is different from SUM.
12722         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12723         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12724         cancel_lru_locks osc
12725         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12726         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12727
12728         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12729         stack_trap "rm -f $TMP/$tfile.tmp"
12730         while read name count samp unit min max sum sumsq; do
12731                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12732                 eval $name=$count || error "Wrong proc format"
12733
12734                 case $name in
12735                 read_bytes|write_bytes)
12736                         [[ "$unit" =~ "bytes" ]] ||
12737                                 error "unit is not 'bytes': $unit"
12738                         (( $count == 2 )) || error "count is not 2: $count"
12739                         (( $min == $PAGE_SIZE )) ||
12740                                 error "min is not $PAGE_SIZE: $min"
12741                         (( $max == $PAGE_SIZE )) ||
12742                                 error "max is not $PAGE_SIZE: $max"
12743                         (( $sum == $PAGE_SIZE * 2 )) ||
12744                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12745                         ;;
12746                 read|write)
12747                         [[ "$unit" =~ "usec" ]] ||
12748                                 error "unit is not 'usec': $unit"
12749                         ;;
12750                 *)      ;;
12751                 esac
12752         done < $TMP/$tfile.tmp
12753
12754         #check that we actually got some stats
12755         [ "$read_bytes" ] || error "Missing read_bytes stats"
12756         [ "$write_bytes" ] || error "Missing write_bytes stats"
12757         [ "$read_bytes" != 0 ] || error "no read done"
12758         [ "$write_bytes" != 0 ] || error "no write done"
12759 }
12760 run_test 127b "verify the llite client stats are sane"
12761
12762 test_127c() { # LU-12394
12763         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12764         local size
12765         local bsize
12766         local reads
12767         local writes
12768         local count
12769
12770         $LCTL set_param llite.*.extents_stats=1
12771         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12772
12773         # Use two stripes so there is enough space in default config
12774         $LFS setstripe -c 2 $DIR/$tfile
12775
12776         # Extent stats start at 0-4K and go in power of two buckets
12777         # LL_HIST_START = 12 --> 2^12 = 4K
12778         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12779         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12780         # small configs
12781         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12782                 do
12783                 # Write and read, 2x each, second time at a non-zero offset
12784                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12785                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12786                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12787                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12788                 rm -f $DIR/$tfile
12789         done
12790
12791         $LCTL get_param llite.*.extents_stats
12792
12793         count=2
12794         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12795                 do
12796                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12797                                 grep -m 1 $bsize)
12798                 reads=$(echo $bucket | awk '{print $5}')
12799                 writes=$(echo $bucket | awk '{print $9}')
12800                 [ "$reads" -eq $count ] ||
12801                         error "$reads reads in < $bsize bucket, expect $count"
12802                 [ "$writes" -eq $count ] ||
12803                         error "$writes writes in < $bsize bucket, expect $count"
12804         done
12805
12806         # Test mmap write and read
12807         $LCTL set_param llite.*.extents_stats=c
12808         size=512
12809         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12810         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12811         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12812
12813         $LCTL get_param llite.*.extents_stats
12814
12815         count=$(((size*1024) / PAGE_SIZE))
12816
12817         bsize=$((2 * PAGE_SIZE / 1024))K
12818
12819         bucket=$($LCTL get_param -n llite.*.extents_stats |
12820                         grep -m 1 $bsize)
12821         reads=$(echo $bucket | awk '{print $5}')
12822         writes=$(echo $bucket | awk '{print $9}')
12823         # mmap writes fault in the page first, creating an additonal read
12824         [ "$reads" -eq $((2 * count)) ] ||
12825                 error "$reads reads in < $bsize bucket, expect $count"
12826         [ "$writes" -eq $count ] ||
12827                 error "$writes writes in < $bsize bucket, expect $count"
12828 }
12829 run_test 127c "test llite extent stats with regular & mmap i/o"
12830
12831 test_128() { # bug 15212
12832         touch $DIR/$tfile
12833         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12834                 find $DIR/$tfile
12835                 find $DIR/$tfile
12836         EOF
12837
12838         result=$(grep error $TMP/$tfile.log)
12839         rm -f $DIR/$tfile $TMP/$tfile.log
12840         [ -z "$result" ] ||
12841                 error "consecutive find's under interactive lfs failed"
12842 }
12843 run_test 128 "interactive lfs for 2 consecutive find's"
12844
12845 set_dir_limits () {
12846         local mntdev
12847         local canondev
12848         local node
12849
12850         local ldproc=/proc/fs/ldiskfs
12851         local facets=$(get_facets MDS)
12852
12853         for facet in ${facets//,/ }; do
12854                 canondev=$(ldiskfs_canon \
12855                            *.$(convert_facet2label $facet).mntdev $facet)
12856                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12857                         ldproc=/sys/fs/ldiskfs
12858                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12859                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12860         done
12861 }
12862
12863 check_mds_dmesg() {
12864         local facets=$(get_facets MDS)
12865         for facet in ${facets//,/ }; do
12866                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12867         done
12868         return 1
12869 }
12870
12871 test_129() {
12872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12873         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12874                 skip "Need MDS version with at least 2.5.56"
12875         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12876                 skip_env "ldiskfs only test"
12877         fi
12878         remote_mds_nodsh && skip "remote MDS with nodsh"
12879
12880         local ENOSPC=28
12881         local has_warning=false
12882
12883         rm -rf $DIR/$tdir
12884         mkdir -p $DIR/$tdir
12885
12886         # block size of mds1
12887         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12888         set_dir_limits $maxsize $((maxsize * 6 / 8))
12889         stack_trap "set_dir_limits 0 0"
12890         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12891         local dirsize=$(stat -c%s "$DIR/$tdir")
12892         local nfiles=0
12893         while (( $dirsize <= $maxsize )); do
12894                 $MCREATE $DIR/$tdir/file_base_$nfiles
12895                 rc=$?
12896                 # check two errors:
12897                 # ENOSPC for ext4 max_dir_size, which has been used since
12898                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12899                 if (( rc == ENOSPC )); then
12900                         set_dir_limits 0 0
12901                         echo "rc=$rc returned as expected after $nfiles files"
12902
12903                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12904                                 error "create failed w/o dir size limit"
12905
12906                         # messages may be rate limited if test is run repeatedly
12907                         check_mds_dmesg '"is approaching max"' ||
12908                                 echo "warning message should be output"
12909                         check_mds_dmesg '"has reached max"' ||
12910                                 echo "reached message should be output"
12911
12912                         dirsize=$(stat -c%s "$DIR/$tdir")
12913
12914                         [[ $dirsize -ge $maxsize ]] && return 0
12915                         error "dirsize $dirsize < $maxsize after $nfiles files"
12916                 elif (( rc != 0 )); then
12917                         break
12918                 fi
12919                 nfiles=$((nfiles + 1))
12920                 dirsize=$(stat -c%s "$DIR/$tdir")
12921         done
12922
12923         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12924 }
12925 run_test 129 "test directory size limit ========================"
12926
12927 OLDIFS="$IFS"
12928 cleanup_130() {
12929         trap 0
12930         IFS="$OLDIFS"
12931 }
12932
12933 test_130a() {
12934         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12935         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12936
12937         trap cleanup_130 EXIT RETURN
12938
12939         local fm_file=$DIR/$tfile
12940         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12941         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12942                 error "dd failed for $fm_file"
12943
12944         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12945         filefrag -ves $fm_file
12946         RC=$?
12947         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12948                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12949         [ $RC != 0 ] && error "filefrag $fm_file failed"
12950
12951         filefrag_op=$(filefrag -ve -k $fm_file |
12952                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12953         lun=$($LFS getstripe -i $fm_file)
12954
12955         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12956         IFS=$'\n'
12957         tot_len=0
12958         for line in $filefrag_op
12959         do
12960                 frag_lun=`echo $line | cut -d: -f5`
12961                 ext_len=`echo $line | cut -d: -f4`
12962                 if (( $frag_lun != $lun )); then
12963                         cleanup_130
12964                         error "FIEMAP on 1-stripe file($fm_file) failed"
12965                         return
12966                 fi
12967                 (( tot_len += ext_len ))
12968         done
12969
12970         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12971                 cleanup_130
12972                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12973                 return
12974         fi
12975
12976         cleanup_130
12977
12978         echo "FIEMAP on single striped file succeeded"
12979 }
12980 run_test 130a "FIEMAP (1-stripe file)"
12981
12982 test_130b() {
12983         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12984
12985         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12986         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12987
12988         trap cleanup_130 EXIT RETURN
12989
12990         local fm_file=$DIR/$tfile
12991         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12992                         error "setstripe on $fm_file"
12993         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12994                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12995
12996         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12997                 error "dd failed on $fm_file"
12998
12999         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13000         filefrag_op=$(filefrag -ve -k $fm_file |
13001                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13002
13003         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13004                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13005
13006         IFS=$'\n'
13007         tot_len=0
13008         num_luns=1
13009         for line in $filefrag_op
13010         do
13011                 frag_lun=$(echo $line | cut -d: -f5 |
13012                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13013                 ext_len=$(echo $line | cut -d: -f4)
13014                 if (( $frag_lun != $last_lun )); then
13015                         if (( tot_len != 1024 )); then
13016                                 cleanup_130
13017                                 error "FIEMAP on $fm_file failed; returned " \
13018                                 "len $tot_len for OST $last_lun instead of 1024"
13019                                 return
13020                         else
13021                                 (( num_luns += 1 ))
13022                                 tot_len=0
13023                         fi
13024                 fi
13025                 (( tot_len += ext_len ))
13026                 last_lun=$frag_lun
13027         done
13028         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13029                 cleanup_130
13030                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13031                         "luns or wrong len for OST $last_lun"
13032                 return
13033         fi
13034
13035         cleanup_130
13036
13037         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13038 }
13039 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13040
13041 test_130c() {
13042         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13043
13044         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13045         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13046
13047         trap cleanup_130 EXIT RETURN
13048
13049         local fm_file=$DIR/$tfile
13050         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13051         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13052                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13053
13054         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13055                         error "dd failed on $fm_file"
13056
13057         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13058         filefrag_op=$(filefrag -ve -k $fm_file |
13059                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13060
13061         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13062                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13063
13064         IFS=$'\n'
13065         tot_len=0
13066         num_luns=1
13067         for line in $filefrag_op
13068         do
13069                 frag_lun=$(echo $line | cut -d: -f5 |
13070                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13071                 ext_len=$(echo $line | cut -d: -f4)
13072                 if (( $frag_lun != $last_lun )); then
13073                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13074                         if (( logical != 512 )); then
13075                                 cleanup_130
13076                                 error "FIEMAP on $fm_file failed; returned " \
13077                                 "logical start for lun $logical instead of 512"
13078                                 return
13079                         fi
13080                         if (( tot_len != 512 )); then
13081                                 cleanup_130
13082                                 error "FIEMAP on $fm_file failed; returned " \
13083                                 "len $tot_len for OST $last_lun instead of 1024"
13084                                 return
13085                         else
13086                                 (( num_luns += 1 ))
13087                                 tot_len=0
13088                         fi
13089                 fi
13090                 (( tot_len += ext_len ))
13091                 last_lun=$frag_lun
13092         done
13093         if (( num_luns != 2 || tot_len != 512 )); then
13094                 cleanup_130
13095                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13096                         "luns or wrong len for OST $last_lun"
13097                 return
13098         fi
13099
13100         cleanup_130
13101
13102         echo "FIEMAP on 2-stripe file with hole succeeded"
13103 }
13104 run_test 130c "FIEMAP (2-stripe file with hole)"
13105
13106 test_130d() {
13107         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13108
13109         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13110         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13111
13112         trap cleanup_130 EXIT RETURN
13113
13114         local fm_file=$DIR/$tfile
13115         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13116                         error "setstripe on $fm_file"
13117         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13118                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13119
13120         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13121         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13122                 error "dd failed on $fm_file"
13123
13124         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13125         filefrag_op=$(filefrag -ve -k $fm_file |
13126                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13127
13128         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13129                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13130
13131         IFS=$'\n'
13132         tot_len=0
13133         num_luns=1
13134         for line in $filefrag_op
13135         do
13136                 frag_lun=$(echo $line | cut -d: -f5 |
13137                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13138                 ext_len=$(echo $line | cut -d: -f4)
13139                 if (( $frag_lun != $last_lun )); then
13140                         if (( tot_len != 1024 )); then
13141                                 cleanup_130
13142                                 error "FIEMAP on $fm_file failed; returned " \
13143                                 "len $tot_len for OST $last_lun instead of 1024"
13144                                 return
13145                         else
13146                                 (( num_luns += 1 ))
13147                                 tot_len=0
13148                         fi
13149                 fi
13150                 (( tot_len += ext_len ))
13151                 last_lun=$frag_lun
13152         done
13153         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13154                 cleanup_130
13155                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13156                         "luns or wrong len for OST $last_lun"
13157                 return
13158         fi
13159
13160         cleanup_130
13161
13162         echo "FIEMAP on N-stripe file succeeded"
13163 }
13164 run_test 130d "FIEMAP (N-stripe file)"
13165
13166 test_130e() {
13167         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13168
13169         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13170         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13171
13172         trap cleanup_130 EXIT RETURN
13173
13174         local fm_file=$DIR/$tfile
13175         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13176
13177         NUM_BLKS=512
13178         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13179         for ((i = 0; i < $NUM_BLKS; i++)); do
13180                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13181                         conv=notrunc > /dev/null 2>&1
13182         done
13183
13184         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13185         filefrag_op=$(filefrag -ve -k $fm_file |
13186                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13187
13188         last_lun=$(echo $filefrag_op | cut -d: -f5)
13189
13190         IFS=$'\n'
13191         tot_len=0
13192         num_luns=1
13193         for line in $filefrag_op; do
13194                 frag_lun=$(echo $line | cut -d: -f5)
13195                 ext_len=$(echo $line | cut -d: -f4)
13196                 if [[ "$frag_lun" != "$last_lun" ]]; then
13197                         if (( tot_len != $EXPECTED_LEN )); then
13198                                 cleanup_130
13199                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13200                         else
13201                                 (( num_luns += 1 ))
13202                                 tot_len=0
13203                         fi
13204                 fi
13205                 (( tot_len += ext_len ))
13206                 last_lun=$frag_lun
13207         done
13208         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13209                 cleanup_130
13210                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13211         fi
13212
13213         echo "FIEMAP with continuation calls succeeded"
13214 }
13215 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13216
13217 test_130f() {
13218         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13219         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13220
13221         local fm_file=$DIR/$tfile
13222         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13223                 error "multiop create with lov_delay_create on $fm_file"
13224
13225         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13226         filefrag_extents=$(filefrag -vek $fm_file |
13227                            awk '/extents? found/ { print $2 }')
13228         if [[ "$filefrag_extents" != "0" ]]; then
13229                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13230         fi
13231
13232         rm -f $fm_file
13233 }
13234 run_test 130f "FIEMAP (unstriped file)"
13235
13236 test_130g() {
13237         local file=$DIR/$tfile
13238         local nr=$((OSTCOUNT * 100))
13239
13240         $LFS setstripe -C $nr $file ||
13241                 error "failed to setstripe -C $nr $file"
13242
13243         dd if=/dev/zero of=$file count=$nr bs=1M
13244         sync
13245         nr=$($LFS getstripe -c $file)
13246
13247         local extents=$(filefrag -v $file |
13248                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13249
13250         echo "filefrag list $extents extents in file with stripecount $nr"
13251         if (( extents < nr )); then
13252                 $LFS getstripe $file
13253                 filefrag -v $file
13254                 error "filefrag printed $extents < $nr extents"
13255         fi
13256
13257         rm -f $file
13258 }
13259 run_test 130g "FIEMAP (overstripe file)"
13260
13261 # Test for writev/readv
13262 test_131a() {
13263         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13264                 error "writev test failed"
13265         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13266                 error "readv failed"
13267         rm -f $DIR/$tfile
13268 }
13269 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13270
13271 test_131b() {
13272         local fsize=$((524288 + 1048576 + 1572864))
13273         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13274                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13275                         error "append writev test failed"
13276
13277         ((fsize += 1572864 + 1048576))
13278         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13279                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13280                         error "append writev test failed"
13281         rm -f $DIR/$tfile
13282 }
13283 run_test 131b "test append writev"
13284
13285 test_131c() {
13286         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13287         error "NOT PASS"
13288 }
13289 run_test 131c "test read/write on file w/o objects"
13290
13291 test_131d() {
13292         rwv -f $DIR/$tfile -w -n 1 1572864
13293         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13294         if [ "$NOB" != 1572864 ]; then
13295                 error "Short read filed: read $NOB bytes instead of 1572864"
13296         fi
13297         rm -f $DIR/$tfile
13298 }
13299 run_test 131d "test short read"
13300
13301 test_131e() {
13302         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13303         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13304         error "read hitting hole failed"
13305         rm -f $DIR/$tfile
13306 }
13307 run_test 131e "test read hitting hole"
13308
13309 check_stats() {
13310         local facet=$1
13311         local op=$2
13312         local want=${3:-0}
13313         local res
13314
13315         case $facet in
13316         mds*) res=$(do_facet $facet \
13317                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13318                  ;;
13319         ost*) res=$(do_facet $facet \
13320                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13321                  ;;
13322         *) error "Wrong facet '$facet'" ;;
13323         esac
13324         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13325         # if the argument $3 is zero, it means any stat increment is ok.
13326         if [[ $want -gt 0 ]]; then
13327                 local count=$(echo $res | awk '{ print $2 }')
13328                 [[ $count -ne $want ]] &&
13329                         error "The $op counter on $facet is $count, not $want"
13330         fi
13331 }
13332
13333 test_133a() {
13334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13335         remote_ost_nodsh && skip "remote OST with nodsh"
13336         remote_mds_nodsh && skip "remote MDS with nodsh"
13337         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13338                 skip_env "MDS doesn't support rename stats"
13339
13340         local testdir=$DIR/${tdir}/stats_testdir
13341
13342         mkdir -p $DIR/${tdir}
13343
13344         # clear stats.
13345         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13346         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13347
13348         # verify mdt stats first.
13349         mkdir ${testdir} || error "mkdir failed"
13350         check_stats $SINGLEMDS "mkdir" 1
13351         touch ${testdir}/${tfile} || error "touch failed"
13352         check_stats $SINGLEMDS "open" 1
13353         check_stats $SINGLEMDS "close" 1
13354         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13355                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13356                 check_stats $SINGLEMDS "mknod" 2
13357         }
13358         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13359         check_stats $SINGLEMDS "unlink" 1
13360         rm -f ${testdir}/${tfile} || error "file remove failed"
13361         check_stats $SINGLEMDS "unlink" 2
13362
13363         # remove working dir and check mdt stats again.
13364         rmdir ${testdir} || error "rmdir failed"
13365         check_stats $SINGLEMDS "rmdir" 1
13366
13367         local testdir1=$DIR/${tdir}/stats_testdir1
13368         mkdir -p ${testdir}
13369         mkdir -p ${testdir1}
13370         touch ${testdir1}/test1
13371         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13372         check_stats $SINGLEMDS "crossdir_rename" 1
13373
13374         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13375         check_stats $SINGLEMDS "samedir_rename" 1
13376
13377         rm -rf $DIR/${tdir}
13378 }
13379 run_test 133a "Verifying MDT stats ========================================"
13380
13381 test_133b() {
13382         local res
13383
13384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13385         remote_ost_nodsh && skip "remote OST with nodsh"
13386         remote_mds_nodsh && skip "remote MDS with nodsh"
13387
13388         local testdir=$DIR/${tdir}/stats_testdir
13389
13390         mkdir -p ${testdir} || error "mkdir failed"
13391         touch ${testdir}/${tfile} || error "touch failed"
13392         cancel_lru_locks mdc
13393
13394         # clear stats.
13395         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13396         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13397
13398         # extra mdt stats verification.
13399         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13400         check_stats $SINGLEMDS "setattr" 1
13401         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13402         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13403         then            # LU-1740
13404                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13405                 check_stats $SINGLEMDS "getattr" 1
13406         fi
13407         rm -rf $DIR/${tdir}
13408
13409         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13410         # so the check below is not reliable
13411         [ $MDSCOUNT -eq 1 ] || return 0
13412
13413         # Sleep to avoid a cached response.
13414         #define OBD_STATFS_CACHE_SECONDS 1
13415         sleep 2
13416         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13417         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13418         $LFS df || error "lfs failed"
13419         check_stats $SINGLEMDS "statfs" 1
13420
13421         # check aggregated statfs (LU-10018)
13422         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13423                 return 0
13424         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13425                 return 0
13426         sleep 2
13427         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13428         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13429         df $DIR
13430         check_stats $SINGLEMDS "statfs" 1
13431
13432         # We want to check that the client didn't send OST_STATFS to
13433         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13434         # extra care is needed here.
13435         if remote_mds; then
13436                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13437                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13438
13439                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13440                 [ "$res" ] && error "OST got STATFS"
13441         fi
13442
13443         return 0
13444 }
13445 run_test 133b "Verifying extra MDT stats =================================="
13446
13447 test_133c() {
13448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13449         remote_ost_nodsh && skip "remote OST with nodsh"
13450         remote_mds_nodsh && skip "remote MDS with nodsh"
13451
13452         local testdir=$DIR/$tdir/stats_testdir
13453
13454         test_mkdir -p $testdir
13455
13456         # verify obdfilter stats.
13457         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13458         sync
13459         cancel_lru_locks osc
13460         wait_delete_completed
13461
13462         # clear stats.
13463         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13464         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13465
13466         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13467                 error "dd failed"
13468         sync
13469         cancel_lru_locks osc
13470         check_stats ost1 "write" 1
13471
13472         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13473         check_stats ost1 "read" 1
13474
13475         > $testdir/$tfile || error "truncate failed"
13476         check_stats ost1 "punch" 1
13477
13478         rm -f $testdir/$tfile || error "file remove failed"
13479         wait_delete_completed
13480         check_stats ost1 "destroy" 1
13481
13482         rm -rf $DIR/$tdir
13483 }
13484 run_test 133c "Verifying OST stats ========================================"
13485
13486 order_2() {
13487         local value=$1
13488         local orig=$value
13489         local order=1
13490
13491         while [ $value -ge 2 ]; do
13492                 order=$((order*2))
13493                 value=$((value/2))
13494         done
13495
13496         if [ $orig -gt $order ]; then
13497                 order=$((order*2))
13498         fi
13499         echo $order
13500 }
13501
13502 size_in_KMGT() {
13503     local value=$1
13504     local size=('K' 'M' 'G' 'T');
13505     local i=0
13506     local size_string=$value
13507
13508     while [ $value -ge 1024 ]; do
13509         if [ $i -gt 3 ]; then
13510             #T is the biggest unit we get here, if that is bigger,
13511             #just return XXXT
13512             size_string=${value}T
13513             break
13514         fi
13515         value=$((value >> 10))
13516         if [ $value -lt 1024 ]; then
13517             size_string=${value}${size[$i]}
13518             break
13519         fi
13520         i=$((i + 1))
13521     done
13522
13523     echo $size_string
13524 }
13525
13526 get_rename_size() {
13527         local size=$1
13528         local context=${2:-.}
13529         local sample=$(do_facet $SINGLEMDS $LCTL \
13530                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13531                 grep -A1 $context |
13532                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13533         echo $sample
13534 }
13535
13536 test_133d() {
13537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13538         remote_ost_nodsh && skip "remote OST with nodsh"
13539         remote_mds_nodsh && skip "remote MDS with nodsh"
13540         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13541                 skip_env "MDS doesn't support rename stats"
13542
13543         local testdir1=$DIR/${tdir}/stats_testdir1
13544         local testdir2=$DIR/${tdir}/stats_testdir2
13545         mkdir -p $DIR/${tdir}
13546
13547         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13548
13549         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13550         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13551
13552         createmany -o $testdir1/test 512 || error "createmany failed"
13553
13554         # check samedir rename size
13555         mv ${testdir1}/test0 ${testdir1}/test_0
13556
13557         local testdir1_size=$(ls -l $DIR/${tdir} |
13558                 awk '/stats_testdir1/ {print $5}')
13559         local testdir2_size=$(ls -l $DIR/${tdir} |
13560                 awk '/stats_testdir2/ {print $5}')
13561
13562         testdir1_size=$(order_2 $testdir1_size)
13563         testdir2_size=$(order_2 $testdir2_size)
13564
13565         testdir1_size=$(size_in_KMGT $testdir1_size)
13566         testdir2_size=$(size_in_KMGT $testdir2_size)
13567
13568         echo "source rename dir size: ${testdir1_size}"
13569         echo "target rename dir size: ${testdir2_size}"
13570
13571         local cmd="do_facet $SINGLEMDS $LCTL "
13572         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13573
13574         eval $cmd || error "$cmd failed"
13575         local samedir=$($cmd | grep 'same_dir')
13576         local same_sample=$(get_rename_size $testdir1_size)
13577         [ -z "$samedir" ] && error "samedir_rename_size count error"
13578         [[ $same_sample -eq 1 ]] ||
13579                 error "samedir_rename_size error $same_sample"
13580         echo "Check same dir rename stats success"
13581
13582         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13583
13584         # check crossdir rename size
13585         mv ${testdir1}/test_0 ${testdir2}/test_0
13586
13587         testdir1_size=$(ls -l $DIR/${tdir} |
13588                 awk '/stats_testdir1/ {print $5}')
13589         testdir2_size=$(ls -l $DIR/${tdir} |
13590                 awk '/stats_testdir2/ {print $5}')
13591
13592         testdir1_size=$(order_2 $testdir1_size)
13593         testdir2_size=$(order_2 $testdir2_size)
13594
13595         testdir1_size=$(size_in_KMGT $testdir1_size)
13596         testdir2_size=$(size_in_KMGT $testdir2_size)
13597
13598         echo "source rename dir size: ${testdir1_size}"
13599         echo "target rename dir size: ${testdir2_size}"
13600
13601         eval $cmd || error "$cmd failed"
13602         local crossdir=$($cmd | grep 'crossdir')
13603         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13604         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13605         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13606         [[ $src_sample -eq 1 ]] ||
13607                 error "crossdir_rename_size error $src_sample"
13608         [[ $tgt_sample -eq 1 ]] ||
13609                 error "crossdir_rename_size error $tgt_sample"
13610         echo "Check cross dir rename stats success"
13611         rm -rf $DIR/${tdir}
13612 }
13613 run_test 133d "Verifying rename_stats ========================================"
13614
13615 test_133e() {
13616         remote_mds_nodsh && skip "remote MDS with nodsh"
13617         remote_ost_nodsh && skip "remote OST with nodsh"
13618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13619
13620         local testdir=$DIR/${tdir}/stats_testdir
13621         local ctr f0 f1 bs=32768 count=42 sum
13622
13623         mkdir -p ${testdir} || error "mkdir failed"
13624
13625         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13626
13627         for ctr in {write,read}_bytes; do
13628                 sync
13629                 cancel_lru_locks osc
13630
13631                 do_facet ost1 $LCTL set_param -n \
13632                         "obdfilter.*.exports.clear=clear"
13633
13634                 if [ $ctr = write_bytes ]; then
13635                         f0=/dev/zero
13636                         f1=${testdir}/${tfile}
13637                 else
13638                         f0=${testdir}/${tfile}
13639                         f1=/dev/null
13640                 fi
13641
13642                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13643                         error "dd failed"
13644                 sync
13645                 cancel_lru_locks osc
13646
13647                 sum=$(do_facet ost1 $LCTL get_param \
13648                         "obdfilter.*.exports.*.stats" |
13649                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13650                                 $1 == ctr { sum += $7 }
13651                                 END { printf("%0.0f", sum) }')
13652
13653                 if ((sum != bs * count)); then
13654                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13655                 fi
13656         done
13657
13658         rm -rf $DIR/${tdir}
13659 }
13660 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13661
13662 test_133f() {
13663         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13664                 skip "too old lustre for get_param -R ($facet_ver)"
13665
13666         # verifying readability.
13667         $LCTL get_param -R '*' &> /dev/null
13668
13669         # Verifing writability with badarea_io.
13670         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13671                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13672                 error "client badarea_io failed"
13673
13674         # remount the FS in case writes/reads /proc break the FS
13675         cleanup || error "failed to unmount"
13676         setup || error "failed to setup"
13677 }
13678 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13679
13680 test_133g() {
13681         remote_mds_nodsh && skip "remote MDS with nodsh"
13682         remote_ost_nodsh && skip "remote OST with nodsh"
13683
13684         local facet
13685         for facet in mds1 ost1; do
13686                 local facet_ver=$(lustre_version_code $facet)
13687                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13688                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13689                 else
13690                         log "$facet: too old lustre for get_param -R"
13691                 fi
13692                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13693                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13694                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13695                                 xargs badarea_io" ||
13696                                         error "$facet badarea_io failed"
13697                 else
13698                         skip_noexit "$facet: too old lustre for get_param -R"
13699                 fi
13700         done
13701
13702         # remount the FS in case writes/reads /proc break the FS
13703         cleanup || error "failed to unmount"
13704         setup || error "failed to setup"
13705 }
13706 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13707
13708 test_133h() {
13709         remote_mds_nodsh && skip "remote MDS with nodsh"
13710         remote_ost_nodsh && skip "remote OST with nodsh"
13711         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13712                 skip "Need MDS version at least 2.9.54"
13713
13714         local facet
13715         for facet in client mds1 ost1; do
13716                 # Get the list of files that are missing the terminating newline
13717                 local plist=$(do_facet $facet
13718                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13719                 local ent
13720                 for ent in $plist; do
13721                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13722                                 awk -v FS='\v' -v RS='\v\v' \
13723                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13724                                         print FILENAME}'" 2>/dev/null)
13725                         [ -z $missing ] || {
13726                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13727                                 error "file does not end with newline: $facet-$ent"
13728                         }
13729                 done
13730         done
13731 }
13732 run_test 133h "Proc files should end with newlines"
13733
13734 test_134a() {
13735         remote_mds_nodsh && skip "remote MDS with nodsh"
13736         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13737                 skip "Need MDS version at least 2.7.54"
13738
13739         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13740         cancel_lru_locks mdc
13741
13742         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13743         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13744         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13745
13746         local nr=1000
13747         createmany -o $DIR/$tdir/f $nr ||
13748                 error "failed to create $nr files in $DIR/$tdir"
13749         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13750
13751         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13752         do_facet mds1 $LCTL set_param fail_loc=0x327
13753         do_facet mds1 $LCTL set_param fail_val=500
13754         touch $DIR/$tdir/m
13755
13756         echo "sleep 10 seconds ..."
13757         sleep 10
13758         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13759
13760         do_facet mds1 $LCTL set_param fail_loc=0
13761         do_facet mds1 $LCTL set_param fail_val=0
13762         [ $lck_cnt -lt $unused ] ||
13763                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13764
13765         rm $DIR/$tdir/m
13766         unlinkmany $DIR/$tdir/f $nr
13767 }
13768 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13769
13770 test_134b() {
13771         remote_mds_nodsh && skip "remote MDS with nodsh"
13772         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13773                 skip "Need MDS version at least 2.7.54"
13774
13775         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13776         cancel_lru_locks mdc
13777
13778         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13779                         ldlm.lock_reclaim_threshold_mb)
13780         # disable reclaim temporarily
13781         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13782
13783         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13784         do_facet mds1 $LCTL set_param fail_loc=0x328
13785         do_facet mds1 $LCTL set_param fail_val=500
13786
13787         $LCTL set_param debug=+trace
13788
13789         local nr=600
13790         createmany -o $DIR/$tdir/f $nr &
13791         local create_pid=$!
13792
13793         echo "Sleep $TIMEOUT seconds ..."
13794         sleep $TIMEOUT
13795         if ! ps -p $create_pid  > /dev/null 2>&1; then
13796                 do_facet mds1 $LCTL set_param fail_loc=0
13797                 do_facet mds1 $LCTL set_param fail_val=0
13798                 do_facet mds1 $LCTL set_param \
13799                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13800                 error "createmany finished incorrectly!"
13801         fi
13802         do_facet mds1 $LCTL set_param fail_loc=0
13803         do_facet mds1 $LCTL set_param fail_val=0
13804         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13805         wait $create_pid || return 1
13806
13807         unlinkmany $DIR/$tdir/f $nr
13808 }
13809 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13810
13811 test_135() {
13812         remote_mds_nodsh && skip "remote MDS with nodsh"
13813         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13814                 skip "Need MDS version at least 2.13.50"
13815         local fname
13816
13817         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13818
13819 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13820         #set only one record at plain llog
13821         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13822
13823         #fill already existed plain llog each 64767
13824         #wrapping whole catalog
13825         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13826
13827         createmany -o $DIR/$tdir/$tfile_ 64700
13828         for (( i = 0; i < 64700; i = i + 2 ))
13829         do
13830                 rm $DIR/$tdir/$tfile_$i &
13831                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13832                 local pid=$!
13833                 wait $pid
13834         done
13835
13836         #waiting osp synchronization
13837         wait_delete_completed
13838 }
13839 run_test 135 "Race catalog processing"
13840
13841 test_136() {
13842         remote_mds_nodsh && skip "remote MDS with nodsh"
13843         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13844                 skip "Need MDS version at least 2.13.50"
13845         local fname
13846
13847         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13848         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13849         #set only one record at plain llog
13850 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13851         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13852
13853         #fill already existed 2 plain llogs each 64767
13854         #wrapping whole catalog
13855         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13856         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13857         wait_delete_completed
13858
13859         createmany -o $DIR/$tdir/$tfile_ 10
13860         sleep 25
13861
13862         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13863         for (( i = 0; i < 10; i = i + 3 ))
13864         do
13865                 rm $DIR/$tdir/$tfile_$i &
13866                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13867                 local pid=$!
13868                 wait $pid
13869                 sleep 7
13870                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13871         done
13872
13873         #waiting osp synchronization
13874         wait_delete_completed
13875 }
13876 run_test 136 "Race catalog processing 2"
13877
13878 test_140() { #bug-17379
13879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13880
13881         test_mkdir $DIR/$tdir
13882         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13883         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13884
13885         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13886         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13887         local i=0
13888         while i=$((i + 1)); do
13889                 test_mkdir $i
13890                 cd $i || error "Changing to $i"
13891                 ln -s ../stat stat || error "Creating stat symlink"
13892                 # Read the symlink until ELOOP present,
13893                 # not LBUGing the system is considered success,
13894                 # we didn't overrun the stack.
13895                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13896                 if [ $ret -ne 0 ]; then
13897                         if [ $ret -eq 40 ]; then
13898                                 break  # -ELOOP
13899                         else
13900                                 error "Open stat symlink"
13901                                         return
13902                         fi
13903                 fi
13904         done
13905         i=$((i - 1))
13906         echo "The symlink depth = $i"
13907         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13908                 error "Invalid symlink depth"
13909
13910         # Test recursive symlink
13911         ln -s symlink_self symlink_self
13912         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13913         echo "open symlink_self returns $ret"
13914         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13915 }
13916 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13917
13918 test_150a() {
13919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13920
13921         local TF="$TMP/$tfile"
13922
13923         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13924         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13925         cp $TF $DIR/$tfile
13926         cancel_lru_locks $OSC
13927         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13928         remount_client $MOUNT
13929         df -P $MOUNT
13930         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13931
13932         $TRUNCATE $TF 6000
13933         $TRUNCATE $DIR/$tfile 6000
13934         cancel_lru_locks $OSC
13935         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13936
13937         echo "12345" >>$TF
13938         echo "12345" >>$DIR/$tfile
13939         cancel_lru_locks $OSC
13940         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13941
13942         echo "12345" >>$TF
13943         echo "12345" >>$DIR/$tfile
13944         cancel_lru_locks $OSC
13945         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13946 }
13947 run_test 150a "truncate/append tests"
13948
13949 test_150b() {
13950         check_set_fallocate_or_skip
13951
13952         touch $DIR/$tfile
13953         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13954         check_fallocate $DIR/$tfile || error "fallocate failed"
13955 }
13956 run_test 150b "Verify fallocate (prealloc) functionality"
13957
13958 test_150bb() {
13959         check_set_fallocate_or_skip
13960
13961         touch $DIR/$tfile
13962         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13963         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
13964         > $DIR/$tfile
13965         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13966         # precomputed md5sum for 20MB of zeroes
13967         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
13968         local sum=($(md5sum $DIR/$tfile))
13969
13970         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
13971
13972         check_set_fallocate 1
13973
13974         > $DIR/$tfile
13975         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
13976         sum=($(md5sum $DIR/$tfile))
13977
13978         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
13979 }
13980 run_test 150bb "Verify fallocate modes both zero space"
13981
13982 test_150c() {
13983         check_set_fallocate_or_skip
13984
13985         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
13986         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13987         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13988         sync; sync_all_data
13989         cancel_lru_locks $OSC
13990         sleep 5
13991         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13992         want=$((OSTCOUNT * 1048576))
13993
13994         # Must allocate all requested space, not more than 5% extra
13995         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13996                 error "bytes $bytes is not $want"
13997
13998         rm -f $DIR/$tfile
13999         # verify fallocate on PFL file
14000         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14001                 error "Create $DIR/$tfile failed"
14002         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
14003                         error "fallocate failed"
14004         sync; sync_all_data
14005         cancel_lru_locks $OSC
14006         sleep 5
14007         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14008         local want=$((1024 * 1048576))
14009
14010         # Must allocate all requested space, not more than 5% extra
14011         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14012                 error "bytes $bytes is not $want"
14013 }
14014 run_test 150c "Verify fallocate Size and Blocks"
14015
14016 test_150d() {
14017         check_set_fallocate_or_skip
14018
14019         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14020         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
14021         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14022         sync; sync_all_data
14023         cancel_lru_locks $OSC
14024         sleep 5
14025         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14026         local want=$((OSTCOUNT * 1048576))
14027
14028         # Must allocate all requested space, not more than 5% extra
14029         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14030                 error "bytes $bytes is not $want"
14031 }
14032 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14033
14034 test_150e() {
14035         check_set_fallocate_or_skip
14036
14037         echo "df before:"
14038         $LFS df
14039         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14040         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14041                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14042
14043         # Find OST with Minimum Size
14044         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14045                        sort -un | head -1)
14046
14047         # Get 100MB per OST of the available space to reduce run time
14048         # else 60% of the available space if we are running SLOW tests
14049         if [ $SLOW == "no" ]; then
14050                 local space=$((1024 * 100 * OSTCOUNT))
14051         else
14052                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14053         fi
14054
14055         fallocate -l${space}k $DIR/$tfile ||
14056                 error "fallocate ${space}k $DIR/$tfile failed"
14057         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14058
14059         # get size immediately after fallocate. This should be correctly
14060         # updated
14061         local size=$(stat -c '%s' $DIR/$tfile)
14062         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14063
14064         # Sleep for a while for statfs to get updated. And not pull from cache.
14065         sleep 2
14066
14067         echo "df after fallocate:"
14068         $LFS df
14069
14070         (( size / 1024 == space )) || error "size $size != requested $space"
14071         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14072                 error "used $used < space $space"
14073
14074         rm $DIR/$tfile || error "rm failed"
14075         sync
14076         wait_delete_completed
14077
14078         echo "df after unlink:"
14079         $LFS df
14080 }
14081 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14082
14083 test_150f() {
14084         local size
14085         local blocks
14086         local want_size_before=20480 # in bytes
14087         local want_blocks_before=40 # 512 sized blocks
14088         local want_blocks_after=24  # 512 sized blocks
14089         local length=$(((want_blocks_before - want_blocks_after) * 512))
14090
14091         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14092                 skip "need at least 2.14.0 for fallocate punch"
14093
14094         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14095                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14096         fi
14097
14098         check_set_fallocate_or_skip
14099         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14100
14101         echo "Verify fallocate punch: Range within the file range"
14102         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14103                 error "dd failed for bs 4096 and count 5"
14104
14105         # Call fallocate with punch range which is within the file range
14106         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14107                 error "fallocate failed: offset 4096 and length $length"
14108         # client must see changes immediately after fallocate
14109         size=$(stat -c '%s' $DIR/$tfile)
14110         blocks=$(stat -c '%b' $DIR/$tfile)
14111
14112         # Verify punch worked.
14113         (( blocks == want_blocks_after )) ||
14114                 error "punch failed: blocks $blocks != $want_blocks_after"
14115
14116         (( size == want_size_before )) ||
14117                 error "punch failed: size $size != $want_size_before"
14118
14119         # Verify there is hole in file
14120         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14121         # precomputed md5sum
14122         local expect="4a9a834a2db02452929c0a348273b4aa"
14123
14124         cksum=($(md5sum $DIR/$tfile))
14125         [[ "${cksum[0]}" == "$expect" ]] ||
14126                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14127
14128         # Start second sub-case for fallocate punch.
14129         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14130         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14131                 error "dd failed for bs 4096 and count 5"
14132
14133         # Punch range less than block size will have no change in block count
14134         want_blocks_after=40  # 512 sized blocks
14135
14136         # Punch overlaps two blocks and less than blocksize
14137         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14138                 error "fallocate failed: offset 4000 length 3000"
14139         size=$(stat -c '%s' $DIR/$tfile)
14140         blocks=$(stat -c '%b' $DIR/$tfile)
14141
14142         # Verify punch worked.
14143         (( blocks == want_blocks_after )) ||
14144                 error "punch failed: blocks $blocks != $want_blocks_after"
14145
14146         (( size == want_size_before )) ||
14147                 error "punch failed: size $size != $want_size_before"
14148
14149         # Verify if range is really zero'ed out. We expect Zeros.
14150         # precomputed md5sum
14151         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14152         cksum=($(md5sum $DIR/$tfile))
14153         [[ "${cksum[0]}" == "$expect" ]] ||
14154                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14155 }
14156 run_test 150f "Verify fallocate punch functionality"
14157
14158 test_150g() {
14159         local space
14160         local size
14161         local blocks
14162         local blocks_after
14163         local size_after
14164         local BS=4096 # Block size in bytes
14165
14166         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14167                 skip "need at least 2.14.0 for fallocate punch"
14168
14169         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14170                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14171         fi
14172
14173         check_set_fallocate_or_skip
14174         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14175
14176         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14177                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14178
14179         # Get 100MB per OST of the available space to reduce run time
14180         # else 60% of the available space if we are running SLOW tests
14181         if [ $SLOW == "no" ]; then
14182                 space=$((1024 * 100 * OSTCOUNT))
14183         else
14184                 # Find OST with Minimum Size
14185                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14186                         sort -un | head -1)
14187                 echo "min size OST: $space"
14188                 space=$(((space * 60)/100 * OSTCOUNT))
14189         fi
14190         # space in 1k units, round to 4k blocks
14191         local blkcount=$((space * 1024 / $BS))
14192
14193         echo "Verify fallocate punch: Very large Range"
14194         fallocate -l${space}k $DIR/$tfile ||
14195                 error "fallocate ${space}k $DIR/$tfile failed"
14196         # write 1M at the end, start and in the middle
14197         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14198                 error "dd failed: bs $BS count 256"
14199         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14200                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14201         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14202                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14203
14204         # Gather stats.
14205         size=$(stat -c '%s' $DIR/$tfile)
14206
14207         # gather punch length.
14208         local punch_size=$((size - (BS * 2)))
14209
14210         echo "punch_size = $punch_size"
14211         echo "size - punch_size: $((size - punch_size))"
14212         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14213
14214         # Call fallocate to punch all except 2 blocks. We leave the
14215         # first and the last block
14216         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14217         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14218                 error "fallocate failed: offset $BS length $punch_size"
14219
14220         size_after=$(stat -c '%s' $DIR/$tfile)
14221         blocks_after=$(stat -c '%b' $DIR/$tfile)
14222
14223         # Verify punch worked.
14224         # Size should be kept
14225         (( size == size_after )) ||
14226                 error "punch failed: size $size != $size_after"
14227
14228         # two 4k data blocks to remain plus possible 1 extra extent block
14229         (( blocks_after <= ((BS / 512) * 3) )) ||
14230                 error "too many blocks remains: $blocks_after"
14231
14232         # Verify that file has hole between the first and the last blocks
14233         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14234         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14235
14236         echo "Hole at [$hole_start, $hole_end)"
14237         (( hole_start == BS )) ||
14238                 error "no hole at offset $BS after punch"
14239
14240         (( hole_end == BS + punch_size )) ||
14241                 error "data at offset $hole_end < $((BS + punch_size))"
14242 }
14243 run_test 150g "Verify fallocate punch on large range"
14244
14245 #LU-2902 roc_hit was not able to read all values from lproc
14246 function roc_hit_init() {
14247         local list=$(comma_list $(osts_nodes))
14248         local dir=$DIR/$tdir-check
14249         local file=$dir/$tfile
14250         local BEFORE
14251         local AFTER
14252         local idx
14253
14254         test_mkdir $dir
14255         #use setstripe to do a write to every ost
14256         for i in $(seq 0 $((OSTCOUNT-1))); do
14257                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14258                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14259                 idx=$(printf %04x $i)
14260                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14261                         awk '$1 == "cache_access" {sum += $7}
14262                                 END { printf("%0.0f", sum) }')
14263
14264                 cancel_lru_locks osc
14265                 cat $file >/dev/null
14266
14267                 AFTER=$(get_osd_param $list *OST*$idx stats |
14268                         awk '$1 == "cache_access" {sum += $7}
14269                                 END { printf("%0.0f", sum) }')
14270
14271                 echo BEFORE:$BEFORE AFTER:$AFTER
14272                 if ! let "AFTER - BEFORE == 4"; then
14273                         rm -rf $dir
14274                         error "roc_hit is not safe to use"
14275                 fi
14276                 rm $file
14277         done
14278
14279         rm -rf $dir
14280 }
14281
14282 function roc_hit() {
14283         local list=$(comma_list $(osts_nodes))
14284         echo $(get_osd_param $list '' stats |
14285                 awk '$1 == "cache_hit" {sum += $7}
14286                         END { printf("%0.0f", sum) }')
14287 }
14288
14289 function set_cache() {
14290         local on=1
14291
14292         if [ "$2" == "off" ]; then
14293                 on=0;
14294         fi
14295         local list=$(comma_list $(osts_nodes))
14296         set_osd_param $list '' $1_cache_enable $on
14297
14298         cancel_lru_locks osc
14299 }
14300
14301 test_151() {
14302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14303         remote_ost_nodsh && skip "remote OST with nodsh"
14304
14305         local CPAGES=3
14306         local list=$(comma_list $(osts_nodes))
14307
14308         # check whether obdfilter is cache capable at all
14309         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14310                 skip "not cache-capable obdfilter"
14311         fi
14312
14313         # check cache is enabled on all obdfilters
14314         if get_osd_param $list '' read_cache_enable | grep 0; then
14315                 skip "oss cache is disabled"
14316         fi
14317
14318         set_osd_param $list '' writethrough_cache_enable 1
14319
14320         # check write cache is enabled on all obdfilters
14321         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14322                 skip "oss write cache is NOT enabled"
14323         fi
14324
14325         roc_hit_init
14326
14327         #define OBD_FAIL_OBD_NO_LRU  0x609
14328         do_nodes $list $LCTL set_param fail_loc=0x609
14329
14330         # pages should be in the case right after write
14331         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14332                 error "dd failed"
14333
14334         local BEFORE=$(roc_hit)
14335         cancel_lru_locks osc
14336         cat $DIR/$tfile >/dev/null
14337         local AFTER=$(roc_hit)
14338
14339         do_nodes $list $LCTL set_param fail_loc=0
14340
14341         if ! let "AFTER - BEFORE == CPAGES"; then
14342                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14343         fi
14344
14345         cancel_lru_locks osc
14346         # invalidates OST cache
14347         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14348         set_osd_param $list '' read_cache_enable 0
14349         cat $DIR/$tfile >/dev/null
14350
14351         # now data shouldn't be found in the cache
14352         BEFORE=$(roc_hit)
14353         cancel_lru_locks osc
14354         cat $DIR/$tfile >/dev/null
14355         AFTER=$(roc_hit)
14356         if let "AFTER - BEFORE != 0"; then
14357                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14358         fi
14359
14360         set_osd_param $list '' read_cache_enable 1
14361         rm -f $DIR/$tfile
14362 }
14363 run_test 151 "test cache on oss and controls ==============================="
14364
14365 test_152() {
14366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14367
14368         local TF="$TMP/$tfile"
14369
14370         # simulate ENOMEM during write
14371 #define OBD_FAIL_OST_NOMEM      0x226
14372         lctl set_param fail_loc=0x80000226
14373         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14374         cp $TF $DIR/$tfile
14375         sync || error "sync failed"
14376         lctl set_param fail_loc=0
14377
14378         # discard client's cache
14379         cancel_lru_locks osc
14380
14381         # simulate ENOMEM during read
14382         lctl set_param fail_loc=0x80000226
14383         cmp $TF $DIR/$tfile || error "cmp failed"
14384         lctl set_param fail_loc=0
14385
14386         rm -f $TF
14387 }
14388 run_test 152 "test read/write with enomem ============================"
14389
14390 test_153() {
14391         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14392 }
14393 run_test 153 "test if fdatasync does not crash ======================="
14394
14395 dot_lustre_fid_permission_check() {
14396         local fid=$1
14397         local ffid=$MOUNT/.lustre/fid/$fid
14398         local test_dir=$2
14399
14400         echo "stat fid $fid"
14401         stat $ffid > /dev/null || error "stat $ffid failed."
14402         echo "touch fid $fid"
14403         touch $ffid || error "touch $ffid failed."
14404         echo "write to fid $fid"
14405         cat /etc/hosts > $ffid || error "write $ffid failed."
14406         echo "read fid $fid"
14407         diff /etc/hosts $ffid || error "read $ffid failed."
14408         echo "append write to fid $fid"
14409         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14410         echo "rename fid $fid"
14411         mv $ffid $test_dir/$tfile.1 &&
14412                 error "rename $ffid to $tfile.1 should fail."
14413         touch $test_dir/$tfile.1
14414         mv $test_dir/$tfile.1 $ffid &&
14415                 error "rename $tfile.1 to $ffid should fail."
14416         rm -f $test_dir/$tfile.1
14417         echo "truncate fid $fid"
14418         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14419         echo "link fid $fid"
14420         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14421         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14422                 echo "setfacl fid $fid"
14423                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14424                 echo "getfacl fid $fid"
14425                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14426         fi
14427         echo "unlink fid $fid"
14428         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14429         echo "mknod fid $fid"
14430         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14431
14432         fid=[0xf00000400:0x1:0x0]
14433         ffid=$MOUNT/.lustre/fid/$fid
14434
14435         echo "stat non-exist fid $fid"
14436         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14437         echo "write to non-exist fid $fid"
14438         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14439         echo "link new fid $fid"
14440         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14441
14442         mkdir -p $test_dir/$tdir
14443         touch $test_dir/$tdir/$tfile
14444         fid=$($LFS path2fid $test_dir/$tdir)
14445         rc=$?
14446         [ $rc -ne 0 ] &&
14447                 error "error: could not get fid for $test_dir/$dir/$tfile."
14448
14449         ffid=$MOUNT/.lustre/fid/$fid
14450
14451         echo "ls $fid"
14452         ls $ffid > /dev/null || error "ls $ffid failed."
14453         echo "touch $fid/$tfile.1"
14454         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14455
14456         echo "touch $MOUNT/.lustre/fid/$tfile"
14457         touch $MOUNT/.lustre/fid/$tfile && \
14458                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14459
14460         echo "setxattr to $MOUNT/.lustre/fid"
14461         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14462
14463         echo "listxattr for $MOUNT/.lustre/fid"
14464         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14465
14466         echo "delxattr from $MOUNT/.lustre/fid"
14467         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14468
14469         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14470         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14471                 error "touch invalid fid should fail."
14472
14473         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14474         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14475                 error "touch non-normal fid should fail."
14476
14477         echo "rename $tdir to $MOUNT/.lustre/fid"
14478         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14479                 error "rename to $MOUNT/.lustre/fid should fail."
14480
14481         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14482         then            # LU-3547
14483                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14484                 local new_obf_mode=777
14485
14486                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14487                 chmod $new_obf_mode $DIR/.lustre/fid ||
14488                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14489
14490                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14491                 [ $obf_mode -eq $new_obf_mode ] ||
14492                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14493
14494                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14495                 chmod $old_obf_mode $DIR/.lustre/fid ||
14496                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14497         fi
14498
14499         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14500         fid=$($LFS path2fid $test_dir/$tfile-2)
14501
14502         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14503         then # LU-5424
14504                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14505                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14506                         error "create lov data thru .lustre failed"
14507         fi
14508         echo "cp /etc/passwd $test_dir/$tfile-2"
14509         cp /etc/passwd $test_dir/$tfile-2 ||
14510                 error "copy to $test_dir/$tfile-2 failed."
14511         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14512         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14513                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14514
14515         rm -rf $test_dir/tfile.lnk
14516         rm -rf $test_dir/$tfile-2
14517 }
14518
14519 test_154A() {
14520         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14521                 skip "Need MDS version at least 2.4.1"
14522
14523         local tf=$DIR/$tfile
14524         touch $tf
14525
14526         local fid=$($LFS path2fid $tf)
14527         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14528
14529         # check that we get the same pathname back
14530         local rootpath
14531         local found
14532         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14533                 echo "$rootpath $fid"
14534                 found=$($LFS fid2path $rootpath "$fid")
14535                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14536                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14537         done
14538
14539         # check wrong root path format
14540         rootpath=$MOUNT"_wrong"
14541         found=$($LFS fid2path $rootpath "$fid")
14542         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14543 }
14544 run_test 154A "lfs path2fid and fid2path basic checks"
14545
14546 test_154B() {
14547         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14548                 skip "Need MDS version at least 2.4.1"
14549
14550         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14551         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14552         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14553         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14554
14555         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14556         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14557
14558         # check that we get the same pathname
14559         echo "PFID: $PFID, name: $name"
14560         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14561         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14562         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14563                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14564
14565         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14566 }
14567 run_test 154B "verify the ll_decode_linkea tool"
14568
14569 test_154a() {
14570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14571         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14572         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14573                 skip "Need MDS version at least 2.2.51"
14574         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14575
14576         cp /etc/hosts $DIR/$tfile
14577
14578         fid=$($LFS path2fid $DIR/$tfile)
14579         rc=$?
14580         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14581
14582         dot_lustre_fid_permission_check "$fid" $DIR ||
14583                 error "dot lustre permission check $fid failed"
14584
14585         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14586
14587         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14588
14589         touch $MOUNT/.lustre/file &&
14590                 error "creation is not allowed under .lustre"
14591
14592         mkdir $MOUNT/.lustre/dir &&
14593                 error "mkdir is not allowed under .lustre"
14594
14595         rm -rf $DIR/$tfile
14596 }
14597 run_test 154a "Open-by-FID"
14598
14599 test_154b() {
14600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14601         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14602         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14603         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14604                 skip "Need MDS version at least 2.2.51"
14605
14606         local remote_dir=$DIR/$tdir/remote_dir
14607         local MDTIDX=1
14608         local rc=0
14609
14610         mkdir -p $DIR/$tdir
14611         $LFS mkdir -i $MDTIDX $remote_dir ||
14612                 error "create remote directory failed"
14613
14614         cp /etc/hosts $remote_dir/$tfile
14615
14616         fid=$($LFS path2fid $remote_dir/$tfile)
14617         rc=$?
14618         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14619
14620         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14621                 error "dot lustre permission check $fid failed"
14622         rm -rf $DIR/$tdir
14623 }
14624 run_test 154b "Open-by-FID for remote directory"
14625
14626 test_154c() {
14627         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14628                 skip "Need MDS version at least 2.4.1"
14629
14630         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14631         local FID1=$($LFS path2fid $DIR/$tfile.1)
14632         local FID2=$($LFS path2fid $DIR/$tfile.2)
14633         local FID3=$($LFS path2fid $DIR/$tfile.3)
14634
14635         local N=1
14636         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14637                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14638                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14639                 local want=FID$N
14640                 [ "$FID" = "${!want}" ] ||
14641                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14642                 N=$((N + 1))
14643         done
14644
14645         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14646         do
14647                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14648                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14649                 N=$((N + 1))
14650         done
14651 }
14652 run_test 154c "lfs path2fid and fid2path multiple arguments"
14653
14654 test_154d() {
14655         remote_mds_nodsh && skip "remote MDS with nodsh"
14656         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14657                 skip "Need MDS version at least 2.5.53"
14658
14659         if remote_mds; then
14660                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14661         else
14662                 nid="0@lo"
14663         fi
14664         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14665         local fd
14666         local cmd
14667
14668         rm -f $DIR/$tfile
14669         touch $DIR/$tfile
14670
14671         local fid=$($LFS path2fid $DIR/$tfile)
14672         # Open the file
14673         fd=$(free_fd)
14674         cmd="exec $fd<$DIR/$tfile"
14675         eval $cmd
14676         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14677         echo "$fid_list" | grep "$fid"
14678         rc=$?
14679
14680         cmd="exec $fd>/dev/null"
14681         eval $cmd
14682         if [ $rc -ne 0 ]; then
14683                 error "FID $fid not found in open files list $fid_list"
14684         fi
14685 }
14686 run_test 154d "Verify open file fid"
14687
14688 test_154e()
14689 {
14690         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14691                 skip "Need MDS version at least 2.6.50"
14692
14693         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14694                 error ".lustre returned by readdir"
14695         fi
14696 }
14697 run_test 154e ".lustre is not returned by readdir"
14698
14699 test_154f() {
14700         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14701
14702         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14703         test_mkdir -p -c1 $DIR/$tdir/d
14704         # test dirs inherit from its stripe
14705         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
14706         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
14707         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
14708         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
14709         touch $DIR/f
14710
14711         # get fid of parents
14712         local FID0=$($LFS path2fid $DIR/$tdir/d)
14713         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14714         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14715         local FID3=$($LFS path2fid $DIR)
14716
14717         # check that path2fid --parents returns expected <parent_fid>/name
14718         # 1) test for a directory (single parent)
14719         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14720         [ "$parent" == "$FID0/foo1" ] ||
14721                 error "expected parent: $FID0/foo1, got: $parent"
14722
14723         # 2) test for a file with nlink > 1 (multiple parents)
14724         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14725         echo "$parent" | grep -F "$FID1/$tfile" ||
14726                 error "$FID1/$tfile not returned in parent list"
14727         echo "$parent" | grep -F "$FID2/link" ||
14728                 error "$FID2/link not returned in parent list"
14729
14730         # 3) get parent by fid
14731         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14732         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14733         echo "$parent" | grep -F "$FID1/$tfile" ||
14734                 error "$FID1/$tfile not returned in parent list (by fid)"
14735         echo "$parent" | grep -F "$FID2/link" ||
14736                 error "$FID2/link not returned in parent list (by fid)"
14737
14738         # 4) test for entry in root directory
14739         parent=$($LFS path2fid --parents $DIR/f)
14740         echo "$parent" | grep -F "$FID3/f" ||
14741                 error "$FID3/f not returned in parent list"
14742
14743         # 5) test it on root directory
14744         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14745                 error "$MOUNT should not have parents"
14746
14747         # enable xattr caching and check that linkea is correctly updated
14748         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14749         save_lustre_params client "llite.*.xattr_cache" > $save
14750         lctl set_param llite.*.xattr_cache 1
14751
14752         # 6.1) linkea update on rename
14753         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14754
14755         # get parents by fid
14756         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14757         # foo1 should no longer be returned in parent list
14758         echo "$parent" | grep -F "$FID1" &&
14759                 error "$FID1 should no longer be in parent list"
14760         # the new path should appear
14761         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14762                 error "$FID2/$tfile.moved is not in parent list"
14763
14764         # 6.2) linkea update on unlink
14765         rm -f $DIR/$tdir/d/foo2/link
14766         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14767         # foo2/link should no longer be returned in parent list
14768         echo "$parent" | grep -F "$FID2/link" &&
14769                 error "$FID2/link should no longer be in parent list"
14770         true
14771
14772         rm -f $DIR/f
14773         restore_lustre_params < $save
14774         rm -f $save
14775 }
14776 run_test 154f "get parent fids by reading link ea"
14777
14778 test_154g()
14779 {
14780         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14781         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14782            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14783                 skip "Need MDS version at least 2.6.92"
14784
14785         mkdir -p $DIR/$tdir
14786         llapi_fid_test -d $DIR/$tdir
14787 }
14788 run_test 154g "various llapi FID tests"
14789
14790 test_155_small_load() {
14791     local temp=$TMP/$tfile
14792     local file=$DIR/$tfile
14793
14794     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14795         error "dd of=$temp bs=6096 count=1 failed"
14796     cp $temp $file
14797     cancel_lru_locks $OSC
14798     cmp $temp $file || error "$temp $file differ"
14799
14800     $TRUNCATE $temp 6000
14801     $TRUNCATE $file 6000
14802     cmp $temp $file || error "$temp $file differ (truncate1)"
14803
14804     echo "12345" >>$temp
14805     echo "12345" >>$file
14806     cmp $temp $file || error "$temp $file differ (append1)"
14807
14808     echo "12345" >>$temp
14809     echo "12345" >>$file
14810     cmp $temp $file || error "$temp $file differ (append2)"
14811
14812     rm -f $temp $file
14813     true
14814 }
14815
14816 test_155_big_load() {
14817         remote_ost_nodsh && skip "remote OST with nodsh"
14818
14819         local temp=$TMP/$tfile
14820         local file=$DIR/$tfile
14821
14822         free_min_max
14823         local cache_size=$(do_facet ost$((MAXI+1)) \
14824                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14825         local large_file_size=$((cache_size * 2))
14826
14827         echo "OSS cache size: $cache_size KB"
14828         echo "Large file size: $large_file_size KB"
14829
14830         [ $MAXV -le $large_file_size ] &&
14831                 skip_env "max available OST size needs > $large_file_size KB"
14832
14833         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14834
14835         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14836                 error "dd of=$temp bs=$large_file_size count=1k failed"
14837         cp $temp $file
14838         ls -lh $temp $file
14839         cancel_lru_locks osc
14840         cmp $temp $file || error "$temp $file differ"
14841
14842         rm -f $temp $file
14843         true
14844 }
14845
14846 save_writethrough() {
14847         local facets=$(get_facets OST)
14848
14849         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14850 }
14851
14852 test_155a() {
14853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14854
14855         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14856
14857         save_writethrough $p
14858
14859         set_cache read on
14860         set_cache writethrough on
14861         test_155_small_load
14862         restore_lustre_params < $p
14863         rm -f $p
14864 }
14865 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14866
14867 test_155b() {
14868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14869
14870         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14871
14872         save_writethrough $p
14873
14874         set_cache read on
14875         set_cache writethrough off
14876         test_155_small_load
14877         restore_lustre_params < $p
14878         rm -f $p
14879 }
14880 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14881
14882 test_155c() {
14883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14884
14885         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14886
14887         save_writethrough $p
14888
14889         set_cache read off
14890         set_cache writethrough on
14891         test_155_small_load
14892         restore_lustre_params < $p
14893         rm -f $p
14894 }
14895 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14896
14897 test_155d() {
14898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14899
14900         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14901
14902         save_writethrough $p
14903
14904         set_cache read off
14905         set_cache writethrough off
14906         test_155_small_load
14907         restore_lustre_params < $p
14908         rm -f $p
14909 }
14910 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14911
14912 test_155e() {
14913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14914
14915         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14916
14917         save_writethrough $p
14918
14919         set_cache read on
14920         set_cache writethrough on
14921         test_155_big_load
14922         restore_lustre_params < $p
14923         rm -f $p
14924 }
14925 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14926
14927 test_155f() {
14928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14929
14930         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14931
14932         save_writethrough $p
14933
14934         set_cache read on
14935         set_cache writethrough off
14936         test_155_big_load
14937         restore_lustre_params < $p
14938         rm -f $p
14939 }
14940 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14941
14942 test_155g() {
14943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14944
14945         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14946
14947         save_writethrough $p
14948
14949         set_cache read off
14950         set_cache writethrough on
14951         test_155_big_load
14952         restore_lustre_params < $p
14953         rm -f $p
14954 }
14955 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14956
14957 test_155h() {
14958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14959
14960         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14961
14962         save_writethrough $p
14963
14964         set_cache read off
14965         set_cache writethrough off
14966         test_155_big_load
14967         restore_lustre_params < $p
14968         rm -f $p
14969 }
14970 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14971
14972 test_156() {
14973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14974         remote_ost_nodsh && skip "remote OST with nodsh"
14975         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14976                 skip "stats not implemented on old servers"
14977         [ "$ost1_FSTYPE" = "zfs" ] &&
14978                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14979
14980         local CPAGES=3
14981         local BEFORE
14982         local AFTER
14983         local file="$DIR/$tfile"
14984         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14985
14986         save_writethrough $p
14987         roc_hit_init
14988
14989         log "Turn on read and write cache"
14990         set_cache read on
14991         set_cache writethrough on
14992
14993         log "Write data and read it back."
14994         log "Read should be satisfied from the cache."
14995         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14996         BEFORE=$(roc_hit)
14997         cancel_lru_locks osc
14998         cat $file >/dev/null
14999         AFTER=$(roc_hit)
15000         if ! let "AFTER - BEFORE == CPAGES"; then
15001                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15002         else
15003                 log "cache hits: before: $BEFORE, after: $AFTER"
15004         fi
15005
15006         log "Read again; it should be satisfied from the cache."
15007         BEFORE=$AFTER
15008         cancel_lru_locks osc
15009         cat $file >/dev/null
15010         AFTER=$(roc_hit)
15011         if ! let "AFTER - BEFORE == CPAGES"; then
15012                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15013         else
15014                 log "cache hits:: before: $BEFORE, after: $AFTER"
15015         fi
15016
15017         log "Turn off the read cache and turn on the write cache"
15018         set_cache read off
15019         set_cache writethrough on
15020
15021         log "Read again; it should be satisfied from the cache."
15022         BEFORE=$(roc_hit)
15023         cancel_lru_locks osc
15024         cat $file >/dev/null
15025         AFTER=$(roc_hit)
15026         if ! let "AFTER - BEFORE == CPAGES"; then
15027                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15028         else
15029                 log "cache hits:: before: $BEFORE, after: $AFTER"
15030         fi
15031
15032         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15033                 # > 2.12.56 uses pagecache if cached
15034                 log "Read again; it should not be satisfied from the cache."
15035                 BEFORE=$AFTER
15036                 cancel_lru_locks osc
15037                 cat $file >/dev/null
15038                 AFTER=$(roc_hit)
15039                 if ! let "AFTER - BEFORE == 0"; then
15040                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15041                 else
15042                         log "cache hits:: before: $BEFORE, after: $AFTER"
15043                 fi
15044         fi
15045
15046         log "Write data and read it back."
15047         log "Read should be satisfied from the cache."
15048         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15049         BEFORE=$(roc_hit)
15050         cancel_lru_locks osc
15051         cat $file >/dev/null
15052         AFTER=$(roc_hit)
15053         if ! let "AFTER - BEFORE == CPAGES"; then
15054                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15055         else
15056                 log "cache hits:: before: $BEFORE, after: $AFTER"
15057         fi
15058
15059         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15060                 # > 2.12.56 uses pagecache if cached
15061                 log "Read again; it should not be satisfied from the cache."
15062                 BEFORE=$AFTER
15063                 cancel_lru_locks osc
15064                 cat $file >/dev/null
15065                 AFTER=$(roc_hit)
15066                 if ! let "AFTER - BEFORE == 0"; then
15067                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15068                 else
15069                         log "cache hits:: before: $BEFORE, after: $AFTER"
15070                 fi
15071         fi
15072
15073         log "Turn off read and write cache"
15074         set_cache read off
15075         set_cache writethrough off
15076
15077         log "Write data and read it back"
15078         log "It should not be satisfied from the cache."
15079         rm -f $file
15080         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15081         cancel_lru_locks osc
15082         BEFORE=$(roc_hit)
15083         cat $file >/dev/null
15084         AFTER=$(roc_hit)
15085         if ! let "AFTER - BEFORE == 0"; then
15086                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15087         else
15088                 log "cache hits:: before: $BEFORE, after: $AFTER"
15089         fi
15090
15091         log "Turn on the read cache and turn off the write cache"
15092         set_cache read on
15093         set_cache writethrough off
15094
15095         log "Write data and read it back"
15096         log "It should not be satisfied from the cache."
15097         rm -f $file
15098         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15099         BEFORE=$(roc_hit)
15100         cancel_lru_locks osc
15101         cat $file >/dev/null
15102         AFTER=$(roc_hit)
15103         if ! let "AFTER - BEFORE == 0"; then
15104                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15105         else
15106                 log "cache hits:: before: $BEFORE, after: $AFTER"
15107         fi
15108
15109         log "Read again; it should be satisfied from the cache."
15110         BEFORE=$(roc_hit)
15111         cancel_lru_locks osc
15112         cat $file >/dev/null
15113         AFTER=$(roc_hit)
15114         if ! let "AFTER - BEFORE == CPAGES"; then
15115                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15116         else
15117                 log "cache hits:: before: $BEFORE, after: $AFTER"
15118         fi
15119
15120         restore_lustre_params < $p
15121         rm -f $p $file
15122 }
15123 run_test 156 "Verification of tunables"
15124
15125 test_160a() {
15126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15127         remote_mds_nodsh && skip "remote MDS with nodsh"
15128         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15129                 skip "Need MDS version at least 2.2.0"
15130
15131         changelog_register || error "changelog_register failed"
15132         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15133         changelog_users $SINGLEMDS | grep -q $cl_user ||
15134                 error "User $cl_user not found in changelog_users"
15135
15136         # change something
15137         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15138         changelog_clear 0 || error "changelog_clear failed"
15139         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15140         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15141         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15142         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15143         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15144         rm $DIR/$tdir/pics/desktop.jpg
15145
15146         changelog_dump | tail -10
15147
15148         echo "verifying changelog mask"
15149         changelog_chmask "-MKDIR"
15150         changelog_chmask "-CLOSE"
15151
15152         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15153         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15154
15155         changelog_chmask "+MKDIR"
15156         changelog_chmask "+CLOSE"
15157
15158         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15159         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15160
15161         changelog_dump | tail -10
15162         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15163         CLOSES=$(changelog_dump | grep -c "CLOSE")
15164         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15165         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15166
15167         # verify contents
15168         echo "verifying target fid"
15169         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15170         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15171         [ "$fidc" == "$fidf" ] ||
15172                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15173         echo "verifying parent fid"
15174         # The FID returned from the Changelog may be the directory shard on
15175         # a different MDT, and not the FID returned by path2fid on the parent.
15176         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15177         # since this is what will matter when recreating this file in the tree.
15178         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15179         local pathp=$($LFS fid2path $MOUNT "$fidp")
15180         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15181                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15182
15183         echo "getting records for $cl_user"
15184         changelog_users $SINGLEMDS
15185         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15186         local nclr=3
15187         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15188                 error "changelog_clear failed"
15189         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15190         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15191         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15192                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15193
15194         local min0_rec=$(changelog_users $SINGLEMDS |
15195                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15196         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15197                           awk '{ print $1; exit; }')
15198
15199         changelog_dump | tail -n 5
15200         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15201         [ $first_rec == $((min0_rec + 1)) ] ||
15202                 error "first index should be $min0_rec + 1 not $first_rec"
15203
15204         # LU-3446 changelog index reset on MDT restart
15205         local cur_rec1=$(changelog_users $SINGLEMDS |
15206                          awk '/^current.index:/ { print $NF }')
15207         changelog_clear 0 ||
15208                 error "clear all changelog records for $cl_user failed"
15209         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15210         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15211                 error "Fail to start $SINGLEMDS"
15212         local cur_rec2=$(changelog_users $SINGLEMDS |
15213                          awk '/^current.index:/ { print $NF }')
15214         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15215         [ $cur_rec1 == $cur_rec2 ] ||
15216                 error "current index should be $cur_rec1 not $cur_rec2"
15217
15218         echo "verifying users from this test are deregistered"
15219         changelog_deregister || error "changelog_deregister failed"
15220         changelog_users $SINGLEMDS | grep -q $cl_user &&
15221                 error "User '$cl_user' still in changelog_users"
15222
15223         # lctl get_param -n mdd.*.changelog_users
15224         # current index: 144
15225         # ID    index (idle seconds)
15226         # cl3   144 (2)
15227         if ! changelog_users $SINGLEMDS | grep "^cl"; then
15228                 # this is the normal case where all users were deregistered
15229                 # make sure no new records are added when no users are present
15230                 local last_rec1=$(changelog_users $SINGLEMDS |
15231                                   awk '/^current.index:/ { print $NF }')
15232                 touch $DIR/$tdir/chloe
15233                 local last_rec2=$(changelog_users $SINGLEMDS |
15234                                   awk '/^current.index:/ { print $NF }')
15235                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15236                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15237         else
15238                 # any changelog users must be leftovers from a previous test
15239                 changelog_users $SINGLEMDS
15240                 echo "other changelog users; can't verify off"
15241         fi
15242 }
15243 run_test 160a "changelog sanity"
15244
15245 test_160b() { # LU-3587
15246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15247         remote_mds_nodsh && skip "remote MDS with nodsh"
15248         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15249                 skip "Need MDS version at least 2.2.0"
15250
15251         changelog_register || error "changelog_register failed"
15252         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15253         changelog_users $SINGLEMDS | grep -q $cl_user ||
15254                 error "User '$cl_user' not found in changelog_users"
15255
15256         local longname1=$(str_repeat a 255)
15257         local longname2=$(str_repeat b 255)
15258
15259         cd $DIR
15260         echo "creating very long named file"
15261         touch $longname1 || error "create of '$longname1' failed"
15262         echo "renaming very long named file"
15263         mv $longname1 $longname2
15264
15265         changelog_dump | grep RENME | tail -n 5
15266         rm -f $longname2
15267 }
15268 run_test 160b "Verify that very long rename doesn't crash in changelog"
15269
15270 test_160c() {
15271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15272         remote_mds_nodsh && skip "remote MDS with nodsh"
15273
15274         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15275                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15276                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15277                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15278
15279         local rc=0
15280
15281         # Registration step
15282         changelog_register || error "changelog_register failed"
15283
15284         rm -rf $DIR/$tdir
15285         mkdir -p $DIR/$tdir
15286         $MCREATE $DIR/$tdir/foo_160c
15287         changelog_chmask "-TRUNC"
15288         $TRUNCATE $DIR/$tdir/foo_160c 200
15289         changelog_chmask "+TRUNC"
15290         $TRUNCATE $DIR/$tdir/foo_160c 199
15291         changelog_dump | tail -n 5
15292         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15293         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15294 }
15295 run_test 160c "verify that changelog log catch the truncate event"
15296
15297 test_160d() {
15298         remote_mds_nodsh && skip "remote MDS with nodsh"
15299         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15301         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15302                 skip "Need MDS version at least 2.7.60"
15303
15304         # Registration step
15305         changelog_register || error "changelog_register failed"
15306
15307         mkdir -p $DIR/$tdir/migrate_dir
15308         changelog_clear 0 || error "changelog_clear failed"
15309
15310         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15311         changelog_dump | tail -n 5
15312         local migrates=$(changelog_dump | grep -c "MIGRT")
15313         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15314 }
15315 run_test 160d "verify that changelog log catch the migrate event"
15316
15317 test_160e() {
15318         remote_mds_nodsh && skip "remote MDS with nodsh"
15319
15320         # Create a user
15321         changelog_register || error "changelog_register failed"
15322
15323         # Delete a future user (expect fail)
15324         local MDT0=$(facet_svc $SINGLEMDS)
15325         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15326         local rc=$?
15327
15328         if [ $rc -eq 0 ]; then
15329                 error "Deleted non-existant user cl77"
15330         elif [ $rc -ne 2 ]; then
15331                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15332         fi
15333
15334         # Clear to a bad index (1 billion should be safe)
15335         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15336         rc=$?
15337
15338         if [ $rc -eq 0 ]; then
15339                 error "Successfully cleared to invalid CL index"
15340         elif [ $rc -ne 22 ]; then
15341                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15342         fi
15343 }
15344 run_test 160e "changelog negative testing (should return errors)"
15345
15346 test_160f() {
15347         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15348         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15349                 skip "Need MDS version at least 2.10.56"
15350
15351         local mdts=$(comma_list $(mdts_nodes))
15352
15353         # Create a user
15354         changelog_register || error "first changelog_register failed"
15355         changelog_register || error "second changelog_register failed"
15356         local cl_users
15357         declare -A cl_user1
15358         declare -A cl_user2
15359         local user_rec1
15360         local user_rec2
15361         local i
15362
15363         # generate some changelog records to accumulate on each MDT
15364         # use all_char because created files should be evenly distributed
15365         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15366                 error "test_mkdir $tdir failed"
15367         log "$(date +%s): creating first files"
15368         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15369                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15370                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15371         done
15372
15373         # check changelogs have been generated
15374         local start=$SECONDS
15375         local idle_time=$((MDSCOUNT * 5 + 5))
15376         local nbcl=$(changelog_dump | wc -l)
15377         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15378
15379         for param in "changelog_max_idle_time=$idle_time" \
15380                      "changelog_gc=1" \
15381                      "changelog_min_gc_interval=2" \
15382                      "changelog_min_free_cat_entries=3"; do
15383                 local MDT0=$(facet_svc $SINGLEMDS)
15384                 local var="${param%=*}"
15385                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15386
15387                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15388                 do_nodes $mdts $LCTL set_param mdd.*.$param
15389         done
15390
15391         # force cl_user2 to be idle (1st part), but also cancel the
15392         # cl_user1 records so that it is not evicted later in the test.
15393         local sleep1=$((idle_time / 2))
15394         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15395         sleep $sleep1
15396
15397         # simulate changelog catalog almost full
15398         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15399         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15400
15401         for i in $(seq $MDSCOUNT); do
15402                 cl_users=(${CL_USERS[mds$i]})
15403                 cl_user1[mds$i]="${cl_users[0]}"
15404                 cl_user2[mds$i]="${cl_users[1]}"
15405
15406                 [ -n "${cl_user1[mds$i]}" ] ||
15407                         error "mds$i: no user registered"
15408                 [ -n "${cl_user2[mds$i]}" ] ||
15409                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15410
15411                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15412                 [ -n "$user_rec1" ] ||
15413                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15414                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15415                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15416                 [ -n "$user_rec2" ] ||
15417                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15418                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15419                      "$user_rec1 + 2 == $user_rec2"
15420                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15421                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15422                               "$user_rec1 + 2, but is $user_rec2"
15423                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15424                 [ -n "$user_rec2" ] ||
15425                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15426                 [ $user_rec1 == $user_rec2 ] ||
15427                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15428                               "$user_rec1, but is $user_rec2"
15429         done
15430
15431         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15432         local sleep2=$((idle_time - (SECONDS - start) + 1))
15433         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15434         sleep $sleep2
15435
15436         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15437         # cl_user1 should be OK because it recently processed records.
15438         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15439         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15440                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15441                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15442         done
15443
15444         # ensure gc thread is done
15445         for i in $(mdts_nodes); do
15446                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15447                         error "$i: GC-thread not done"
15448         done
15449
15450         local first_rec
15451         for (( i = 1; i <= MDSCOUNT; i++ )); do
15452                 # check cl_user1 still registered
15453                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15454                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15455                 # check cl_user2 unregistered
15456                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15457                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15458
15459                 # check changelogs are present and starting at $user_rec1 + 1
15460                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15461                 [ -n "$user_rec1" ] ||
15462                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15463                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15464                             awk '{ print $1; exit; }')
15465
15466                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15467                 [ $((user_rec1 + 1)) == $first_rec ] ||
15468                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15469         done
15470 }
15471 run_test 160f "changelog garbage collect (timestamped users)"
15472
15473 test_160g() {
15474         remote_mds_nodsh && skip "remote MDS with nodsh"
15475         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15476                 skip "Need MDS version at least 2.10.56"
15477
15478         local mdts=$(comma_list $(mdts_nodes))
15479
15480         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15481         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15482
15483         # Create a user
15484         changelog_register || error "first changelog_register failed"
15485         changelog_register || error "second changelog_register failed"
15486         local cl_users
15487         declare -A cl_user1
15488         declare -A cl_user2
15489         local user_rec1
15490         local user_rec2
15491         local i
15492
15493         # generate some changelog records to accumulate on each MDT
15494         # use all_char because created files should be evenly distributed
15495         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15496                 error "test_mkdir $tdir failed"
15497         for ((i = 0; i < MDSCOUNT; i++)); do
15498                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15499                         error "create $DIR/$tdir/d$i.1 failed"
15500         done
15501
15502         # check changelogs have been generated
15503         local nbcl=$(changelog_dump | wc -l)
15504         (( $nbcl > 0 )) || error "no changelogs found"
15505
15506         # reduce the max_idle_indexes value to make sure we exceed it
15507         for param in "changelog_max_idle_indexes=1" \
15508                      "changelog_gc=1" \
15509                      "changelog_min_gc_interval=2" \
15510                      "changelog_min_free_cat_entries=3"; do
15511                 local MDT0=$(facet_svc $SINGLEMDS)
15512                 local var="${param%=*}"
15513                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15514
15515                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15516                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15517                         error "unable to set mdd.*.$param"
15518         done
15519
15520         # simulate changelog catalog almost full
15521         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15522         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15523
15524         local start=$SECONDS
15525         for i in $(seq $MDSCOUNT); do
15526                 cl_users=(${CL_USERS[mds$i]})
15527                 cl_user1[mds$i]="${cl_users[0]}"
15528                 cl_user2[mds$i]="${cl_users[1]}"
15529
15530                 [ -n "${cl_user1[mds$i]}" ] ||
15531                         error "mds$i: no user registered"
15532                 [ -n "${cl_user2[mds$i]}" ] ||
15533                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15534
15535                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15536                 [ -n "$user_rec1" ] ||
15537                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15538                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15539                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15540                 [ -n "$user_rec2" ] ||
15541                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15542                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15543                      "$user_rec1 + 2 == $user_rec2"
15544                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15545                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15546                               "$user_rec1 + 2, but is $user_rec2"
15547                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15548                 [ -n "$user_rec2" ] ||
15549                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15550                 [ $user_rec1 == $user_rec2 ] ||
15551                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15552                               "$user_rec1, but is $user_rec2"
15553         done
15554
15555         # ensure we are past the previous changelog_min_gc_interval set above
15556         local sleep2=$((start + 2 - SECONDS))
15557         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15558
15559         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15560         # cl_user1 should be OK because it recently processed records.
15561         for ((i = 0; i < MDSCOUNT; i++)); do
15562                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15563                         error "create $DIR/$tdir/d$i.3 failed"
15564         done
15565
15566         # ensure gc thread is done
15567         for i in $(mdts_nodes); do
15568                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15569                         error "$i: GC-thread not done"
15570         done
15571
15572         local first_rec
15573         for (( i = 1; i <= MDSCOUNT; i++ )); do
15574                 # check cl_user1 still registered
15575                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15576                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15577                 # check cl_user2 unregistered
15578                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15579                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15580
15581                 # check changelogs are present and starting at $user_rec1 + 1
15582                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15583                 [ -n "$user_rec1" ] ||
15584                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15585                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15586                             awk '{ print $1; exit; }')
15587
15588                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15589                 [ $((user_rec1 + 1)) == $first_rec ] ||
15590                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15591         done
15592 }
15593 run_test 160g "changelog garbage collect (old users)"
15594
15595 test_160h() {
15596         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15597         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15598                 skip "Need MDS version at least 2.10.56"
15599
15600         local mdts=$(comma_list $(mdts_nodes))
15601
15602         # Create a user
15603         changelog_register || error "first changelog_register failed"
15604         changelog_register || error "second changelog_register failed"
15605         local cl_users
15606         declare -A cl_user1
15607         declare -A cl_user2
15608         local user_rec1
15609         local user_rec2
15610         local i
15611
15612         # generate some changelog records to accumulate on each MDT
15613         # use all_char because created files should be evenly distributed
15614         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15615                 error "test_mkdir $tdir failed"
15616         for ((i = 0; i < MDSCOUNT; i++)); do
15617                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15618                         error "create $DIR/$tdir/d$i.1 failed"
15619         done
15620
15621         # check changelogs have been generated
15622         local nbcl=$(changelog_dump | wc -l)
15623         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15624
15625         for param in "changelog_max_idle_time=10" \
15626                      "changelog_gc=1" \
15627                      "changelog_min_gc_interval=2"; do
15628                 local MDT0=$(facet_svc $SINGLEMDS)
15629                 local var="${param%=*}"
15630                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15631
15632                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15633                 do_nodes $mdts $LCTL set_param mdd.*.$param
15634         done
15635
15636         # force cl_user2 to be idle (1st part)
15637         sleep 9
15638
15639         for i in $(seq $MDSCOUNT); do
15640                 cl_users=(${CL_USERS[mds$i]})
15641                 cl_user1[mds$i]="${cl_users[0]}"
15642                 cl_user2[mds$i]="${cl_users[1]}"
15643
15644                 [ -n "${cl_user1[mds$i]}" ] ||
15645                         error "mds$i: no user registered"
15646                 [ -n "${cl_user2[mds$i]}" ] ||
15647                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15648
15649                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15650                 [ -n "$user_rec1" ] ||
15651                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15652                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15653                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15654                 [ -n "$user_rec2" ] ||
15655                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15656                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15657                      "$user_rec1 + 2 == $user_rec2"
15658                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15659                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15660                               "$user_rec1 + 2, but is $user_rec2"
15661                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15662                 [ -n "$user_rec2" ] ||
15663                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15664                 [ $user_rec1 == $user_rec2 ] ||
15665                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15666                               "$user_rec1, but is $user_rec2"
15667         done
15668
15669         # force cl_user2 to be idle (2nd part) and to reach
15670         # changelog_max_idle_time
15671         sleep 2
15672
15673         # force each GC-thread start and block then
15674         # one per MDT/MDD, set fail_val accordingly
15675         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15676         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15677
15678         # generate more changelogs to trigger fail_loc
15679         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15680                 error "create $DIR/$tdir/${tfile}bis failed"
15681
15682         # stop MDT to stop GC-thread, should be done in back-ground as it will
15683         # block waiting for the thread to be released and exit
15684         declare -A stop_pids
15685         for i in $(seq $MDSCOUNT); do
15686                 stop mds$i &
15687                 stop_pids[mds$i]=$!
15688         done
15689
15690         for i in $(mdts_nodes); do
15691                 local facet
15692                 local nb=0
15693                 local facets=$(facets_up_on_host $i)
15694
15695                 for facet in ${facets//,/ }; do
15696                         if [[ $facet == mds* ]]; then
15697                                 nb=$((nb + 1))
15698                         fi
15699                 done
15700                 # ensure each MDS's gc threads are still present and all in "R"
15701                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15702                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15703                         error "$i: expected $nb GC-thread"
15704                 wait_update $i \
15705                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15706                         "R" 20 ||
15707                         error "$i: GC-thread not found in R-state"
15708                 # check umounts of each MDT on MDS have reached kthread_stop()
15709                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15710                         error "$i: expected $nb umount"
15711                 wait_update $i \
15712                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15713                         error "$i: umount not found in D-state"
15714         done
15715
15716         # release all GC-threads
15717         do_nodes $mdts $LCTL set_param fail_loc=0
15718
15719         # wait for MDT stop to complete
15720         for i in $(seq $MDSCOUNT); do
15721                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15722         done
15723
15724         # XXX
15725         # may try to check if any orphan changelog records are present
15726         # via ldiskfs/zfs and llog_reader...
15727
15728         # re-start/mount MDTs
15729         for i in $(seq $MDSCOUNT); do
15730                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15731                         error "Fail to start mds$i"
15732         done
15733
15734         local first_rec
15735         for i in $(seq $MDSCOUNT); do
15736                 # check cl_user1 still registered
15737                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15738                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15739                 # check cl_user2 unregistered
15740                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15741                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15742
15743                 # check changelogs are present and starting at $user_rec1 + 1
15744                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15745                 [ -n "$user_rec1" ] ||
15746                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15747                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15748                             awk '{ print $1; exit; }')
15749
15750                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15751                 [ $((user_rec1 + 1)) == $first_rec ] ||
15752                         error "mds$i: first index should be $user_rec1 + 1, " \
15753                               "but is $first_rec"
15754         done
15755 }
15756 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15757               "during mount"
15758
15759 test_160i() {
15760
15761         local mdts=$(comma_list $(mdts_nodes))
15762
15763         changelog_register || error "first changelog_register failed"
15764
15765         # generate some changelog records to accumulate on each MDT
15766         # use all_char because created files should be evenly distributed
15767         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15768                 error "test_mkdir $tdir failed"
15769         for ((i = 0; i < MDSCOUNT; i++)); do
15770                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15771                         error "create $DIR/$tdir/d$i.1 failed"
15772         done
15773
15774         # check changelogs have been generated
15775         local nbcl=$(changelog_dump | wc -l)
15776         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15777
15778         # simulate race between register and unregister
15779         # XXX as fail_loc is set per-MDS, with DNE configs the race
15780         # simulation will only occur for one MDT per MDS and for the
15781         # others the normal race scenario will take place
15782         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15783         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15784         do_nodes $mdts $LCTL set_param fail_val=1
15785
15786         # unregister 1st user
15787         changelog_deregister &
15788         local pid1=$!
15789         # wait some time for deregister work to reach race rdv
15790         sleep 2
15791         # register 2nd user
15792         changelog_register || error "2nd user register failed"
15793
15794         wait $pid1 || error "1st user deregister failed"
15795
15796         local i
15797         local last_rec
15798         declare -A LAST_REC
15799         for i in $(seq $MDSCOUNT); do
15800                 if changelog_users mds$i | grep "^cl"; then
15801                         # make sure new records are added with one user present
15802                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15803                                           awk '/^current.index:/ { print $NF }')
15804                 else
15805                         error "mds$i has no user registered"
15806                 fi
15807         done
15808
15809         # generate more changelog records to accumulate on each MDT
15810         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15811                 error "create $DIR/$tdir/${tfile}bis failed"
15812
15813         for i in $(seq $MDSCOUNT); do
15814                 last_rec=$(changelog_users $SINGLEMDS |
15815                            awk '/^current.index:/ { print $NF }')
15816                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15817                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15818                         error "changelogs are off on mds$i"
15819         done
15820 }
15821 run_test 160i "changelog user register/unregister race"
15822
15823 test_160j() {
15824         remote_mds_nodsh && skip "remote MDS with nodsh"
15825         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15826                 skip "Need MDS version at least 2.12.56"
15827
15828         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15829         stack_trap "umount $MOUNT2" EXIT
15830
15831         changelog_register || error "first changelog_register failed"
15832         stack_trap "changelog_deregister" EXIT
15833
15834         # generate some changelog
15835         # use all_char because created files should be evenly distributed
15836         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15837                 error "mkdir $tdir failed"
15838         for ((i = 0; i < MDSCOUNT; i++)); do
15839                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15840                         error "create $DIR/$tdir/d$i.1 failed"
15841         done
15842
15843         # open the changelog device
15844         exec 3>/dev/changelog-$FSNAME-MDT0000
15845         stack_trap "exec 3>&-" EXIT
15846         exec 4</dev/changelog-$FSNAME-MDT0000
15847         stack_trap "exec 4<&-" EXIT
15848
15849         # umount the first lustre mount
15850         umount $MOUNT
15851         stack_trap "mount_client $MOUNT" EXIT
15852
15853         # read changelog, which may or may not fail, but should not crash
15854         cat <&4 >/dev/null
15855
15856         # clear changelog
15857         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15858         changelog_users $SINGLEMDS | grep -q $cl_user ||
15859                 error "User $cl_user not found in changelog_users"
15860
15861         printf 'clear:'$cl_user':0' >&3
15862 }
15863 run_test 160j "client can be umounted while its chanangelog is being used"
15864
15865 test_160k() {
15866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15867         remote_mds_nodsh && skip "remote MDS with nodsh"
15868
15869         mkdir -p $DIR/$tdir/1/1
15870
15871         changelog_register || error "changelog_register failed"
15872         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15873
15874         changelog_users $SINGLEMDS | grep -q $cl_user ||
15875                 error "User '$cl_user' not found in changelog_users"
15876 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15877         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15878         rmdir $DIR/$tdir/1/1 & sleep 1
15879         mkdir $DIR/$tdir/2
15880         touch $DIR/$tdir/2/2
15881         rm -rf $DIR/$tdir/2
15882
15883         wait
15884         sleep 4
15885
15886         changelog_dump | grep rmdir || error "rmdir not recorded"
15887 }
15888 run_test 160k "Verify that changelog records are not lost"
15889
15890 # Verifies that a file passed as a parameter has recently had an operation
15891 # performed on it that has generated an MTIME changelog which contains the
15892 # correct parent FID. As files might reside on a different MDT from the
15893 # parent directory in DNE configurations, the FIDs are translated to paths
15894 # before being compared, which should be identical
15895 compare_mtime_changelog() {
15896         local file="${1}"
15897         local mdtidx
15898         local mtime
15899         local cl_fid
15900         local pdir
15901         local dir
15902
15903         mdtidx=$($LFS getstripe --mdt-index $file)
15904         mdtidx=$(printf "%04x" $mdtidx)
15905
15906         # Obtain the parent FID from the MTIME changelog
15907         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15908         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15909
15910         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15911         [ -z "$cl_fid" ] && error "parent FID not present"
15912
15913         # Verify that the path for the parent FID is the same as the path for
15914         # the test directory
15915         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15916
15917         dir=$(dirname $1)
15918
15919         [[ "${pdir%/}" == "$dir" ]] ||
15920                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15921 }
15922
15923 test_160l() {
15924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15925
15926         remote_mds_nodsh && skip "remote MDS with nodsh"
15927         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15928                 skip "Need MDS version at least 2.13.55"
15929
15930         local cl_user
15931
15932         changelog_register || error "changelog_register failed"
15933         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15934
15935         changelog_users $SINGLEMDS | grep -q $cl_user ||
15936                 error "User '$cl_user' not found in changelog_users"
15937
15938         # Clear some types so that MTIME changelogs are generated
15939         changelog_chmask "-CREAT"
15940         changelog_chmask "-CLOSE"
15941
15942         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15943
15944         # Test CL_MTIME during setattr
15945         touch $DIR/$tdir/$tfile
15946         compare_mtime_changelog $DIR/$tdir/$tfile
15947
15948         # Test CL_MTIME during close
15949         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15950         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15951 }
15952 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15953
15954 test_160m() {
15955         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15956         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
15957                 skip "Need MDS version at least 2.14.51"
15958         local cl_users
15959         local cl_user1
15960         local cl_user2
15961         local pid1
15962
15963         # Create a user
15964         changelog_register || error "first changelog_register failed"
15965         changelog_register || error "second changelog_register failed"
15966
15967         cl_users=(${CL_USERS[mds1]})
15968         cl_user1="${cl_users[0]}"
15969         cl_user2="${cl_users[1]}"
15970         # generate some changelog records to accumulate on MDT0
15971         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
15972         createmany -m $DIR/$tdir/$tfile 50 ||
15973                 error "create $DIR/$tdir/$tfile failed"
15974         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
15975         rm -f $DIR/$tdir
15976
15977         # check changelogs have been generated
15978         local nbcl=$(changelog_dump | wc -l)
15979         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15980
15981 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
15982         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
15983
15984         __changelog_clear mds1 $cl_user1 +10
15985         __changelog_clear mds1 $cl_user2 0 &
15986         pid1=$!
15987         sleep 2
15988         __changelog_clear mds1 $cl_user1 0 ||
15989                 error "fail to cancel record for $cl_user1"
15990         wait $pid1
15991         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
15992 }
15993 run_test 160m "Changelog clear race"
15994
15995
15996 test_161a() {
15997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15998
15999         test_mkdir -c1 $DIR/$tdir
16000         cp /etc/hosts $DIR/$tdir/$tfile
16001         test_mkdir -c1 $DIR/$tdir/foo1
16002         test_mkdir -c1 $DIR/$tdir/foo2
16003         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16004         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16005         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16006         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16007         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16008         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16009                 $LFS fid2path $DIR $FID
16010                 error "bad link ea"
16011         fi
16012         # middle
16013         rm $DIR/$tdir/foo2/zachary
16014         # last
16015         rm $DIR/$tdir/foo2/thor
16016         # first
16017         rm $DIR/$tdir/$tfile
16018         # rename
16019         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16020         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16021                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16022         rm $DIR/$tdir/foo2/maggie
16023
16024         # overflow the EA
16025         local longname=$tfile.avg_len_is_thirty_two_
16026         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16027                 error_noexit 'failed to unlink many hardlinks'" EXIT
16028         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16029                 error "failed to hardlink many files"
16030         links=$($LFS fid2path $DIR $FID | wc -l)
16031         echo -n "${links}/1000 links in link EA"
16032         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16033 }
16034 run_test 161a "link ea sanity"
16035
16036 test_161b() {
16037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16038         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16039
16040         local MDTIDX=1
16041         local remote_dir=$DIR/$tdir/remote_dir
16042
16043         mkdir -p $DIR/$tdir
16044         $LFS mkdir -i $MDTIDX $remote_dir ||
16045                 error "create remote directory failed"
16046
16047         cp /etc/hosts $remote_dir/$tfile
16048         mkdir -p $remote_dir/foo1
16049         mkdir -p $remote_dir/foo2
16050         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16051         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16052         ln $remote_dir/$tfile $remote_dir/foo1/luna
16053         ln $remote_dir/$tfile $remote_dir/foo2/thor
16054
16055         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16056                      tr -d ']')
16057         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16058                 $LFS fid2path $DIR $FID
16059                 error "bad link ea"
16060         fi
16061         # middle
16062         rm $remote_dir/foo2/zachary
16063         # last
16064         rm $remote_dir/foo2/thor
16065         # first
16066         rm $remote_dir/$tfile
16067         # rename
16068         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16069         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16070         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16071                 $LFS fid2path $DIR $FID
16072                 error "bad link rename"
16073         fi
16074         rm $remote_dir/foo2/maggie
16075
16076         # overflow the EA
16077         local longname=filename_avg_len_is_thirty_two_
16078         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16079                 error "failed to hardlink many files"
16080         links=$($LFS fid2path $DIR $FID | wc -l)
16081         echo -n "${links}/1000 links in link EA"
16082         [[ ${links} -gt 60 ]] ||
16083                 error "expected at least 60 links in link EA"
16084         unlinkmany $remote_dir/foo2/$longname 1000 ||
16085         error "failed to unlink many hardlinks"
16086 }
16087 run_test 161b "link ea sanity under remote directory"
16088
16089 test_161c() {
16090         remote_mds_nodsh && skip "remote MDS with nodsh"
16091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16092         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16093                 skip "Need MDS version at least 2.1.5"
16094
16095         # define CLF_RENAME_LAST 0x0001
16096         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16097         changelog_register || error "changelog_register failed"
16098
16099         rm -rf $DIR/$tdir
16100         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16101         touch $DIR/$tdir/foo_161c
16102         touch $DIR/$tdir/bar_161c
16103         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16104         changelog_dump | grep RENME | tail -n 5
16105         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16106         changelog_clear 0 || error "changelog_clear failed"
16107         if [ x$flags != "x0x1" ]; then
16108                 error "flag $flags is not 0x1"
16109         fi
16110
16111         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16112         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16113         touch $DIR/$tdir/foo_161c
16114         touch $DIR/$tdir/bar_161c
16115         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16116         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16117         changelog_dump | grep RENME | tail -n 5
16118         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16119         changelog_clear 0 || error "changelog_clear failed"
16120         if [ x$flags != "x0x0" ]; then
16121                 error "flag $flags is not 0x0"
16122         fi
16123         echo "rename overwrite a target having nlink > 1," \
16124                 "changelog record has flags of $flags"
16125
16126         # rename doesn't overwrite a target (changelog flag 0x0)
16127         touch $DIR/$tdir/foo_161c
16128         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16129         changelog_dump | grep RENME | tail -n 5
16130         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16131         changelog_clear 0 || error "changelog_clear failed"
16132         if [ x$flags != "x0x0" ]; then
16133                 error "flag $flags is not 0x0"
16134         fi
16135         echo "rename doesn't overwrite a target," \
16136                 "changelog record has flags of $flags"
16137
16138         # define CLF_UNLINK_LAST 0x0001
16139         # unlink a file having nlink = 1 (changelog flag 0x1)
16140         rm -f $DIR/$tdir/foo2_161c
16141         changelog_dump | grep UNLNK | tail -n 5
16142         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16143         changelog_clear 0 || error "changelog_clear failed"
16144         if [ x$flags != "x0x1" ]; then
16145                 error "flag $flags is not 0x1"
16146         fi
16147         echo "unlink a file having nlink = 1," \
16148                 "changelog record has flags of $flags"
16149
16150         # unlink a file having nlink > 1 (changelog flag 0x0)
16151         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16152         rm -f $DIR/$tdir/foobar_161c
16153         changelog_dump | grep UNLNK | tail -n 5
16154         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16155         changelog_clear 0 || error "changelog_clear failed"
16156         if [ x$flags != "x0x0" ]; then
16157                 error "flag $flags is not 0x0"
16158         fi
16159         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16160 }
16161 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16162
16163 test_161d() {
16164         remote_mds_nodsh && skip "remote MDS with nodsh"
16165         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16166
16167         local pid
16168         local fid
16169
16170         changelog_register || error "changelog_register failed"
16171
16172         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16173         # interfer with $MOUNT/.lustre/fid/ access
16174         mkdir $DIR/$tdir
16175         [[ $? -eq 0 ]] || error "mkdir failed"
16176
16177         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16178         $LCTL set_param fail_loc=0x8000140c
16179         # 5s pause
16180         $LCTL set_param fail_val=5
16181
16182         # create file
16183         echo foofoo > $DIR/$tdir/$tfile &
16184         pid=$!
16185
16186         # wait for create to be delayed
16187         sleep 2
16188
16189         ps -p $pid
16190         [[ $? -eq 0 ]] || error "create should be blocked"
16191
16192         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16193         stack_trap "rm -f $tempfile"
16194         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16195         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16196         # some delay may occur during ChangeLog publishing and file read just
16197         # above, that could allow file write to happen finally
16198         [[ -s $tempfile ]] && echo "file should be empty"
16199
16200         $LCTL set_param fail_loc=0
16201
16202         wait $pid
16203         [[ $? -eq 0 ]] || error "create failed"
16204 }
16205 run_test 161d "create with concurrent .lustre/fid access"
16206
16207 check_path() {
16208         local expected="$1"
16209         shift
16210         local fid="$2"
16211
16212         local path
16213         path=$($LFS fid2path "$@")
16214         local rc=$?
16215
16216         if [ $rc -ne 0 ]; then
16217                 error "path looked up of '$expected' failed: rc=$rc"
16218         elif [ "$path" != "$expected" ]; then
16219                 error "path looked up '$path' instead of '$expected'"
16220         else
16221                 echo "FID '$fid' resolves to path '$path' as expected"
16222         fi
16223 }
16224
16225 test_162a() { # was test_162
16226         test_mkdir -p -c1 $DIR/$tdir/d2
16227         touch $DIR/$tdir/d2/$tfile
16228         touch $DIR/$tdir/d2/x1
16229         touch $DIR/$tdir/d2/x2
16230         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16231         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16232         # regular file
16233         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16234         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16235
16236         # softlink
16237         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16238         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16239         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16240
16241         # softlink to wrong file
16242         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16243         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16244         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16245
16246         # hardlink
16247         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16248         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16249         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16250         # fid2path dir/fsname should both work
16251         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16252         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16253
16254         # hardlink count: check that there are 2 links
16255         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16256         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16257
16258         # hardlink indexing: remove the first link
16259         rm $DIR/$tdir/d2/p/q/r/hlink
16260         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16261 }
16262 run_test 162a "path lookup sanity"
16263
16264 test_162b() {
16265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16266         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16267
16268         mkdir $DIR/$tdir
16269         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16270                                 error "create striped dir failed"
16271
16272         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16273                                         tail -n 1 | awk '{print $2}')
16274         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16275
16276         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16277         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16278
16279         # regular file
16280         for ((i=0;i<5;i++)); do
16281                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16282                         error "get fid for f$i failed"
16283                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16284
16285                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16286                         error "get fid for d$i failed"
16287                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16288         done
16289
16290         return 0
16291 }
16292 run_test 162b "striped directory path lookup sanity"
16293
16294 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16295 test_162c() {
16296         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16297                 skip "Need MDS version at least 2.7.51"
16298
16299         local lpath=$tdir.local
16300         local rpath=$tdir.remote
16301
16302         test_mkdir $DIR/$lpath
16303         test_mkdir $DIR/$rpath
16304
16305         for ((i = 0; i <= 101; i++)); do
16306                 lpath="$lpath/$i"
16307                 mkdir $DIR/$lpath
16308                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16309                         error "get fid for local directory $DIR/$lpath failed"
16310                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16311
16312                 rpath="$rpath/$i"
16313                 test_mkdir $DIR/$rpath
16314                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16315                         error "get fid for remote directory $DIR/$rpath failed"
16316                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16317         done
16318
16319         return 0
16320 }
16321 run_test 162c "fid2path works with paths 100 or more directories deep"
16322
16323 oalr_event_count() {
16324         local event="${1}"
16325         local trace="${2}"
16326
16327         awk -v name="${FSNAME}-OST0000" \
16328             -v event="${event}" \
16329             '$1 == "TRACE" && $2 == event && $3 == name' \
16330             "${trace}" |
16331         wc -l
16332 }
16333
16334 oalr_expect_event_count() {
16335         local event="${1}"
16336         local trace="${2}"
16337         local expect="${3}"
16338         local count
16339
16340         count=$(oalr_event_count "${event}" "${trace}")
16341         if ((count == expect)); then
16342                 return 0
16343         fi
16344
16345         error_noexit "${event} event count was '${count}', expected ${expect}"
16346         cat "${trace}" >&2
16347         exit 1
16348 }
16349
16350 cleanup_165() {
16351         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16352         stop ost1
16353         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16354 }
16355
16356 setup_165() {
16357         sync # Flush previous IOs so we can count log entries.
16358         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16359         stack_trap cleanup_165 EXIT
16360 }
16361
16362 test_165a() {
16363         local trace="/tmp/${tfile}.trace"
16364         local rc
16365         local count
16366
16367         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16368                 skip "OFD access log unsupported"
16369
16370         setup_165
16371         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16372         sleep 5
16373
16374         do_facet ost1 ofd_access_log_reader --list
16375         stop ost1
16376
16377         do_facet ost1 killall -TERM ofd_access_log_reader
16378         wait
16379         rc=$?
16380
16381         if ((rc != 0)); then
16382                 error "ofd_access_log_reader exited with rc = '${rc}'"
16383         fi
16384
16385         # Parse trace file for discovery events:
16386         oalr_expect_event_count alr_log_add "${trace}" 1
16387         oalr_expect_event_count alr_log_eof "${trace}" 1
16388         oalr_expect_event_count alr_log_free "${trace}" 1
16389 }
16390 run_test 165a "ofd access log discovery"
16391
16392 test_165b() {
16393         local trace="/tmp/${tfile}.trace"
16394         local file="${DIR}/${tfile}"
16395         local pfid1
16396         local pfid2
16397         local -a entry
16398         local rc
16399         local count
16400         local size
16401         local flags
16402
16403         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16404                 skip "OFD access log unsupported"
16405
16406         setup_165
16407         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16408         sleep 5
16409
16410         do_facet ost1 ofd_access_log_reader --list
16411
16412         lfs setstripe -c 1 -i 0 "${file}"
16413         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16414                 error "cannot create '${file}'"
16415
16416         sleep 5
16417         do_facet ost1 killall -TERM ofd_access_log_reader
16418         wait
16419         rc=$?
16420
16421         if ((rc != 0)); then
16422                 error "ofd_access_log_reader exited with rc = '${rc}'"
16423         fi
16424
16425         oalr_expect_event_count alr_log_entry "${trace}" 1
16426
16427         pfid1=$($LFS path2fid "${file}")
16428
16429         # 1     2             3   4    5     6   7    8    9     10
16430         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16431         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16432
16433         echo "entry = '${entry[*]}'" >&2
16434
16435         pfid2=${entry[4]}
16436         if [[ "${pfid1}" != "${pfid2}" ]]; then
16437                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16438         fi
16439
16440         size=${entry[8]}
16441         if ((size != 1048576)); then
16442                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16443         fi
16444
16445         flags=${entry[10]}
16446         if [[ "${flags}" != "w" ]]; then
16447                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16448         fi
16449
16450         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16451         sleep 5
16452
16453         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16454                 error "cannot read '${file}'"
16455         sleep 5
16456
16457         do_facet ost1 killall -TERM ofd_access_log_reader
16458         wait
16459         rc=$?
16460
16461         if ((rc != 0)); then
16462                 error "ofd_access_log_reader exited with rc = '${rc}'"
16463         fi
16464
16465         oalr_expect_event_count alr_log_entry "${trace}" 1
16466
16467         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16468         echo "entry = '${entry[*]}'" >&2
16469
16470         pfid2=${entry[4]}
16471         if [[ "${pfid1}" != "${pfid2}" ]]; then
16472                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16473         fi
16474
16475         size=${entry[8]}
16476         if ((size != 524288)); then
16477                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16478         fi
16479
16480         flags=${entry[10]}
16481         if [[ "${flags}" != "r" ]]; then
16482                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16483         fi
16484 }
16485 run_test 165b "ofd access log entries are produced and consumed"
16486
16487 test_165c() {
16488         local trace="/tmp/${tfile}.trace"
16489         local file="${DIR}/${tdir}/${tfile}"
16490
16491         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16492                 skip "OFD access log unsupported"
16493
16494         test_mkdir "${DIR}/${tdir}"
16495
16496         setup_165
16497         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16498         sleep 5
16499
16500         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16501
16502         # 4096 / 64 = 64. Create twice as many entries.
16503         for ((i = 0; i < 128; i++)); do
16504                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16505                         error "cannot create file"
16506         done
16507
16508         sync
16509
16510         do_facet ost1 killall -TERM ofd_access_log_reader
16511         wait
16512         rc=$?
16513         if ((rc != 0)); then
16514                 error "ofd_access_log_reader exited with rc = '${rc}'"
16515         fi
16516
16517         unlinkmany  "${file}-%d" 128
16518 }
16519 run_test 165c "full ofd access logs do not block IOs"
16520
16521 oal_get_read_count() {
16522         local stats="$1"
16523
16524         # STATS lustre-OST0001 alr_read_count 1
16525
16526         do_facet ost1 cat "${stats}" |
16527         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16528              END { print count; }'
16529 }
16530
16531 oal_expect_read_count() {
16532         local stats="$1"
16533         local count
16534         local expect="$2"
16535
16536         # Ask ofd_access_log_reader to write stats.
16537         do_facet ost1 killall -USR1 ofd_access_log_reader
16538
16539         # Allow some time for things to happen.
16540         sleep 1
16541
16542         count=$(oal_get_read_count "${stats}")
16543         if ((count == expect)); then
16544                 return 0
16545         fi
16546
16547         error_noexit "bad read count, got ${count}, expected ${expect}"
16548         do_facet ost1 cat "${stats}" >&2
16549         exit 1
16550 }
16551
16552 test_165d() {
16553         local stats="/tmp/${tfile}.stats"
16554         local file="${DIR}/${tdir}/${tfile}"
16555         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16556
16557         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16558                 skip "OFD access log unsupported"
16559
16560         test_mkdir "${DIR}/${tdir}"
16561
16562         setup_165
16563         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16564         sleep 5
16565
16566         lfs setstripe -c 1 -i 0 "${file}"
16567
16568         do_facet ost1 lctl set_param "${param}=rw"
16569         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16570                 error "cannot create '${file}'"
16571         oal_expect_read_count "${stats}" 1
16572
16573         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16574                 error "cannot read '${file}'"
16575         oal_expect_read_count "${stats}" 2
16576
16577         do_facet ost1 lctl set_param "${param}=r"
16578         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16579                 error "cannot create '${file}'"
16580         oal_expect_read_count "${stats}" 2
16581
16582         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16583                 error "cannot read '${file}'"
16584         oal_expect_read_count "${stats}" 3
16585
16586         do_facet ost1 lctl set_param "${param}=w"
16587         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16588                 error "cannot create '${file}'"
16589         oal_expect_read_count "${stats}" 4
16590
16591         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16592                 error "cannot read '${file}'"
16593         oal_expect_read_count "${stats}" 4
16594
16595         do_facet ost1 lctl set_param "${param}=0"
16596         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16597                 error "cannot create '${file}'"
16598         oal_expect_read_count "${stats}" 4
16599
16600         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16601                 error "cannot read '${file}'"
16602         oal_expect_read_count "${stats}" 4
16603
16604         do_facet ost1 killall -TERM ofd_access_log_reader
16605         wait
16606         rc=$?
16607         if ((rc != 0)); then
16608                 error "ofd_access_log_reader exited with rc = '${rc}'"
16609         fi
16610 }
16611 run_test 165d "ofd_access_log mask works"
16612
16613 test_165e() {
16614         local stats="/tmp/${tfile}.stats"
16615         local file0="${DIR}/${tdir}-0/${tfile}"
16616         local file1="${DIR}/${tdir}-1/${tfile}"
16617
16618         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16619                 skip "OFD access log unsupported"
16620
16621         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16622
16623         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16624         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16625
16626         lfs setstripe -c 1 -i 0 "${file0}"
16627         lfs setstripe -c 1 -i 0 "${file1}"
16628
16629         setup_165
16630         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16631         sleep 5
16632
16633         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16634                 error "cannot create '${file0}'"
16635         sync
16636         oal_expect_read_count "${stats}" 0
16637
16638         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16639                 error "cannot create '${file1}'"
16640         sync
16641         oal_expect_read_count "${stats}" 1
16642
16643         do_facet ost1 killall -TERM ofd_access_log_reader
16644         wait
16645         rc=$?
16646         if ((rc != 0)); then
16647                 error "ofd_access_log_reader exited with rc = '${rc}'"
16648         fi
16649 }
16650 run_test 165e "ofd_access_log MDT index filter works"
16651
16652 test_165f() {
16653         local trace="/tmp/${tfile}.trace"
16654         local rc
16655         local count
16656
16657         setup_165
16658         do_facet ost1 timeout 60 ofd_access_log_reader \
16659                 --exit-on-close --debug=- --trace=- > "${trace}" &
16660         sleep 5
16661         stop ost1
16662
16663         wait
16664         rc=$?
16665
16666         if ((rc != 0)); then
16667                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
16668                 cat "${trace}"
16669                 exit 1
16670         fi
16671 }
16672 run_test 165f "ofd_access_log_reader --exit-on-close works"
16673
16674 test_169() {
16675         # do directio so as not to populate the page cache
16676         log "creating a 10 Mb file"
16677         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
16678                 error "multiop failed while creating a file"
16679         log "starting reads"
16680         dd if=$DIR/$tfile of=/dev/null bs=4096 &
16681         log "truncating the file"
16682         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
16683                 error "multiop failed while truncating the file"
16684         log "killing dd"
16685         kill %+ || true # reads might have finished
16686         echo "wait until dd is finished"
16687         wait
16688         log "removing the temporary file"
16689         rm -rf $DIR/$tfile || error "tmp file removal failed"
16690 }
16691 run_test 169 "parallel read and truncate should not deadlock"
16692
16693 test_170() {
16694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16695
16696         $LCTL clear     # bug 18514
16697         $LCTL debug_daemon start $TMP/${tfile}_log_good
16698         touch $DIR/$tfile
16699         $LCTL debug_daemon stop
16700         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
16701                 error "sed failed to read log_good"
16702
16703         $LCTL debug_daemon start $TMP/${tfile}_log_good
16704         rm -rf $DIR/$tfile
16705         $LCTL debug_daemon stop
16706
16707         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
16708                error "lctl df log_bad failed"
16709
16710         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16711         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16712
16713         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
16714         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
16715
16716         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
16717                 error "bad_line good_line1 good_line2 are empty"
16718
16719         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16720         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
16721         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
16722
16723         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
16724         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
16725         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
16726
16727         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
16728                 error "bad_line_new good_line_new are empty"
16729
16730         local expected_good=$((good_line1 + good_line2*2))
16731
16732         rm -f $TMP/${tfile}*
16733         # LU-231, short malformed line may not be counted into bad lines
16734         if [ $bad_line -ne $bad_line_new ] &&
16735                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
16736                 error "expected $bad_line bad lines, but got $bad_line_new"
16737                 return 1
16738         fi
16739
16740         if [ $expected_good -ne $good_line_new ]; then
16741                 error "expected $expected_good good lines, but got $good_line_new"
16742                 return 2
16743         fi
16744         true
16745 }
16746 run_test 170 "test lctl df to handle corrupted log ====================="
16747
16748 test_171() { # bug20592
16749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16750
16751         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
16752         $LCTL set_param fail_loc=0x50e
16753         $LCTL set_param fail_val=3000
16754         multiop_bg_pause $DIR/$tfile O_s || true
16755         local MULTIPID=$!
16756         kill -USR1 $MULTIPID
16757         # cause log dump
16758         sleep 3
16759         wait $MULTIPID
16760         if dmesg | grep "recursive fault"; then
16761                 error "caught a recursive fault"
16762         fi
16763         $LCTL set_param fail_loc=0
16764         true
16765 }
16766 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16767
16768 # it would be good to share it with obdfilter-survey/iokit-libecho code
16769 setup_obdecho_osc () {
16770         local rc=0
16771         local ost_nid=$1
16772         local obdfilter_name=$2
16773         echo "Creating new osc for $obdfilter_name on $ost_nid"
16774         # make sure we can find loopback nid
16775         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16776
16777         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16778                            ${obdfilter_name}_osc_UUID || rc=2; }
16779         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16780                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16781         return $rc
16782 }
16783
16784 cleanup_obdecho_osc () {
16785         local obdfilter_name=$1
16786         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16787         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16788         return 0
16789 }
16790
16791 obdecho_test() {
16792         local OBD=$1
16793         local node=$2
16794         local pages=${3:-64}
16795         local rc=0
16796         local id
16797
16798         local count=10
16799         local obd_size=$(get_obd_size $node $OBD)
16800         local page_size=$(get_page_size $node)
16801         if [[ -n "$obd_size" ]]; then
16802                 local new_count=$((obd_size / (pages * page_size / 1024)))
16803                 [[ $new_count -ge $count ]] || count=$new_count
16804         fi
16805
16806         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16807         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16808                            rc=2; }
16809         if [ $rc -eq 0 ]; then
16810             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16811             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16812         fi
16813         echo "New object id is $id"
16814         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16815                            rc=4; }
16816         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16817                            "test_brw $count w v $pages $id" || rc=4; }
16818         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16819                            rc=4; }
16820         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16821                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16822         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16823                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16824         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16825         return $rc
16826 }
16827
16828 test_180a() {
16829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16830
16831         if ! [ -d /sys/fs/lustre/echo_client ] &&
16832            ! module_loaded obdecho; then
16833                 load_module obdecho/obdecho &&
16834                         stack_trap "rmmod obdecho" EXIT ||
16835                         error "unable to load obdecho on client"
16836         fi
16837
16838         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16839         local host=$($LCTL get_param -n osc.$osc.import |
16840                      awk '/current_connection:/ { print $2 }' )
16841         local target=$($LCTL get_param -n osc.$osc.import |
16842                        awk '/target:/ { print $2 }' )
16843         target=${target%_UUID}
16844
16845         if [ -n "$target" ]; then
16846                 setup_obdecho_osc $host $target &&
16847                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16848                         { error "obdecho setup failed with $?"; return; }
16849
16850                 obdecho_test ${target}_osc client ||
16851                         error "obdecho_test failed on ${target}_osc"
16852         else
16853                 $LCTL get_param osc.$osc.import
16854                 error "there is no osc.$osc.import target"
16855         fi
16856 }
16857 run_test 180a "test obdecho on osc"
16858
16859 test_180b() {
16860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16861         remote_ost_nodsh && skip "remote OST with nodsh"
16862
16863         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16864                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16865                 error "failed to load module obdecho"
16866
16867         local target=$(do_facet ost1 $LCTL dl |
16868                        awk '/obdfilter/ { print $4; exit; }')
16869
16870         if [ -n "$target" ]; then
16871                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16872         else
16873                 do_facet ost1 $LCTL dl
16874                 error "there is no obdfilter target on ost1"
16875         fi
16876 }
16877 run_test 180b "test obdecho directly on obdfilter"
16878
16879 test_180c() { # LU-2598
16880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16881         remote_ost_nodsh && skip "remote OST with nodsh"
16882         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16883                 skip "Need MDS version at least 2.4.0"
16884
16885         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16886                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16887                 error "failed to load module obdecho"
16888
16889         local target=$(do_facet ost1 $LCTL dl |
16890                        awk '/obdfilter/ { print $4; exit; }')
16891
16892         if [ -n "$target" ]; then
16893                 local pages=16384 # 64MB bulk I/O RPC size
16894
16895                 obdecho_test "$target" ost1 "$pages" ||
16896                         error "obdecho_test with pages=$pages failed with $?"
16897         else
16898                 do_facet ost1 $LCTL dl
16899                 error "there is no obdfilter target on ost1"
16900         fi
16901 }
16902 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16903
16904 test_181() { # bug 22177
16905         test_mkdir $DIR/$tdir
16906         # create enough files to index the directory
16907         createmany -o $DIR/$tdir/foobar 4000
16908         # print attributes for debug purpose
16909         lsattr -d .
16910         # open dir
16911         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16912         MULTIPID=$!
16913         # remove the files & current working dir
16914         unlinkmany $DIR/$tdir/foobar 4000
16915         rmdir $DIR/$tdir
16916         kill -USR1 $MULTIPID
16917         wait $MULTIPID
16918         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16919         return 0
16920 }
16921 run_test 181 "Test open-unlinked dir ========================"
16922
16923 test_182() {
16924         local fcount=1000
16925         local tcount=10
16926
16927         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16928
16929         $LCTL set_param mdc.*.rpc_stats=clear
16930
16931         for (( i = 0; i < $tcount; i++ )) ; do
16932                 mkdir $DIR/$tdir/$i
16933         done
16934
16935         for (( i = 0; i < $tcount; i++ )) ; do
16936                 createmany -o $DIR/$tdir/$i/f- $fcount &
16937         done
16938         wait
16939
16940         for (( i = 0; i < $tcount; i++ )) ; do
16941                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16942         done
16943         wait
16944
16945         $LCTL get_param mdc.*.rpc_stats
16946
16947         rm -rf $DIR/$tdir
16948 }
16949 run_test 182 "Test parallel modify metadata operations ================"
16950
16951 test_183() { # LU-2275
16952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16953         remote_mds_nodsh && skip "remote MDS with nodsh"
16954         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16955                 skip "Need MDS version at least 2.3.56"
16956
16957         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16958         echo aaa > $DIR/$tdir/$tfile
16959
16960 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16961         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16962
16963         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16964         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16965
16966         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16967
16968         # Flush negative dentry cache
16969         touch $DIR/$tdir/$tfile
16970
16971         # We are not checking for any leaked references here, they'll
16972         # become evident next time we do cleanup with module unload.
16973         rm -rf $DIR/$tdir
16974 }
16975 run_test 183 "No crash or request leak in case of strange dispositions ========"
16976
16977 # test suite 184 is for LU-2016, LU-2017
16978 test_184a() {
16979         check_swap_layouts_support
16980
16981         dir0=$DIR/$tdir/$testnum
16982         test_mkdir -p -c1 $dir0
16983         ref1=/etc/passwd
16984         ref2=/etc/group
16985         file1=$dir0/f1
16986         file2=$dir0/f2
16987         $LFS setstripe -c1 $file1
16988         cp $ref1 $file1
16989         $LFS setstripe -c2 $file2
16990         cp $ref2 $file2
16991         gen1=$($LFS getstripe -g $file1)
16992         gen2=$($LFS getstripe -g $file2)
16993
16994         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16995         gen=$($LFS getstripe -g $file1)
16996         [[ $gen1 != $gen ]] ||
16997                 "Layout generation on $file1 does not change"
16998         gen=$($LFS getstripe -g $file2)
16999         [[ $gen2 != $gen ]] ||
17000                 "Layout generation on $file2 does not change"
17001
17002         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17003         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17004
17005         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17006 }
17007 run_test 184a "Basic layout swap"
17008
17009 test_184b() {
17010         check_swap_layouts_support
17011
17012         dir0=$DIR/$tdir/$testnum
17013         mkdir -p $dir0 || error "creating dir $dir0"
17014         file1=$dir0/f1
17015         file2=$dir0/f2
17016         file3=$dir0/f3
17017         dir1=$dir0/d1
17018         dir2=$dir0/d2
17019         mkdir $dir1 $dir2
17020         $LFS setstripe -c1 $file1
17021         $LFS setstripe -c2 $file2
17022         $LFS setstripe -c1 $file3
17023         chown $RUNAS_ID $file3
17024         gen1=$($LFS getstripe -g $file1)
17025         gen2=$($LFS getstripe -g $file2)
17026
17027         $LFS swap_layouts $dir1 $dir2 &&
17028                 error "swap of directories layouts should fail"
17029         $LFS swap_layouts $dir1 $file1 &&
17030                 error "swap of directory and file layouts should fail"
17031         $RUNAS $LFS swap_layouts $file1 $file2 &&
17032                 error "swap of file we cannot write should fail"
17033         $LFS swap_layouts $file1 $file3 &&
17034                 error "swap of file with different owner should fail"
17035         /bin/true # to clear error code
17036 }
17037 run_test 184b "Forbidden layout swap (will generate errors)"
17038
17039 test_184c() {
17040         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17041         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17042         check_swap_layouts_support
17043         check_swap_layout_no_dom $DIR
17044
17045         local dir0=$DIR/$tdir/$testnum
17046         mkdir -p $dir0 || error "creating dir $dir0"
17047
17048         local ref1=$dir0/ref1
17049         local ref2=$dir0/ref2
17050         local file1=$dir0/file1
17051         local file2=$dir0/file2
17052         # create a file large enough for the concurrent test
17053         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17054         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17055         echo "ref file size: ref1($(stat -c %s $ref1))," \
17056              "ref2($(stat -c %s $ref2))"
17057
17058         cp $ref2 $file2
17059         dd if=$ref1 of=$file1 bs=16k &
17060         local DD_PID=$!
17061
17062         # Make sure dd starts to copy file, but wait at most 5 seconds
17063         local loops=0
17064         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17065
17066         $LFS swap_layouts $file1 $file2
17067         local rc=$?
17068         wait $DD_PID
17069         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17070         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17071
17072         # how many bytes copied before swapping layout
17073         local copied=$(stat -c %s $file2)
17074         local remaining=$(stat -c %s $ref1)
17075         remaining=$((remaining - copied))
17076         echo "Copied $copied bytes before swapping layout..."
17077
17078         cmp -n $copied $file1 $ref2 | grep differ &&
17079                 error "Content mismatch [0, $copied) of ref2 and file1"
17080         cmp -n $copied $file2 $ref1 ||
17081                 error "Content mismatch [0, $copied) of ref1 and file2"
17082         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17083                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17084
17085         # clean up
17086         rm -f $ref1 $ref2 $file1 $file2
17087 }
17088 run_test 184c "Concurrent write and layout swap"
17089
17090 test_184d() {
17091         check_swap_layouts_support
17092         check_swap_layout_no_dom $DIR
17093         [ -z "$(which getfattr 2>/dev/null)" ] &&
17094                 skip_env "no getfattr command"
17095
17096         local file1=$DIR/$tdir/$tfile-1
17097         local file2=$DIR/$tdir/$tfile-2
17098         local file3=$DIR/$tdir/$tfile-3
17099         local lovea1
17100         local lovea2
17101
17102         mkdir -p $DIR/$tdir
17103         touch $file1 || error "create $file1 failed"
17104         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17105                 error "create $file2 failed"
17106         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17107                 error "create $file3 failed"
17108         lovea1=$(get_layout_param $file1)
17109
17110         $LFS swap_layouts $file2 $file3 ||
17111                 error "swap $file2 $file3 layouts failed"
17112         $LFS swap_layouts $file1 $file2 ||
17113                 error "swap $file1 $file2 layouts failed"
17114
17115         lovea2=$(get_layout_param $file2)
17116         echo "$lovea1"
17117         echo "$lovea2"
17118         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17119
17120         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17121         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17122 }
17123 run_test 184d "allow stripeless layouts swap"
17124
17125 test_184e() {
17126         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17127                 skip "Need MDS version at least 2.6.94"
17128         check_swap_layouts_support
17129         check_swap_layout_no_dom $DIR
17130         [ -z "$(which getfattr 2>/dev/null)" ] &&
17131                 skip_env "no getfattr command"
17132
17133         local file1=$DIR/$tdir/$tfile-1
17134         local file2=$DIR/$tdir/$tfile-2
17135         local file3=$DIR/$tdir/$tfile-3
17136         local lovea
17137
17138         mkdir -p $DIR/$tdir
17139         touch $file1 || error "create $file1 failed"
17140         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17141                 error "create $file2 failed"
17142         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17143                 error "create $file3 failed"
17144
17145         $LFS swap_layouts $file1 $file2 ||
17146                 error "swap $file1 $file2 layouts failed"
17147
17148         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17149         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17150
17151         echo 123 > $file1 || error "Should be able to write into $file1"
17152
17153         $LFS swap_layouts $file1 $file3 ||
17154                 error "swap $file1 $file3 layouts failed"
17155
17156         echo 123 > $file1 || error "Should be able to write into $file1"
17157
17158         rm -rf $file1 $file2 $file3
17159 }
17160 run_test 184e "Recreate layout after stripeless layout swaps"
17161
17162 test_184f() {
17163         # Create a file with name longer than sizeof(struct stat) ==
17164         # 144 to see if we can get chars from the file name to appear
17165         # in the returned striping. Note that 'f' == 0x66.
17166         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17167
17168         mkdir -p $DIR/$tdir
17169         mcreate $DIR/$tdir/$file
17170         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17171                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17172         fi
17173 }
17174 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17175
17176 test_185() { # LU-2441
17177         # LU-3553 - no volatile file support in old servers
17178         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17179                 skip "Need MDS version at least 2.3.60"
17180
17181         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17182         touch $DIR/$tdir/spoo
17183         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17184         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17185                 error "cannot create/write a volatile file"
17186         [ "$FILESET" == "" ] &&
17187         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17188                 error "FID is still valid after close"
17189
17190         multiop_bg_pause $DIR/$tdir vVw4096_c
17191         local multi_pid=$!
17192
17193         local OLD_IFS=$IFS
17194         IFS=":"
17195         local fidv=($fid)
17196         IFS=$OLD_IFS
17197         # assume that the next FID for this client is sequential, since stdout
17198         # is unfortunately eaten by multiop_bg_pause
17199         local n=$((${fidv[1]} + 1))
17200         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17201         if [ "$FILESET" == "" ]; then
17202                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17203                         error "FID is missing before close"
17204         fi
17205         kill -USR1 $multi_pid
17206         # 1 second delay, so if mtime change we will see it
17207         sleep 1
17208         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17209         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17210 }
17211 run_test 185 "Volatile file support"
17212
17213 function create_check_volatile() {
17214         local idx=$1
17215         local tgt
17216
17217         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17218         local PID=$!
17219         sleep 1
17220         local FID=$(cat /tmp/${tfile}.fid)
17221         [ "$FID" == "" ] && error "can't get FID for volatile"
17222         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17223         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17224         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17225         kill -USR1 $PID
17226         wait
17227         sleep 1
17228         cancel_lru_locks mdc # flush opencache
17229         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17230         return 0
17231 }
17232
17233 test_185a(){
17234         # LU-12516 - volatile creation via .lustre
17235         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17236                 skip "Need MDS version at least 2.3.55"
17237
17238         create_check_volatile 0
17239         [ $MDSCOUNT -lt 2 ] && return 0
17240
17241         # DNE case
17242         create_check_volatile 1
17243
17244         return 0
17245 }
17246 run_test 185a "Volatile file creation in .lustre/fid/"
17247
17248 test_187a() {
17249         remote_mds_nodsh && skip "remote MDS with nodsh"
17250         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17251                 skip "Need MDS version at least 2.3.0"
17252
17253         local dir0=$DIR/$tdir/$testnum
17254         mkdir -p $dir0 || error "creating dir $dir0"
17255
17256         local file=$dir0/file1
17257         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17258         local dv1=$($LFS data_version $file)
17259         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17260         local dv2=$($LFS data_version $file)
17261         [[ $dv1 != $dv2 ]] ||
17262                 error "data version did not change on write $dv1 == $dv2"
17263
17264         # clean up
17265         rm -f $file1
17266 }
17267 run_test 187a "Test data version change"
17268
17269 test_187b() {
17270         remote_mds_nodsh && skip "remote MDS with nodsh"
17271         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17272                 skip "Need MDS version at least 2.3.0"
17273
17274         local dir0=$DIR/$tdir/$testnum
17275         mkdir -p $dir0 || error "creating dir $dir0"
17276
17277         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17278         [[ ${DV[0]} != ${DV[1]} ]] ||
17279                 error "data version did not change on write"\
17280                       " ${DV[0]} == ${DV[1]}"
17281
17282         # clean up
17283         rm -f $file1
17284 }
17285 run_test 187b "Test data version change on volatile file"
17286
17287 test_200() {
17288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17289         remote_mgs_nodsh && skip "remote MGS with nodsh"
17290         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17291
17292         local POOL=${POOL:-cea1}
17293         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17294         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17295         # Pool OST targets
17296         local first_ost=0
17297         local last_ost=$(($OSTCOUNT - 1))
17298         local ost_step=2
17299         local ost_list=$(seq $first_ost $ost_step $last_ost)
17300         local ost_range="$first_ost $last_ost $ost_step"
17301         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17302         local file_dir=$POOL_ROOT/file_tst
17303         local subdir=$test_path/subdir
17304         local rc=0
17305
17306         while : ; do
17307                 # former test_200a test_200b
17308                 pool_add $POOL                          || { rc=$? ; break; }
17309                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17310                 # former test_200c test_200d
17311                 mkdir -p $test_path
17312                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17313                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17314                 mkdir -p $subdir
17315                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17316                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17317                                                         || { rc=$? ; break; }
17318                 # former test_200e test_200f
17319                 local files=$((OSTCOUNT*3))
17320                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17321                                                         || { rc=$? ; break; }
17322                 pool_create_files $POOL $file_dir $files "$ost_list" \
17323                                                         || { rc=$? ; break; }
17324                 # former test_200g test_200h
17325                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17326                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17327
17328                 # former test_201a test_201b test_201c
17329                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17330
17331                 local f=$test_path/$tfile
17332                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17333                 pool_remove $POOL $f                    || { rc=$? ; break; }
17334                 break
17335         done
17336
17337         destroy_test_pools
17338
17339         return $rc
17340 }
17341 run_test 200 "OST pools"
17342
17343 # usage: default_attr <count | size | offset>
17344 default_attr() {
17345         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17346 }
17347
17348 # usage: check_default_stripe_attr
17349 check_default_stripe_attr() {
17350         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17351         case $1 in
17352         --stripe-count|-c)
17353                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17354         --stripe-size|-S)
17355                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17356         --stripe-index|-i)
17357                 EXPECTED=-1;;
17358         *)
17359                 error "unknown getstripe attr '$1'"
17360         esac
17361
17362         [ $ACTUAL == $EXPECTED ] ||
17363                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17364 }
17365
17366 test_204a() {
17367         test_mkdir $DIR/$tdir
17368         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17369
17370         check_default_stripe_attr --stripe-count
17371         check_default_stripe_attr --stripe-size
17372         check_default_stripe_attr --stripe-index
17373 }
17374 run_test 204a "Print default stripe attributes"
17375
17376 test_204b() {
17377         test_mkdir $DIR/$tdir
17378         $LFS setstripe --stripe-count 1 $DIR/$tdir
17379
17380         check_default_stripe_attr --stripe-size
17381         check_default_stripe_attr --stripe-index
17382 }
17383 run_test 204b "Print default stripe size and offset"
17384
17385 test_204c() {
17386         test_mkdir $DIR/$tdir
17387         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17388
17389         check_default_stripe_attr --stripe-count
17390         check_default_stripe_attr --stripe-index
17391 }
17392 run_test 204c "Print default stripe count and offset"
17393
17394 test_204d() {
17395         test_mkdir $DIR/$tdir
17396         $LFS setstripe --stripe-index 0 $DIR/$tdir
17397
17398         check_default_stripe_attr --stripe-count
17399         check_default_stripe_attr --stripe-size
17400 }
17401 run_test 204d "Print default stripe count and size"
17402
17403 test_204e() {
17404         test_mkdir $DIR/$tdir
17405         $LFS setstripe -d $DIR/$tdir
17406
17407         check_default_stripe_attr --stripe-count --raw
17408         check_default_stripe_attr --stripe-size --raw
17409         check_default_stripe_attr --stripe-index --raw
17410 }
17411 run_test 204e "Print raw stripe attributes"
17412
17413 test_204f() {
17414         test_mkdir $DIR/$tdir
17415         $LFS setstripe --stripe-count 1 $DIR/$tdir
17416
17417         check_default_stripe_attr --stripe-size --raw
17418         check_default_stripe_attr --stripe-index --raw
17419 }
17420 run_test 204f "Print raw stripe size and offset"
17421
17422 test_204g() {
17423         test_mkdir $DIR/$tdir
17424         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17425
17426         check_default_stripe_attr --stripe-count --raw
17427         check_default_stripe_attr --stripe-index --raw
17428 }
17429 run_test 204g "Print raw stripe count and offset"
17430
17431 test_204h() {
17432         test_mkdir $DIR/$tdir
17433         $LFS setstripe --stripe-index 0 $DIR/$tdir
17434
17435         check_default_stripe_attr --stripe-count --raw
17436         check_default_stripe_attr --stripe-size --raw
17437 }
17438 run_test 204h "Print raw stripe count and size"
17439
17440 # Figure out which job scheduler is being used, if any,
17441 # or use a fake one
17442 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17443         JOBENV=SLURM_JOB_ID
17444 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17445         JOBENV=LSB_JOBID
17446 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17447         JOBENV=PBS_JOBID
17448 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17449         JOBENV=LOADL_STEP_ID
17450 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17451         JOBENV=JOB_ID
17452 else
17453         $LCTL list_param jobid_name > /dev/null 2>&1
17454         if [ $? -eq 0 ]; then
17455                 JOBENV=nodelocal
17456         else
17457                 JOBENV=FAKE_JOBID
17458         fi
17459 fi
17460 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17461
17462 verify_jobstats() {
17463         local cmd=($1)
17464         shift
17465         local facets="$@"
17466
17467 # we don't really need to clear the stats for this test to work, since each
17468 # command has a unique jobid, but it makes debugging easier if needed.
17469 #       for facet in $facets; do
17470 #               local dev=$(convert_facet2label $facet)
17471 #               # clear old jobstats
17472 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17473 #       done
17474
17475         # use a new JobID for each test, or we might see an old one
17476         [ "$JOBENV" = "FAKE_JOBID" ] &&
17477                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17478
17479         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17480
17481         [ "$JOBENV" = "nodelocal" ] && {
17482                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17483                 $LCTL set_param jobid_name=$FAKE_JOBID
17484                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17485         }
17486
17487         log "Test: ${cmd[*]}"
17488         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17489
17490         if [ $JOBENV = "FAKE_JOBID" ]; then
17491                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17492         else
17493                 ${cmd[*]}
17494         fi
17495
17496         # all files are created on OST0000
17497         for facet in $facets; do
17498                 local stats="*.$(convert_facet2label $facet).job_stats"
17499
17500                 # strip out libtool wrappers for in-tree executables
17501                 if [ $(do_facet $facet lctl get_param $stats |
17502                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17503                         do_facet $facet lctl get_param $stats
17504                         error "No jobstats for $JOBVAL found on $facet::$stats"
17505                 fi
17506         done
17507 }
17508
17509 jobstats_set() {
17510         local new_jobenv=$1
17511
17512         set_persistent_param_and_check client "jobid_var" \
17513                 "$FSNAME.sys.jobid_var" $new_jobenv
17514 }
17515
17516 test_205a() { # Job stats
17517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17518         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17519                 skip "Need MDS version with at least 2.7.1"
17520         remote_mgs_nodsh && skip "remote MGS with nodsh"
17521         remote_mds_nodsh && skip "remote MDS with nodsh"
17522         remote_ost_nodsh && skip "remote OST with nodsh"
17523         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17524                 skip "Server doesn't support jobstats"
17525         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17526
17527         local old_jobenv=$($LCTL get_param -n jobid_var)
17528         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17529
17530         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17531                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17532         else
17533                 stack_trap "do_facet mgs $PERM_CMD \
17534                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17535         fi
17536         changelog_register
17537
17538         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17539                                 mdt.*.job_cleanup_interval | head -n 1)
17540         local new_interval=5
17541         do_facet $SINGLEMDS \
17542                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17543         stack_trap "do_facet $SINGLEMDS \
17544                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17545         local start=$SECONDS
17546
17547         local cmd
17548         # mkdir
17549         cmd="mkdir $DIR/$tdir"
17550         verify_jobstats "$cmd" "$SINGLEMDS"
17551         # rmdir
17552         cmd="rmdir $DIR/$tdir"
17553         verify_jobstats "$cmd" "$SINGLEMDS"
17554         # mkdir on secondary MDT
17555         if [ $MDSCOUNT -gt 1 ]; then
17556                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17557                 verify_jobstats "$cmd" "mds2"
17558         fi
17559         # mknod
17560         cmd="mknod $DIR/$tfile c 1 3"
17561         verify_jobstats "$cmd" "$SINGLEMDS"
17562         # unlink
17563         cmd="rm -f $DIR/$tfile"
17564         verify_jobstats "$cmd" "$SINGLEMDS"
17565         # create all files on OST0000 so verify_jobstats can find OST stats
17566         # open & close
17567         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17568         verify_jobstats "$cmd" "$SINGLEMDS"
17569         # setattr
17570         cmd="touch $DIR/$tfile"
17571         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17572         # write
17573         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17574         verify_jobstats "$cmd" "ost1"
17575         # read
17576         cancel_lru_locks osc
17577         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17578         verify_jobstats "$cmd" "ost1"
17579         # truncate
17580         cmd="$TRUNCATE $DIR/$tfile 0"
17581         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17582         # rename
17583         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17584         verify_jobstats "$cmd" "$SINGLEMDS"
17585         # jobstats expiry - sleep until old stats should be expired
17586         local left=$((new_interval + 5 - (SECONDS - start)))
17587         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17588                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17589                         "0" $left
17590         cmd="mkdir $DIR/$tdir.expire"
17591         verify_jobstats "$cmd" "$SINGLEMDS"
17592         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17593             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17594
17595         # Ensure that jobid are present in changelog (if supported by MDS)
17596         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17597                 changelog_dump | tail -10
17598                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17599                 [ $jobids -eq 9 ] ||
17600                         error "Wrong changelog jobid count $jobids != 9"
17601
17602                 # LU-5862
17603                 JOBENV="disable"
17604                 jobstats_set $JOBENV
17605                 touch $DIR/$tfile
17606                 changelog_dump | grep $tfile
17607                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17608                 [ $jobids -eq 0 ] ||
17609                         error "Unexpected jobids when jobid_var=$JOBENV"
17610         fi
17611
17612         # test '%j' access to environment variable - if supported
17613         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17614                 JOBENV="JOBCOMPLEX"
17615                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17616
17617                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17618         fi
17619
17620         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17621                 JOBENV="JOBCOMPLEX"
17622                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17623
17624                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17625         fi
17626
17627         # test '%j' access to per-session jobid - if supported
17628         if lctl list_param jobid_this_session > /dev/null 2>&1
17629         then
17630                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17631                 lctl set_param jobid_this_session=$USER
17632
17633                 JOBENV="JOBCOMPLEX"
17634                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17635
17636                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17637         fi
17638 }
17639 run_test 205a "Verify job stats"
17640
17641 # LU-13117, LU-13597
17642 test_205b() {
17643         job_stats="mdt.*.job_stats"
17644         $LCTL set_param $job_stats=clear
17645         # Setting jobid_var to USER might not be supported
17646         $LCTL set_param jobid_var=USER || true
17647         $LCTL set_param jobid_name="%e.%u"
17648         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
17649         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17650                 grep "job_id:.*foolish" &&
17651                         error "Unexpected jobid found"
17652         do_facet $SINGLEMDS $LCTL get_param $job_stats |
17653                 grep "open:.*min.*max.*sum" ||
17654                         error "wrong job_stats format found"
17655 }
17656 run_test 205b "Verify job stats jobid and output format"
17657
17658 # LU-13733
17659 test_205c() {
17660         $LCTL set_param llite.*.stats=0
17661         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
17662         $LCTL get_param llite.*.stats
17663         $LCTL get_param llite.*.stats | grep \
17664                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
17665                         error "wrong client stats format found"
17666 }
17667 run_test 205c "Verify client stats format"
17668
17669 # LU-1480, LU-1773 and LU-1657
17670 test_206() {
17671         mkdir -p $DIR/$tdir
17672         $LFS setstripe -c -1 $DIR/$tdir
17673 #define OBD_FAIL_LOV_INIT 0x1403
17674         $LCTL set_param fail_loc=0xa0001403
17675         $LCTL set_param fail_val=1
17676         touch $DIR/$tdir/$tfile || true
17677 }
17678 run_test 206 "fail lov_init_raid0() doesn't lbug"
17679
17680 test_207a() {
17681         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17682         local fsz=`stat -c %s $DIR/$tfile`
17683         cancel_lru_locks mdc
17684
17685         # do not return layout in getattr intent
17686 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
17687         $LCTL set_param fail_loc=0x170
17688         local sz=`stat -c %s $DIR/$tfile`
17689
17690         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
17691
17692         rm -rf $DIR/$tfile
17693 }
17694 run_test 207a "can refresh layout at glimpse"
17695
17696 test_207b() {
17697         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
17698         local cksum=`md5sum $DIR/$tfile`
17699         local fsz=`stat -c %s $DIR/$tfile`
17700         cancel_lru_locks mdc
17701         cancel_lru_locks osc
17702
17703         # do not return layout in getattr intent
17704 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
17705         $LCTL set_param fail_loc=0x171
17706
17707         # it will refresh layout after the file is opened but before read issues
17708         echo checksum is "$cksum"
17709         echo "$cksum" |md5sum -c --quiet || error "file differs"
17710
17711         rm -rf $DIR/$tfile
17712 }
17713 run_test 207b "can refresh layout at open"
17714
17715 test_208() {
17716         # FIXME: in this test suite, only RD lease is used. This is okay
17717         # for now as only exclusive open is supported. After generic lease
17718         # is done, this test suite should be revised. - Jinshan
17719
17720         remote_mds_nodsh && skip "remote MDS with nodsh"
17721         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
17722                 skip "Need MDS version at least 2.4.52"
17723
17724         echo "==== test 1: verify get lease work"
17725         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
17726
17727         echo "==== test 2: verify lease can be broken by upcoming open"
17728         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17729         local PID=$!
17730         sleep 1
17731
17732         $MULTIOP $DIR/$tfile oO_RDONLY:c
17733         kill -USR1 $PID && wait $PID || error "break lease error"
17734
17735         echo "==== test 3: verify lease can't be granted if an open already exists"
17736         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
17737         local PID=$!
17738         sleep 1
17739
17740         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
17741         kill -USR1 $PID && wait $PID || error "open file error"
17742
17743         echo "==== test 4: lease can sustain over recovery"
17744         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17745         PID=$!
17746         sleep 1
17747
17748         fail mds1
17749
17750         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
17751
17752         echo "==== test 5: lease broken can't be regained by replay"
17753         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
17754         PID=$!
17755         sleep 1
17756
17757         # open file to break lease and then recovery
17758         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
17759         fail mds1
17760
17761         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
17762
17763         rm -f $DIR/$tfile
17764 }
17765 run_test 208 "Exclusive open"
17766
17767 test_209() {
17768         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17769                 skip_env "must have disp_stripe"
17770
17771         touch $DIR/$tfile
17772         sync; sleep 5; sync;
17773
17774         echo 3 > /proc/sys/vm/drop_caches
17775         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17776                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17777         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17778
17779         # open/close 500 times
17780         for i in $(seq 500); do
17781                 cat $DIR/$tfile
17782         done
17783
17784         echo 3 > /proc/sys/vm/drop_caches
17785         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17786                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17787         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17788
17789         echo "before: $req_before, after: $req_after"
17790         [ $((req_after - req_before)) -ge 300 ] &&
17791                 error "open/close requests are not freed"
17792         return 0
17793 }
17794 run_test 209 "read-only open/close requests should be freed promptly"
17795
17796 test_210() {
17797         local pid
17798
17799         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17800         pid=$!
17801         sleep 1
17802
17803         $LFS getstripe $DIR/$tfile
17804         kill -USR1 $pid
17805         wait $pid || error "multiop failed"
17806
17807         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17808         pid=$!
17809         sleep 1
17810
17811         $LFS getstripe $DIR/$tfile
17812         kill -USR1 $pid
17813         wait $pid || error "multiop failed"
17814 }
17815 run_test 210 "lfs getstripe does not break leases"
17816
17817 test_212() {
17818         size=`date +%s`
17819         size=$((size % 8192 + 1))
17820         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17821         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17822         rm -f $DIR/f212 $DIR/f212.xyz
17823 }
17824 run_test 212 "Sendfile test ============================================"
17825
17826 test_213() {
17827         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17828         cancel_lru_locks osc
17829         lctl set_param fail_loc=0x8000040f
17830         # generate a read lock
17831         cat $DIR/$tfile > /dev/null
17832         # write to the file, it will try to cancel the above read lock.
17833         cat /etc/hosts >> $DIR/$tfile
17834 }
17835 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17836
17837 test_214() { # for bug 20133
17838         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17839         for (( i=0; i < 340; i++ )) ; do
17840                 touch $DIR/$tdir/d214c/a$i
17841         done
17842
17843         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17844         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17845         ls $DIR/d214c || error "ls $DIR/d214c failed"
17846         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17847         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17848 }
17849 run_test 214 "hash-indexed directory test - bug 20133"
17850
17851 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17852 create_lnet_proc_files() {
17853         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17854 }
17855
17856 # counterpart of create_lnet_proc_files
17857 remove_lnet_proc_files() {
17858         rm -f $TMP/lnet_$1.sys
17859 }
17860
17861 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17862 # 3rd arg as regexp for body
17863 check_lnet_proc_stats() {
17864         local l=$(cat "$TMP/lnet_$1" |wc -l)
17865         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17866
17867         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17868 }
17869
17870 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17871 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17872 # optional and can be regexp for 2nd line (lnet.routes case)
17873 check_lnet_proc_entry() {
17874         local blp=2          # blp stands for 'position of 1st line of body'
17875         [ -z "$5" ] || blp=3 # lnet.routes case
17876
17877         local l=$(cat "$TMP/lnet_$1" |wc -l)
17878         # subtracting one from $blp because the body can be empty
17879         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17880
17881         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17882                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17883
17884         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17885                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17886
17887         # bail out if any unexpected line happened
17888         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17889         [ "$?" != 0 ] || error "$2 misformatted"
17890 }
17891
17892 test_215() { # for bugs 18102, 21079, 21517
17893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17894
17895         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17896         local P='[1-9][0-9]*'           # positive numeric
17897         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17898         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17899         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17900         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17901
17902         local L1 # regexp for 1st line
17903         local L2 # regexp for 2nd line (optional)
17904         local BR # regexp for the rest (body)
17905
17906         # lnet.stats should look as 11 space-separated non-negative numerics
17907         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17908         create_lnet_proc_files "stats"
17909         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17910         remove_lnet_proc_files "stats"
17911
17912         # lnet.routes should look like this:
17913         # Routing disabled/enabled
17914         # net hops priority state router
17915         # where net is a string like tcp0, hops > 0, priority >= 0,
17916         # state is up/down,
17917         # router is a string like 192.168.1.1@tcp2
17918         L1="^Routing (disabled|enabled)$"
17919         L2="^net +hops +priority +state +router$"
17920         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17921         create_lnet_proc_files "routes"
17922         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17923         remove_lnet_proc_files "routes"
17924
17925         # lnet.routers should look like this:
17926         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17927         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17928         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17929         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17930         L1="^ref +rtr_ref +alive +router$"
17931         BR="^$P +$P +(up|down) +$NID$"
17932         create_lnet_proc_files "routers"
17933         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17934         remove_lnet_proc_files "routers"
17935
17936         # lnet.peers should look like this:
17937         # nid refs state last max rtr min tx min queue
17938         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17939         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17940         # numeric (0 or >0 or <0), queue >= 0.
17941         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17942         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17943         create_lnet_proc_files "peers"
17944         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17945         remove_lnet_proc_files "peers"
17946
17947         # lnet.buffers  should look like this:
17948         # pages count credits min
17949         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17950         L1="^pages +count +credits +min$"
17951         BR="^ +$N +$N +$I +$I$"
17952         create_lnet_proc_files "buffers"
17953         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17954         remove_lnet_proc_files "buffers"
17955
17956         # lnet.nis should look like this:
17957         # nid status alive refs peer rtr max tx min
17958         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17959         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17960         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17961         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17962         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17963         create_lnet_proc_files "nis"
17964         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17965         remove_lnet_proc_files "nis"
17966
17967         # can we successfully write to lnet.stats?
17968         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17969 }
17970 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17971
17972 test_216() { # bug 20317
17973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17974         remote_ost_nodsh && skip "remote OST with nodsh"
17975
17976         local node
17977         local facets=$(get_facets OST)
17978         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17979
17980         save_lustre_params client "osc.*.contention_seconds" > $p
17981         save_lustre_params $facets \
17982                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17983         save_lustre_params $facets \
17984                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17985         save_lustre_params $facets \
17986                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17987         clear_stats osc.*.osc_stats
17988
17989         # agressive lockless i/o settings
17990         do_nodes $(comma_list $(osts_nodes)) \
17991                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17992                         ldlm.namespaces.filter-*.contended_locks=0 \
17993                         ldlm.namespaces.filter-*.contention_seconds=60"
17994         lctl set_param -n osc.*.contention_seconds=60
17995
17996         $DIRECTIO write $DIR/$tfile 0 10 4096
17997         $CHECKSTAT -s 40960 $DIR/$tfile
17998
17999         # disable lockless i/o
18000         do_nodes $(comma_list $(osts_nodes)) \
18001                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18002                         ldlm.namespaces.filter-*.contended_locks=32 \
18003                         ldlm.namespaces.filter-*.contention_seconds=0"
18004         lctl set_param -n osc.*.contention_seconds=0
18005         clear_stats osc.*.osc_stats
18006
18007         dd if=/dev/zero of=$DIR/$tfile count=0
18008         $CHECKSTAT -s 0 $DIR/$tfile
18009
18010         restore_lustre_params <$p
18011         rm -f $p
18012         rm $DIR/$tfile
18013 }
18014 run_test 216 "check lockless direct write updates file size and kms correctly"
18015
18016 test_217() { # bug 22430
18017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18018
18019         local node
18020         local nid
18021
18022         for node in $(nodes_list); do
18023                 nid=$(host_nids_address $node $NETTYPE)
18024                 if [[ $nid = *-* ]] ; then
18025                         echo "lctl ping $(h2nettype $nid)"
18026                         lctl ping $(h2nettype $nid)
18027                 else
18028                         echo "skipping $node (no hyphen detected)"
18029                 fi
18030         done
18031 }
18032 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18033
18034 test_218() {
18035        # do directio so as not to populate the page cache
18036        log "creating a 10 Mb file"
18037        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18038        log "starting reads"
18039        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18040        log "truncating the file"
18041        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18042        log "killing dd"
18043        kill %+ || true # reads might have finished
18044        echo "wait until dd is finished"
18045        wait
18046        log "removing the temporary file"
18047        rm -rf $DIR/$tfile || error "tmp file removal failed"
18048 }
18049 run_test 218 "parallel read and truncate should not deadlock"
18050
18051 test_219() {
18052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18053
18054         # write one partial page
18055         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18056         # set no grant so vvp_io_commit_write will do sync write
18057         $LCTL set_param fail_loc=0x411
18058         # write a full page at the end of file
18059         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18060
18061         $LCTL set_param fail_loc=0
18062         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18063         $LCTL set_param fail_loc=0x411
18064         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18065
18066         # LU-4201
18067         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18068         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18069 }
18070 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18071
18072 test_220() { #LU-325
18073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18074         remote_ost_nodsh && skip "remote OST with nodsh"
18075         remote_mds_nodsh && skip "remote MDS with nodsh"
18076         remote_mgs_nodsh && skip "remote MGS with nodsh"
18077
18078         local OSTIDX=0
18079
18080         # create on MDT0000 so the last_id and next_id are correct
18081         mkdir $DIR/$tdir
18082         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18083         OST=${OST%_UUID}
18084
18085         # on the mdt's osc
18086         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18087         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18088                         osp.$mdtosc_proc1.prealloc_last_id)
18089         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18090                         osp.$mdtosc_proc1.prealloc_next_id)
18091
18092         $LFS df -i
18093
18094         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18095         #define OBD_FAIL_OST_ENOINO              0x229
18096         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18097         create_pool $FSNAME.$TESTNAME || return 1
18098         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18099
18100         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18101
18102         MDSOBJS=$((last_id - next_id))
18103         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18104
18105         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18106         echo "OST still has $count kbytes free"
18107
18108         echo "create $MDSOBJS files @next_id..."
18109         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18110
18111         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18112                         osp.$mdtosc_proc1.prealloc_last_id)
18113         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18114                         osp.$mdtosc_proc1.prealloc_next_id)
18115
18116         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18117         $LFS df -i
18118
18119         echo "cleanup..."
18120
18121         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18122         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18123
18124         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18125                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18126         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18127                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18128         echo "unlink $MDSOBJS files @$next_id..."
18129         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18130 }
18131 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18132
18133 test_221() {
18134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18135
18136         dd if=`which date` of=$MOUNT/date oflag=sync
18137         chmod +x $MOUNT/date
18138
18139         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18140         $LCTL set_param fail_loc=0x80001401
18141
18142         $MOUNT/date > /dev/null
18143         rm -f $MOUNT/date
18144 }
18145 run_test 221 "make sure fault and truncate race to not cause OOM"
18146
18147 test_222a () {
18148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18149
18150         rm -rf $DIR/$tdir
18151         test_mkdir $DIR/$tdir
18152         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18153         createmany -o $DIR/$tdir/$tfile 10
18154         cancel_lru_locks mdc
18155         cancel_lru_locks osc
18156         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18157         $LCTL set_param fail_loc=0x31a
18158         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18159         $LCTL set_param fail_loc=0
18160         rm -r $DIR/$tdir
18161 }
18162 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18163
18164 test_222b () {
18165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18166
18167         rm -rf $DIR/$tdir
18168         test_mkdir $DIR/$tdir
18169         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18170         createmany -o $DIR/$tdir/$tfile 10
18171         cancel_lru_locks mdc
18172         cancel_lru_locks osc
18173         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18174         $LCTL set_param fail_loc=0x31a
18175         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18176         $LCTL set_param fail_loc=0
18177 }
18178 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18179
18180 test_223 () {
18181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18182
18183         rm -rf $DIR/$tdir
18184         test_mkdir $DIR/$tdir
18185         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18186         createmany -o $DIR/$tdir/$tfile 10
18187         cancel_lru_locks mdc
18188         cancel_lru_locks osc
18189         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18190         $LCTL set_param fail_loc=0x31b
18191         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18192         $LCTL set_param fail_loc=0
18193         rm -r $DIR/$tdir
18194 }
18195 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18196
18197 test_224a() { # LU-1039, MRP-303
18198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18199
18200         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18201         $LCTL set_param fail_loc=0x508
18202         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18203         $LCTL set_param fail_loc=0
18204         df $DIR
18205 }
18206 run_test 224a "Don't panic on bulk IO failure"
18207
18208 test_224b() { # LU-1039, MRP-303
18209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18210
18211         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18212         cancel_lru_locks osc
18213         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18214         $LCTL set_param fail_loc=0x515
18215         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18216         $LCTL set_param fail_loc=0
18217         df $DIR
18218 }
18219 run_test 224b "Don't panic on bulk IO failure"
18220
18221 test_224c() { # LU-6441
18222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18223         remote_mds_nodsh && skip "remote MDS with nodsh"
18224
18225         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18226         save_writethrough $p
18227         set_cache writethrough on
18228
18229         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18230         local at_max=$($LCTL get_param -n at_max)
18231         local timeout=$($LCTL get_param -n timeout)
18232         local test_at="at_max"
18233         local param_at="$FSNAME.sys.at_max"
18234         local test_timeout="timeout"
18235         local param_timeout="$FSNAME.sys.timeout"
18236
18237         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18238
18239         set_persistent_param_and_check client "$test_at" "$param_at" 0
18240         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18241
18242         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18243         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18244         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18245         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18246         sync
18247         do_facet ost1 "$LCTL set_param fail_loc=0"
18248
18249         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18250         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18251                 $timeout
18252
18253         $LCTL set_param -n $pages_per_rpc
18254         restore_lustre_params < $p
18255         rm -f $p
18256 }
18257 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18258
18259 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18260 test_225a () {
18261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18262         if [ -z ${MDSSURVEY} ]; then
18263                 skip_env "mds-survey not found"
18264         fi
18265         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18266                 skip "Need MDS version at least 2.2.51"
18267
18268         local mds=$(facet_host $SINGLEMDS)
18269         local target=$(do_nodes $mds 'lctl dl' |
18270                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18271
18272         local cmd1="file_count=1000 thrhi=4"
18273         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18274         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18275         local cmd="$cmd1 $cmd2 $cmd3"
18276
18277         rm -f ${TMP}/mds_survey*
18278         echo + $cmd
18279         eval $cmd || error "mds-survey with zero-stripe failed"
18280         cat ${TMP}/mds_survey*
18281         rm -f ${TMP}/mds_survey*
18282 }
18283 run_test 225a "Metadata survey sanity with zero-stripe"
18284
18285 test_225b () {
18286         if [ -z ${MDSSURVEY} ]; then
18287                 skip_env "mds-survey not found"
18288         fi
18289         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18290                 skip "Need MDS version at least 2.2.51"
18291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18292         remote_mds_nodsh && skip "remote MDS with nodsh"
18293         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18294                 skip_env "Need to mount OST to test"
18295         fi
18296
18297         local mds=$(facet_host $SINGLEMDS)
18298         local target=$(do_nodes $mds 'lctl dl' |
18299                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18300
18301         local cmd1="file_count=1000 thrhi=4"
18302         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18303         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18304         local cmd="$cmd1 $cmd2 $cmd3"
18305
18306         rm -f ${TMP}/mds_survey*
18307         echo + $cmd
18308         eval $cmd || error "mds-survey with stripe_count failed"
18309         cat ${TMP}/mds_survey*
18310         rm -f ${TMP}/mds_survey*
18311 }
18312 run_test 225b "Metadata survey sanity with stripe_count = 1"
18313
18314 mcreate_path2fid () {
18315         local mode=$1
18316         local major=$2
18317         local minor=$3
18318         local name=$4
18319         local desc=$5
18320         local path=$DIR/$tdir/$name
18321         local fid
18322         local rc
18323         local fid_path
18324
18325         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18326                 error "cannot create $desc"
18327
18328         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18329         rc=$?
18330         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18331
18332         fid_path=$($LFS fid2path $MOUNT $fid)
18333         rc=$?
18334         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18335
18336         [ "$path" == "$fid_path" ] ||
18337                 error "fid2path returned $fid_path, expected $path"
18338
18339         echo "pass with $path and $fid"
18340 }
18341
18342 test_226a () {
18343         rm -rf $DIR/$tdir
18344         mkdir -p $DIR/$tdir
18345
18346         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18347         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18348         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18349         mcreate_path2fid 0040666 0 0 dir "directory"
18350         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18351         mcreate_path2fid 0100666 0 0 file "regular file"
18352         mcreate_path2fid 0120666 0 0 link "symbolic link"
18353         mcreate_path2fid 0140666 0 0 sock "socket"
18354 }
18355 run_test 226a "call path2fid and fid2path on files of all type"
18356
18357 test_226b () {
18358         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18359
18360         local MDTIDX=1
18361
18362         rm -rf $DIR/$tdir
18363         mkdir -p $DIR/$tdir
18364         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18365                 error "create remote directory failed"
18366         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18367         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18368                                 "character special file (null)"
18369         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18370                                 "character special file (no device)"
18371         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18372         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18373                                 "block special file (loop)"
18374         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18375         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18376         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18377 }
18378 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18379
18380 test_226c () {
18381         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18382         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18383                 skip "Need MDS version at least 2.13.55"
18384
18385         local submnt=/mnt/submnt
18386         local srcfile=/etc/passwd
18387         local dstfile=$submnt/passwd
18388         local path
18389         local fid
18390
18391         rm -rf $DIR/$tdir
18392         rm -rf $submnt
18393         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18394                 error "create remote directory failed"
18395         mkdir -p $submnt || error "create $submnt failed"
18396         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18397                 error "mount $submnt failed"
18398         stack_trap "umount $submnt" EXIT
18399
18400         cp $srcfile $dstfile
18401         fid=$($LFS path2fid $dstfile)
18402         path=$($LFS fid2path $submnt "$fid")
18403         [ "$path" = "$dstfile" ] ||
18404                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18405 }
18406 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18407
18408 # LU-1299 Executing or running ldd on a truncated executable does not
18409 # cause an out-of-memory condition.
18410 test_227() {
18411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18412         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18413
18414         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18415         chmod +x $MOUNT/date
18416
18417         $MOUNT/date > /dev/null
18418         ldd $MOUNT/date > /dev/null
18419         rm -f $MOUNT/date
18420 }
18421 run_test 227 "running truncated executable does not cause OOM"
18422
18423 # LU-1512 try to reuse idle OI blocks
18424 test_228a() {
18425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18426         remote_mds_nodsh && skip "remote MDS with nodsh"
18427         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18428
18429         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18430         local myDIR=$DIR/$tdir
18431
18432         mkdir -p $myDIR
18433         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18434         $LCTL set_param fail_loc=0x80001002
18435         createmany -o $myDIR/t- 10000
18436         $LCTL set_param fail_loc=0
18437         # The guard is current the largest FID holder
18438         touch $myDIR/guard
18439         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18440                     tr -d '[')
18441         local IDX=$(($SEQ % 64))
18442
18443         do_facet $SINGLEMDS sync
18444         # Make sure journal flushed.
18445         sleep 6
18446         local blk1=$(do_facet $SINGLEMDS \
18447                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18448                      grep Blockcount | awk '{print $4}')
18449
18450         # Remove old files, some OI blocks will become idle.
18451         unlinkmany $myDIR/t- 10000
18452         # Create new files, idle OI blocks should be reused.
18453         createmany -o $myDIR/t- 2000
18454         do_facet $SINGLEMDS sync
18455         # Make sure journal flushed.
18456         sleep 6
18457         local blk2=$(do_facet $SINGLEMDS \
18458                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18459                      grep Blockcount | awk '{print $4}')
18460
18461         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18462 }
18463 run_test 228a "try to reuse idle OI blocks"
18464
18465 test_228b() {
18466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18467         remote_mds_nodsh && skip "remote MDS with nodsh"
18468         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18469
18470         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18471         local myDIR=$DIR/$tdir
18472
18473         mkdir -p $myDIR
18474         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18475         $LCTL set_param fail_loc=0x80001002
18476         createmany -o $myDIR/t- 10000
18477         $LCTL set_param fail_loc=0
18478         # The guard is current the largest FID holder
18479         touch $myDIR/guard
18480         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18481                     tr -d '[')
18482         local IDX=$(($SEQ % 64))
18483
18484         do_facet $SINGLEMDS sync
18485         # Make sure journal flushed.
18486         sleep 6
18487         local blk1=$(do_facet $SINGLEMDS \
18488                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18489                      grep Blockcount | awk '{print $4}')
18490
18491         # Remove old files, some OI blocks will become idle.
18492         unlinkmany $myDIR/t- 10000
18493
18494         # stop the MDT
18495         stop $SINGLEMDS || error "Fail to stop MDT."
18496         # remount the MDT
18497         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18498
18499         df $MOUNT || error "Fail to df."
18500         # Create new files, idle OI blocks should be reused.
18501         createmany -o $myDIR/t- 2000
18502         do_facet $SINGLEMDS sync
18503         # Make sure journal flushed.
18504         sleep 6
18505         local blk2=$(do_facet $SINGLEMDS \
18506                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18507                      grep Blockcount | awk '{print $4}')
18508
18509         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18510 }
18511 run_test 228b "idle OI blocks can be reused after MDT restart"
18512
18513 #LU-1881
18514 test_228c() {
18515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18516         remote_mds_nodsh && skip "remote MDS with nodsh"
18517         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18518
18519         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18520         local myDIR=$DIR/$tdir
18521
18522         mkdir -p $myDIR
18523         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18524         $LCTL set_param fail_loc=0x80001002
18525         # 20000 files can guarantee there are index nodes in the OI file
18526         createmany -o $myDIR/t- 20000
18527         $LCTL set_param fail_loc=0
18528         # The guard is current the largest FID holder
18529         touch $myDIR/guard
18530         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18531                     tr -d '[')
18532         local IDX=$(($SEQ % 64))
18533
18534         do_facet $SINGLEMDS sync
18535         # Make sure journal flushed.
18536         sleep 6
18537         local blk1=$(do_facet $SINGLEMDS \
18538                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18539                      grep Blockcount | awk '{print $4}')
18540
18541         # Remove old files, some OI blocks will become idle.
18542         unlinkmany $myDIR/t- 20000
18543         rm -f $myDIR/guard
18544         # The OI file should become empty now
18545
18546         # Create new files, idle OI blocks should be reused.
18547         createmany -o $myDIR/t- 2000
18548         do_facet $SINGLEMDS sync
18549         # Make sure journal flushed.
18550         sleep 6
18551         local blk2=$(do_facet $SINGLEMDS \
18552                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18553                      grep Blockcount | awk '{print $4}')
18554
18555         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18556 }
18557 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18558
18559 test_229() { # LU-2482, LU-3448
18560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18561         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18562         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18563                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18564
18565         rm -f $DIR/$tfile
18566
18567         # Create a file with a released layout and stripe count 2.
18568         $MULTIOP $DIR/$tfile H2c ||
18569                 error "failed to create file with released layout"
18570
18571         $LFS getstripe -v $DIR/$tfile
18572
18573         local pattern=$($LFS getstripe -L $DIR/$tfile)
18574         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18575
18576         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18577                 error "getstripe"
18578         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18579         stat $DIR/$tfile || error "failed to stat released file"
18580
18581         chown $RUNAS_ID $DIR/$tfile ||
18582                 error "chown $RUNAS_ID $DIR/$tfile failed"
18583
18584         chgrp $RUNAS_ID $DIR/$tfile ||
18585                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18586
18587         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18588         rm $DIR/$tfile || error "failed to remove released file"
18589 }
18590 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18591
18592 test_230a() {
18593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18594         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18595         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18596                 skip "Need MDS version at least 2.11.52"
18597
18598         local MDTIDX=1
18599
18600         test_mkdir $DIR/$tdir
18601         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18602         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18603         [ $mdt_idx -ne 0 ] &&
18604                 error "create local directory on wrong MDT $mdt_idx"
18605
18606         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18607                         error "create remote directory failed"
18608         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18609         [ $mdt_idx -ne $MDTIDX ] &&
18610                 error "create remote directory on wrong MDT $mdt_idx"
18611
18612         createmany -o $DIR/$tdir/test_230/t- 10 ||
18613                 error "create files on remote directory failed"
18614         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18615         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18616         rm -r $DIR/$tdir || error "unlink remote directory failed"
18617 }
18618 run_test 230a "Create remote directory and files under the remote directory"
18619
18620 test_230b() {
18621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18622         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18623         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18624                 skip "Need MDS version at least 2.11.52"
18625
18626         local MDTIDX=1
18627         local mdt_index
18628         local i
18629         local file
18630         local pid
18631         local stripe_count
18632         local migrate_dir=$DIR/$tdir/migrate_dir
18633         local other_dir=$DIR/$tdir/other_dir
18634
18635         test_mkdir $DIR/$tdir
18636         test_mkdir -i0 -c1 $migrate_dir
18637         test_mkdir -i0 -c1 $other_dir
18638         for ((i=0; i<10; i++)); do
18639                 mkdir -p $migrate_dir/dir_${i}
18640                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18641                         error "create files under remote dir failed $i"
18642         done
18643
18644         cp /etc/passwd $migrate_dir/$tfile
18645         cp /etc/passwd $other_dir/$tfile
18646         chattr +SAD $migrate_dir
18647         chattr +SAD $migrate_dir/$tfile
18648
18649         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18650         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18651         local old_dir_mode=$(stat -c%f $migrate_dir)
18652         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
18653
18654         mkdir -p $migrate_dir/dir_default_stripe2
18655         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
18656         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
18657
18658         mkdir -p $other_dir
18659         ln $migrate_dir/$tfile $other_dir/luna
18660         ln $migrate_dir/$tfile $migrate_dir/sofia
18661         ln $other_dir/$tfile $migrate_dir/david
18662         ln -s $migrate_dir/$tfile $other_dir/zachary
18663         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
18664         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
18665
18666         local len
18667         local lnktgt
18668
18669         # inline symlink
18670         for len in 58 59 60; do
18671                 lnktgt=$(str_repeat 'l' $len)
18672                 touch $migrate_dir/$lnktgt
18673                 ln -s $lnktgt $migrate_dir/${len}char_ln
18674         done
18675
18676         # PATH_MAX
18677         for len in 4094 4095; do
18678                 lnktgt=$(str_repeat 'l' $len)
18679                 ln -s $lnktgt $migrate_dir/${len}char_ln
18680         done
18681
18682         # NAME_MAX
18683         for len in 254 255; do
18684                 touch $migrate_dir/$(str_repeat 'l' $len)
18685         done
18686
18687         $LFS migrate -m $MDTIDX $migrate_dir ||
18688                 error "fails on migrating remote dir to MDT1"
18689
18690         echo "migratate to MDT1, then checking.."
18691         for ((i = 0; i < 10; i++)); do
18692                 for file in $(find $migrate_dir/dir_${i}); do
18693                         mdt_index=$($LFS getstripe -m $file)
18694                         # broken symlink getstripe will fail
18695                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18696                                 error "$file is not on MDT${MDTIDX}"
18697                 done
18698         done
18699
18700         # the multiple link file should still in MDT0
18701         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
18702         [ $mdt_index == 0 ] ||
18703                 error "$file is not on MDT${MDTIDX}"
18704
18705         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18706         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18707                 error " expect $old_dir_flag get $new_dir_flag"
18708
18709         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18710         [ "$old_file_flag" = "$new_file_flag" ] ||
18711                 error " expect $old_file_flag get $new_file_flag"
18712
18713         local new_dir_mode=$(stat -c%f $migrate_dir)
18714         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18715                 error "expect mode $old_dir_mode get $new_dir_mode"
18716
18717         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18718         [ "$old_file_mode" = "$new_file_mode" ] ||
18719                 error "expect mode $old_file_mode get $new_file_mode"
18720
18721         diff /etc/passwd $migrate_dir/$tfile ||
18722                 error "$tfile different after migration"
18723
18724         diff /etc/passwd $other_dir/luna ||
18725                 error "luna different after migration"
18726
18727         diff /etc/passwd $migrate_dir/sofia ||
18728                 error "sofia different after migration"
18729
18730         diff /etc/passwd $migrate_dir/david ||
18731                 error "david different after migration"
18732
18733         diff /etc/passwd $other_dir/zachary ||
18734                 error "zachary different after migration"
18735
18736         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18737                 error "${tfile}_ln different after migration"
18738
18739         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18740                 error "${tfile}_ln_other different after migration"
18741
18742         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
18743         [ $stripe_count = 2 ] ||
18744                 error "dir strpe_count $d != 2 after migration."
18745
18746         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
18747         [ $stripe_count = 2 ] ||
18748                 error "file strpe_count $d != 2 after migration."
18749
18750         #migrate back to MDT0
18751         MDTIDX=0
18752
18753         $LFS migrate -m $MDTIDX $migrate_dir ||
18754                 error "fails on migrating remote dir to MDT0"
18755
18756         echo "migrate back to MDT0, checking.."
18757         for file in $(find $migrate_dir); do
18758                 mdt_index=$($LFS getstripe -m $file)
18759                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
18760                         error "$file is not on MDT${MDTIDX}"
18761         done
18762
18763         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
18764         [ "$old_dir_flag" = "$new_dir_flag" ] ||
18765                 error " expect $old_dir_flag get $new_dir_flag"
18766
18767         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
18768         [ "$old_file_flag" = "$new_file_flag" ] ||
18769                 error " expect $old_file_flag get $new_file_flag"
18770
18771         local new_dir_mode=$(stat -c%f $migrate_dir)
18772         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18773                 error "expect mode $old_dir_mode get $new_dir_mode"
18774
18775         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18776         [ "$old_file_mode" = "$new_file_mode" ] ||
18777                 error "expect mode $old_file_mode get $new_file_mode"
18778
18779         diff /etc/passwd ${migrate_dir}/$tfile ||
18780                 error "$tfile different after migration"
18781
18782         diff /etc/passwd ${other_dir}/luna ||
18783                 error "luna different after migration"
18784
18785         diff /etc/passwd ${migrate_dir}/sofia ||
18786                 error "sofia different after migration"
18787
18788         diff /etc/passwd ${other_dir}/zachary ||
18789                 error "zachary different after migration"
18790
18791         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18792                 error "${tfile}_ln different after migration"
18793
18794         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18795                 error "${tfile}_ln_other different after migration"
18796
18797         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18798         [ $stripe_count = 2 ] ||
18799                 error "dir strpe_count $d != 2 after migration."
18800
18801         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18802         [ $stripe_count = 2 ] ||
18803                 error "file strpe_count $d != 2 after migration."
18804
18805         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18806 }
18807 run_test 230b "migrate directory"
18808
18809 test_230c() {
18810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18811         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18812         remote_mds_nodsh && skip "remote MDS with nodsh"
18813         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18814                 skip "Need MDS version at least 2.11.52"
18815
18816         local MDTIDX=1
18817         local total=3
18818         local mdt_index
18819         local file
18820         local migrate_dir=$DIR/$tdir/migrate_dir
18821
18822         #If migrating directory fails in the middle, all entries of
18823         #the directory is still accessiable.
18824         test_mkdir $DIR/$tdir
18825         test_mkdir -i0 -c1 $migrate_dir
18826         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18827         stat $migrate_dir
18828         createmany -o $migrate_dir/f $total ||
18829                 error "create files under ${migrate_dir} failed"
18830
18831         # fail after migrating top dir, and this will fail only once, so the
18832         # first sub file migration will fail (currently f3), others succeed.
18833         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18834         do_facet mds1 lctl set_param fail_loc=0x1801
18835         local t=$(ls $migrate_dir | wc -l)
18836         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18837                 error "migrate should fail"
18838         local u=$(ls $migrate_dir | wc -l)
18839         [ "$u" == "$t" ] || error "$u != $t during migration"
18840
18841         # add new dir/file should succeed
18842         mkdir $migrate_dir/dir ||
18843                 error "mkdir failed under migrating directory"
18844         touch $migrate_dir/file ||
18845                 error "create file failed under migrating directory"
18846
18847         # add file with existing name should fail
18848         for file in $migrate_dir/f*; do
18849                 stat $file > /dev/null || error "stat $file failed"
18850                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18851                         error "open(O_CREAT|O_EXCL) $file should fail"
18852                 $MULTIOP $file m && error "create $file should fail"
18853                 touch $DIR/$tdir/remote_dir/$tfile ||
18854                         error "touch $tfile failed"
18855                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18856                         error "link $file should fail"
18857                 mdt_index=$($LFS getstripe -m $file)
18858                 if [ $mdt_index == 0 ]; then
18859                         # file failed to migrate is not allowed to rename to
18860                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18861                                 error "rename to $file should fail"
18862                 else
18863                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18864                                 error "rename to $file failed"
18865                 fi
18866                 echo hello >> $file || error "write $file failed"
18867         done
18868
18869         # resume migration with different options should fail
18870         $LFS migrate -m 0 $migrate_dir &&
18871                 error "migrate -m 0 $migrate_dir should fail"
18872
18873         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18874                 error "migrate -c 2 $migrate_dir should fail"
18875
18876         # resume migration should succeed
18877         $LFS migrate -m $MDTIDX $migrate_dir ||
18878                 error "migrate $migrate_dir failed"
18879
18880         echo "Finish migration, then checking.."
18881         for file in $(find $migrate_dir); do
18882                 mdt_index=$($LFS getstripe -m $file)
18883                 [ $mdt_index == $MDTIDX ] ||
18884                         error "$file is not on MDT${MDTIDX}"
18885         done
18886
18887         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18888 }
18889 run_test 230c "check directory accessiblity if migration failed"
18890
18891 test_230d() {
18892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18893         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18894         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18895                 skip "Need MDS version at least 2.11.52"
18896         # LU-11235
18897         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18898
18899         local migrate_dir=$DIR/$tdir/migrate_dir
18900         local old_index
18901         local new_index
18902         local old_count
18903         local new_count
18904         local new_hash
18905         local mdt_index
18906         local i
18907         local j
18908
18909         old_index=$((RANDOM % MDSCOUNT))
18910         old_count=$((MDSCOUNT - old_index))
18911         new_index=$((RANDOM % MDSCOUNT))
18912         new_count=$((MDSCOUNT - new_index))
18913         new_hash=1 # for all_char
18914
18915         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18916         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18917
18918         test_mkdir $DIR/$tdir
18919         test_mkdir -i $old_index -c $old_count $migrate_dir
18920
18921         for ((i=0; i<100; i++)); do
18922                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18923                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18924                         error "create files under remote dir failed $i"
18925         done
18926
18927         echo -n "Migrate from MDT$old_index "
18928         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18929         echo -n "to MDT$new_index"
18930         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18931         echo
18932
18933         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18934         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18935                 error "migrate remote dir error"
18936
18937         echo "Finish migration, then checking.."
18938         for file in $(find $migrate_dir); do
18939                 mdt_index=$($LFS getstripe -m $file)
18940                 if [ $mdt_index -lt $new_index ] ||
18941                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18942                         error "$file is on MDT$mdt_index"
18943                 fi
18944         done
18945
18946         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18947 }
18948 run_test 230d "check migrate big directory"
18949
18950 test_230e() {
18951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18952         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18953         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18954                 skip "Need MDS version at least 2.11.52"
18955
18956         local i
18957         local j
18958         local a_fid
18959         local b_fid
18960
18961         mkdir -p $DIR/$tdir
18962         mkdir $DIR/$tdir/migrate_dir
18963         mkdir $DIR/$tdir/other_dir
18964         touch $DIR/$tdir/migrate_dir/a
18965         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18966         ls $DIR/$tdir/other_dir
18967
18968         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18969                 error "migrate dir fails"
18970
18971         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18972         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18973
18974         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18975         [ $mdt_index == 0 ] || error "a is not on MDT0"
18976
18977         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18978                 error "migrate dir fails"
18979
18980         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18981         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18982
18983         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18984         [ $mdt_index == 1 ] || error "a is not on MDT1"
18985
18986         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18987         [ $mdt_index == 1 ] || error "b is not on MDT1"
18988
18989         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18990         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18991
18992         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18993
18994         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18995 }
18996 run_test 230e "migrate mulitple local link files"
18997
18998 test_230f() {
18999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19000         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19001         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19002                 skip "Need MDS version at least 2.11.52"
19003
19004         local a_fid
19005         local ln_fid
19006
19007         mkdir -p $DIR/$tdir
19008         mkdir $DIR/$tdir/migrate_dir
19009         $LFS mkdir -i1 $DIR/$tdir/other_dir
19010         touch $DIR/$tdir/migrate_dir/a
19011         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19012         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19013         ls $DIR/$tdir/other_dir
19014
19015         # a should be migrated to MDT1, since no other links on MDT0
19016         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19017                 error "#1 migrate dir fails"
19018         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19019         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19020         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19021         [ $mdt_index == 1 ] || error "a is not on MDT1"
19022
19023         # a should stay on MDT1, because it is a mulitple link file
19024         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19025                 error "#2 migrate dir fails"
19026         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19027         [ $mdt_index == 1 ] || error "a is not on MDT1"
19028
19029         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19030                 error "#3 migrate dir fails"
19031
19032         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19033         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19034         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19035
19036         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19037         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19038
19039         # a should be migrated to MDT0, since no other links on MDT1
19040         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19041                 error "#4 migrate dir fails"
19042         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19043         [ $mdt_index == 0 ] || error "a is not on MDT0"
19044
19045         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19046 }
19047 run_test 230f "migrate mulitple remote link files"
19048
19049 test_230g() {
19050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19051         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19052         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19053                 skip "Need MDS version at least 2.11.52"
19054
19055         mkdir -p $DIR/$tdir/migrate_dir
19056
19057         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19058                 error "migrating dir to non-exist MDT succeeds"
19059         true
19060 }
19061 run_test 230g "migrate dir to non-exist MDT"
19062
19063 test_230h() {
19064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19065         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19066         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19067                 skip "Need MDS version at least 2.11.52"
19068
19069         local mdt_index
19070
19071         mkdir -p $DIR/$tdir/migrate_dir
19072
19073         $LFS migrate -m1 $DIR &&
19074                 error "migrating mountpoint1 should fail"
19075
19076         $LFS migrate -m1 $DIR/$tdir/.. &&
19077                 error "migrating mountpoint2 should fail"
19078
19079         # same as mv
19080         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19081                 error "migrating $tdir/migrate_dir/.. should fail"
19082
19083         true
19084 }
19085 run_test 230h "migrate .. and root"
19086
19087 test_230i() {
19088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19089         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19090         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19091                 skip "Need MDS version at least 2.11.52"
19092
19093         mkdir -p $DIR/$tdir/migrate_dir
19094
19095         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19096                 error "migration fails with a tailing slash"
19097
19098         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19099                 error "migration fails with two tailing slashes"
19100 }
19101 run_test 230i "lfs migrate -m tolerates trailing slashes"
19102
19103 test_230j() {
19104         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19105         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19106                 skip "Need MDS version at least 2.11.52"
19107
19108         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19109         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19110                 error "create $tfile failed"
19111         cat /etc/passwd > $DIR/$tdir/$tfile
19112
19113         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19114
19115         cmp /etc/passwd $DIR/$tdir/$tfile ||
19116                 error "DoM file mismatch after migration"
19117 }
19118 run_test 230j "DoM file data not changed after dir migration"
19119
19120 test_230k() {
19121         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19122         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19123                 skip "Need MDS version at least 2.11.56"
19124
19125         local total=20
19126         local files_on_starting_mdt=0
19127
19128         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19129         $LFS getdirstripe $DIR/$tdir
19130         for i in $(seq $total); do
19131                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19132                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19133                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19134         done
19135
19136         echo "$files_on_starting_mdt files on MDT0"
19137
19138         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19139         $LFS getdirstripe $DIR/$tdir
19140
19141         files_on_starting_mdt=0
19142         for i in $(seq $total); do
19143                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19144                         error "file $tfile.$i mismatch after migration"
19145                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19146                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19147         done
19148
19149         echo "$files_on_starting_mdt files on MDT1 after migration"
19150         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19151
19152         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19153         $LFS getdirstripe $DIR/$tdir
19154
19155         files_on_starting_mdt=0
19156         for i in $(seq $total); do
19157                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19158                         error "file $tfile.$i mismatch after 2nd migration"
19159                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19160                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19161         done
19162
19163         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19164         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19165
19166         true
19167 }
19168 run_test 230k "file data not changed after dir migration"
19169
19170 test_230l() {
19171         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19172         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19173                 skip "Need MDS version at least 2.11.56"
19174
19175         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19176         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19177                 error "create files under remote dir failed $i"
19178         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19179 }
19180 run_test 230l "readdir between MDTs won't crash"
19181
19182 test_230m() {
19183         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19184         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19185                 skip "Need MDS version at least 2.11.56"
19186
19187         local MDTIDX=1
19188         local mig_dir=$DIR/$tdir/migrate_dir
19189         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19190         local shortstr="b"
19191         local val
19192
19193         echo "Creating files and dirs with xattrs"
19194         test_mkdir $DIR/$tdir
19195         test_mkdir -i0 -c1 $mig_dir
19196         mkdir $mig_dir/dir
19197         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19198                 error "cannot set xattr attr1 on dir"
19199         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19200                 error "cannot set xattr attr2 on dir"
19201         touch $mig_dir/dir/f0
19202         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19203                 error "cannot set xattr attr1 on file"
19204         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19205                 error "cannot set xattr attr2 on file"
19206         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19207         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19208         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19209         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19210         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19211         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19212         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19213         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19214         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19215
19216         echo "Migrating to MDT1"
19217         $LFS migrate -m $MDTIDX $mig_dir ||
19218                 error "fails on migrating dir to MDT1"
19219
19220         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19221         echo "Checking xattrs"
19222         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19223         [ "$val" = $longstr ] ||
19224                 error "expecting xattr1 $longstr on dir, found $val"
19225         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19226         [ "$val" = $shortstr ] ||
19227                 error "expecting xattr2 $shortstr on dir, found $val"
19228         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19229         [ "$val" = $longstr ] ||
19230                 error "expecting xattr1 $longstr on file, found $val"
19231         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19232         [ "$val" = $shortstr ] ||
19233                 error "expecting xattr2 $shortstr on file, found $val"
19234 }
19235 run_test 230m "xattrs not changed after dir migration"
19236
19237 test_230n() {
19238         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19239         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19240                 skip "Need MDS version at least 2.13.53"
19241
19242         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19243         cat /etc/hosts > $DIR/$tdir/$tfile
19244         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19245         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19246
19247         cmp /etc/hosts $DIR/$tdir/$tfile ||
19248                 error "File data mismatch after migration"
19249 }
19250 run_test 230n "Dir migration with mirrored file"
19251
19252 test_230o() {
19253         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19254         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19255                 skip "Need MDS version at least 2.13.52"
19256
19257         local mdts=$(comma_list $(mdts_nodes))
19258         local timeout=100
19259         local restripe_status
19260         local delta
19261         local i
19262
19263         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19264
19265         # in case "crush" hash type is not set
19266         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19267
19268         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19269                            mdt.*MDT0000.enable_dir_restripe)
19270         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19271         stack_trap "do_nodes $mdts $LCTL set_param \
19272                     mdt.*.enable_dir_restripe=$restripe_status"
19273
19274         mkdir $DIR/$tdir
19275         createmany -m $DIR/$tdir/f 100 ||
19276                 error "create files under remote dir failed $i"
19277         createmany -d $DIR/$tdir/d 100 ||
19278                 error "create dirs under remote dir failed $i"
19279
19280         for i in $(seq 2 $MDSCOUNT); do
19281                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19282                 $LFS setdirstripe -c $i $DIR/$tdir ||
19283                         error "split -c $i $tdir failed"
19284                 wait_update $HOSTNAME \
19285                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19286                         error "dir split not finished"
19287                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19288                         awk '/migrate/ {sum += $2} END { print sum }')
19289                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19290                 # delta is around total_files/stripe_count
19291                 (( $delta < 200 / (i - 1) + 4 )) ||
19292                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19293         done
19294 }
19295 run_test 230o "dir split"
19296
19297 test_230p() {
19298         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19299         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19300                 skip "Need MDS version at least 2.13.52"
19301
19302         local mdts=$(comma_list $(mdts_nodes))
19303         local timeout=100
19304         local restripe_status
19305         local delta
19306         local i
19307
19308         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19309
19310         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19311
19312         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19313                            mdt.*MDT0000.enable_dir_restripe)
19314         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19315         stack_trap "do_nodes $mdts $LCTL set_param \
19316                     mdt.*.enable_dir_restripe=$restripe_status"
19317
19318         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19319         createmany -m $DIR/$tdir/f 100 ||
19320                 error "create files under remote dir failed $i"
19321         createmany -d $DIR/$tdir/d 100 ||
19322                 error "create dirs under remote dir failed $i"
19323
19324         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
19325                 local mdt_hash="crush"
19326
19327                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19328                 $LFS setdirstripe -c $i $DIR/$tdir ||
19329                         error "split -c $i $tdir failed"
19330                 [ $i -eq 1 ] && mdt_hash="none"
19331                 wait_update $HOSTNAME \
19332                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19333                         error "dir merge not finished"
19334                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19335                         awk '/migrate/ {sum += $2} END { print sum }')
19336                 echo "$delta migrated when dir merge $((i + 1)) to $i stripes"
19337                 # delta is around total_files/stripe_count
19338                 (( $delta < 200 / i + 4 )) ||
19339                         error "$delta files migrated >= $((200 / i + 4))"
19340         done
19341 }
19342 run_test 230p "dir merge"
19343
19344 test_230q() {
19345         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19346         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19347                 skip "Need MDS version at least 2.13.52"
19348
19349         local mdts=$(comma_list $(mdts_nodes))
19350         local saved_threshold=$(do_facet mds1 \
19351                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19352         local saved_delta=$(do_facet mds1 \
19353                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19354         local threshold=100
19355         local delta=2
19356         local total=0
19357         local stripe_count=0
19358         local stripe_index
19359         local nr_files
19360         local create
19361
19362         # test with fewer files on ZFS
19363         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19364
19365         stack_trap "do_nodes $mdts $LCTL set_param \
19366                     mdt.*.dir_split_count=$saved_threshold"
19367         stack_trap "do_nodes $mdts $LCTL set_param \
19368                     mdt.*.dir_split_delta=$saved_delta"
19369         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19370         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19371         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19372         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19373         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19374         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19375
19376         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19377         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19378
19379         create=$((threshold * 3 / 2))
19380         while [ $stripe_count -lt $MDSCOUNT ]; do
19381                 createmany -m $DIR/$tdir/f $total $create ||
19382                         error "create sub files failed"
19383                 stat $DIR/$tdir > /dev/null
19384                 total=$((total + create))
19385                 stripe_count=$((stripe_count + delta))
19386                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19387
19388                 wait_update $HOSTNAME \
19389                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19390                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19391
19392                 wait_update $HOSTNAME \
19393                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19394                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19395
19396                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19397                 echo "$nr_files/$total files on MDT$stripe_index after split"
19398                 # allow 10% margin of imbalance with crush hash
19399                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19400                         error "$nr_files files on MDT$stripe_index after split"
19401
19402                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19403                 [ $nr_files -eq $total ] ||
19404                         error "total sub files $nr_files != $total"
19405         done
19406 }
19407 run_test 230q "dir auto split"
19408
19409 test_230r() {
19410         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19411         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19412         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19413                 skip "Need MDS version at least 2.13.54"
19414
19415         # maximum amount of local locks:
19416         # parent striped dir - 2 locks
19417         # new stripe in parent to migrate to - 1 lock
19418         # source and target - 2 locks
19419         # Total 5 locks for regular file
19420         mkdir -p $DIR/$tdir
19421         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19422         touch $DIR/$tdir/dir1/eee
19423
19424         # create 4 hardlink for 4 more locks
19425         # Total: 9 locks > RS_MAX_LOCKS (8)
19426         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19427         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19428         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19429         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19430         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19431         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19432         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19433         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19434
19435         cancel_lru_locks mdc
19436
19437         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19438                 error "migrate dir fails"
19439
19440         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19441 }
19442 run_test 230r "migrate with too many local locks"
19443
19444 test_230s() {
19445         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19446                 skip "Need MDS version at least 2.13.57"
19447
19448         local mdts=$(comma_list $(mdts_nodes))
19449         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19450                                 mdt.*MDT0000.enable_dir_restripe)
19451
19452         stack_trap "do_nodes $mdts $LCTL set_param \
19453                     mdt.*.enable_dir_restripe=$restripe_status"
19454
19455         local st
19456         for st in 0 1; do
19457                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19458                 test_mkdir $DIR/$tdir
19459                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19460                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19461                 rmdir $DIR/$tdir
19462         done
19463 }
19464 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19465
19466 test_230t()
19467 {
19468         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19469         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19470                 skip "Need MDS version at least 2.14.50"
19471
19472         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19473         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19474         $LFS project -p 1 -s $DIR/$tdir ||
19475                 error "set $tdir project id failed"
19476         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19477                 error "set subdir project id failed"
19478         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19479 }
19480 run_test 230t "migrate directory with project ID set"
19481
19482 test_231a()
19483 {
19484         # For simplicity this test assumes that max_pages_per_rpc
19485         # is the same across all OSCs
19486         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19487         local bulk_size=$((max_pages * PAGE_SIZE))
19488         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19489                                        head -n 1)
19490
19491         mkdir -p $DIR/$tdir
19492         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19493                 error "failed to set stripe with -S ${brw_size}M option"
19494
19495         # clear the OSC stats
19496         $LCTL set_param osc.*.stats=0 &>/dev/null
19497         stop_writeback
19498
19499         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19500         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19501                 oflag=direct &>/dev/null || error "dd failed"
19502
19503         sync; sleep 1; sync # just to be safe
19504         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19505         if [ x$nrpcs != "x1" ]; then
19506                 $LCTL get_param osc.*.stats
19507                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19508         fi
19509
19510         start_writeback
19511         # Drop the OSC cache, otherwise we will read from it
19512         cancel_lru_locks osc
19513
19514         # clear the OSC stats
19515         $LCTL set_param osc.*.stats=0 &>/dev/null
19516
19517         # Client reads $bulk_size.
19518         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19519                 iflag=direct &>/dev/null || error "dd failed"
19520
19521         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19522         if [ x$nrpcs != "x1" ]; then
19523                 $LCTL get_param osc.*.stats
19524                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19525         fi
19526 }
19527 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19528
19529 test_231b() {
19530         mkdir -p $DIR/$tdir
19531         local i
19532         for i in {0..1023}; do
19533                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19534                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19535                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19536         done
19537         sync
19538 }
19539 run_test 231b "must not assert on fully utilized OST request buffer"
19540
19541 test_232a() {
19542         mkdir -p $DIR/$tdir
19543         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19544
19545         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19546         do_facet ost1 $LCTL set_param fail_loc=0x31c
19547
19548         # ignore dd failure
19549         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19550
19551         do_facet ost1 $LCTL set_param fail_loc=0
19552         umount_client $MOUNT || error "umount failed"
19553         mount_client $MOUNT || error "mount failed"
19554         stop ost1 || error "cannot stop ost1"
19555         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19556 }
19557 run_test 232a "failed lock should not block umount"
19558
19559 test_232b() {
19560         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19561                 skip "Need MDS version at least 2.10.58"
19562
19563         mkdir -p $DIR/$tdir
19564         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19565         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19566         sync
19567         cancel_lru_locks osc
19568
19569         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19570         do_facet ost1 $LCTL set_param fail_loc=0x31c
19571
19572         # ignore failure
19573         $LFS data_version $DIR/$tdir/$tfile || true
19574
19575         do_facet ost1 $LCTL set_param fail_loc=0
19576         umount_client $MOUNT || error "umount failed"
19577         mount_client $MOUNT || error "mount failed"
19578         stop ost1 || error "cannot stop ost1"
19579         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19580 }
19581 run_test 232b "failed data version lock should not block umount"
19582
19583 test_233a() {
19584         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19585                 skip "Need MDS version at least 2.3.64"
19586         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19587
19588         local fid=$($LFS path2fid $MOUNT)
19589
19590         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19591                 error "cannot access $MOUNT using its FID '$fid'"
19592 }
19593 run_test 233a "checking that OBF of the FS root succeeds"
19594
19595 test_233b() {
19596         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19597                 skip "Need MDS version at least 2.5.90"
19598         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19599
19600         local fid=$($LFS path2fid $MOUNT/.lustre)
19601
19602         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19603                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19604
19605         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19606         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19607                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19608 }
19609 run_test 233b "checking that OBF of the FS .lustre succeeds"
19610
19611 test_234() {
19612         local p="$TMP/sanityN-$TESTNAME.parameters"
19613         save_lustre_params client "llite.*.xattr_cache" > $p
19614         lctl set_param llite.*.xattr_cache 1 ||
19615                 skip_env "xattr cache is not supported"
19616
19617         mkdir -p $DIR/$tdir || error "mkdir failed"
19618         touch $DIR/$tdir/$tfile || error "touch failed"
19619         # OBD_FAIL_LLITE_XATTR_ENOMEM
19620         $LCTL set_param fail_loc=0x1405
19621         getfattr -n user.attr $DIR/$tdir/$tfile &&
19622                 error "getfattr should have failed with ENOMEM"
19623         $LCTL set_param fail_loc=0x0
19624         rm -rf $DIR/$tdir
19625
19626         restore_lustre_params < $p
19627         rm -f $p
19628 }
19629 run_test 234 "xattr cache should not crash on ENOMEM"
19630
19631 test_235() {
19632         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
19633                 skip "Need MDS version at least 2.4.52"
19634
19635         flock_deadlock $DIR/$tfile
19636         local RC=$?
19637         case $RC in
19638                 0)
19639                 ;;
19640                 124) error "process hangs on a deadlock"
19641                 ;;
19642                 *) error "error executing flock_deadlock $DIR/$tfile"
19643                 ;;
19644         esac
19645 }
19646 run_test 235 "LU-1715: flock deadlock detection does not work properly"
19647
19648 #LU-2935
19649 test_236() {
19650         check_swap_layouts_support
19651
19652         local ref1=/etc/passwd
19653         local ref2=/etc/group
19654         local file1=$DIR/$tdir/f1
19655         local file2=$DIR/$tdir/f2
19656
19657         test_mkdir -c1 $DIR/$tdir
19658         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
19659         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
19660         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
19661         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
19662         local fd=$(free_fd)
19663         local cmd="exec $fd<>$file2"
19664         eval $cmd
19665         rm $file2
19666         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
19667                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
19668         cmd="exec $fd>&-"
19669         eval $cmd
19670         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19671
19672         #cleanup
19673         rm -rf $DIR/$tdir
19674 }
19675 run_test 236 "Layout swap on open unlinked file"
19676
19677 # LU-4659 linkea consistency
19678 test_238() {
19679         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
19680                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
19681                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
19682                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
19683
19684         touch $DIR/$tfile
19685         ln $DIR/$tfile $DIR/$tfile.lnk
19686         touch $DIR/$tfile.new
19687         mv $DIR/$tfile.new $DIR/$tfile
19688         local fid1=$($LFS path2fid $DIR/$tfile)
19689         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
19690         local path1=$($LFS fid2path $FSNAME "$fid1")
19691         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
19692         local path2=$($LFS fid2path $FSNAME "$fid2")
19693         [ $tfile.lnk == $path2 ] ||
19694                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
19695         rm -f $DIR/$tfile*
19696 }
19697 run_test 238 "Verify linkea consistency"
19698
19699 test_239A() { # was test_239
19700         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
19701                 skip "Need MDS version at least 2.5.60"
19702
19703         local list=$(comma_list $(mdts_nodes))
19704
19705         mkdir -p $DIR/$tdir
19706         createmany -o $DIR/$tdir/f- 5000
19707         unlinkmany $DIR/$tdir/f- 5000
19708         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
19709                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
19710         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
19711                         osp.*MDT*.sync_in_flight" | calc_sum)
19712         [ "$changes" -eq 0 ] || error "$changes not synced"
19713 }
19714 run_test 239A "osp_sync test"
19715
19716 test_239a() { #LU-5297
19717         remote_mds_nodsh && skip "remote MDS with nodsh"
19718
19719         touch $DIR/$tfile
19720         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
19721         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
19722         chgrp $RUNAS_GID $DIR/$tfile
19723         wait_delete_completed
19724 }
19725 run_test 239a "process invalid osp sync record correctly"
19726
19727 test_239b() { #LU-5297
19728         remote_mds_nodsh && skip "remote MDS with nodsh"
19729
19730         touch $DIR/$tfile1
19731         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
19732         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
19733         chgrp $RUNAS_GID $DIR/$tfile1
19734         wait_delete_completed
19735         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19736         touch $DIR/$tfile2
19737         chgrp $RUNAS_GID $DIR/$tfile2
19738         wait_delete_completed
19739 }
19740 run_test 239b "process osp sync record with ENOMEM error correctly"
19741
19742 test_240() {
19743         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19744         remote_mds_nodsh && skip "remote MDS with nodsh"
19745
19746         mkdir -p $DIR/$tdir
19747
19748         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
19749                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
19750         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
19751                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
19752
19753         umount_client $MOUNT || error "umount failed"
19754         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
19755         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
19756         mount_client $MOUNT || error "failed to mount client"
19757
19758         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
19759         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
19760 }
19761 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
19762
19763 test_241_bio() {
19764         local count=$1
19765         local bsize=$2
19766
19767         for LOOP in $(seq $count); do
19768                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
19769                 cancel_lru_locks $OSC || true
19770         done
19771 }
19772
19773 test_241_dio() {
19774         local count=$1
19775         local bsize=$2
19776
19777         for LOOP in $(seq $1); do
19778                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
19779                         2>/dev/null
19780         done
19781 }
19782
19783 test_241a() { # was test_241
19784         local bsize=$PAGE_SIZE
19785
19786         (( bsize < 40960 )) && bsize=40960
19787         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19788         ls -la $DIR/$tfile
19789         cancel_lru_locks $OSC
19790         test_241_bio 1000 $bsize &
19791         PID=$!
19792         test_241_dio 1000 $bsize
19793         wait $PID
19794 }
19795 run_test 241a "bio vs dio"
19796
19797 test_241b() {
19798         local bsize=$PAGE_SIZE
19799
19800         (( bsize < 40960 )) && bsize=40960
19801         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
19802         ls -la $DIR/$tfile
19803         test_241_dio 1000 $bsize &
19804         PID=$!
19805         test_241_dio 1000 $bsize
19806         wait $PID
19807 }
19808 run_test 241b "dio vs dio"
19809
19810 test_242() {
19811         remote_mds_nodsh && skip "remote MDS with nodsh"
19812
19813         mkdir -p $DIR/$tdir
19814         touch $DIR/$tdir/$tfile
19815
19816         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19817         do_facet mds1 lctl set_param fail_loc=0x105
19818         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19819
19820         do_facet mds1 lctl set_param fail_loc=0
19821         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19822 }
19823 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19824
19825 test_243()
19826 {
19827         test_mkdir $DIR/$tdir
19828         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19829 }
19830 run_test 243 "various group lock tests"
19831
19832 test_244a()
19833 {
19834         test_mkdir $DIR/$tdir
19835         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19836         sendfile_grouplock $DIR/$tdir/$tfile || \
19837                 error "sendfile+grouplock failed"
19838         rm -rf $DIR/$tdir
19839 }
19840 run_test 244a "sendfile with group lock tests"
19841
19842 test_244b()
19843 {
19844         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19845
19846         local threads=50
19847         local size=$((1024*1024))
19848
19849         test_mkdir $DIR/$tdir
19850         for i in $(seq 1 $threads); do
19851                 local file=$DIR/$tdir/file_$((i / 10))
19852                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19853                 local pids[$i]=$!
19854         done
19855         for i in $(seq 1 $threads); do
19856                 wait ${pids[$i]}
19857         done
19858 }
19859 run_test 244b "multi-threaded write with group lock"
19860
19861 test_245() {
19862         local flagname="multi_mod_rpcs"
19863         local connect_data_name="max_mod_rpcs"
19864         local out
19865
19866         # check if multiple modify RPCs flag is set
19867         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19868                 grep "connect_flags:")
19869         echo "$out"
19870
19871         echo "$out" | grep -qw $flagname
19872         if [ $? -ne 0 ]; then
19873                 echo "connect flag $flagname is not set"
19874                 return
19875         fi
19876
19877         # check if multiple modify RPCs data is set
19878         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19879         echo "$out"
19880
19881         echo "$out" | grep -qw $connect_data_name ||
19882                 error "import should have connect data $connect_data_name"
19883 }
19884 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19885
19886 cleanup_247() {
19887         local submount=$1
19888
19889         trap 0
19890         umount_client $submount
19891         rmdir $submount
19892 }
19893
19894 test_247a() {
19895         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19896                 grep -q subtree ||
19897                 skip_env "Fileset feature is not supported"
19898
19899         local submount=${MOUNT}_$tdir
19900
19901         mkdir $MOUNT/$tdir
19902         mkdir -p $submount || error "mkdir $submount failed"
19903         FILESET="$FILESET/$tdir" mount_client $submount ||
19904                 error "mount $submount failed"
19905         trap "cleanup_247 $submount" EXIT
19906         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19907         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19908                 error "read $MOUNT/$tdir/$tfile failed"
19909         cleanup_247 $submount
19910 }
19911 run_test 247a "mount subdir as fileset"
19912
19913 test_247b() {
19914         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19915                 skip_env "Fileset feature is not supported"
19916
19917         local submount=${MOUNT}_$tdir
19918
19919         rm -rf $MOUNT/$tdir
19920         mkdir -p $submount || error "mkdir $submount failed"
19921         SKIP_FILESET=1
19922         FILESET="$FILESET/$tdir" mount_client $submount &&
19923                 error "mount $submount should fail"
19924         rmdir $submount
19925 }
19926 run_test 247b "mount subdir that dose not exist"
19927
19928 test_247c() {
19929         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19930                 skip_env "Fileset feature is not supported"
19931
19932         local submount=${MOUNT}_$tdir
19933
19934         mkdir -p $MOUNT/$tdir/dir1
19935         mkdir -p $submount || error "mkdir $submount failed"
19936         trap "cleanup_247 $submount" EXIT
19937         FILESET="$FILESET/$tdir" mount_client $submount ||
19938                 error "mount $submount failed"
19939         local fid=$($LFS path2fid $MOUNT/)
19940         $LFS fid2path $submount $fid && error "fid2path should fail"
19941         cleanup_247 $submount
19942 }
19943 run_test 247c "running fid2path outside subdirectory root"
19944
19945 test_247d() {
19946         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19947                 skip "Fileset feature is not supported"
19948
19949         local submount=${MOUNT}_$tdir
19950
19951         mkdir -p $MOUNT/$tdir/dir1
19952         mkdir -p $submount || error "mkdir $submount failed"
19953         FILESET="$FILESET/$tdir" mount_client $submount ||
19954                 error "mount $submount failed"
19955         trap "cleanup_247 $submount" EXIT
19956
19957         local td=$submount/dir1
19958         local fid=$($LFS path2fid $td)
19959         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19960
19961         # check that we get the same pathname back
19962         local rootpath
19963         local found
19964         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19965                 echo "$rootpath $fid"
19966                 found=$($LFS fid2path $rootpath "$fid")
19967                 [ -n "found" ] || error "fid2path should succeed"
19968                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19969         done
19970         # check wrong root path format
19971         rootpath=$submount"_wrong"
19972         found=$($LFS fid2path $rootpath "$fid")
19973         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19974
19975         cleanup_247 $submount
19976 }
19977 run_test 247d "running fid2path inside subdirectory root"
19978
19979 # LU-8037
19980 test_247e() {
19981         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19982                 grep -q subtree ||
19983                 skip "Fileset feature is not supported"
19984
19985         local submount=${MOUNT}_$tdir
19986
19987         mkdir $MOUNT/$tdir
19988         mkdir -p $submount || error "mkdir $submount failed"
19989         FILESET="$FILESET/.." mount_client $submount &&
19990                 error "mount $submount should fail"
19991         rmdir $submount
19992 }
19993 run_test 247e "mount .. as fileset"
19994
19995 test_247f() {
19996         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19997         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19998                 skip "Need at least version 2.13.52"
19999         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20000                 skip "Need at least version 2.14.50"
20001         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20002                 grep -q subtree ||
20003                 skip "Fileset feature is not supported"
20004
20005         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20006         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20007                 error "mkdir remote failed"
20008         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
20009         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20010                 error "mkdir striped failed"
20011         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20012
20013         local submount=${MOUNT}_$tdir
20014
20015         mkdir -p $submount || error "mkdir $submount failed"
20016         stack_trap "rmdir $submount"
20017
20018         local dir
20019         local stat
20020         local fileset=$FILESET
20021         local mdts=$(comma_list $(mdts_nodes))
20022
20023         stat=$(do_facet mds1 $LCTL get_param -n \
20024                 mdt.*MDT0000.enable_remote_subdir_mount)
20025         stack_trap "do_nodes $mdts $LCTL set_param \
20026                 mdt.*.enable_remote_subdir_mount=$stat"
20027
20028         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20029         stack_trap "umount_client $submount"
20030         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20031                 error "mount remote dir $dir should fail"
20032
20033         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20034                 $tdir/striped/. ; do
20035                 FILESET="$fileset/$dir" mount_client $submount ||
20036                         error "mount $dir failed"
20037                 umount_client $submount
20038         done
20039
20040         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20041         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20042                 error "mount $tdir/remote failed"
20043 }
20044 run_test 247f "mount striped or remote directory as fileset"
20045
20046 test_247g() {
20047         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20048         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20049                 skip "Need at least version 2.14.50"
20050
20051         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20052                 error "mkdir $tdir failed"
20053         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20054
20055         local submount=${MOUNT}_$tdir
20056
20057         mkdir -p $submount || error "mkdir $submount failed"
20058         stack_trap "rmdir $submount"
20059
20060         FILESET="$fileset/$tdir" mount_client $submount ||
20061                 error "mount $dir failed"
20062         stack_trap "umount $submount"
20063
20064         local mdts=$(comma_list $(mdts_nodes))
20065
20066         local nrpcs
20067
20068         stat $submount > /dev/null
20069         cancel_lru_locks $MDC
20070         stat $submount > /dev/null
20071         stat $submount/$tfile > /dev/null
20072         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20073         stat $submount/$tfile > /dev/null
20074         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20075                 awk '/getattr/ {sum += $2} END {print sum}')
20076
20077         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20078 }
20079 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20080
20081 test_248a() {
20082         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20083         [ -z "$fast_read_sav" ] && skip "no fast read support"
20084
20085         # create a large file for fast read verification
20086         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20087
20088         # make sure the file is created correctly
20089         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20090                 { rm -f $DIR/$tfile; skip "file creation error"; }
20091
20092         echo "Test 1: verify that fast read is 4 times faster on cache read"
20093
20094         # small read with fast read enabled
20095         $LCTL set_param -n llite.*.fast_read=1
20096         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20097                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20098                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20099         # small read with fast read disabled
20100         $LCTL set_param -n llite.*.fast_read=0
20101         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20102                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20103                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20104
20105         # verify that fast read is 4 times faster for cache read
20106         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20107                 error_not_in_vm "fast read was not 4 times faster: " \
20108                            "$t_fast vs $t_slow"
20109
20110         echo "Test 2: verify the performance between big and small read"
20111         $LCTL set_param -n llite.*.fast_read=1
20112
20113         # 1k non-cache read
20114         cancel_lru_locks osc
20115         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20116                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20117                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20118
20119         # 1M non-cache read
20120         cancel_lru_locks osc
20121         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20122                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20123                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20124
20125         # verify that big IO is not 4 times faster than small IO
20126         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20127                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20128
20129         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20130         rm -f $DIR/$tfile
20131 }
20132 run_test 248a "fast read verification"
20133
20134 test_248b() {
20135         # Default short_io_bytes=16384, try both smaller and larger sizes.
20136         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20137         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20138         echo "bs=53248 count=113 normal buffered write"
20139         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20140                 error "dd of initial data file failed"
20141         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20142
20143         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20144         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20145                 error "dd with sync normal writes failed"
20146         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20147
20148         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20149         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20150                 error "dd with sync small writes failed"
20151         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20152
20153         cancel_lru_locks osc
20154
20155         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20156         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20157         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20158         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20159                 iflag=direct || error "dd with O_DIRECT small read failed"
20160         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20161         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20162                 error "compare $TMP/$tfile.1 failed"
20163
20164         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20165         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20166
20167         # just to see what the maximum tunable value is, and test parsing
20168         echo "test invalid parameter 2MB"
20169         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20170                 error "too-large short_io_bytes allowed"
20171         echo "test maximum parameter 512KB"
20172         # if we can set a larger short_io_bytes, run test regardless of version
20173         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20174                 # older clients may not allow setting it this large, that's OK
20175                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20176                         skip "Need at least client version 2.13.50"
20177                 error "medium short_io_bytes failed"
20178         fi
20179         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20180         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20181
20182         echo "test large parameter 64KB"
20183         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20184         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20185
20186         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20187         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20188                 error "dd with sync large writes failed"
20189         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20190
20191         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20192         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20193         num=$((113 * 4096 / PAGE_SIZE))
20194         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20195         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20196                 error "dd with O_DIRECT large writes failed"
20197         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20198                 error "compare $DIR/$tfile.3 failed"
20199
20200         cancel_lru_locks osc
20201
20202         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20203         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20204                 error "dd with O_DIRECT large read failed"
20205         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20206                 error "compare $TMP/$tfile.2 failed"
20207
20208         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20209         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20210                 error "dd with O_DIRECT large read failed"
20211         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20212                 error "compare $TMP/$tfile.3 failed"
20213 }
20214 run_test 248b "test short_io read and write for both small and large sizes"
20215
20216 test_249() { # LU-7890
20217         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20218                 skip "Need at least version 2.8.54"
20219
20220         rm -f $DIR/$tfile
20221         $LFS setstripe -c 1 $DIR/$tfile
20222         # Offset 2T == 4k * 512M
20223         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20224                 error "dd to 2T offset failed"
20225 }
20226 run_test 249 "Write above 2T file size"
20227
20228 test_250() {
20229         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20230          && skip "no 16TB file size limit on ZFS"
20231
20232         $LFS setstripe -c 1 $DIR/$tfile
20233         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20234         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20235         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20236         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20237                 conv=notrunc,fsync && error "append succeeded"
20238         return 0
20239 }
20240 run_test 250 "Write above 16T limit"
20241
20242 test_251() {
20243         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20244
20245         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20246         #Skip once - writing the first stripe will succeed
20247         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20248         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20249                 error "short write happened"
20250
20251         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20252         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20253                 error "short read happened"
20254
20255         rm -f $DIR/$tfile
20256 }
20257 run_test 251 "Handling short read and write correctly"
20258
20259 test_252() {
20260         remote_mds_nodsh && skip "remote MDS with nodsh"
20261         remote_ost_nodsh && skip "remote OST with nodsh"
20262         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20263                 skip_env "ldiskfs only test"
20264         fi
20265
20266         local tgt
20267         local dev
20268         local out
20269         local uuid
20270         local num
20271         local gen
20272
20273         # check lr_reader on OST0000
20274         tgt=ost1
20275         dev=$(facet_device $tgt)
20276         out=$(do_facet $tgt $LR_READER $dev)
20277         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20278         echo "$out"
20279         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20280         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20281                 error "Invalid uuid returned by $LR_READER on target $tgt"
20282         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20283
20284         # check lr_reader -c on MDT0000
20285         tgt=mds1
20286         dev=$(facet_device $tgt)
20287         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20288                 skip "$LR_READER does not support additional options"
20289         fi
20290         out=$(do_facet $tgt $LR_READER -c $dev)
20291         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20292         echo "$out"
20293         num=$(echo "$out" | grep -c "mdtlov")
20294         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20295                 error "Invalid number of mdtlov clients returned by $LR_READER"
20296         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20297
20298         # check lr_reader -cr on MDT0000
20299         out=$(do_facet $tgt $LR_READER -cr $dev)
20300         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20301         echo "$out"
20302         echo "$out" | grep -q "^reply_data:$" ||
20303                 error "$LR_READER should have returned 'reply_data' section"
20304         num=$(echo "$out" | grep -c "client_generation")
20305         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20306 }
20307 run_test 252 "check lr_reader tool"
20308
20309 test_253() {
20310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20311         remote_mds_nodsh && skip "remote MDS with nodsh"
20312         remote_mgs_nodsh && skip "remote MGS with nodsh"
20313
20314         local ostidx=0
20315         local rc=0
20316         local ost_name=$(ostname_from_index $ostidx)
20317
20318         # on the mdt's osc
20319         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20320         do_facet $SINGLEMDS $LCTL get_param -n \
20321                 osp.$mdtosc_proc1.reserved_mb_high ||
20322                 skip  "remote MDS does not support reserved_mb_high"
20323
20324         rm -rf $DIR/$tdir
20325         wait_mds_ost_sync
20326         wait_delete_completed
20327         mkdir $DIR/$tdir
20328
20329         pool_add $TESTNAME || error "Pool creation failed"
20330         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20331
20332         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20333                 error "Setstripe failed"
20334
20335         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20336
20337         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20338                     grep "watermarks")
20339         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20340
20341         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20342                         osp.$mdtosc_proc1.prealloc_status)
20343         echo "prealloc_status $oa_status"
20344
20345         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20346                 error "File creation should fail"
20347
20348         #object allocation was stopped, but we still able to append files
20349         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20350                 oflag=append || error "Append failed"
20351
20352         rm -f $DIR/$tdir/$tfile.0
20353
20354         # For this test, we want to delete the files we created to go out of
20355         # space but leave the watermark, so we remain nearly out of space
20356         ost_watermarks_enospc_delete_files $tfile $ostidx
20357
20358         wait_delete_completed
20359
20360         sleep_maxage
20361
20362         for i in $(seq 10 12); do
20363                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20364                         2>/dev/null || error "File creation failed after rm"
20365         done
20366
20367         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20368                         osp.$mdtosc_proc1.prealloc_status)
20369         echo "prealloc_status $oa_status"
20370
20371         if (( oa_status != 0 )); then
20372                 error "Object allocation still disable after rm"
20373         fi
20374 }
20375 run_test 253 "Check object allocation limit"
20376
20377 test_254() {
20378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20379         remote_mds_nodsh && skip "remote MDS with nodsh"
20380         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20381                 skip "MDS does not support changelog_size"
20382
20383         local cl_user
20384         local MDT0=$(facet_svc $SINGLEMDS)
20385
20386         changelog_register || error "changelog_register failed"
20387
20388         changelog_clear 0 || error "changelog_clear failed"
20389
20390         local size1=$(do_facet $SINGLEMDS \
20391                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20392         echo "Changelog size $size1"
20393
20394         rm -rf $DIR/$tdir
20395         $LFS mkdir -i 0 $DIR/$tdir
20396         # change something
20397         mkdir -p $DIR/$tdir/pics/2008/zachy
20398         touch $DIR/$tdir/pics/2008/zachy/timestamp
20399         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20400         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20401         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20402         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20403         rm $DIR/$tdir/pics/desktop.jpg
20404
20405         local size2=$(do_facet $SINGLEMDS \
20406                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20407         echo "Changelog size after work $size2"
20408
20409         (( $size2 > $size1 )) ||
20410                 error "new Changelog size=$size2 less than old size=$size1"
20411 }
20412 run_test 254 "Check changelog size"
20413
20414 ladvise_no_type()
20415 {
20416         local type=$1
20417         local file=$2
20418
20419         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20420                 awk -F: '{print $2}' | grep $type > /dev/null
20421         if [ $? -ne 0 ]; then
20422                 return 0
20423         fi
20424         return 1
20425 }
20426
20427 ladvise_no_ioctl()
20428 {
20429         local file=$1
20430
20431         lfs ladvise -a willread $file > /dev/null 2>&1
20432         if [ $? -eq 0 ]; then
20433                 return 1
20434         fi
20435
20436         lfs ladvise -a willread $file 2>&1 |
20437                 grep "Inappropriate ioctl for device" > /dev/null
20438         if [ $? -eq 0 ]; then
20439                 return 0
20440         fi
20441         return 1
20442 }
20443
20444 percent() {
20445         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20446 }
20447
20448 # run a random read IO workload
20449 # usage: random_read_iops <filename> <filesize> <iosize>
20450 random_read_iops() {
20451         local file=$1
20452         local fsize=$2
20453         local iosize=${3:-4096}
20454
20455         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20456                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20457 }
20458
20459 drop_file_oss_cache() {
20460         local file="$1"
20461         local nodes="$2"
20462
20463         $LFS ladvise -a dontneed $file 2>/dev/null ||
20464                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20465 }
20466
20467 ladvise_willread_performance()
20468 {
20469         local repeat=10
20470         local average_origin=0
20471         local average_cache=0
20472         local average_ladvise=0
20473
20474         for ((i = 1; i <= $repeat; i++)); do
20475                 echo "Iter $i/$repeat: reading without willread hint"
20476                 cancel_lru_locks osc
20477                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20478                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20479                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20480                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20481
20482                 cancel_lru_locks osc
20483                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20484                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20485                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20486
20487                 cancel_lru_locks osc
20488                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20489                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20490                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20491                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20492                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20493         done
20494         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20495         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20496         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20497
20498         speedup_cache=$(percent $average_cache $average_origin)
20499         speedup_ladvise=$(percent $average_ladvise $average_origin)
20500
20501         echo "Average uncached read: $average_origin"
20502         echo "Average speedup with OSS cached read: " \
20503                 "$average_cache = +$speedup_cache%"
20504         echo "Average speedup with ladvise willread: " \
20505                 "$average_ladvise = +$speedup_ladvise%"
20506
20507         local lowest_speedup=20
20508         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20509                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20510                         "got $average_cache%. Skipping ladvise willread check."
20511                 return 0
20512         fi
20513
20514         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20515         # it is still good to run until then to exercise 'ladvise willread'
20516         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20517                 [ "$ost1_FSTYPE" = "zfs" ] &&
20518                 echo "osd-zfs does not support dontneed or drop_caches" &&
20519                 return 0
20520
20521         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20522         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20523                 error_not_in_vm "Speedup with willread is less than " \
20524                         "$lowest_speedup%, got $average_ladvise%"
20525 }
20526
20527 test_255a() {
20528         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20529                 skip "lustre < 2.8.54 does not support ladvise "
20530         remote_ost_nodsh && skip "remote OST with nodsh"
20531
20532         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20533
20534         ladvise_no_type willread $DIR/$tfile &&
20535                 skip "willread ladvise is not supported"
20536
20537         ladvise_no_ioctl $DIR/$tfile &&
20538                 skip "ladvise ioctl is not supported"
20539
20540         local size_mb=100
20541         local size=$((size_mb * 1048576))
20542         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20543                 error "dd to $DIR/$tfile failed"
20544
20545         lfs ladvise -a willread $DIR/$tfile ||
20546                 error "Ladvise failed with no range argument"
20547
20548         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20549                 error "Ladvise failed with no -l or -e argument"
20550
20551         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20552                 error "Ladvise failed with only -e argument"
20553
20554         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20555                 error "Ladvise failed with only -l argument"
20556
20557         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20558                 error "End offset should not be smaller than start offset"
20559
20560         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20561                 error "End offset should not be equal to start offset"
20562
20563         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20564                 error "Ladvise failed with overflowing -s argument"
20565
20566         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20567                 error "Ladvise failed with overflowing -e argument"
20568
20569         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20570                 error "Ladvise failed with overflowing -l argument"
20571
20572         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20573                 error "Ladvise succeeded with conflicting -l and -e arguments"
20574
20575         echo "Synchronous ladvise should wait"
20576         local delay=4
20577 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20578         do_nodes $(comma_list $(osts_nodes)) \
20579                 $LCTL set_param fail_val=$delay fail_loc=0x237
20580
20581         local start_ts=$SECONDS
20582         lfs ladvise -a willread $DIR/$tfile ||
20583                 error "Ladvise failed with no range argument"
20584         local end_ts=$SECONDS
20585         local inteval_ts=$((end_ts - start_ts))
20586
20587         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20588                 error "Synchronous advice didn't wait reply"
20589         fi
20590
20591         echo "Asynchronous ladvise shouldn't wait"
20592         local start_ts=$SECONDS
20593         lfs ladvise -a willread -b $DIR/$tfile ||
20594                 error "Ladvise failed with no range argument"
20595         local end_ts=$SECONDS
20596         local inteval_ts=$((end_ts - start_ts))
20597
20598         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20599                 error "Asynchronous advice blocked"
20600         fi
20601
20602         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20603         ladvise_willread_performance
20604 }
20605 run_test 255a "check 'lfs ladvise -a willread'"
20606
20607 facet_meminfo() {
20608         local facet=$1
20609         local info=$2
20610
20611         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20612 }
20613
20614 test_255b() {
20615         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20616                 skip "lustre < 2.8.54 does not support ladvise "
20617         remote_ost_nodsh && skip "remote OST with nodsh"
20618
20619         lfs setstripe -c 1 -i 0 $DIR/$tfile
20620
20621         ladvise_no_type dontneed $DIR/$tfile &&
20622                 skip "dontneed ladvise is not supported"
20623
20624         ladvise_no_ioctl $DIR/$tfile &&
20625                 skip "ladvise ioctl is not supported"
20626
20627         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20628                 [ "$ost1_FSTYPE" = "zfs" ] &&
20629                 skip "zfs-osd does not support 'ladvise dontneed'"
20630
20631         local size_mb=100
20632         local size=$((size_mb * 1048576))
20633         # In order to prevent disturbance of other processes, only check 3/4
20634         # of the memory usage
20635         local kibibytes=$((size_mb * 1024 * 3 / 4))
20636
20637         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20638                 error "dd to $DIR/$tfile failed"
20639
20640         #force write to complete before dropping OST cache & checking memory
20641         sync
20642
20643         local total=$(facet_meminfo ost1 MemTotal)
20644         echo "Total memory: $total KiB"
20645
20646         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
20647         local before_read=$(facet_meminfo ost1 Cached)
20648         echo "Cache used before read: $before_read KiB"
20649
20650         lfs ladvise -a willread $DIR/$tfile ||
20651                 error "Ladvise willread failed"
20652         local after_read=$(facet_meminfo ost1 Cached)
20653         echo "Cache used after read: $after_read KiB"
20654
20655         lfs ladvise -a dontneed $DIR/$tfile ||
20656                 error "Ladvise dontneed again failed"
20657         local no_read=$(facet_meminfo ost1 Cached)
20658         echo "Cache used after dontneed ladvise: $no_read KiB"
20659
20660         if [ $total -lt $((before_read + kibibytes)) ]; then
20661                 echo "Memory is too small, abort checking"
20662                 return 0
20663         fi
20664
20665         if [ $((before_read + kibibytes)) -gt $after_read ]; then
20666                 error "Ladvise willread should use more memory" \
20667                         "than $kibibytes KiB"
20668         fi
20669
20670         if [ $((no_read + kibibytes)) -gt $after_read ]; then
20671                 error "Ladvise dontneed should release more memory" \
20672                         "than $kibibytes KiB"
20673         fi
20674 }
20675 run_test 255b "check 'lfs ladvise -a dontneed'"
20676
20677 test_255c() {
20678         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
20679                 skip "lustre < 2.10.50 does not support lockahead"
20680
20681         local ost1_imp=$(get_osc_import_name client ost1)
20682         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
20683                          cut -d'.' -f2)
20684         local count
20685         local new_count
20686         local difference
20687         local i
20688         local rc
20689
20690         test_mkdir -p $DIR/$tdir
20691         $LFS setstripe -i 0 -c 1 $DIR/$tdir
20692
20693         #test 10 returns only success/failure
20694         i=10
20695         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20696         rc=$?
20697         if [ $rc -eq 255 ]; then
20698                 error "Ladvise test${i} failed, ${rc}"
20699         fi
20700
20701         #test 11 counts lock enqueue requests, all others count new locks
20702         i=11
20703         count=$(do_facet ost1 \
20704                 $LCTL get_param -n ost.OSS.ost.stats)
20705         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
20706
20707         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20708         rc=$?
20709         if [ $rc -eq 255 ]; then
20710                 error "Ladvise test${i} failed, ${rc}"
20711         fi
20712
20713         new_count=$(do_facet ost1 \
20714                 $LCTL get_param -n ost.OSS.ost.stats)
20715         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
20716                    awk '{ print $2 }')
20717
20718         difference="$((new_count - count))"
20719         if [ $difference -ne $rc ]; then
20720                 error "Ladvise test${i}, bad enqueue count, returned " \
20721                       "${rc}, actual ${difference}"
20722         fi
20723
20724         for i in $(seq 12 21); do
20725                 # If we do not do this, we run the risk of having too many
20726                 # locks and starting lock cancellation while we are checking
20727                 # lock counts.
20728                 cancel_lru_locks osc
20729
20730                 count=$($LCTL get_param -n \
20731                        ldlm.namespaces.$imp_name.lock_unused_count)
20732
20733                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
20734                 rc=$?
20735                 if [ $rc -eq 255 ]; then
20736                         error "Ladvise test ${i} failed, ${rc}"
20737                 fi
20738
20739                 new_count=$($LCTL get_param -n \
20740                        ldlm.namespaces.$imp_name.lock_unused_count)
20741                 difference="$((new_count - count))"
20742
20743                 # Test 15 output is divided by 100 to map down to valid return
20744                 if [ $i -eq 15 ]; then
20745                         rc="$((rc * 100))"
20746                 fi
20747
20748                 if [ $difference -ne $rc ]; then
20749                         error "Ladvise test ${i}, bad lock count, returned " \
20750                               "${rc}, actual ${difference}"
20751                 fi
20752         done
20753
20754         #test 22 returns only success/failure
20755         i=22
20756         lockahead_test -d $DIR/$tdir -t $i -f $tfile
20757         rc=$?
20758         if [ $rc -eq 255 ]; then
20759                 error "Ladvise test${i} failed, ${rc}"
20760         fi
20761 }
20762 run_test 255c "suite of ladvise lockahead tests"
20763
20764 test_256() {
20765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20766         remote_mds_nodsh && skip "remote MDS with nodsh"
20767         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20768         changelog_users $SINGLEMDS | grep "^cl" &&
20769                 skip "active changelog user"
20770
20771         local cl_user
20772         local cat_sl
20773         local mdt_dev
20774
20775         mdt_dev=$(mdsdevname 1)
20776         echo $mdt_dev
20777
20778         changelog_register || error "changelog_register failed"
20779
20780         rm -rf $DIR/$tdir
20781         mkdir -p $DIR/$tdir
20782
20783         changelog_clear 0 || error "changelog_clear failed"
20784
20785         # change something
20786         touch $DIR/$tdir/{1..10}
20787
20788         # stop the MDT
20789         stop $SINGLEMDS || error "Fail to stop MDT"
20790
20791         # remount the MDT
20792
20793         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
20794
20795         #after mount new plainllog is used
20796         touch $DIR/$tdir/{11..19}
20797         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
20798         stack_trap "rm -f $tmpfile"
20799         cat_sl=$(do_facet $SINGLEMDS "sync; \
20800                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20801                  llog_reader $tmpfile | grep -c type=1064553b")
20802         do_facet $SINGLEMDS llog_reader $tmpfile
20803
20804         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
20805
20806         changelog_clear 0 || error "changelog_clear failed"
20807
20808         cat_sl=$(do_facet $SINGLEMDS "sync; \
20809                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
20810                  llog_reader $tmpfile | grep -c type=1064553b")
20811
20812         if (( cat_sl == 2 )); then
20813                 error "Empty plain llog was not deleted from changelog catalog"
20814         elif (( cat_sl != 1 )); then
20815                 error "Active plain llog shouldn't be deleted from catalog"
20816         fi
20817 }
20818 run_test 256 "Check llog delete for empty and not full state"
20819
20820 test_257() {
20821         remote_mds_nodsh && skip "remote MDS with nodsh"
20822         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20823                 skip "Need MDS version at least 2.8.55"
20824
20825         test_mkdir $DIR/$tdir
20826
20827         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
20828                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
20829         stat $DIR/$tdir
20830
20831 #define OBD_FAIL_MDS_XATTR_REP                  0x161
20832         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20833         local facet=mds$((mdtidx + 1))
20834         set_nodes_failloc $(facet_active_host $facet) 0x80000161
20835         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
20836
20837         stop $facet || error "stop MDS failed"
20838         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
20839                 error "start MDS fail"
20840         wait_recovery_complete $facet
20841 }
20842 run_test 257 "xattr locks are not lost"
20843
20844 # Verify we take the i_mutex when security requires it
20845 test_258a() {
20846 #define OBD_FAIL_IMUTEX_SEC 0x141c
20847         $LCTL set_param fail_loc=0x141c
20848         touch $DIR/$tfile
20849         chmod u+s $DIR/$tfile
20850         chmod a+rwx $DIR/$tfile
20851         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20852         RC=$?
20853         if [ $RC -ne 0 ]; then
20854                 error "error, failed to take i_mutex, rc=$?"
20855         fi
20856         rm -f $DIR/$tfile
20857 }
20858 run_test 258a "verify i_mutex security behavior when suid attributes is set"
20859
20860 # Verify we do NOT take the i_mutex in the normal case
20861 test_258b() {
20862 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20863         $LCTL set_param fail_loc=0x141d
20864         touch $DIR/$tfile
20865         chmod a+rwx $DIR
20866         chmod a+rw $DIR/$tfile
20867         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20868         RC=$?
20869         if [ $RC -ne 0 ]; then
20870                 error "error, took i_mutex unnecessarily, rc=$?"
20871         fi
20872         rm -f $DIR/$tfile
20873
20874 }
20875 run_test 258b "verify i_mutex security behavior"
20876
20877 test_259() {
20878         local file=$DIR/$tfile
20879         local before
20880         local after
20881
20882         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20883
20884         stack_trap "rm -f $file" EXIT
20885
20886         wait_delete_completed
20887         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20888         echo "before: $before"
20889
20890         $LFS setstripe -i 0 -c 1 $file
20891         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20892         sync_all_data
20893         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20894         echo "after write: $after"
20895
20896 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20897         do_facet ost1 $LCTL set_param fail_loc=0x2301
20898         $TRUNCATE $file 0
20899         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20900         echo "after truncate: $after"
20901
20902         stop ost1
20903         do_facet ost1 $LCTL set_param fail_loc=0
20904         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20905         sleep 2
20906         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20907         echo "after restart: $after"
20908         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20909                 error "missing truncate?"
20910
20911         return 0
20912 }
20913 run_test 259 "crash at delayed truncate"
20914
20915 test_260() {
20916 #define OBD_FAIL_MDC_CLOSE               0x806
20917         $LCTL set_param fail_loc=0x80000806
20918         touch $DIR/$tfile
20919
20920 }
20921 run_test 260 "Check mdc_close fail"
20922
20923 ### Data-on-MDT sanity tests ###
20924 test_270a() {
20925         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20926                 skip "Need MDS version at least 2.10.55 for DoM"
20927
20928         # create DoM file
20929         local dom=$DIR/$tdir/dom_file
20930         local tmp=$DIR/$tdir/tmp_file
20931
20932         mkdir -p $DIR/$tdir
20933
20934         # basic checks for DoM component creation
20935         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20936                 error "Can set MDT layout to non-first entry"
20937
20938         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20939                 error "Can define multiple entries as MDT layout"
20940
20941         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20942
20943         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20944         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20945         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20946
20947         local mdtidx=$($LFS getstripe -m $dom)
20948         local mdtname=MDT$(printf %04x $mdtidx)
20949         local facet=mds$((mdtidx + 1))
20950         local space_check=1
20951
20952         # Skip free space checks with ZFS
20953         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20954
20955         # write
20956         sync
20957         local size_tmp=$((65536 * 3))
20958         local mdtfree1=$(do_facet $facet \
20959                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20960
20961         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20962         # check also direct IO along write
20963         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20964         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20965         sync
20966         cmp $tmp $dom || error "file data is different"
20967         [ $(stat -c%s $dom) == $size_tmp ] ||
20968                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20969         if [ $space_check == 1 ]; then
20970                 local mdtfree2=$(do_facet $facet \
20971                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20972
20973                 # increase in usage from by $size_tmp
20974                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20975                         error "MDT free space wrong after write: " \
20976                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20977         fi
20978
20979         # truncate
20980         local size_dom=10000
20981
20982         $TRUNCATE $dom $size_dom
20983         [ $(stat -c%s $dom) == $size_dom ] ||
20984                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20985         if [ $space_check == 1 ]; then
20986                 mdtfree1=$(do_facet $facet \
20987                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20988                 # decrease in usage from $size_tmp to new $size_dom
20989                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20990                   $(((size_tmp - size_dom) / 1024)) ] ||
20991                         error "MDT free space is wrong after truncate: " \
20992                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20993         fi
20994
20995         # append
20996         cat $tmp >> $dom
20997         sync
20998         size_dom=$((size_dom + size_tmp))
20999         [ $(stat -c%s $dom) == $size_dom ] ||
21000                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21001         if [ $space_check == 1 ]; then
21002                 mdtfree2=$(do_facet $facet \
21003                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21004                 # increase in usage by $size_tmp from previous
21005                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21006                         error "MDT free space is wrong after append: " \
21007                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21008         fi
21009
21010         # delete
21011         rm $dom
21012         if [ $space_check == 1 ]; then
21013                 mdtfree1=$(do_facet $facet \
21014                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21015                 # decrease in usage by $size_dom from previous
21016                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21017                         error "MDT free space is wrong after removal: " \
21018                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21019         fi
21020
21021         # combined striping
21022         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21023                 error "Can't create DoM + OST striping"
21024
21025         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21026         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21027         # check also direct IO along write
21028         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21029         sync
21030         cmp $tmp $dom || error "file data is different"
21031         [ $(stat -c%s $dom) == $size_tmp ] ||
21032                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21033         rm $dom $tmp
21034
21035         return 0
21036 }
21037 run_test 270a "DoM: basic functionality tests"
21038
21039 test_270b() {
21040         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21041                 skip "Need MDS version at least 2.10.55"
21042
21043         local dom=$DIR/$tdir/dom_file
21044         local max_size=1048576
21045
21046         mkdir -p $DIR/$tdir
21047         $LFS setstripe -E $max_size -L mdt $dom
21048
21049         # truncate over the limit
21050         $TRUNCATE $dom $(($max_size + 1)) &&
21051                 error "successful truncate over the maximum size"
21052         # write over the limit
21053         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21054                 error "successful write over the maximum size"
21055         # append over the limit
21056         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21057         echo "12345" >> $dom && error "successful append over the maximum size"
21058         rm $dom
21059
21060         return 0
21061 }
21062 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21063
21064 test_270c() {
21065         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21066                 skip "Need MDS version at least 2.10.55"
21067
21068         mkdir -p $DIR/$tdir
21069         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21070
21071         # check files inherit DoM EA
21072         touch $DIR/$tdir/first
21073         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21074                 error "bad pattern"
21075         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21076                 error "bad stripe count"
21077         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21078                 error "bad stripe size"
21079
21080         # check directory inherits DoM EA and uses it as default
21081         mkdir $DIR/$tdir/subdir
21082         touch $DIR/$tdir/subdir/second
21083         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21084                 error "bad pattern in sub-directory"
21085         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21086                 error "bad stripe count in sub-directory"
21087         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21088                 error "bad stripe size in sub-directory"
21089         return 0
21090 }
21091 run_test 270c "DoM: DoM EA inheritance tests"
21092
21093 test_270d() {
21094         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21095                 skip "Need MDS version at least 2.10.55"
21096
21097         mkdir -p $DIR/$tdir
21098         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21099
21100         # inherit default DoM striping
21101         mkdir $DIR/$tdir/subdir
21102         touch $DIR/$tdir/subdir/f1
21103
21104         # change default directory striping
21105         $LFS setstripe -c 1 $DIR/$tdir/subdir
21106         touch $DIR/$tdir/subdir/f2
21107         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21108                 error "wrong default striping in file 2"
21109         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21110                 error "bad pattern in file 2"
21111         return 0
21112 }
21113 run_test 270d "DoM: change striping from DoM to RAID0"
21114
21115 test_270e() {
21116         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21117                 skip "Need MDS version at least 2.10.55"
21118
21119         mkdir -p $DIR/$tdir/dom
21120         mkdir -p $DIR/$tdir/norm
21121         DOMFILES=20
21122         NORMFILES=10
21123         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21124         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21125
21126         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21127         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21128
21129         # find DoM files by layout
21130         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21131         [ $NUM -eq  $DOMFILES ] ||
21132                 error "lfs find -L: found $NUM, expected $DOMFILES"
21133         echo "Test 1: lfs find 20 DOM files by layout: OK"
21134
21135         # there should be 1 dir with default DOM striping
21136         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21137         [ $NUM -eq  1 ] ||
21138                 error "lfs find -L: found $NUM, expected 1 dir"
21139         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21140
21141         # find DoM files by stripe size
21142         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21143         [ $NUM -eq  $DOMFILES ] ||
21144                 error "lfs find -S: found $NUM, expected $DOMFILES"
21145         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21146
21147         # find files by stripe offset except DoM files
21148         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21149         [ $NUM -eq  $NORMFILES ] ||
21150                 error "lfs find -i: found $NUM, expected $NORMFILES"
21151         echo "Test 5: lfs find no DOM files by stripe index: OK"
21152         return 0
21153 }
21154 run_test 270e "DoM: lfs find with DoM files test"
21155
21156 test_270f() {
21157         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21158                 skip "Need MDS version at least 2.10.55"
21159
21160         local mdtname=${FSNAME}-MDT0000-mdtlov
21161         local dom=$DIR/$tdir/dom_file
21162         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21163                                                 lod.$mdtname.dom_stripesize)
21164         local dom_limit=131072
21165
21166         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21167         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21168                                                 lod.$mdtname.dom_stripesize)
21169         [ ${dom_limit} -eq ${dom_current} ] ||
21170                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21171
21172         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21173         $LFS setstripe -d $DIR/$tdir
21174         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21175                 error "Can't set directory default striping"
21176
21177         # exceed maximum stripe size
21178         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21179                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21180         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21181                 error "Able to create DoM component size more than LOD limit"
21182
21183         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21184         dom_current=$(do_facet mds1 $LCTL get_param -n \
21185                                                 lod.$mdtname.dom_stripesize)
21186         [ 0 -eq ${dom_current} ] ||
21187                 error "Can't set zero DoM stripe limit"
21188         rm $dom
21189
21190         # attempt to create DoM file on server with disabled DoM should
21191         # remove DoM entry from layout and be succeed
21192         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21193                 error "Can't create DoM file (DoM is disabled)"
21194         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21195                 error "File has DoM component while DoM is disabled"
21196         rm $dom
21197
21198         # attempt to create DoM file with only DoM stripe should return error
21199         $LFS setstripe -E $dom_limit -L mdt $dom &&
21200                 error "Able to create DoM-only file while DoM is disabled"
21201
21202         # too low values to be aligned with smallest stripe size 64K
21203         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21204         dom_current=$(do_facet mds1 $LCTL get_param -n \
21205                                                 lod.$mdtname.dom_stripesize)
21206         [ 30000 -eq ${dom_current} ] &&
21207                 error "Can set too small DoM stripe limit"
21208
21209         # 64K is a minimal stripe size in Lustre, expect limit of that size
21210         [ 65536 -eq ${dom_current} ] ||
21211                 error "Limit is not set to 64K but ${dom_current}"
21212
21213         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21214         dom_current=$(do_facet mds1 $LCTL get_param -n \
21215                                                 lod.$mdtname.dom_stripesize)
21216         echo $dom_current
21217         [ 2147483648 -eq ${dom_current} ] &&
21218                 error "Can set too large DoM stripe limit"
21219
21220         do_facet mds1 $LCTL set_param -n \
21221                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21222         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21223                 error "Can't create DoM component size after limit change"
21224         do_facet mds1 $LCTL set_param -n \
21225                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21226         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21227                 error "Can't create DoM file after limit decrease"
21228         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21229                 error "Can create big DoM component after limit decrease"
21230         touch ${dom}_def ||
21231                 error "Can't create file with old default layout"
21232
21233         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21234         return 0
21235 }
21236 run_test 270f "DoM: maximum DoM stripe size checks"
21237
21238 test_270g() {
21239         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21240                 skip "Need MDS version at least 2.13.52"
21241         local dom=$DIR/$tdir/$tfile
21242
21243         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21244         local lodname=${FSNAME}-MDT0000-mdtlov
21245
21246         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21247         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21248         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21249         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21250
21251         local dom_limit=1024
21252         local dom_threshold="50%"
21253
21254         $LFS setstripe -d $DIR/$tdir
21255         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21256                 error "Can't set directory default striping"
21257
21258         do_facet mds1 $LCTL set_param -n \
21259                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21260         # set 0 threshold and create DOM file to change tunable stripesize
21261         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21262         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21263                 error "Failed to create $dom file"
21264         # now tunable dom_cur_stripesize should reach maximum
21265         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21266                                         lod.${lodname}.dom_stripesize_cur_kb)
21267         [[ $dom_current == $dom_limit ]] ||
21268                 error "Current DOM stripesize is not maximum"
21269         rm $dom
21270
21271         # set threshold for further tests
21272         do_facet mds1 $LCTL set_param -n \
21273                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21274         echo "DOM threshold is $dom_threshold free space"
21275         local dom_def
21276         local dom_set
21277         # Spoof bfree to exceed threshold
21278         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21279         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21280         for spfree in 40 20 0 15 30 55; do
21281                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21282                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21283                         error "Failed to create $dom file"
21284                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21285                                         lod.${lodname}.dom_stripesize_cur_kb)
21286                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21287                 [[ $dom_def != $dom_current ]] ||
21288                         error "Default stripe size was not changed"
21289                 if [[ $spfree > 0 ]] ; then
21290                         dom_set=$($LFS getstripe -S $dom)
21291                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21292                                 error "DOM component size is still old"
21293                 else
21294                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21295                                 error "DoM component is set with no free space"
21296                 fi
21297                 rm $dom
21298                 dom_current=$dom_def
21299         done
21300 }
21301 run_test 270g "DoM: default DoM stripe size depends on free space"
21302
21303 test_270h() {
21304         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21305                 skip "Need MDS version at least 2.13.53"
21306
21307         local mdtname=${FSNAME}-MDT0000-mdtlov
21308         local dom=$DIR/$tdir/$tfile
21309         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21310
21311         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21312         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21313
21314         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21315         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21316                 error "can't create OST file"
21317         # mirrored file with DOM entry in the second mirror
21318         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21319                 error "can't create mirror with DoM component"
21320
21321         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21322
21323         # DOM component in the middle and has other enries in the same mirror,
21324         # should succeed but lost DoM component
21325         $LFS setstripe --copy=${dom}_1 $dom ||
21326                 error "Can't create file from OST|DOM mirror layout"
21327         # check new file has no DoM layout after all
21328         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21329                 error "File has DoM component while DoM is disabled"
21330 }
21331 run_test 270h "DoM: DoM stripe removal when disabled on server"
21332
21333 test_271a() {
21334         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21335                 skip "Need MDS version at least 2.10.55"
21336
21337         local dom=$DIR/$tdir/dom
21338
21339         mkdir -p $DIR/$tdir
21340
21341         $LFS setstripe -E 1024K -L mdt $dom
21342
21343         lctl set_param -n mdc.*.stats=clear
21344         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21345         cat $dom > /dev/null
21346         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21347         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21348         ls $dom
21349         rm -f $dom
21350 }
21351 run_test 271a "DoM: data is cached for read after write"
21352
21353 test_271b() {
21354         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21355                 skip "Need MDS version at least 2.10.55"
21356
21357         local dom=$DIR/$tdir/dom
21358
21359         mkdir -p $DIR/$tdir
21360
21361         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21362
21363         lctl set_param -n mdc.*.stats=clear
21364         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21365         cancel_lru_locks mdc
21366         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21367         # second stat to check size is cached on client
21368         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21369         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21370         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21371         rm -f $dom
21372 }
21373 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21374
21375 test_271ba() {
21376         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21377                 skip "Need MDS version at least 2.10.55"
21378
21379         local dom=$DIR/$tdir/dom
21380
21381         mkdir -p $DIR/$tdir
21382
21383         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21384
21385         lctl set_param -n mdc.*.stats=clear
21386         lctl set_param -n osc.*.stats=clear
21387         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21388         cancel_lru_locks mdc
21389         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21390         # second stat to check size is cached on client
21391         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21392         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21393         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21394         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21395         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21396         rm -f $dom
21397 }
21398 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21399
21400
21401 get_mdc_stats() {
21402         local mdtidx=$1
21403         local param=$2
21404         local mdt=MDT$(printf %04x $mdtidx)
21405
21406         if [ -z $param ]; then
21407                 lctl get_param -n mdc.*$mdt*.stats
21408         else
21409                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21410         fi
21411 }
21412
21413 test_271c() {
21414         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21415                 skip "Need MDS version at least 2.10.55"
21416
21417         local dom=$DIR/$tdir/dom
21418
21419         mkdir -p $DIR/$tdir
21420
21421         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21422
21423         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21424         local facet=mds$((mdtidx + 1))
21425
21426         cancel_lru_locks mdc
21427         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21428         createmany -o $dom 1000
21429         lctl set_param -n mdc.*.stats=clear
21430         smalliomany -w $dom 1000 200
21431         get_mdc_stats $mdtidx
21432         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21433         # Each file has 1 open, 1 IO enqueues, total 2000
21434         # but now we have also +1 getxattr for security.capability, total 3000
21435         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21436         unlinkmany $dom 1000
21437
21438         cancel_lru_locks mdc
21439         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21440         createmany -o $dom 1000
21441         lctl set_param -n mdc.*.stats=clear
21442         smalliomany -w $dom 1000 200
21443         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21444         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21445         # for OPEN and IO lock.
21446         [ $((enq - enq_2)) -ge 1000 ] ||
21447                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21448         unlinkmany $dom 1000
21449         return 0
21450 }
21451 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21452
21453 cleanup_271def_tests() {
21454         trap 0
21455         rm -f $1
21456 }
21457
21458 test_271d() {
21459         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21460                 skip "Need MDS version at least 2.10.57"
21461
21462         local dom=$DIR/$tdir/dom
21463         local tmp=$TMP/$tfile
21464         trap "cleanup_271def_tests $tmp" EXIT
21465
21466         mkdir -p $DIR/$tdir
21467
21468         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21469
21470         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21471
21472         cancel_lru_locks mdc
21473         dd if=/dev/urandom of=$tmp bs=1000 count=1
21474         dd if=$tmp of=$dom bs=1000 count=1
21475         cancel_lru_locks mdc
21476
21477         cat /etc/hosts >> $tmp
21478         lctl set_param -n mdc.*.stats=clear
21479
21480         # append data to the same file it should update local page
21481         echo "Append to the same page"
21482         cat /etc/hosts >> $dom
21483         local num=$(get_mdc_stats $mdtidx ost_read)
21484         local ra=$(get_mdc_stats $mdtidx req_active)
21485         local rw=$(get_mdc_stats $mdtidx req_waittime)
21486
21487         [ -z $num ] || error "$num READ RPC occured"
21488         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21489         echo "... DONE"
21490
21491         # compare content
21492         cmp $tmp $dom || error "file miscompare"
21493
21494         cancel_lru_locks mdc
21495         lctl set_param -n mdc.*.stats=clear
21496
21497         echo "Open and read file"
21498         cat $dom > /dev/null
21499         local num=$(get_mdc_stats $mdtidx ost_read)
21500         local ra=$(get_mdc_stats $mdtidx req_active)
21501         local rw=$(get_mdc_stats $mdtidx req_waittime)
21502
21503         [ -z $num ] || error "$num READ RPC occured"
21504         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21505         echo "... DONE"
21506
21507         # compare content
21508         cmp $tmp $dom || error "file miscompare"
21509
21510         return 0
21511 }
21512 run_test 271d "DoM: read on open (1K file in reply buffer)"
21513
21514 test_271f() {
21515         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21516                 skip "Need MDS version at least 2.10.57"
21517
21518         local dom=$DIR/$tdir/dom
21519         local tmp=$TMP/$tfile
21520         trap "cleanup_271def_tests $tmp" EXIT
21521
21522         mkdir -p $DIR/$tdir
21523
21524         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21525
21526         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21527
21528         cancel_lru_locks mdc
21529         dd if=/dev/urandom of=$tmp bs=265000 count=1
21530         dd if=$tmp of=$dom bs=265000 count=1
21531         cancel_lru_locks mdc
21532         cat /etc/hosts >> $tmp
21533         lctl set_param -n mdc.*.stats=clear
21534
21535         echo "Append to the same page"
21536         cat /etc/hosts >> $dom
21537         local num=$(get_mdc_stats $mdtidx ost_read)
21538         local ra=$(get_mdc_stats $mdtidx req_active)
21539         local rw=$(get_mdc_stats $mdtidx req_waittime)
21540
21541         [ -z $num ] || error "$num READ RPC occured"
21542         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21543         echo "... DONE"
21544
21545         # compare content
21546         cmp $tmp $dom || error "file miscompare"
21547
21548         cancel_lru_locks mdc
21549         lctl set_param -n mdc.*.stats=clear
21550
21551         echo "Open and read file"
21552         cat $dom > /dev/null
21553         local num=$(get_mdc_stats $mdtidx ost_read)
21554         local ra=$(get_mdc_stats $mdtidx req_active)
21555         local rw=$(get_mdc_stats $mdtidx req_waittime)
21556
21557         [ -z $num ] && num=0
21558         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21559         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21560         echo "... DONE"
21561
21562         # compare content
21563         cmp $tmp $dom || error "file miscompare"
21564
21565         return 0
21566 }
21567 run_test 271f "DoM: read on open (200K file and read tail)"
21568
21569 test_271g() {
21570         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21571                 skip "Skipping due to old client or server version"
21572
21573         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21574         # to get layout
21575         $CHECKSTAT -t file $DIR1/$tfile
21576
21577         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21578         MULTIOP_PID=$!
21579         sleep 1
21580         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21581         $LCTL set_param fail_loc=0x80000314
21582         rm $DIR1/$tfile || error "Unlink fails"
21583         RC=$?
21584         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21585         [ $RC -eq 0 ] || error "Failed write to stale object"
21586 }
21587 run_test 271g "Discard DoM data vs client flush race"
21588
21589 test_272a() {
21590         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21591                 skip "Need MDS version at least 2.11.50"
21592
21593         local dom=$DIR/$tdir/dom
21594         mkdir -p $DIR/$tdir
21595
21596         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21597         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21598                 error "failed to write data into $dom"
21599         local old_md5=$(md5sum $dom)
21600
21601         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21602                 error "failed to migrate to the same DoM component"
21603
21604         local new_md5=$(md5sum $dom)
21605
21606         [ "$old_md5" == "$new_md5" ] ||
21607                 error "md5sum differ: $old_md5, $new_md5"
21608
21609         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21610                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21611 }
21612 run_test 272a "DoM migration: new layout with the same DOM component"
21613
21614 test_272b() {
21615         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21616                 skip "Need MDS version at least 2.11.50"
21617
21618         local dom=$DIR/$tdir/dom
21619         mkdir -p $DIR/$tdir
21620         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21621
21622         local mdtidx=$($LFS getstripe -m $dom)
21623         local mdtname=MDT$(printf %04x $mdtidx)
21624         local facet=mds$((mdtidx + 1))
21625
21626         local mdtfree1=$(do_facet $facet \
21627                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21628         dd if=/dev/urandom of=$dom bs=2M count=1 ||
21629                 error "failed to write data into $dom"
21630         local old_md5=$(md5sum $dom)
21631         cancel_lru_locks mdc
21632         local mdtfree1=$(do_facet $facet \
21633                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21634
21635         $LFS migrate -c2 $dom ||
21636                 error "failed to migrate to the new composite layout"
21637         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21638                 error "MDT stripe was not removed"
21639
21640         cancel_lru_locks mdc
21641         local new_md5=$(md5sum $dom)
21642         [ "$old_md5" == "$new_md5" ] ||
21643                 error "$old_md5 != $new_md5"
21644
21645         # Skip free space checks with ZFS
21646         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21647                 local mdtfree2=$(do_facet $facet \
21648                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21649                 [ $mdtfree2 -gt $mdtfree1 ] ||
21650                         error "MDT space is not freed after migration"
21651         fi
21652         return 0
21653 }
21654 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
21655
21656 test_272c() {
21657         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21658                 skip "Need MDS version at least 2.11.50"
21659
21660         local dom=$DIR/$tdir/$tfile
21661         mkdir -p $DIR/$tdir
21662         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21663
21664         local mdtidx=$($LFS getstripe -m $dom)
21665         local mdtname=MDT$(printf %04x $mdtidx)
21666         local facet=mds$((mdtidx + 1))
21667
21668         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21669                 error "failed to write data into $dom"
21670         local old_md5=$(md5sum $dom)
21671         cancel_lru_locks mdc
21672         local mdtfree1=$(do_facet $facet \
21673                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21674
21675         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
21676                 error "failed to migrate to the new composite layout"
21677         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
21678                 error "MDT stripe was not removed"
21679
21680         cancel_lru_locks mdc
21681         local new_md5=$(md5sum $dom)
21682         [ "$old_md5" == "$new_md5" ] ||
21683                 error "$old_md5 != $new_md5"
21684
21685         # Skip free space checks with ZFS
21686         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21687                 local mdtfree2=$(do_facet $facet \
21688                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21689                 [ $mdtfree2 -gt $mdtfree1 ] ||
21690                         error "MDS space is not freed after migration"
21691         fi
21692         return 0
21693 }
21694 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
21695
21696 test_272d() {
21697         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21698                 skip "Need MDS version at least 2.12.55"
21699
21700         local dom=$DIR/$tdir/$tfile
21701         mkdir -p $DIR/$tdir
21702         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21703
21704         local mdtidx=$($LFS getstripe -m $dom)
21705         local mdtname=MDT$(printf %04x $mdtidx)
21706         local facet=mds$((mdtidx + 1))
21707
21708         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
21709                 error "failed to write data into $dom"
21710         local old_md5=$(md5sum $dom)
21711         cancel_lru_locks mdc
21712         local mdtfree1=$(do_facet $facet \
21713                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21714
21715         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
21716                 error "failed mirroring to the new composite layout"
21717         $LFS mirror resync $dom ||
21718                 error "failed mirror resync"
21719         $LFS mirror split --mirror-id 1 -d $dom ||
21720                 error "failed mirror split"
21721
21722         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21723                 error "MDT stripe was not removed"
21724
21725         cancel_lru_locks mdc
21726         local new_md5=$(md5sum $dom)
21727         [ "$old_md5" == "$new_md5" ] ||
21728                 error "$old_md5 != $new_md5"
21729
21730         # Skip free space checks with ZFS
21731         if [ "$(facet_fstype $facet)" != "zfs" ]; then
21732                 local mdtfree2=$(do_facet $facet \
21733                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21734                 [ $mdtfree2 -gt $mdtfree1 ] ||
21735                         error "MDS space is not freed after DOM mirror deletion"
21736         fi
21737         return 0
21738 }
21739 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
21740
21741 test_272e() {
21742         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21743                 skip "Need MDS version at least 2.12.55"
21744
21745         local dom=$DIR/$tdir/$tfile
21746         mkdir -p $DIR/$tdir
21747         $LFS setstripe -c 2 $dom
21748
21749         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21750                 error "failed to write data into $dom"
21751         local old_md5=$(md5sum $dom)
21752         cancel_lru_locks mdc
21753
21754         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
21755                 error "failed mirroring to the DOM layout"
21756         $LFS mirror resync $dom ||
21757                 error "failed mirror resync"
21758         $LFS mirror split --mirror-id 1 -d $dom ||
21759                 error "failed mirror split"
21760
21761         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
21762                 error "MDT stripe was not removed"
21763
21764         cancel_lru_locks mdc
21765         local new_md5=$(md5sum $dom)
21766         [ "$old_md5" == "$new_md5" ] ||
21767                 error "$old_md5 != $new_md5"
21768
21769         return 0
21770 }
21771 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
21772
21773 test_272f() {
21774         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
21775                 skip "Need MDS version at least 2.12.55"
21776
21777         local dom=$DIR/$tdir/$tfile
21778         mkdir -p $DIR/$tdir
21779         $LFS setstripe -c 2 $dom
21780
21781         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
21782                 error "failed to write data into $dom"
21783         local old_md5=$(md5sum $dom)
21784         cancel_lru_locks mdc
21785
21786         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
21787                 error "failed migrating to the DOM file"
21788
21789         cancel_lru_locks mdc
21790         local new_md5=$(md5sum $dom)
21791         [ "$old_md5" != "$new_md5" ] &&
21792                 error "$old_md5 != $new_md5"
21793
21794         return 0
21795 }
21796 run_test 272f "DoM migration: OST-striped file to DOM file"
21797
21798 test_273a() {
21799         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21800                 skip "Need MDS version at least 2.11.50"
21801
21802         # Layout swap cannot be done if either file has DOM component,
21803         # this will never be supported, migration should be used instead
21804
21805         local dom=$DIR/$tdir/$tfile
21806         mkdir -p $DIR/$tdir
21807
21808         $LFS setstripe -c2 ${dom}_plain
21809         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
21810         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
21811                 error "can swap layout with DoM component"
21812         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
21813                 error "can swap layout with DoM component"
21814
21815         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
21816         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
21817                 error "can swap layout with DoM component"
21818         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
21819                 error "can swap layout with DoM component"
21820         return 0
21821 }
21822 run_test 273a "DoM: layout swapping should fail with DOM"
21823
21824 test_273b() {
21825         mkdir -p $DIR/$tdir
21826         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
21827
21828 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
21829         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
21830
21831         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
21832 }
21833 run_test 273b "DoM: race writeback and object destroy"
21834
21835 test_275() {
21836         remote_ost_nodsh && skip "remote OST with nodsh"
21837         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
21838                 skip "Need OST version >= 2.10.57"
21839
21840         local file=$DIR/$tfile
21841         local oss
21842
21843         oss=$(comma_list $(osts_nodes))
21844
21845         dd if=/dev/urandom of=$file bs=1M count=2 ||
21846                 error "failed to create a file"
21847         cancel_lru_locks osc
21848
21849         #lock 1
21850         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21851                 error "failed to read a file"
21852
21853 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
21854         $LCTL set_param fail_loc=0x8000031f
21855
21856         cancel_lru_locks osc &
21857         sleep 1
21858
21859 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
21860         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
21861         #IO takes another lock, but matches the PENDING one
21862         #and places it to the IO RPC
21863         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
21864                 error "failed to read a file with PENDING lock"
21865 }
21866 run_test 275 "Read on a canceled duplicate lock"
21867
21868 test_276() {
21869         remote_ost_nodsh && skip "remote OST with nodsh"
21870         local pid
21871
21872         do_facet ost1 "(while true; do \
21873                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21874                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21875         pid=$!
21876
21877         for LOOP in $(seq 20); do
21878                 stop ost1
21879                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21880         done
21881         kill -9 $pid
21882         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21883                 rm $TMP/sanity_276_pid"
21884 }
21885 run_test 276 "Race between mount and obd_statfs"
21886
21887 test_277() {
21888         $LCTL set_param ldlm.namespaces.*.lru_size=0
21889         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21890         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21891                         grep ^used_mb | awk '{print $2}')
21892         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21893         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21894                 oflag=direct conv=notrunc
21895         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21896                         grep ^used_mb | awk '{print $2}')
21897         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21898 }
21899 run_test 277 "Direct IO shall drop page cache"
21900
21901 test_278() {
21902         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21903         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21904         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21905                 skip "needs the same host for mdt1 mdt2" && return
21906
21907         local pid1
21908         local pid2
21909
21910 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21911         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21912         stop mds2 &
21913         pid2=$!
21914
21915         stop mds1
21916
21917         echo "Starting MDTs"
21918         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21919         wait $pid2
21920 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21921 #will return NULL
21922         do_facet mds2 $LCTL set_param fail_loc=0
21923
21924         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21925         wait_recovery_complete mds2
21926 }
21927 run_test 278 "Race starting MDS between MDTs stop/start"
21928
21929 test_280() {
21930         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21931                 skip "Need MGS version at least 2.13.52"
21932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21933         combined_mgs_mds || skip "needs combined MGS/MDT"
21934
21935         umount_client $MOUNT
21936 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21937         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21938
21939         mount_client $MOUNT &
21940         sleep 1
21941         stop mgs || error "stop mgs failed"
21942         #for a race mgs would crash
21943         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21944         # make sure we unmount client before remounting
21945         wait
21946         umount_client $MOUNT
21947         mount_client $MOUNT || error "mount client failed"
21948 }
21949 run_test 280 "Race between MGS umount and client llog processing"
21950
21951 cleanup_test_300() {
21952         trap 0
21953         umask $SAVE_UMASK
21954 }
21955 test_striped_dir() {
21956         local mdt_index=$1
21957         local stripe_count
21958         local stripe_index
21959
21960         mkdir -p $DIR/$tdir
21961
21962         SAVE_UMASK=$(umask)
21963         trap cleanup_test_300 RETURN EXIT
21964
21965         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21966                                                 $DIR/$tdir/striped_dir ||
21967                 error "set striped dir error"
21968
21969         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21970         [ "$mode" = "755" ] || error "expect 755 got $mode"
21971
21972         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21973                 error "getdirstripe failed"
21974         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21975         if [ "$stripe_count" != "2" ]; then
21976                 error "1:stripe_count is $stripe_count, expect 2"
21977         fi
21978         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21979         if [ "$stripe_count" != "2" ]; then
21980                 error "2:stripe_count is $stripe_count, expect 2"
21981         fi
21982
21983         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21984         if [ "$stripe_index" != "$mdt_index" ]; then
21985                 error "stripe_index is $stripe_index, expect $mdt_index"
21986         fi
21987
21988         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21989                 error "nlink error after create striped dir"
21990
21991         mkdir $DIR/$tdir/striped_dir/a
21992         mkdir $DIR/$tdir/striped_dir/b
21993
21994         stat $DIR/$tdir/striped_dir/a ||
21995                 error "create dir under striped dir failed"
21996         stat $DIR/$tdir/striped_dir/b ||
21997                 error "create dir under striped dir failed"
21998
21999         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22000                 error "nlink error after mkdir"
22001
22002         rmdir $DIR/$tdir/striped_dir/a
22003         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22004                 error "nlink error after rmdir"
22005
22006         rmdir $DIR/$tdir/striped_dir/b
22007         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22008                 error "nlink error after rmdir"
22009
22010         chattr +i $DIR/$tdir/striped_dir
22011         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22012                 error "immutable flags not working under striped dir!"
22013         chattr -i $DIR/$tdir/striped_dir
22014
22015         rmdir $DIR/$tdir/striped_dir ||
22016                 error "rmdir striped dir error"
22017
22018         cleanup_test_300
22019
22020         true
22021 }
22022
22023 test_300a() {
22024         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22025                 skip "skipped for lustre < 2.7.0"
22026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22027         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22028
22029         test_striped_dir 0 || error "failed on striped dir on MDT0"
22030         test_striped_dir 1 || error "failed on striped dir on MDT0"
22031 }
22032 run_test 300a "basic striped dir sanity test"
22033
22034 test_300b() {
22035         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22036                 skip "skipped for lustre < 2.7.0"
22037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22038         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22039
22040         local i
22041         local mtime1
22042         local mtime2
22043         local mtime3
22044
22045         test_mkdir $DIR/$tdir || error "mkdir fail"
22046         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22047                 error "set striped dir error"
22048         for i in {0..9}; do
22049                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22050                 sleep 1
22051                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22052                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22053                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22054                 sleep 1
22055                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22056                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22057                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22058         done
22059         true
22060 }
22061 run_test 300b "check ctime/mtime for striped dir"
22062
22063 test_300c() {
22064         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22065                 skip "skipped for lustre < 2.7.0"
22066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22067         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22068
22069         local file_count
22070
22071         mkdir -p $DIR/$tdir
22072         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22073                 error "set striped dir error"
22074
22075         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22076                 error "chown striped dir failed"
22077
22078         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22079                 error "create 5k files failed"
22080
22081         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22082
22083         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22084
22085         rm -rf $DIR/$tdir
22086 }
22087 run_test 300c "chown && check ls under striped directory"
22088
22089 test_300d() {
22090         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22091                 skip "skipped for lustre < 2.7.0"
22092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22093         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22094
22095         local stripe_count
22096         local file
22097
22098         mkdir -p $DIR/$tdir
22099         $LFS setstripe -c 2 $DIR/$tdir
22100
22101         #local striped directory
22102         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22103                 error "set striped dir error"
22104         #look at the directories for debug purposes
22105         ls -l $DIR/$tdir
22106         $LFS getdirstripe $DIR/$tdir
22107         ls -l $DIR/$tdir/striped_dir
22108         $LFS getdirstripe $DIR/$tdir/striped_dir
22109         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22110                 error "create 10 files failed"
22111
22112         #remote striped directory
22113         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22114                 error "set striped dir error"
22115         #look at the directories for debug purposes
22116         ls -l $DIR/$tdir
22117         $LFS getdirstripe $DIR/$tdir
22118         ls -l $DIR/$tdir/remote_striped_dir
22119         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22120         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22121                 error "create 10 files failed"
22122
22123         for file in $(find $DIR/$tdir); do
22124                 stripe_count=$($LFS getstripe -c $file)
22125                 [ $stripe_count -eq 2 ] ||
22126                         error "wrong stripe $stripe_count for $file"
22127         done
22128
22129         rm -rf $DIR/$tdir
22130 }
22131 run_test 300d "check default stripe under striped directory"
22132
22133 test_300e() {
22134         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22135                 skip "Need MDS version at least 2.7.55"
22136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22137         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22138
22139         local stripe_count
22140         local file
22141
22142         mkdir -p $DIR/$tdir
22143
22144         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22145                 error "set striped dir error"
22146
22147         touch $DIR/$tdir/striped_dir/a
22148         touch $DIR/$tdir/striped_dir/b
22149         touch $DIR/$tdir/striped_dir/c
22150
22151         mkdir $DIR/$tdir/striped_dir/dir_a
22152         mkdir $DIR/$tdir/striped_dir/dir_b
22153         mkdir $DIR/$tdir/striped_dir/dir_c
22154
22155         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22156                 error "set striped adir under striped dir error"
22157
22158         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22159                 error "set striped bdir under striped dir error"
22160
22161         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22162                 error "set striped cdir under striped dir error"
22163
22164         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22165                 error "rename dir under striped dir fails"
22166
22167         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22168                 error "rename dir under different stripes fails"
22169
22170         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22171                 error "rename file under striped dir should succeed"
22172
22173         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22174                 error "rename dir under striped dir should succeed"
22175
22176         rm -rf $DIR/$tdir
22177 }
22178 run_test 300e "check rename under striped directory"
22179
22180 test_300f() {
22181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22182         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22183         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22184                 skip "Need MDS version at least 2.7.55"
22185
22186         local stripe_count
22187         local file
22188
22189         rm -rf $DIR/$tdir
22190         mkdir -p $DIR/$tdir
22191
22192         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22193                 error "set striped dir error"
22194
22195         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22196                 error "set striped dir error"
22197
22198         touch $DIR/$tdir/striped_dir/a
22199         mkdir $DIR/$tdir/striped_dir/dir_a
22200         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22201                 error "create striped dir under striped dir fails"
22202
22203         touch $DIR/$tdir/striped_dir1/b
22204         mkdir $DIR/$tdir/striped_dir1/dir_b
22205         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22206                 error "create striped dir under striped dir fails"
22207
22208         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22209                 error "rename dir under different striped dir should fail"
22210
22211         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22212                 error "rename striped dir under diff striped dir should fail"
22213
22214         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22215                 error "rename file under diff striped dirs fails"
22216
22217         rm -rf $DIR/$tdir
22218 }
22219 run_test 300f "check rename cross striped directory"
22220
22221 test_300_check_default_striped_dir()
22222 {
22223         local dirname=$1
22224         local default_count=$2
22225         local default_index=$3
22226         local stripe_count
22227         local stripe_index
22228         local dir_stripe_index
22229         local dir
22230
22231         echo "checking $dirname $default_count $default_index"
22232         $LFS setdirstripe -D -c $default_count -i $default_index \
22233                                 -H all_char $DIR/$tdir/$dirname ||
22234                 error "set default stripe on striped dir error"
22235         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22236         [ $stripe_count -eq $default_count ] ||
22237                 error "expect $default_count get $stripe_count for $dirname"
22238
22239         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22240         [ $stripe_index -eq $default_index ] ||
22241                 error "expect $default_index get $stripe_index for $dirname"
22242
22243         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22244                                                 error "create dirs failed"
22245
22246         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22247         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22248         for dir in $(find $DIR/$tdir/$dirname/*); do
22249                 stripe_count=$($LFS getdirstripe -c $dir)
22250                 (( $stripe_count == $default_count )) ||
22251                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22252                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22253                 error "stripe count $default_count != $stripe_count for $dir"
22254
22255                 stripe_index=$($LFS getdirstripe -i $dir)
22256                 [ $default_index -eq -1 ] ||
22257                         [ $stripe_index -eq $default_index ] ||
22258                         error "$stripe_index != $default_index for $dir"
22259
22260                 #check default stripe
22261                 stripe_count=$($LFS getdirstripe -D -c $dir)
22262                 [ $stripe_count -eq $default_count ] ||
22263                 error "default count $default_count != $stripe_count for $dir"
22264
22265                 stripe_index=$($LFS getdirstripe -D -i $dir)
22266                 [ $stripe_index -eq $default_index ] ||
22267                 error "default index $default_index != $stripe_index for $dir"
22268         done
22269         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22270 }
22271
22272 test_300g() {
22273         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22274         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22275                 skip "Need MDS version at least 2.7.55"
22276
22277         local dir
22278         local stripe_count
22279         local stripe_index
22280
22281         mkdir $DIR/$tdir
22282         mkdir $DIR/$tdir/normal_dir
22283
22284         #Checking when client cache stripe index
22285         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22286         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22287                 error "create striped_dir failed"
22288
22289         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22290                 error "create dir0 fails"
22291         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22292         [ $stripe_index -eq 0 ] ||
22293                 error "dir0 expect index 0 got $stripe_index"
22294
22295         mkdir $DIR/$tdir/striped_dir/dir1 ||
22296                 error "create dir1 fails"
22297         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22298         [ $stripe_index -eq 1 ] ||
22299                 error "dir1 expect index 1 got $stripe_index"
22300
22301         #check default stripe count/stripe index
22302         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22303         test_300_check_default_striped_dir normal_dir 1 0
22304         test_300_check_default_striped_dir normal_dir -1 1
22305         test_300_check_default_striped_dir normal_dir 2 -1
22306
22307         #delete default stripe information
22308         echo "delete default stripeEA"
22309         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22310                 error "set default stripe on striped dir error"
22311
22312         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22313         for dir in $(find $DIR/$tdir/normal_dir/*); do
22314                 stripe_count=$($LFS getdirstripe -c $dir)
22315                 [ $stripe_count -eq 0 ] ||
22316                         error "expect 1 get $stripe_count for $dir"
22317                 stripe_index=$($LFS getdirstripe -i $dir)
22318                 [ $stripe_index -eq 0 ] ||
22319                         error "expect 0 get $stripe_index for $dir"
22320         done
22321 }
22322 run_test 300g "check default striped directory for normal directory"
22323
22324 test_300h() {
22325         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22326         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22327                 skip "Need MDS version at least 2.7.55"
22328
22329         local dir
22330         local stripe_count
22331
22332         mkdir $DIR/$tdir
22333         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22334                 error "set striped dir error"
22335
22336         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22337         test_300_check_default_striped_dir striped_dir 1 0
22338         test_300_check_default_striped_dir striped_dir -1 1
22339         test_300_check_default_striped_dir striped_dir 2 -1
22340
22341         #delete default stripe information
22342         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22343                 error "set default stripe on striped dir error"
22344
22345         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22346         for dir in $(find $DIR/$tdir/striped_dir/*); do
22347                 stripe_count=$($LFS getdirstripe -c $dir)
22348                 [ $stripe_count -eq 0 ] ||
22349                         error "expect 1 get $stripe_count for $dir"
22350         done
22351 }
22352 run_test 300h "check default striped directory for striped directory"
22353
22354 test_300i() {
22355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22357         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22358                 skip "Need MDS version at least 2.7.55"
22359
22360         local stripe_count
22361         local file
22362
22363         mkdir $DIR/$tdir
22364
22365         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22366                 error "set striped dir error"
22367
22368         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22369                 error "create files under striped dir failed"
22370
22371         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22372                 error "set striped hashdir error"
22373
22374         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22375                 error "create dir0 under hash dir failed"
22376         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22377                 error "create dir1 under hash dir failed"
22378         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22379                 error "create dir2 under hash dir failed"
22380
22381         # unfortunately, we need to umount to clear dir layout cache for now
22382         # once we fully implement dir layout, we can drop this
22383         umount_client $MOUNT || error "umount failed"
22384         mount_client $MOUNT || error "mount failed"
22385
22386         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22387         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22388         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22389
22390         #set the stripe to be unknown hash type
22391         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22392         $LCTL set_param fail_loc=0x1901
22393         for ((i = 0; i < 10; i++)); do
22394                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22395                         error "stat f-$i failed"
22396                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22397         done
22398
22399         touch $DIR/$tdir/striped_dir/f0 &&
22400                 error "create under striped dir with unknown hash should fail"
22401
22402         $LCTL set_param fail_loc=0
22403
22404         umount_client $MOUNT || error "umount failed"
22405         mount_client $MOUNT || error "mount failed"
22406
22407         return 0
22408 }
22409 run_test 300i "client handle unknown hash type striped directory"
22410
22411 test_300j() {
22412         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22414         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22415                 skip "Need MDS version at least 2.7.55"
22416
22417         local stripe_count
22418         local file
22419
22420         mkdir $DIR/$tdir
22421
22422         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22423         $LCTL set_param fail_loc=0x1702
22424         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22425                 error "set striped dir error"
22426
22427         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22428                 error "create files under striped dir failed"
22429
22430         $LCTL set_param fail_loc=0
22431
22432         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22433
22434         return 0
22435 }
22436 run_test 300j "test large update record"
22437
22438 test_300k() {
22439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22440         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22441         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22442                 skip "Need MDS version at least 2.7.55"
22443
22444         # this test needs a huge transaction
22445         local kb
22446         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22447              osd*.$FSNAME-MDT0000.kbytestotal")
22448         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22449
22450         local stripe_count
22451         local file
22452
22453         mkdir $DIR/$tdir
22454
22455         #define OBD_FAIL_LARGE_STRIPE   0x1703
22456         $LCTL set_param fail_loc=0x1703
22457         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22458                 error "set striped dir error"
22459         $LCTL set_param fail_loc=0
22460
22461         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22462                 error "getstripeddir fails"
22463         rm -rf $DIR/$tdir/striped_dir ||
22464                 error "unlink striped dir fails"
22465
22466         return 0
22467 }
22468 run_test 300k "test large striped directory"
22469
22470 test_300l() {
22471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22472         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22473         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22474                 skip "Need MDS version at least 2.7.55"
22475
22476         local stripe_index
22477
22478         test_mkdir -p $DIR/$tdir/striped_dir
22479         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22480                         error "chown $RUNAS_ID failed"
22481         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22482                 error "set default striped dir failed"
22483
22484         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22485         $LCTL set_param fail_loc=0x80000158
22486         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22487
22488         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22489         [ $stripe_index -eq 1 ] ||
22490                 error "expect 1 get $stripe_index for $dir"
22491 }
22492 run_test 300l "non-root user to create dir under striped dir with stale layout"
22493
22494 test_300m() {
22495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22496         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22497         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22498                 skip "Need MDS version at least 2.7.55"
22499
22500         mkdir -p $DIR/$tdir/striped_dir
22501         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22502                 error "set default stripes dir error"
22503
22504         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22505
22506         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22507         [ $stripe_count -eq 0 ] ||
22508                         error "expect 0 get $stripe_count for a"
22509
22510         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22511                 error "set default stripes dir error"
22512
22513         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22514
22515         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22516         [ $stripe_count -eq 0 ] ||
22517                         error "expect 0 get $stripe_count for b"
22518
22519         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22520                 error "set default stripes dir error"
22521
22522         mkdir $DIR/$tdir/striped_dir/c &&
22523                 error "default stripe_index is invalid, mkdir c should fails"
22524
22525         rm -rf $DIR/$tdir || error "rmdir fails"
22526 }
22527 run_test 300m "setstriped directory on single MDT FS"
22528
22529 cleanup_300n() {
22530         local list=$(comma_list $(mdts_nodes))
22531
22532         trap 0
22533         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22534 }
22535
22536 test_300n() {
22537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22538         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22539         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22540                 skip "Need MDS version at least 2.7.55"
22541         remote_mds_nodsh && skip "remote MDS with nodsh"
22542
22543         local stripe_index
22544         local list=$(comma_list $(mdts_nodes))
22545
22546         trap cleanup_300n RETURN EXIT
22547         mkdir -p $DIR/$tdir
22548         chmod 777 $DIR/$tdir
22549         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22550                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22551                 error "create striped dir succeeds with gid=0"
22552
22553         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22554         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22555                 error "create striped dir fails with gid=-1"
22556
22557         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22558         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22559                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22560                 error "set default striped dir succeeds with gid=0"
22561
22562
22563         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22564         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22565                 error "set default striped dir fails with gid=-1"
22566
22567
22568         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22569         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22570                                         error "create test_dir fails"
22571         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22572                                         error "create test_dir1 fails"
22573         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22574                                         error "create test_dir2 fails"
22575         cleanup_300n
22576 }
22577 run_test 300n "non-root user to create dir under striped dir with default EA"
22578
22579 test_300o() {
22580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22581         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22582         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22583                 skip "Need MDS version at least 2.7.55"
22584
22585         local numfree1
22586         local numfree2
22587
22588         mkdir -p $DIR/$tdir
22589
22590         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22591         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22592         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22593                 skip "not enough free inodes $numfree1 $numfree2"
22594         fi
22595
22596         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22597         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22598         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22599                 skip "not enough free space $numfree1 $numfree2"
22600         fi
22601
22602         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22603                 error "setdirstripe fails"
22604
22605         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22606                 error "create dirs fails"
22607
22608         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22609         ls $DIR/$tdir/striped_dir > /dev/null ||
22610                 error "ls striped dir fails"
22611         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22612                 error "unlink big striped dir fails"
22613 }
22614 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22615
22616 test_300p() {
22617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22618         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22619         remote_mds_nodsh && skip "remote MDS with nodsh"
22620
22621         mkdir -p $DIR/$tdir
22622
22623         #define OBD_FAIL_OUT_ENOSPC     0x1704
22624         do_facet mds2 lctl set_param fail_loc=0x80001704
22625         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22626                  && error "create striped directory should fail"
22627
22628         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22629
22630         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
22631         true
22632 }
22633 run_test 300p "create striped directory without space"
22634
22635 test_300q() {
22636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22637         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22638
22639         local fd=$(free_fd)
22640         local cmd="exec $fd<$tdir"
22641         cd $DIR
22642         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
22643         eval $cmd
22644         cmd="exec $fd<&-"
22645         trap "eval $cmd" EXIT
22646         cd $tdir || error "cd $tdir fails"
22647         rmdir  ../$tdir || error "rmdir $tdir fails"
22648         mkdir local_dir && error "create dir succeeds"
22649         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
22650         eval $cmd
22651         return 0
22652 }
22653 run_test 300q "create remote directory under orphan directory"
22654
22655 test_300r() {
22656         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22657                 skip "Need MDS version at least 2.7.55" && return
22658         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22659
22660         mkdir $DIR/$tdir
22661
22662         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
22663                 error "set striped dir error"
22664
22665         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22666                 error "getstripeddir fails"
22667
22668         local stripe_count
22669         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
22670                       awk '/lmv_stripe_count:/ { print $2 }')
22671
22672         [ $MDSCOUNT -ne $stripe_count ] &&
22673                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
22674
22675         rm -rf $DIR/$tdir/striped_dir ||
22676                 error "unlink striped dir fails"
22677 }
22678 run_test 300r "test -1 striped directory"
22679
22680 test_300s_helper() {
22681         local count=$1
22682
22683         local stripe_dir=$DIR/$tdir/striped_dir.$count
22684
22685         $LFS mkdir -c $count $stripe_dir ||
22686                 error "lfs mkdir -c error"
22687
22688         $LFS getdirstripe $stripe_dir ||
22689                 error "lfs getdirstripe fails"
22690
22691         local stripe_count
22692         stripe_count=$($LFS getdirstripe $stripe_dir |
22693                       awk '/lmv_stripe_count:/ { print $2 }')
22694
22695         [ $count -ne $stripe_count ] &&
22696                 error_noexit "bad stripe count $stripe_count expected $count"
22697
22698         local dupe_stripes
22699         dupe_stripes=$($LFS getdirstripe $stripe_dir |
22700                 awk '/0x/ {count[$1] += 1}; END {
22701                         for (idx in count) {
22702                                 if (count[idx]>1) {
22703                                         print "index " idx " count " count[idx]
22704                                 }
22705                         }
22706                 }')
22707
22708         if [[ -n "$dupe_stripes" ]] ; then
22709                 lfs getdirstripe $stripe_dir
22710                 error_noexit "Dupe MDT above: $dupe_stripes "
22711         fi
22712
22713         rm -rf $stripe_dir ||
22714                 error_noexit "unlink $stripe_dir fails"
22715 }
22716
22717 test_300s() {
22718         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22719                 skip "Need MDS version at least 2.7.55" && return
22720         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22721
22722         mkdir $DIR/$tdir
22723         for count in $(seq 2 $MDSCOUNT); do
22724                 test_300s_helper $count
22725         done
22726 }
22727 run_test 300s "test lfs mkdir -c without -i"
22728
22729
22730 prepare_remote_file() {
22731         mkdir $DIR/$tdir/src_dir ||
22732                 error "create remote source failed"
22733
22734         cp /etc/hosts $DIR/$tdir/src_dir/a ||
22735                  error "cp to remote source failed"
22736         touch $DIR/$tdir/src_dir/a
22737
22738         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
22739                 error "create remote target dir failed"
22740
22741         touch $DIR/$tdir/tgt_dir/b
22742
22743         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
22744                 error "rename dir cross MDT failed!"
22745
22746         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
22747                 error "src_child still exists after rename"
22748
22749         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
22750                 error "missing file(a) after rename"
22751
22752         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
22753                 error "diff after rename"
22754 }
22755
22756 test_310a() {
22757         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22759
22760         local remote_file=$DIR/$tdir/tgt_dir/b
22761
22762         mkdir -p $DIR/$tdir
22763
22764         prepare_remote_file || error "prepare remote file failed"
22765
22766         #open-unlink file
22767         $OPENUNLINK $remote_file $remote_file ||
22768                 error "openunlink $remote_file failed"
22769         $CHECKSTAT -a $remote_file || error "$remote_file exists"
22770 }
22771 run_test 310a "open unlink remote file"
22772
22773 test_310b() {
22774         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
22775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22776
22777         local remote_file=$DIR/$tdir/tgt_dir/b
22778
22779         mkdir -p $DIR/$tdir
22780
22781         prepare_remote_file || error "prepare remote file failed"
22782
22783         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22784         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
22785         $CHECKSTAT -t file $remote_file || error "check file failed"
22786 }
22787 run_test 310b "unlink remote file with multiple links while open"
22788
22789 test_310c() {
22790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22791         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
22792
22793         local remote_file=$DIR/$tdir/tgt_dir/b
22794
22795         mkdir -p $DIR/$tdir
22796
22797         prepare_remote_file || error "prepare remote file failed"
22798
22799         ln $remote_file $DIR/$tfile || error "link failed for remote file"
22800         multiop_bg_pause $remote_file O_uc ||
22801                         error "mulitop failed for remote file"
22802         MULTIPID=$!
22803         $MULTIOP $DIR/$tfile Ouc
22804         kill -USR1 $MULTIPID
22805         wait $MULTIPID
22806 }
22807 run_test 310c "open-unlink remote file with multiple links"
22808
22809 #LU-4825
22810 test_311() {
22811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22812         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22813         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
22814                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
22815         remote_mds_nodsh && skip "remote MDS with nodsh"
22816
22817         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22818         local mdts=$(comma_list $(mdts_nodes))
22819
22820         mkdir -p $DIR/$tdir
22821         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22822         createmany -o $DIR/$tdir/$tfile. 1000
22823
22824         # statfs data is not real time, let's just calculate it
22825         old_iused=$((old_iused + 1000))
22826
22827         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22828                         osp.*OST0000*MDT0000.create_count")
22829         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22830                                 osp.*OST0000*MDT0000.max_create_count")
22831         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
22832
22833         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
22834         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
22835         [ $index -ne 0 ] || error "$tfile stripe index is 0"
22836
22837         unlinkmany $DIR/$tdir/$tfile. 1000
22838
22839         do_nodes $mdts "$LCTL set_param -n \
22840                         osp.*OST0000*.max_create_count=$max_count"
22841         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
22842                 do_nodes $mdts "$LCTL set_param -n \
22843                                 osp.*OST0000*.create_count=$count"
22844         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
22845                         grep "=0" && error "create_count is zero"
22846
22847         local new_iused
22848         for i in $(seq 120); do
22849                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
22850                 # system may be too busy to destroy all objs in time, use
22851                 # a somewhat small value to not fail autotest
22852                 [ $((old_iused - new_iused)) -gt 400 ] && break
22853                 sleep 1
22854         done
22855
22856         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
22857         [ $((old_iused - new_iused)) -gt 400 ] ||
22858                 error "objs not destroyed after unlink"
22859 }
22860 run_test 311 "disable OSP precreate, and unlink should destroy objs"
22861
22862 zfs_oid_to_objid()
22863 {
22864         local ost=$1
22865         local objid=$2
22866
22867         local vdevdir=$(dirname $(facet_vdevice $ost))
22868         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
22869         local zfs_zapid=$(do_facet $ost $cmd |
22870                           grep -w "/O/0/d$((objid%32))" -C 5 |
22871                           awk '/Object/{getline; print $1}')
22872         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
22873                           awk "/$objid = /"'{printf $3}')
22874
22875         echo $zfs_objid
22876 }
22877
22878 zfs_object_blksz() {
22879         local ost=$1
22880         local objid=$2
22881
22882         local vdevdir=$(dirname $(facet_vdevice $ost))
22883         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22884         local blksz=$(do_facet $ost $cmd $objid |
22885                       awk '/dblk/{getline; printf $4}')
22886
22887         case "${blksz: -1}" in
22888                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22889                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22890                 *) ;;
22891         esac
22892
22893         echo $blksz
22894 }
22895
22896 test_312() { # LU-4856
22897         remote_ost_nodsh && skip "remote OST with nodsh"
22898         [ "$ost1_FSTYPE" = "zfs" ] ||
22899                 skip_env "the test only applies to zfs"
22900
22901         local max_blksz=$(do_facet ost1 \
22902                           $ZFS get -p recordsize $(facet_device ost1) |
22903                           awk '!/VALUE/{print $3}')
22904
22905         # to make life a little bit easier
22906         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22907         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22908
22909         local tf=$DIR/$tdir/$tfile
22910         touch $tf
22911         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22912
22913         # Get ZFS object id
22914         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22915         # block size change by sequential overwrite
22916         local bs
22917
22918         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22919                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22920
22921                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22922                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22923         done
22924         rm -f $tf
22925
22926         # block size change by sequential append write
22927         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22928         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22929         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22930         local count
22931
22932         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22933                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22934                         oflag=sync conv=notrunc
22935
22936                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22937                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22938                         error "blksz error, actual $blksz, " \
22939                                 "expected: 2 * $count * $PAGE_SIZE"
22940         done
22941         rm -f $tf
22942
22943         # random write
22944         touch $tf
22945         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22946         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22947
22948         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22949         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22950         [ $blksz -eq $PAGE_SIZE ] ||
22951                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22952
22953         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22954         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22955         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22956
22957         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22958         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22959         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22960 }
22961 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22962
22963 test_313() {
22964         remote_ost_nodsh && skip "remote OST with nodsh"
22965
22966         local file=$DIR/$tfile
22967
22968         rm -f $file
22969         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22970
22971         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22972         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22973         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22974                 error "write should failed"
22975         do_facet ost1 "$LCTL set_param fail_loc=0"
22976         rm -f $file
22977 }
22978 run_test 313 "io should fail after last_rcvd update fail"
22979
22980 test_314() {
22981         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22982
22983         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22984         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22985         rm -f $DIR/$tfile
22986         wait_delete_completed
22987         do_facet ost1 "$LCTL set_param fail_loc=0"
22988 }
22989 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22990
22991 test_315() { # LU-618
22992         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22993
22994         local file=$DIR/$tfile
22995         rm -f $file
22996
22997         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22998                 error "multiop file write failed"
22999         $MULTIOP $file oO_RDONLY:r4063232_c &
23000         PID=$!
23001
23002         sleep 2
23003
23004         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23005         kill -USR1 $PID
23006
23007         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23008         rm -f $file
23009 }
23010 run_test 315 "read should be accounted"
23011
23012 test_316() {
23013         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23014         large_xattr_enabled || skip_env "ea_inode feature disabled"
23015
23016         rm -rf $DIR/$tdir/d
23017         mkdir -p $DIR/$tdir/d
23018         chown nobody $DIR/$tdir/d
23019         touch $DIR/$tdir/d/file
23020
23021         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23022 }
23023 run_test 316 "lfs mv"
23024
23025 test_317() {
23026         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23027                 skip "Need MDS version at least 2.11.53"
23028         if [ "$ost1_FSTYPE" == "zfs" ]; then
23029                 skip "LU-10370: no implementation for ZFS"
23030         fi
23031
23032         local trunc_sz
23033         local grant_blk_size
23034
23035         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23036                         awk '/grant_block_size:/ { print $2; exit; }')
23037         #
23038         # Create File of size 5M. Truncate it to below size's and verify
23039         # blocks count.
23040         #
23041         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23042                 error "Create file $DIR/$tfile failed"
23043         stack_trap "rm -f $DIR/$tfile" EXIT
23044
23045         for trunc_sz in 2097152 4097 4000 509 0; do
23046                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23047                         error "truncate $tfile to $trunc_sz failed"
23048                 local sz=$(stat --format=%s $DIR/$tfile)
23049                 local blk=$(stat --format=%b $DIR/$tfile)
23050                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23051                                      grant_blk_size) * 8))
23052
23053                 if [[ $blk -ne $trunc_blk ]]; then
23054                         $(which stat) $DIR/$tfile
23055                         error "Expected Block $trunc_blk got $blk for $tfile"
23056                 fi
23057
23058                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23059                         error "Expected Size $trunc_sz got $sz for $tfile"
23060         done
23061
23062         #
23063         # sparse file test
23064         # Create file with a hole and write actual two blocks. Block count
23065         # must be 16.
23066         #
23067         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23068                 conv=fsync || error "Create file : $DIR/$tfile"
23069
23070         # Calculate the final truncate size.
23071         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23072
23073         #
23074         # truncate to size $trunc_sz bytes. Strip the last block
23075         # The block count must drop to 8
23076         #
23077         $TRUNCATE $DIR/$tfile $trunc_sz ||
23078                 error "truncate $tfile to $trunc_sz failed"
23079
23080         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23081         sz=$(stat --format=%s $DIR/$tfile)
23082         blk=$(stat --format=%b $DIR/$tfile)
23083
23084         if [[ $blk -ne $trunc_bsz ]]; then
23085                 $(which stat) $DIR/$tfile
23086                 error "Expected Block $trunc_bsz got $blk for $tfile"
23087         fi
23088
23089         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23090                 error "Expected Size $trunc_sz got $sz for $tfile"
23091 }
23092 run_test 317 "Verify blocks get correctly update after truncate"
23093
23094 test_318() {
23095         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23096         local old_max_active=$($LCTL get_param -n \
23097                             ${llite_name}.max_read_ahead_async_active \
23098                             2>/dev/null)
23099
23100         $LCTL set_param llite.*.max_read_ahead_async_active=256
23101         local max_active=$($LCTL get_param -n \
23102                            ${llite_name}.max_read_ahead_async_active \
23103                            2>/dev/null)
23104         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23105
23106         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23107                 error "set max_read_ahead_async_active should succeed"
23108
23109         $LCTL set_param llite.*.max_read_ahead_async_active=512
23110         max_active=$($LCTL get_param -n \
23111                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23112         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23113
23114         # restore @max_active
23115         [ $old_max_active -ne 0 ] && $LCTL set_param \
23116                 llite.*.max_read_ahead_async_active=$old_max_active
23117
23118         local old_threshold=$($LCTL get_param -n \
23119                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23120         local max_per_file_mb=$($LCTL get_param -n \
23121                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23122
23123         local invalid=$(($max_per_file_mb + 1))
23124         $LCTL set_param \
23125                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23126                         && error "set $invalid should fail"
23127
23128         local valid=$(($invalid - 1))
23129         $LCTL set_param \
23130                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23131                         error "set $valid should succeed"
23132         local threshold=$($LCTL get_param -n \
23133                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23134         [ $threshold -eq $valid ] || error \
23135                 "expect threshold $valid got $threshold"
23136         $LCTL set_param \
23137                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23138 }
23139 run_test 318 "Verify async readahead tunables"
23140
23141 test_319() {
23142         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23143
23144         local before=$(date +%s)
23145         local evict
23146         local mdir=$DIR/$tdir
23147         local file=$mdir/xxx
23148
23149         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23150         touch $file
23151
23152 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23153         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23154         $LFS mv -m1 $file &
23155
23156         sleep 1
23157         dd if=$file of=/dev/null
23158         wait
23159         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23160           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23161
23162         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23163 }
23164 run_test 319 "lost lease lock on migrate error"
23165
23166 test_398a() { # LU-4198
23167         local ost1_imp=$(get_osc_import_name client ost1)
23168         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23169                          cut -d'.' -f2)
23170
23171         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23172         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23173
23174         # request a new lock on client
23175         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23176
23177         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23178         local lock_count=$($LCTL get_param -n \
23179                            ldlm.namespaces.$imp_name.lru_size)
23180         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23181
23182         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23183
23184         # no lock cached, should use lockless IO and not enqueue new lock
23185         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23186         lock_count=$($LCTL get_param -n \
23187                      ldlm.namespaces.$imp_name.lru_size)
23188         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23189 }
23190 run_test 398a "direct IO should cancel lock otherwise lockless"
23191
23192 test_398b() { # LU-4198
23193         which fio || skip_env "no fio installed"
23194         $LFS setstripe -c -1 $DIR/$tfile
23195
23196         local size=12
23197         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23198
23199         local njobs=4
23200         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23201         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23202                 --numjobs=$njobs --fallocate=none \
23203                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23204                 --filename=$DIR/$tfile &
23205         bg_pid=$!
23206
23207         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23208         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23209                 --numjobs=$njobs --fallocate=none \
23210                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23211                 --filename=$DIR/$tfile || true
23212         wait $bg_pid
23213
23214         rm -f $DIR/$tfile
23215 }
23216 run_test 398b "DIO and buffer IO race"
23217
23218 test_398c() { # LU-4198
23219         local ost1_imp=$(get_osc_import_name client ost1)
23220         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23221                          cut -d'.' -f2)
23222
23223         which fio || skip_env "no fio installed"
23224
23225         saved_debug=$($LCTL get_param -n debug)
23226         $LCTL set_param debug=0
23227
23228         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23229         ((size /= 1024)) # by megabytes
23230         ((size /= 2)) # write half of the OST at most
23231         [ $size -gt 40 ] && size=40 #reduce test time anyway
23232
23233         $LFS setstripe -c 1 $DIR/$tfile
23234
23235         # it seems like ldiskfs reserves more space than necessary if the
23236         # writing blocks are not mapped, so it extends the file firstly
23237         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23238         cancel_lru_locks osc
23239
23240         # clear and verify rpc_stats later
23241         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23242
23243         local njobs=4
23244         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23245         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23246                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23247                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23248                 --filename=$DIR/$tfile
23249         [ $? -eq 0 ] || error "fio write error"
23250
23251         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23252                 error "Locks were requested while doing AIO"
23253
23254         # get the percentage of 1-page I/O
23255         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23256                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23257                 awk '{print $7}')
23258         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23259
23260         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23261         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23262                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23263                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23264                 --filename=$DIR/$tfile
23265         [ $? -eq 0 ] || error "fio mixed read write error"
23266
23267         echo "AIO with large block size ${size}M"
23268         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23269                 --numjobs=1 --fallocate=none --ioengine=libaio \
23270                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23271                 --filename=$DIR/$tfile
23272         [ $? -eq 0 ] || error "fio large block size failed"
23273
23274         rm -f $DIR/$tfile
23275         $LCTL set_param debug="$saved_debug"
23276 }
23277 run_test 398c "run fio to test AIO"
23278
23279 test_398d() { #  LU-13846
23280         which aiocp || skip_env "no aiocp installed"
23281         local aio_file=$DIR/$tfile.aio
23282
23283         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23284
23285         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23286         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23287         stack_trap "rm -f $DIR/$tfile $aio_file"
23288
23289         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23290
23291         # make sure we don't crash and fail properly
23292         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23293                 error "aio not aligned with PAGE SIZE should fail"
23294
23295         rm -f $DIR/$tfile $aio_file
23296 }
23297 run_test 398d "run aiocp to verify block size > stripe size"
23298
23299 test_398e() {
23300         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23301         touch $DIR/$tfile.new
23302         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23303 }
23304 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23305
23306 test_398f() { #  LU-14687
23307         which aiocp || skip_env "no aiocp installed"
23308         local aio_file=$DIR/$tfile.aio
23309
23310         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23311
23312         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23313         stack_trap "rm -f $DIR/$tfile $aio_file"
23314
23315         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23316         $LCTL set_param fail_loc=0x1418
23317         # make sure we don't crash and fail properly
23318         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23319                 error "aio with page allocation failure succeeded"
23320         $LCTL set_param fail_loc=0
23321         diff $DIR/$tfile $aio_file
23322         [[ $? != 0 ]] || error "no diff after failed aiocp"
23323 }
23324 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23325
23326 test_fake_rw() {
23327         local read_write=$1
23328         if [ "$read_write" = "write" ]; then
23329                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23330         elif [ "$read_write" = "read" ]; then
23331                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23332         else
23333                 error "argument error"
23334         fi
23335
23336         # turn off debug for performance testing
23337         local saved_debug=$($LCTL get_param -n debug)
23338         $LCTL set_param debug=0
23339
23340         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23341
23342         # get ost1 size - $FSNAME-OST0000
23343         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23344         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23345         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23346
23347         if [ "$read_write" = "read" ]; then
23348                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23349         fi
23350
23351         local start_time=$(date +%s.%N)
23352         $dd_cmd bs=1M count=$blocks oflag=sync ||
23353                 error "real dd $read_write error"
23354         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23355
23356         if [ "$read_write" = "write" ]; then
23357                 rm -f $DIR/$tfile
23358         fi
23359
23360         # define OBD_FAIL_OST_FAKE_RW           0x238
23361         do_facet ost1 $LCTL set_param fail_loc=0x238
23362
23363         local start_time=$(date +%s.%N)
23364         $dd_cmd bs=1M count=$blocks oflag=sync ||
23365                 error "fake dd $read_write error"
23366         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
23367
23368         if [ "$read_write" = "write" ]; then
23369                 # verify file size
23370                 cancel_lru_locks osc
23371                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
23372                         error "$tfile size not $blocks MB"
23373         fi
23374         do_facet ost1 $LCTL set_param fail_loc=0
23375
23376         echo "fake $read_write $duration_fake vs. normal $read_write" \
23377                 "$duration in seconds"
23378         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
23379                 error_not_in_vm "fake write is slower"
23380
23381         $LCTL set_param -n debug="$saved_debug"
23382         rm -f $DIR/$tfile
23383 }
23384 test_399a() { # LU-7655 for OST fake write
23385         remote_ost_nodsh && skip "remote OST with nodsh"
23386
23387         test_fake_rw write
23388 }
23389 run_test 399a "fake write should not be slower than normal write"
23390
23391 test_399b() { # LU-8726 for OST fake read
23392         remote_ost_nodsh && skip "remote OST with nodsh"
23393         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
23394                 skip_env "ldiskfs only test"
23395         fi
23396
23397         test_fake_rw read
23398 }
23399 run_test 399b "fake read should not be slower than normal read"
23400
23401 test_400a() { # LU-1606, was conf-sanity test_74
23402         if ! which $CC > /dev/null 2>&1; then
23403                 skip_env "$CC is not installed"
23404         fi
23405
23406         local extra_flags=''
23407         local out=$TMP/$tfile
23408         local prefix=/usr/include/lustre
23409         local prog
23410
23411         # Oleg removes c files in his test rig so test if any c files exist
23412         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
23413                 skip_env "Needed c test files are missing"
23414
23415         if ! [[ -d $prefix ]]; then
23416                 # Assume we're running in tree and fixup the include path.
23417                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
23418                 extra_flags+=" -L$LUSTRE/utils/.lib"
23419         fi
23420
23421         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
23422                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
23423                         error "client api broken"
23424         done
23425         rm -f $out
23426 }
23427 run_test 400a "Lustre client api program can compile and link"
23428
23429 test_400b() { # LU-1606, LU-5011
23430         local header
23431         local out=$TMP/$tfile
23432         local prefix=/usr/include/linux/lustre
23433
23434         # We use a hard coded prefix so that this test will not fail
23435         # when run in tree. There are headers in lustre/include/lustre/
23436         # that are not packaged (like lustre_idl.h) and have more
23437         # complicated include dependencies (like config.h and lnet/types.h).
23438         # Since this test about correct packaging we just skip them when
23439         # they don't exist (see below) rather than try to fixup cppflags.
23440
23441         if ! which $CC > /dev/null 2>&1; then
23442                 skip_env "$CC is not installed"
23443         fi
23444
23445         for header in $prefix/*.h; do
23446                 if ! [[ -f "$header" ]]; then
23447                         continue
23448                 fi
23449
23450                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
23451                         continue # lustre_ioctl.h is internal header
23452                 fi
23453
23454                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
23455                         error "cannot compile '$header'"
23456         done
23457         rm -f $out
23458 }
23459 run_test 400b "packaged headers can be compiled"
23460
23461 test_401a() { #LU-7437
23462         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
23463         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
23464
23465         #count the number of parameters by "list_param -R"
23466         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
23467         #count the number of parameters by listing proc files
23468         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
23469         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
23470         echo "proc_dirs='$proc_dirs'"
23471         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
23472         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
23473                       sort -u | wc -l)
23474
23475         [ $params -eq $procs ] ||
23476                 error "found $params parameters vs. $procs proc files"
23477
23478         # test the list_param -D option only returns directories
23479         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
23480         #count the number of parameters by listing proc directories
23481         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
23482                 sort -u | wc -l)
23483
23484         [ $params -eq $procs ] ||
23485                 error "found $params parameters vs. $procs proc files"
23486 }
23487 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
23488
23489 test_401b() {
23490         # jobid_var may not allow arbitrary values, so use jobid_name
23491         # if available
23492         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23493                 local testname=jobid_name tmp='testing%p'
23494         else
23495                 local testname=jobid_var tmp=testing
23496         fi
23497
23498         local save=$($LCTL get_param -n $testname)
23499
23500         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
23501                 error "no error returned when setting bad parameters"
23502
23503         local jobid_new=$($LCTL get_param -n foe $testname baz)
23504         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
23505
23506         $LCTL set_param -n fog=bam $testname=$save bat=fog
23507         local jobid_old=$($LCTL get_param -n foe $testname bag)
23508         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
23509 }
23510 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
23511
23512 test_401c() {
23513         # jobid_var may not allow arbitrary values, so use jobid_name
23514         # if available
23515         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23516                 local testname=jobid_name
23517         else
23518                 local testname=jobid_var
23519         fi
23520
23521         local jobid_var_old=$($LCTL get_param -n $testname)
23522         local jobid_var_new
23523
23524         $LCTL set_param $testname= &&
23525                 error "no error returned for 'set_param a='"
23526
23527         jobid_var_new=$($LCTL get_param -n $testname)
23528         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23529                 error "$testname was changed by setting without value"
23530
23531         $LCTL set_param $testname &&
23532                 error "no error returned for 'set_param a'"
23533
23534         jobid_var_new=$($LCTL get_param -n $testname)
23535         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
23536                 error "$testname was changed by setting without value"
23537 }
23538 run_test 401c "Verify 'lctl set_param' without value fails in either format."
23539
23540 test_401d() {
23541         # jobid_var may not allow arbitrary values, so use jobid_name
23542         # if available
23543         if $LCTL list_param jobid_name > /dev/null 2>&1; then
23544                 local testname=jobid_name new_value='foo=bar%p'
23545         else
23546                 local testname=jobid_var new_valuie=foo=bar
23547         fi
23548
23549         local jobid_var_old=$($LCTL get_param -n $testname)
23550         local jobid_var_new
23551
23552         $LCTL set_param $testname=$new_value ||
23553                 error "'set_param a=b' did not accept a value containing '='"
23554
23555         jobid_var_new=$($LCTL get_param -n $testname)
23556         [[ "$jobid_var_new" == "$new_value" ]] ||
23557                 error "'set_param a=b' failed on a value containing '='"
23558
23559         # Reset the $testname to test the other format
23560         $LCTL set_param $testname=$jobid_var_old
23561         jobid_var_new=$($LCTL get_param -n $testname)
23562         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23563                 error "failed to reset $testname"
23564
23565         $LCTL set_param $testname $new_value ||
23566                 error "'set_param a b' did not accept a value containing '='"
23567
23568         jobid_var_new=$($LCTL get_param -n $testname)
23569         [[ "$jobid_var_new" == "$new_value" ]] ||
23570                 error "'set_param a b' failed on a value containing '='"
23571
23572         $LCTL set_param $testname $jobid_var_old
23573         jobid_var_new=$($LCTL get_param -n $testname)
23574         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
23575                 error "failed to reset $testname"
23576 }
23577 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
23578
23579 test_402() {
23580         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
23581         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
23582                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
23583         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
23584                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
23585                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
23586         remote_mds_nodsh && skip "remote MDS with nodsh"
23587
23588         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
23589 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
23590         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
23591         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
23592                 echo "Touch failed - OK"
23593 }
23594 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
23595
23596 test_403() {
23597         local file1=$DIR/$tfile.1
23598         local file2=$DIR/$tfile.2
23599         local tfile=$TMP/$tfile
23600
23601         rm -f $file1 $file2 $tfile
23602
23603         touch $file1
23604         ln $file1 $file2
23605
23606         # 30 sec OBD_TIMEOUT in ll_getattr()
23607         # right before populating st_nlink
23608         $LCTL set_param fail_loc=0x80001409
23609         stat -c %h $file1 > $tfile &
23610
23611         # create an alias, drop all locks and reclaim the dentry
23612         < $file2
23613         cancel_lru_locks mdc
23614         cancel_lru_locks osc
23615         sysctl -w vm.drop_caches=2
23616
23617         wait
23618
23619         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
23620
23621         rm -f $tfile $file1 $file2
23622 }
23623 run_test 403 "i_nlink should not drop to zero due to aliasing"
23624
23625 test_404() { # LU-6601
23626         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
23627                 skip "Need server version newer than 2.8.52"
23628         remote_mds_nodsh && skip "remote MDS with nodsh"
23629
23630         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
23631                 awk '/osp .*-osc-MDT/ { print $4}')
23632
23633         local osp
23634         for osp in $mosps; do
23635                 echo "Deactivate: " $osp
23636                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
23637                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23638                         awk -vp=$osp '$4 == p { print $2 }')
23639                 [ $stat = IN ] || {
23640                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23641                         error "deactivate error"
23642                 }
23643                 echo "Activate: " $osp
23644                 do_facet $SINGLEMDS $LCTL --device %$osp activate
23645                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
23646                         awk -vp=$osp '$4 == p { print $2 }')
23647                 [ $stat = UP ] || {
23648                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
23649                         error "activate error"
23650                 }
23651         done
23652 }
23653 run_test 404 "validate manual {de}activated works properly for OSPs"
23654
23655 test_405() {
23656         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23657         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
23658                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
23659                         skip "Layout swap lock is not supported"
23660
23661         check_swap_layouts_support
23662         check_swap_layout_no_dom $DIR
23663
23664         test_mkdir $DIR/$tdir
23665         swap_lock_test -d $DIR/$tdir ||
23666                 error "One layout swap locked test failed"
23667 }
23668 run_test 405 "Various layout swap lock tests"
23669
23670 test_406() {
23671         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23672         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
23673         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
23674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23675         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
23676                 skip "Need MDS version at least 2.8.50"
23677
23678         local def_stripe_size=$($LFS getstripe -S $MOUNT)
23679         local test_pool=$TESTNAME
23680
23681         pool_add $test_pool || error "pool_add failed"
23682         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
23683                 error "pool_add_targets failed"
23684
23685         save_layout_restore_at_exit $MOUNT
23686
23687         # parent set default stripe count only, child will stripe from both
23688         # parent and fs default
23689         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
23690                 error "setstripe $MOUNT failed"
23691         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23692         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
23693         for i in $(seq 10); do
23694                 local f=$DIR/$tdir/$tfile.$i
23695                 touch $f || error "touch failed"
23696                 local count=$($LFS getstripe -c $f)
23697                 [ $count -eq $OSTCOUNT ] ||
23698                         error "$f stripe count $count != $OSTCOUNT"
23699                 local offset=$($LFS getstripe -i $f)
23700                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
23701                 local size=$($LFS getstripe -S $f)
23702                 [ $size -eq $((def_stripe_size * 2)) ] ||
23703                         error "$f stripe size $size != $((def_stripe_size * 2))"
23704                 local pool=$($LFS getstripe -p $f)
23705                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
23706         done
23707
23708         # change fs default striping, delete parent default striping, now child
23709         # will stripe from new fs default striping only
23710         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
23711                 error "change $MOUNT default stripe failed"
23712         $LFS setstripe -c 0 $DIR/$tdir ||
23713                 error "delete $tdir default stripe failed"
23714         for i in $(seq 11 20); do
23715                 local f=$DIR/$tdir/$tfile.$i
23716                 touch $f || error "touch $f failed"
23717                 local count=$($LFS getstripe -c $f)
23718                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
23719                 local offset=$($LFS getstripe -i $f)
23720                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
23721                 local size=$($LFS getstripe -S $f)
23722                 [ $size -eq $def_stripe_size ] ||
23723                         error "$f stripe size $size != $def_stripe_size"
23724                 local pool=$($LFS getstripe -p $f)
23725                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
23726         done
23727
23728         unlinkmany $DIR/$tdir/$tfile. 1 20
23729
23730         local f=$DIR/$tdir/$tfile
23731         pool_remove_all_targets $test_pool $f
23732         pool_remove $test_pool $f
23733 }
23734 run_test 406 "DNE support fs default striping"
23735
23736 test_407() {
23737         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23738         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23739                 skip "Need MDS version at least 2.8.55"
23740         remote_mds_nodsh && skip "remote MDS with nodsh"
23741
23742         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
23743                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
23744         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
23745                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
23746         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
23747
23748         #define OBD_FAIL_DT_TXN_STOP    0x2019
23749         for idx in $(seq $MDSCOUNT); do
23750                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
23751         done
23752         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
23753         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
23754                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
23755         true
23756 }
23757 run_test 407 "transaction fail should cause operation fail"
23758
23759 test_408() {
23760         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
23761
23762         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
23763         lctl set_param fail_loc=0x8000040a
23764         # let ll_prepare_partial_page() fail
23765         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
23766
23767         rm -f $DIR/$tfile
23768
23769         # create at least 100 unused inodes so that
23770         # shrink_icache_memory(0) should not return 0
23771         touch $DIR/$tfile-{0..100}
23772         rm -f $DIR/$tfile-{0..100}
23773         sync
23774
23775         echo 2 > /proc/sys/vm/drop_caches
23776 }
23777 run_test 408 "drop_caches should not hang due to page leaks"
23778
23779 test_409()
23780 {
23781         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23782
23783         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
23784         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
23785         touch $DIR/$tdir/guard || error "(2) Fail to create"
23786
23787         local PREFIX=$(str_repeat 'A' 128)
23788         echo "Create 1K hard links start at $(date)"
23789         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23790                 error "(3) Fail to hard link"
23791
23792         echo "Links count should be right although linkEA overflow"
23793         stat $DIR/$tdir/guard || error "(4) Fail to stat"
23794         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
23795         [ $linkcount -eq 1001 ] ||
23796                 error "(5) Unexpected hard links count: $linkcount"
23797
23798         echo "List all links start at $(date)"
23799         ls -l $DIR/$tdir/foo > /dev/null ||
23800                 error "(6) Fail to list $DIR/$tdir/foo"
23801
23802         echo "Unlink hard links start at $(date)"
23803         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
23804                 error "(7) Fail to unlink"
23805         echo "Unlink hard links finished at $(date)"
23806 }
23807 run_test 409 "Large amount of cross-MDTs hard links on the same file"
23808
23809 test_410()
23810 {
23811         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
23812                 skip "Need client version at least 2.9.59"
23813         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
23814                 skip "Need MODULES build"
23815
23816         # Create a file, and stat it from the kernel
23817         local testfile=$DIR/$tfile
23818         touch $testfile
23819
23820         local run_id=$RANDOM
23821         local my_ino=$(stat --format "%i" $testfile)
23822
23823         # Try to insert the module. This will always fail as the
23824         # module is designed to not be inserted.
23825         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
23826             &> /dev/null
23827
23828         # Anything but success is a test failure
23829         dmesg | grep -q \
23830             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
23831             error "no inode match"
23832 }
23833 run_test 410 "Test inode number returned from kernel thread"
23834
23835 cleanup_test411_cgroup() {
23836         trap 0
23837         rmdir "$1"
23838 }
23839
23840 test_411() {
23841         local cg_basedir=/sys/fs/cgroup/memory
23842         # LU-9966
23843         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
23844                 skip "no setup for cgroup"
23845
23846         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
23847                 error "test file creation failed"
23848         cancel_lru_locks osc
23849
23850         # Create a very small memory cgroup to force a slab allocation error
23851         local cgdir=$cg_basedir/osc_slab_alloc
23852         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
23853         trap "cleanup_test411_cgroup $cgdir" EXIT
23854         echo 2M > $cgdir/memory.kmem.limit_in_bytes
23855         echo 1M > $cgdir/memory.limit_in_bytes
23856
23857         # Should not LBUG, just be killed by oom-killer
23858         # dd will return 0 even allocation failure in some environment.
23859         # So don't check return value
23860         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
23861         cleanup_test411_cgroup $cgdir
23862
23863         return 0
23864 }
23865 run_test 411 "Slab allocation error with cgroup does not LBUG"
23866
23867 test_412() {
23868         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23869         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
23870                 skip "Need server version at least 2.10.55"
23871         fi
23872
23873         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
23874                 error "mkdir failed"
23875         $LFS getdirstripe $DIR/$tdir
23876         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
23877         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
23878                 error "expect $((MDSCOUT - 1)) get $stripe_index"
23879         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
23880         [ $stripe_count -eq 2 ] ||
23881                 error "expect 2 get $stripe_count"
23882 }
23883 run_test 412 "mkdir on specific MDTs"
23884
23885 test_qos_mkdir() {
23886         local mkdir_cmd=$1
23887         local stripe_count=$2
23888         local mdts=$(comma_list $(mdts_nodes))
23889
23890         local testdir
23891         local lmv_qos_prio_free
23892         local lmv_qos_threshold_rr
23893         local lmv_qos_maxage
23894         local lod_qos_prio_free
23895         local lod_qos_threshold_rr
23896         local lod_qos_maxage
23897         local count
23898         local i
23899
23900         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
23901         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
23902         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
23903                 head -n1)
23904         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
23905         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
23906         stack_trap "$LCTL set_param \
23907                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
23908         stack_trap "$LCTL set_param \
23909                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23910         stack_trap "$LCTL set_param \
23911                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23912
23913         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23914                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23915         lod_qos_prio_free=${lod_qos_prio_free%%%}
23916         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23917                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23918         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23919         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23920                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23921         stack_trap "do_nodes $mdts $LCTL set_param \
23922                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23923         stack_trap "do_nodes $mdts $LCTL set_param \
23924                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23925                 EXIT
23926         stack_trap "do_nodes $mdts $LCTL set_param \
23927                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23928
23929         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23930         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23931
23932         testdir=$DIR/$tdir-s$stripe_count/rr
23933
23934         local stripe_index=$($LFS getstripe -m $testdir)
23935         local test_mkdir_rr=true
23936
23937         getfattr -d -m dmv $testdir | grep dmv
23938         if [ $? -eq 0 ] && [ $MDS1_VERSION -ge $(version_code 2.14.51) ]; then
23939                 local inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
23940
23941                 (( $inherit_rr == 0 )) && test_mkdir_rr=false
23942         fi
23943
23944         echo
23945         $test_mkdir_rr &&
23946                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
23947                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
23948
23949         for i in $(seq $((100 * MDSCOUNT))); do
23950                 eval $mkdir_cmd $testdir/subdir$i ||
23951                         error "$mkdir_cmd subdir$i failed"
23952         done
23953
23954         for i in $(seq $MDSCOUNT); do
23955                 count=$($LFS getdirstripe -i $testdir/* |
23956                                 grep ^$((i - 1))$ | wc -l)
23957                 echo "$count directories created on MDT$((i - 1))"
23958                 if $test_mkdir_rr; then
23959                         (( $count == 100 )) ||
23960                                 error "subdirs are not evenly distributed"
23961                 elif [ $((i - 1)) -eq $stripe_index ]; then
23962                         (( $count == 100 * MDSCOUNT )) ||
23963                                 error "$count subdirs created on MDT$((i - 1))"
23964                 else
23965                         (( $count == 0 )) ||
23966                                 error "$count subdirs created on MDT$((i - 1))"
23967                 fi
23968
23969                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
23970                         count=$($LFS getdirstripe $testdir/* |
23971                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23972                         echo "$count stripes created on MDT$((i - 1))"
23973                         # deviation should < 5% of average
23974                         (( $count < 95 * stripe_count )) ||
23975                         (( $count > 105 * stripe_count)) &&
23976                                 error "stripes are not evenly distributed"
23977                 fi
23978         done
23979
23980         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23981         do_nodes $mdts $LCTL set_param \
23982                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23983
23984         echo
23985         echo "Check for uneven MDTs: "
23986
23987         local ffree
23988         local bavail
23989         local max
23990         local min
23991         local max_index
23992         local min_index
23993         local tmp
23994
23995         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23996         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23997         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23998
23999         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24000         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24001         max_index=0
24002         min_index=0
24003         for ((i = 1; i < ${#ffree[@]}; i++)); do
24004                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24005                 if [ $tmp -gt $max ]; then
24006                         max=$tmp
24007                         max_index=$i
24008                 fi
24009                 if [ $tmp -lt $min ]; then
24010                         min=$tmp
24011                         min_index=$i
24012                 fi
24013         done
24014
24015         (( ${ffree[min_index]} == 0 )) &&
24016                 skip "no free files in MDT$min_index"
24017         (( ${ffree[min_index]} > 100000000 )) &&
24018                 skip "too many free files in MDT$min_index"
24019
24020         # Check if we need to generate uneven MDTs
24021         local threshold=50
24022         local diff=$(((max - min) * 100 / min))
24023         local value="$(generate_string 1024)"
24024
24025         while [ $diff -lt $threshold ]; do
24026                 # generate uneven MDTs, create till $threshold% diff
24027                 echo -n "weight diff=$diff% must be > $threshold% ..."
24028                 count=$((${ffree[min_index]} / 10))
24029                 # 50 sec per 10000 files in vm
24030                 (( $count < 100000 )) || [ "$SLOW" != "no" ] ||
24031                         skip "$count files to create"
24032                 echo "Fill MDT$min_index with $count files"
24033                 [ -d $DIR/$tdir-MDT$min_index ] ||
24034                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
24035                         error "mkdir $tdir-MDT$min_index failed"
24036                 createmany -d $DIR/$tdir-MDT$min_index/d $count ||
24037                         error "create d$count failed"
24038
24039                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24040                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24041                 max=$(((${ffree[max_index]} >> 8) * \
24042                         (${bavail[max_index]} * bsize >> 16)))
24043                 min=$(((${ffree[min_index]} >> 8) * \
24044                         (${bavail[min_index]} * bsize >> 16)))
24045                 diff=$(((max - min) * 100 / min))
24046         done
24047
24048         echo "MDT filesfree available: ${ffree[@]}"
24049         echo "MDT blocks available: ${bavail[@]}"
24050         echo "weight diff=$diff%"
24051
24052         echo
24053         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24054
24055         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24056         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24057         # decrease statfs age, so that it can be updated in time
24058         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24059         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24060
24061         sleep 1
24062
24063         testdir=$DIR/$tdir-s$stripe_count/qos
24064
24065         for i in $(seq $((100 * MDSCOUNT))); do
24066                 eval $mkdir_cmd $testdir/subdir$i ||
24067                         error "$mkdir_cmd subdir$i failed"
24068         done
24069
24070         for i in $(seq $MDSCOUNT); do
24071                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
24072                         wc -l)
24073                 echo "$count directories created on MDT$((i - 1))"
24074
24075                 if [ $stripe_count -gt 1 ]; then
24076                         count=$($LFS getdirstripe $testdir/* |
24077                                 grep -P "^\s+$((i - 1))\t" | wc -l)
24078                         echo "$count stripes created on MDT$((i - 1))"
24079                 fi
24080         done
24081
24082         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
24083         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
24084
24085         # D-value should > 10% of averge
24086         (( $max - $min < 10 )) &&
24087                 error "subdirs shouldn't be evenly distributed"
24088
24089         # ditto
24090         if [ $stripe_count -gt 1 ]; then
24091                 max=$($LFS getdirstripe $testdir/* |
24092                         grep -P "^\s+$max_index\t" | wc -l)
24093                 min=$($LFS getdirstripe $testdir/* |
24094                         grep -P "^\s+$min_index\t" | wc -l)
24095                 (( $max - $min < 10 * $stripe_count )) &&
24096                         error "stripes shouldn't be evenly distributed"|| true
24097         fi
24098 }
24099
24100 test_413a() {
24101         [ $MDSCOUNT -lt 2 ] &&
24102                 skip "We need at least 2 MDTs for this test"
24103
24104         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24105                 skip "Need server version at least 2.12.52"
24106
24107         local stripe_count
24108
24109         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24110                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24111                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24112                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
24113                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
24114         done
24115 }
24116 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24117
24118 test_413b() {
24119         [ $MDSCOUNT -lt 2 ] &&
24120                 skip "We need at least 2 MDTs for this test"
24121
24122         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24123                 skip "Need server version at least 2.12.52"
24124
24125         local testdir
24126         local stripe_count
24127
24128         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24129                 testdir=$DIR/$tdir-s$stripe_count
24130                 mkdir $testdir || error "mkdir $testdir failed"
24131                 mkdir $testdir/rr || error "mkdir rr failed"
24132                 mkdir $testdir/qos || error "mkdir qos failed"
24133                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24134                         $testdir/rr || error "setdirstripe rr failed"
24135                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24136                         error "setdirstripe failed"
24137                 test_qos_mkdir "mkdir" $stripe_count
24138         done
24139 }
24140 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24141
24142 test_413c() {
24143         [ $MDSCOUNT -ge 2 ] ||
24144                 skip "We need at least 2 MDTs for this test"
24145
24146         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] ||
24147                 skip "Need server version at least 2.14.50"
24148
24149         local testdir
24150         local inherit
24151         local inherit_rr
24152
24153         testdir=$DIR/${tdir}-s1
24154         mkdir $testdir || error "mkdir $testdir failed"
24155         mkdir $testdir/rr || error "mkdir rr failed"
24156         mkdir $testdir/qos || error "mkdir qos failed"
24157         # default max_inherit is -1, default max_inherit_rr is 0
24158         $LFS setdirstripe -D -c 1 $testdir/rr ||
24159                 error "setdirstripe rr failed"
24160         $LFS setdirstripe -D -c 1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24161                 error "setdirstripe qos failed"
24162         test_qos_mkdir "mkdir" 1
24163
24164         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24165         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24166         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24167         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24168         (( $inherit_rr == 0 )) ||
24169                 error "rr/level1 inherit-rr $inherit_rr != 0"
24170
24171         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24172         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24173         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24174         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24175         (( $inherit_rr == 0 )) ||
24176                 error "qos/level1 inherit-rr $inherit_rr !=0"
24177         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24178         getfattr -d -m dmv $testdir/qos/level1/level2 | grep dmv &&
24179                 error "level2 shouldn't have default LMV" || true
24180 }
24181 run_test 413c "mkdir with default LMV max inherit rr"
24182
24183 test_414() {
24184 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24185         $LCTL set_param fail_loc=0x80000521
24186         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24187         rm -f $DIR/$tfile
24188 }
24189 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24190
24191 test_415() {
24192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24193         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24194                 skip "Need server version at least 2.11.52"
24195
24196         # LU-11102
24197         local total
24198         local setattr_pid
24199         local start_time
24200         local end_time
24201         local duration
24202
24203         total=500
24204         # this test may be slow on ZFS
24205         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24206
24207         # though this test is designed for striped directory, let's test normal
24208         # directory too since lock is always saved as CoS lock.
24209         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24210         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24211
24212         (
24213                 while true; do
24214                         touch $DIR/$tdir
24215                 done
24216         ) &
24217         setattr_pid=$!
24218
24219         start_time=$(date +%s)
24220         for i in $(seq $total); do
24221                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24222                         > /dev/null
24223         done
24224         end_time=$(date +%s)
24225         duration=$((end_time - start_time))
24226
24227         kill -9 $setattr_pid
24228
24229         echo "rename $total files took $duration sec"
24230         [ $duration -lt 100 ] || error "rename took $duration sec"
24231 }
24232 run_test 415 "lock revoke is not missing"
24233
24234 test_416() {
24235         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24236                 skip "Need server version at least 2.11.55"
24237
24238         # define OBD_FAIL_OSD_TXN_START    0x19a
24239         do_facet mds1 lctl set_param fail_loc=0x19a
24240
24241         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24242
24243         true
24244 }
24245 run_test 416 "transaction start failure won't cause system hung"
24246
24247 cleanup_417() {
24248         trap 0
24249         do_nodes $(comma_list $(mdts_nodes)) \
24250                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24251         do_nodes $(comma_list $(mdts_nodes)) \
24252                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24253         do_nodes $(comma_list $(mdts_nodes)) \
24254                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24255 }
24256
24257 test_417() {
24258         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24259         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24260                 skip "Need MDS version at least 2.11.56"
24261
24262         trap cleanup_417 RETURN EXIT
24263
24264         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24265         do_nodes $(comma_list $(mdts_nodes)) \
24266                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24267         $LFS migrate -m 0 $DIR/$tdir.1 &&
24268                 error "migrate dir $tdir.1 should fail"
24269
24270         do_nodes $(comma_list $(mdts_nodes)) \
24271                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24272         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24273                 error "create remote dir $tdir.2 should fail"
24274
24275         do_nodes $(comma_list $(mdts_nodes)) \
24276                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
24277         $LFS mkdir -c 2 $DIR/$tdir.3 &&
24278                 error "create striped dir $tdir.3 should fail"
24279         true
24280 }
24281 run_test 417 "disable remote dir, striped dir and dir migration"
24282
24283 # Checks that the outputs of df [-i] and lfs df [-i] match
24284 #
24285 # usage: check_lfs_df <blocks | inodes> <mountpoint>
24286 check_lfs_df() {
24287         local dir=$2
24288         local inodes
24289         local df_out
24290         local lfs_df_out
24291         local count
24292         local passed=false
24293
24294         # blocks or inodes
24295         [ "$1" == "blocks" ] && inodes= || inodes="-i"
24296
24297         for count in {1..100}; do
24298                 cancel_lru_locks
24299                 sync; sleep 0.2
24300
24301                 # read the lines of interest
24302                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
24303                         error "df $inodes $dir | tail -n +2 failed"
24304                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
24305                         error "lfs df $inodes $dir | grep summary: failed"
24306
24307                 # skip first substrings of each output as they are different
24308                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
24309                 # compare the two outputs
24310                 passed=true
24311                 for i in {1..5}; do
24312                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
24313                 done
24314                 $passed && break
24315         done
24316
24317         if ! $passed; then
24318                 df -P $inodes $dir
24319                 echo
24320                 lfs df $inodes $dir
24321                 error "df and lfs df $1 output mismatch: "      \
24322                       "df ${inodes}: ${df_out[*]}, "            \
24323                       "lfs df ${inodes}: ${lfs_df_out[*]}"
24324         fi
24325 }
24326
24327 test_418() {
24328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24329
24330         local dir=$DIR/$tdir
24331         local numfiles=$((RANDOM % 4096 + 2))
24332         local numblocks=$((RANDOM % 256 + 1))
24333
24334         wait_delete_completed
24335         test_mkdir $dir
24336
24337         # check block output
24338         check_lfs_df blocks $dir
24339         # check inode output
24340         check_lfs_df inodes $dir
24341
24342         # create a single file and retest
24343         echo "Creating a single file and testing"
24344         createmany -o $dir/$tfile- 1 &>/dev/null ||
24345                 error "creating 1 file in $dir failed"
24346         check_lfs_df blocks $dir
24347         check_lfs_df inodes $dir
24348
24349         # create a random number of files
24350         echo "Creating $((numfiles - 1)) files and testing"
24351         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
24352                 error "creating $((numfiles - 1)) files in $dir failed"
24353
24354         # write a random number of blocks to the first test file
24355         echo "Writing $numblocks 4K blocks and testing"
24356         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
24357                 count=$numblocks &>/dev/null ||
24358                 error "dd to $dir/${tfile}-0 failed"
24359
24360         # retest
24361         check_lfs_df blocks $dir
24362         check_lfs_df inodes $dir
24363
24364         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
24365                 error "unlinking $numfiles files in $dir failed"
24366 }
24367 run_test 418 "df and lfs df outputs match"
24368
24369 test_419()
24370 {
24371         local dir=$DIR/$tdir
24372
24373         mkdir -p $dir
24374         touch $dir/file
24375
24376         cancel_lru_locks mdc
24377
24378         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
24379         $LCTL set_param fail_loc=0x1410
24380         cat $dir/file
24381         $LCTL set_param fail_loc=0
24382         rm -rf $dir
24383 }
24384 run_test 419 "Verify open file by name doesn't crash kernel"
24385
24386 test_420()
24387 {
24388         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
24389                 skip "Need MDS version at least 2.12.53"
24390
24391         local SAVE_UMASK=$(umask)
24392         local dir=$DIR/$tdir
24393         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
24394
24395         mkdir -p $dir
24396         umask 0000
24397         mkdir -m03777 $dir/testdir
24398         ls -dn $dir/testdir
24399         # Need to remove trailing '.' when SELinux is enabled
24400         local dirperms=$(ls -dn $dir/testdir |
24401                          awk '{ sub(/\.$/, "", $1); print $1}')
24402         [ $dirperms == "drwxrwsrwt" ] ||
24403                 error "incorrect perms on $dir/testdir"
24404
24405         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
24406                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
24407         ls -n $dir/testdir/testfile
24408         local fileperms=$(ls -n $dir/testdir/testfile |
24409                           awk '{ sub(/\.$/, "", $1); print $1}')
24410         [ $fileperms == "-rwxr-xr-x" ] ||
24411                 error "incorrect perms on $dir/testdir/testfile"
24412
24413         umask $SAVE_UMASK
24414 }
24415 run_test 420 "clear SGID bit on non-directories for non-members"
24416
24417 test_421a() {
24418         local cnt
24419         local fid1
24420         local fid2
24421
24422         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24423                 skip "Need MDS version at least 2.12.54"
24424
24425         test_mkdir $DIR/$tdir
24426         createmany -o $DIR/$tdir/f 3
24427         cnt=$(ls -1 $DIR/$tdir | wc -l)
24428         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24429
24430         fid1=$(lfs path2fid $DIR/$tdir/f1)
24431         fid2=$(lfs path2fid $DIR/$tdir/f2)
24432         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
24433
24434         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
24435         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
24436
24437         cnt=$(ls -1 $DIR/$tdir | wc -l)
24438         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24439
24440         rm -f $DIR/$tdir/f3 || error "can't remove f3"
24441         createmany -o $DIR/$tdir/f 3
24442         cnt=$(ls -1 $DIR/$tdir | wc -l)
24443         [ $cnt != 3 ] && error "unexpected #files: $cnt"
24444
24445         fid1=$(lfs path2fid $DIR/$tdir/f1)
24446         fid2=$(lfs path2fid $DIR/$tdir/f2)
24447         echo "remove using fsname $FSNAME"
24448         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
24449
24450         cnt=$(ls -1 $DIR/$tdir | wc -l)
24451         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
24452 }
24453 run_test 421a "simple rm by fid"
24454
24455 test_421b() {
24456         local cnt
24457         local FID1
24458         local FID2
24459
24460         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24461                 skip "Need MDS version at least 2.12.54"
24462
24463         test_mkdir $DIR/$tdir
24464         createmany -o $DIR/$tdir/f 3
24465         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
24466         MULTIPID=$!
24467
24468         FID1=$(lfs path2fid $DIR/$tdir/f1)
24469         FID2=$(lfs path2fid $DIR/$tdir/f2)
24470         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
24471
24472         kill -USR1 $MULTIPID
24473         wait
24474
24475         cnt=$(ls $DIR/$tdir | wc -l)
24476         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
24477 }
24478 run_test 421b "rm by fid on open file"
24479
24480 test_421c() {
24481         local cnt
24482         local FIDS
24483
24484         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24485                 skip "Need MDS version at least 2.12.54"
24486
24487         test_mkdir $DIR/$tdir
24488         createmany -o $DIR/$tdir/f 3
24489         touch $DIR/$tdir/$tfile
24490         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
24491         cnt=$(ls -1 $DIR/$tdir | wc -l)
24492         [ $cnt != 184 ] && error "unexpected #files: $cnt"
24493
24494         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
24495         $LFS rmfid $DIR $FID1 || error "rmfid failed"
24496
24497         cnt=$(ls $DIR/$tdir | wc -l)
24498         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
24499 }
24500 run_test 421c "rm by fid against hardlinked files"
24501
24502 test_421d() {
24503         local cnt
24504         local FIDS
24505
24506         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24507                 skip "Need MDS version at least 2.12.54"
24508
24509         test_mkdir $DIR/$tdir
24510         createmany -o $DIR/$tdir/f 4097
24511         cnt=$(ls -1 $DIR/$tdir | wc -l)
24512         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
24513
24514         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
24515         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24516
24517         cnt=$(ls $DIR/$tdir | wc -l)
24518         rm -rf $DIR/$tdir
24519         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24520 }
24521 run_test 421d "rmfid en masse"
24522
24523 test_421e() {
24524         local cnt
24525         local FID
24526
24527         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24528         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24529                 skip "Need MDS version at least 2.12.54"
24530
24531         mkdir -p $DIR/$tdir
24532         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24533         createmany -o $DIR/$tdir/striped_dir/f 512
24534         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24535         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24536
24537         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24538                 sed "s/[/][^:]*://g")
24539         $LFS rmfid $DIR $FIDS || error "rmfid failed"
24540
24541         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24542         rm -rf $DIR/$tdir
24543         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24544 }
24545 run_test 421e "rmfid in DNE"
24546
24547 test_421f() {
24548         local cnt
24549         local FID
24550
24551         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24552                 skip "Need MDS version at least 2.12.54"
24553
24554         test_mkdir $DIR/$tdir
24555         touch $DIR/$tdir/f
24556         cnt=$(ls -1 $DIR/$tdir | wc -l)
24557         [ $cnt != 1 ] && error "unexpected #files: $cnt"
24558
24559         FID=$(lfs path2fid $DIR/$tdir/f)
24560         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
24561         # rmfid should fail
24562         cnt=$(ls -1 $DIR/$tdir | wc -l)
24563         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
24564
24565         chmod a+rw $DIR/$tdir
24566         ls -la $DIR/$tdir
24567         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
24568         # rmfid should fail
24569         cnt=$(ls -1 $DIR/$tdir | wc -l)
24570         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
24571
24572         rm -f $DIR/$tdir/f
24573         $RUNAS touch $DIR/$tdir/f
24574         FID=$(lfs path2fid $DIR/$tdir/f)
24575         echo "rmfid as root"
24576         $LFS rmfid $DIR $FID || error "rmfid as root failed"
24577         cnt=$(ls -1 $DIR/$tdir | wc -l)
24578         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
24579
24580         rm -f $DIR/$tdir/f
24581         $RUNAS touch $DIR/$tdir/f
24582         cnt=$(ls -1 $DIR/$tdir | wc -l)
24583         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
24584         FID=$(lfs path2fid $DIR/$tdir/f)
24585         # rmfid w/o user_fid2path mount option should fail
24586         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
24587         cnt=$(ls -1 $DIR/$tdir | wc -l)
24588         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
24589
24590         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
24591         stack_trap "rmdir $tmpdir"
24592         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
24593                 error "failed to mount client'"
24594         stack_trap "umount_client $tmpdir"
24595
24596         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
24597         # rmfid should succeed
24598         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
24599         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
24600
24601         # rmfid shouldn't allow to remove files due to dir's permission
24602         chmod a+rwx $tmpdir/$tdir
24603         touch $tmpdir/$tdir/f
24604         ls -la $tmpdir/$tdir
24605         FID=$(lfs path2fid $tmpdir/$tdir/f)
24606         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
24607         return 0
24608 }
24609 run_test 421f "rmfid checks permissions"
24610
24611 test_421g() {
24612         local cnt
24613         local FIDS
24614
24615         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24616         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
24617                 skip "Need MDS version at least 2.12.54"
24618
24619         mkdir -p $DIR/$tdir
24620         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24621         createmany -o $DIR/$tdir/striped_dir/f 512
24622         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24623         [ $cnt != 512 ] && error "unexpected #files: $cnt"
24624
24625         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
24626                 sed "s/[/][^:]*://g")
24627
24628         rm -f $DIR/$tdir/striped_dir/f1*
24629         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
24630         removed=$((512 - cnt))
24631
24632         # few files have been just removed, so we expect
24633         # rmfid to fail on their fids
24634         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
24635         [ $removed != $errors ] && error "$errors != $removed"
24636
24637         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
24638         rm -rf $DIR/$tdir
24639         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
24640 }
24641 run_test 421g "rmfid to return errors properly"
24642
24643 test_422() {
24644         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
24645         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
24646         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
24647         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
24648         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
24649
24650         local amc=$(at_max_get client)
24651         local amo=$(at_max_get mds1)
24652         local timeout=`lctl get_param -n timeout`
24653
24654         at_max_set 0 client
24655         at_max_set 0 mds1
24656
24657 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
24658         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
24659                         fail_val=$(((2*timeout + 10)*1000))
24660         touch $DIR/$tdir/d3/file &
24661         sleep 2
24662 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
24663         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
24664                         fail_val=$((2*timeout + 5))
24665         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
24666         local pid=$!
24667         sleep 1
24668         kill -9 $pid
24669         sleep $((2 * timeout))
24670         echo kill $pid
24671         kill -9 $pid
24672         lctl mark touch
24673         touch $DIR/$tdir/d2/file3
24674         touch $DIR/$tdir/d2/file4
24675         touch $DIR/$tdir/d2/file5
24676
24677         wait
24678         at_max_set $amc client
24679         at_max_set $amo mds1
24680
24681         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
24682         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
24683                 error "Watchdog is always throttled"
24684 }
24685 run_test 422 "kill a process with RPC in progress"
24686
24687 stat_test() {
24688     df -h $MOUNT &
24689     df -h $MOUNT &
24690     df -h $MOUNT &
24691     df -h $MOUNT &
24692     df -h $MOUNT &
24693     df -h $MOUNT &
24694 }
24695
24696 test_423() {
24697     local _stats
24698     # ensure statfs cache is expired
24699     sleep 2;
24700
24701     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
24702     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
24703
24704     return 0
24705 }
24706 run_test 423 "statfs should return a right data"
24707
24708 test_424() {
24709 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
24710         $LCTL set_param fail_loc=0x80000522
24711         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24712         rm -f $DIR/$tfile
24713 }
24714 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
24715
24716 test_425() {
24717         test_mkdir -c -1 $DIR/$tdir
24718         $LFS setstripe -c -1 $DIR/$tdir
24719
24720         lru_resize_disable "" 100
24721         stack_trap "lru_resize_enable" EXIT
24722
24723         sleep 5
24724
24725         for i in $(seq $((MDSCOUNT * 125))); do
24726                 local t=$DIR/$tdir/$tfile_$i
24727
24728                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
24729                         error_noexit "Create file $t"
24730         done
24731         stack_trap "rm -rf $DIR/$tdir" EXIT
24732
24733         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
24734                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
24735                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
24736
24737                 [ $lock_count -le $lru_size ] ||
24738                         error "osc lock count $lock_count > lru size $lru_size"
24739         done
24740
24741         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
24742                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
24743                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
24744
24745                 [ $lock_count -le $lru_size ] ||
24746                         error "mdc lock count $lock_count > lru size $lru_size"
24747         done
24748 }
24749 run_test 425 "lock count should not exceed lru size"
24750
24751 test_426() {
24752         splice-test -r $DIR/$tfile
24753         splice-test -rd $DIR/$tfile
24754         splice-test $DIR/$tfile
24755         splice-test -d $DIR/$tfile
24756 }
24757 run_test 426 "splice test on Lustre"
24758
24759 test_427() {
24760         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
24761         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
24762                 skip "Need MDS version at least 2.12.4"
24763         local log
24764
24765         mkdir $DIR/$tdir
24766         mkdir $DIR/$tdir/1
24767         mkdir $DIR/$tdir/2
24768         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
24769         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
24770
24771         $LFS getdirstripe $DIR/$tdir/1/dir
24772
24773         #first setfattr for creating updatelog
24774         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
24775
24776 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
24777         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
24778         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
24779         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
24780
24781         sleep 2
24782         fail mds2
24783         wait_recovery_complete mds2 $((2*TIMEOUT))
24784
24785         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
24786         echo $log | grep "get update log failed" &&
24787                 error "update log corruption is detected" || true
24788 }
24789 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
24790
24791 test_428() {
24792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24793         local cache_limit=$CACHE_MAX
24794
24795         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
24796         $LCTL set_param -n llite.*.max_cached_mb=64
24797
24798         mkdir $DIR/$tdir
24799         $LFS setstripe -c 1 $DIR/$tdir
24800         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
24801         stack_trap "rm -f $DIR/$tdir/$tfile.*"
24802         #test write
24803         for f in $(seq 4); do
24804                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
24805         done
24806         wait
24807
24808         cancel_lru_locks osc
24809         # Test read
24810         for f in $(seq 4); do
24811                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
24812         done
24813         wait
24814 }
24815 run_test 428 "large block size IO should not hang"
24816
24817 test_429() { # LU-7915 / LU-10948
24818         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
24819         local testfile=$DIR/$tfile
24820         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
24821         local new_flag=1
24822         local first_rpc
24823         local second_rpc
24824         local third_rpc
24825
24826         $LCTL get_param $ll_opencache_threshold_count ||
24827                 skip "client does not have opencache parameter"
24828
24829         set_opencache $new_flag
24830         stack_trap "restore_opencache"
24831         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
24832                 error "enable opencache failed"
24833         touch $testfile
24834         # drop MDC DLM locks
24835         cancel_lru_locks mdc
24836         # clear MDC RPC stats counters
24837         $LCTL set_param $mdc_rpcstats=clear
24838
24839         # According to the current implementation, we need to run 3 times
24840         # open & close file to verify if opencache is enabled correctly.
24841         # 1st, RPCs are sent for lookup/open and open handle is released on
24842         #      close finally.
24843         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
24844         #      so open handle won't be released thereafter.
24845         # 3rd, No RPC is sent out.
24846         $MULTIOP $testfile oc || error "multiop failed"
24847         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24848         echo "1st: $first_rpc RPCs in flight"
24849
24850         $MULTIOP $testfile oc || error "multiop failed"
24851         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24852         echo "2nd: $second_rpc RPCs in flight"
24853
24854         $MULTIOP $testfile oc || error "multiop failed"
24855         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
24856         echo "3rd: $third_rpc RPCs in flight"
24857
24858         #verify no MDC RPC is sent
24859         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
24860 }
24861 run_test 429 "verify if opencache flag on client side does work"
24862
24863 lseek_test_430() {
24864         local offset
24865         local file=$1
24866
24867         # data at [200K, 400K)
24868         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
24869                 error "256K->512K dd fails"
24870         # data at [2M, 3M)
24871         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
24872                 error "2M->3M dd fails"
24873         # data at [4M, 5M)
24874         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
24875                 error "4M->5M dd fails"
24876         echo "Data at 256K...512K, 2M...3M and 4M...5M"
24877         # start at first component hole #1
24878         printf "Seeking hole from 1000 ... "
24879         offset=$(lseek_test -l 1000 $file)
24880         echo $offset
24881         [[ $offset == 1000 ]] || error "offset $offset != 1000"
24882         printf "Seeking data from 1000 ... "
24883         offset=$(lseek_test -d 1000 $file)
24884         echo $offset
24885         [[ $offset == 262144 ]] || error "offset $offset != 262144"
24886
24887         # start at first component data block
24888         printf "Seeking hole from 300000 ... "
24889         offset=$(lseek_test -l 300000 $file)
24890         echo $offset
24891         [[ $offset == 524288 ]] || error "offset $offset != 524288"
24892         printf "Seeking data from 300000 ... "
24893         offset=$(lseek_test -d 300000 $file)
24894         echo $offset
24895         [[ $offset == 300000 ]] || error "offset $offset != 300000"
24896
24897         # start at the first component but beyond end of object size
24898         printf "Seeking hole from 1000000 ... "
24899         offset=$(lseek_test -l 1000000 $file)
24900         echo $offset
24901         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24902         printf "Seeking data from 1000000 ... "
24903         offset=$(lseek_test -d 1000000 $file)
24904         echo $offset
24905         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24906
24907         # start at second component stripe 2 (empty file)
24908         printf "Seeking hole from 1500000 ... "
24909         offset=$(lseek_test -l 1500000 $file)
24910         echo $offset
24911         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
24912         printf "Seeking data from 1500000 ... "
24913         offset=$(lseek_test -d 1500000 $file)
24914         echo $offset
24915         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
24916
24917         # start at second component stripe 1 (all data)
24918         printf "Seeking hole from 3000000 ... "
24919         offset=$(lseek_test -l 3000000 $file)
24920         echo $offset
24921         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
24922         printf "Seeking data from 3000000 ... "
24923         offset=$(lseek_test -d 3000000 $file)
24924         echo $offset
24925         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
24926
24927         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
24928                 error "2nd dd fails"
24929         echo "Add data block at 640K...1280K"
24930
24931         # start at before new data block, in hole
24932         printf "Seeking hole from 600000 ... "
24933         offset=$(lseek_test -l 600000 $file)
24934         echo $offset
24935         [[ $offset == 600000 ]] || error "offset $offset != 600000"
24936         printf "Seeking data from 600000 ... "
24937         offset=$(lseek_test -d 600000 $file)
24938         echo $offset
24939         [[ $offset == 655360 ]] || error "offset $offset != 655360"
24940
24941         # start at the first component new data block
24942         printf "Seeking hole from 1000000 ... "
24943         offset=$(lseek_test -l 1000000 $file)
24944         echo $offset
24945         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24946         printf "Seeking data from 1000000 ... "
24947         offset=$(lseek_test -d 1000000 $file)
24948         echo $offset
24949         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
24950
24951         # start at second component stripe 2, new data
24952         printf "Seeking hole from 1200000 ... "
24953         offset=$(lseek_test -l 1200000 $file)
24954         echo $offset
24955         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
24956         printf "Seeking data from 1200000 ... "
24957         offset=$(lseek_test -d 1200000 $file)
24958         echo $offset
24959         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
24960
24961         # start beyond file end
24962         printf "Using offset > filesize ... "
24963         lseek_test -l 4000000 $file && error "lseek should fail"
24964         printf "Using offset > filesize ... "
24965         lseek_test -d 4000000 $file && error "lseek should fail"
24966
24967         printf "Done\n\n"
24968 }
24969
24970 test_430a() {
24971         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
24972                 skip "MDT does not support SEEK_HOLE"
24973
24974         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
24975                 skip "OST does not support SEEK_HOLE"
24976
24977         local file=$DIR/$tdir/$tfile
24978
24979         mkdir -p $DIR/$tdir
24980
24981         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
24982         # OST stripe #1 will have continuous data at [1M, 3M)
24983         # OST stripe #2 is empty
24984         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
24985         lseek_test_430 $file
24986         rm $file
24987         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
24988         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
24989         lseek_test_430 $file
24990         rm $file
24991         $LFS setstripe -c2 -S 512K $file
24992         echo "Two stripes, stripe size 512K"
24993         lseek_test_430 $file
24994         rm $file
24995         # FLR with stale mirror
24996         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
24997                        -N -c2 -S 1M $file
24998         echo "Mirrored file:"
24999         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25000         echo "Plain 2 stripes 1M"
25001         lseek_test_430 $file
25002         rm $file
25003 }
25004 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25005
25006 test_430b() {
25007         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25008                 skip "OST does not support SEEK_HOLE"
25009
25010         local offset
25011         local file=$DIR/$tdir/$tfile
25012
25013         mkdir -p $DIR/$tdir
25014         # Empty layout lseek should fail
25015         $MCREATE $file
25016         # seek from 0
25017         printf "Seeking hole from 0 ... "
25018         lseek_test -l 0 $file && error "lseek should fail"
25019         printf "Seeking data from 0 ... "
25020         lseek_test -d 0 $file && error "lseek should fail"
25021         rm $file
25022
25023         # 1M-hole file
25024         $LFS setstripe -E 1M -c2 -E eof $file
25025         $TRUNCATE $file 1048576
25026         printf "Seeking hole from 1000000 ... "
25027         offset=$(lseek_test -l 1000000 $file)
25028         echo $offset
25029         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25030         printf "Seeking data from 1000000 ... "
25031         lseek_test -d 1000000 $file && error "lseek should fail"
25032         rm $file
25033
25034         # full component followed by non-inited one
25035         $LFS setstripe -E 1M -c2 -E eof $file
25036         dd if=/dev/urandom of=$file bs=1M count=1
25037         printf "Seeking hole from 1000000 ... "
25038         offset=$(lseek_test -l 1000000 $file)
25039         echo $offset
25040         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25041         printf "Seeking hole from 1048576 ... "
25042         lseek_test -l 1048576 $file && error "lseek should fail"
25043         # init second component and truncate back
25044         echo "123" >> $file
25045         $TRUNCATE $file 1048576
25046         printf "Seeking hole from 1000000 ... "
25047         offset=$(lseek_test -l 1000000 $file)
25048         echo $offset
25049         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25050         printf "Seeking hole from 1048576 ... "
25051         lseek_test -l 1048576 $file && error "lseek should fail"
25052         # boundary checks for big values
25053         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25054         offset=$(lseek_test -d 0 $file.10g)
25055         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25056         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25057         offset=$(lseek_test -d 0 $file.100g)
25058         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25059         return 0
25060 }
25061 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25062
25063 test_430c() {
25064         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25065                 skip "OST does not support SEEK_HOLE"
25066
25067         local file=$DIR/$tdir/$tfile
25068         local start
25069
25070         mkdir -p $DIR/$tdir
25071         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25072
25073         # cp version 8.33+ prefers lseek over fiemap
25074         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25075                 start=$SECONDS
25076                 time cp $file /dev/null
25077                 (( SECONDS - start < 5 )) ||
25078                         error "cp: too long runtime $((SECONDS - start))"
25079
25080         fi
25081         # tar version 1.29+ supports SEEK_HOLE/DATA
25082         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25083                 start=$SECONDS
25084                 time tar cS $file - | cat > /dev/null
25085                 (( SECONDS - start < 5 )) ||
25086                         error "tar: too long runtime $((SECONDS - start))"
25087         fi
25088 }
25089 run_test 430c "lseek: external tools check"
25090
25091 test_431() { # LU-14187
25092         local file=$DIR/$tdir/$tfile
25093
25094         mkdir -p $DIR/$tdir
25095         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25096         dd if=/dev/urandom of=$file bs=4k count=1
25097         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25098         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25099         #define OBD_FAIL_OST_RESTART_IO 0x251
25100         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25101         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25102         cp $file $file.0
25103         cancel_lru_locks
25104         sync_all_data
25105         echo 3 > /proc/sys/vm/drop_caches
25106         diff  $file $file.0 || error "data diff"
25107 }
25108 run_test 431 "Restart transaction for IO"
25109
25110 prep_801() {
25111         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25112         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25113                 skip "Need server version at least 2.9.55"
25114
25115         start_full_debug_logging
25116 }
25117
25118 post_801() {
25119         stop_full_debug_logging
25120 }
25121
25122 barrier_stat() {
25123         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25124                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25125                            awk '/The barrier for/ { print $7 }')
25126                 echo $st
25127         else
25128                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25129                 echo \'$st\'
25130         fi
25131 }
25132
25133 barrier_expired() {
25134         local expired
25135
25136         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25137                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25138                           awk '/will be expired/ { print $7 }')
25139         else
25140                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25141         fi
25142
25143         echo $expired
25144 }
25145
25146 test_801a() {
25147         prep_801
25148
25149         echo "Start barrier_freeze at: $(date)"
25150         #define OBD_FAIL_BARRIER_DELAY          0x2202
25151         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25152         # Do not reduce barrier time - See LU-11873
25153         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25154
25155         sleep 2
25156         local b_status=$(barrier_stat)
25157         echo "Got barrier status at: $(date)"
25158         [ "$b_status" = "'freezing_p1'" ] ||
25159                 error "(1) unexpected barrier status $b_status"
25160
25161         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25162         wait
25163         b_status=$(barrier_stat)
25164         [ "$b_status" = "'frozen'" ] ||
25165                 error "(2) unexpected barrier status $b_status"
25166
25167         local expired=$(barrier_expired)
25168         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25169         sleep $((expired + 3))
25170
25171         b_status=$(barrier_stat)
25172         [ "$b_status" = "'expired'" ] ||
25173                 error "(3) unexpected barrier status $b_status"
25174
25175         # Do not reduce barrier time - See LU-11873
25176         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25177                 error "(4) fail to freeze barrier"
25178
25179         b_status=$(barrier_stat)
25180         [ "$b_status" = "'frozen'" ] ||
25181                 error "(5) unexpected barrier status $b_status"
25182
25183         echo "Start barrier_thaw at: $(date)"
25184         #define OBD_FAIL_BARRIER_DELAY          0x2202
25185         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25186         do_facet mgs $LCTL barrier_thaw $FSNAME &
25187
25188         sleep 2
25189         b_status=$(barrier_stat)
25190         echo "Got barrier status at: $(date)"
25191         [ "$b_status" = "'thawing'" ] ||
25192                 error "(6) unexpected barrier status $b_status"
25193
25194         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25195         wait
25196         b_status=$(barrier_stat)
25197         [ "$b_status" = "'thawed'" ] ||
25198                 error "(7) unexpected barrier status $b_status"
25199
25200         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25201         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25202         do_facet mgs $LCTL barrier_freeze $FSNAME
25203
25204         b_status=$(barrier_stat)
25205         [ "$b_status" = "'failed'" ] ||
25206                 error "(8) unexpected barrier status $b_status"
25207
25208         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25209         do_facet mgs $LCTL barrier_thaw $FSNAME
25210
25211         post_801
25212 }
25213 run_test 801a "write barrier user interfaces and stat machine"
25214
25215 test_801b() {
25216         prep_801
25217
25218         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25219         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25220         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25221         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25222         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25223
25224         cancel_lru_locks mdc
25225
25226         # 180 seconds should be long enough
25227         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25228
25229         local b_status=$(barrier_stat)
25230         [ "$b_status" = "'frozen'" ] ||
25231                 error "(6) unexpected barrier status $b_status"
25232
25233         mkdir $DIR/$tdir/d0/d10 &
25234         mkdir_pid=$!
25235
25236         touch $DIR/$tdir/d1/f13 &
25237         touch_pid=$!
25238
25239         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25240         ln_pid=$!
25241
25242         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
25243         mv_pid=$!
25244
25245         rm -f $DIR/$tdir/d4/f12 &
25246         rm_pid=$!
25247
25248         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
25249
25250         # To guarantee taht the 'stat' is not blocked
25251         b_status=$(barrier_stat)
25252         [ "$b_status" = "'frozen'" ] ||
25253                 error "(8) unexpected barrier status $b_status"
25254
25255         # let above commands to run at background
25256         sleep 5
25257
25258         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
25259         ps -p $touch_pid || error "(10) touch should be blocked"
25260         ps -p $ln_pid || error "(11) link should be blocked"
25261         ps -p $mv_pid || error "(12) rename should be blocked"
25262         ps -p $rm_pid || error "(13) unlink should be blocked"
25263
25264         b_status=$(barrier_stat)
25265         [ "$b_status" = "'frozen'" ] ||
25266                 error "(14) unexpected barrier status $b_status"
25267
25268         do_facet mgs $LCTL barrier_thaw $FSNAME
25269         b_status=$(barrier_stat)
25270         [ "$b_status" = "'thawed'" ] ||
25271                 error "(15) unexpected barrier status $b_status"
25272
25273         wait $mkdir_pid || error "(16) mkdir should succeed"
25274         wait $touch_pid || error "(17) touch should succeed"
25275         wait $ln_pid || error "(18) link should succeed"
25276         wait $mv_pid || error "(19) rename should succeed"
25277         wait $rm_pid || error "(20) unlink should succeed"
25278
25279         post_801
25280 }
25281 run_test 801b "modification will be blocked by write barrier"
25282
25283 test_801c() {
25284         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25285
25286         prep_801
25287
25288         stop mds2 || error "(1) Fail to stop mds2"
25289
25290         do_facet mgs $LCTL barrier_freeze $FSNAME 30
25291
25292         local b_status=$(barrier_stat)
25293         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
25294                 do_facet mgs $LCTL barrier_thaw $FSNAME
25295                 error "(2) unexpected barrier status $b_status"
25296         }
25297
25298         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25299                 error "(3) Fail to rescan barrier bitmap"
25300
25301         # Do not reduce barrier time - See LU-11873
25302         do_facet mgs $LCTL barrier_freeze $FSNAME 20
25303
25304         b_status=$(barrier_stat)
25305         [ "$b_status" = "'frozen'" ] ||
25306                 error "(4) unexpected barrier status $b_status"
25307
25308         do_facet mgs $LCTL barrier_thaw $FSNAME
25309         b_status=$(barrier_stat)
25310         [ "$b_status" = "'thawed'" ] ||
25311                 error "(5) unexpected barrier status $b_status"
25312
25313         local devname=$(mdsdevname 2)
25314
25315         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
25316
25317         do_facet mgs $LCTL barrier_rescan $FSNAME ||
25318                 error "(7) Fail to rescan barrier bitmap"
25319
25320         post_801
25321 }
25322 run_test 801c "rescan barrier bitmap"
25323
25324 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
25325 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
25326 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
25327 saved_MOUNT_OPTS=$MOUNT_OPTS
25328
25329 cleanup_802a() {
25330         trap 0
25331
25332         stopall
25333         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
25334         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
25335         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
25336         MOUNT_OPTS=$saved_MOUNT_OPTS
25337         setupall
25338 }
25339
25340 test_802a() {
25341         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
25342         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25343         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25344                 skip "Need server version at least 2.9.55"
25345
25346         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
25347
25348         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25349
25350         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25351                 error "(2) Fail to copy"
25352
25353         trap cleanup_802a EXIT
25354
25355         # sync by force before remount as readonly
25356         sync; sync_all_data; sleep 3; sync_all_data
25357
25358         stopall
25359
25360         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
25361         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
25362         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
25363
25364         echo "Mount the server as read only"
25365         setupall server_only || error "(3) Fail to start servers"
25366
25367         echo "Mount client without ro should fail"
25368         mount_client $MOUNT &&
25369                 error "(4) Mount client without 'ro' should fail"
25370
25371         echo "Mount client with ro should succeed"
25372         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
25373         mount_client $MOUNT ||
25374                 error "(5) Mount client with 'ro' should succeed"
25375
25376         echo "Modify should be refused"
25377         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25378
25379         echo "Read should be allowed"
25380         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25381                 error "(7) Read should succeed under ro mode"
25382
25383         cleanup_802a
25384 }
25385 run_test 802a "simulate readonly device"
25386
25387 test_802b() {
25388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25389         remote_mds_nodsh && skip "remote MDS with nodsh"
25390
25391         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
25392                 skip "readonly option not available"
25393
25394         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
25395
25396         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
25397                 error "(2) Fail to copy"
25398
25399         # write back all cached data before setting MDT to readonly
25400         cancel_lru_locks
25401         sync_all_data
25402
25403         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
25404         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
25405
25406         echo "Modify should be refused"
25407         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
25408
25409         echo "Read should be allowed"
25410         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
25411                 error "(7) Read should succeed under ro mode"
25412
25413         # disable readonly
25414         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
25415 }
25416 run_test 802b "be able to set MDTs to readonly"
25417
25418 test_803a() {
25419         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25420         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25421                 skip "MDS needs to be newer than 2.10.54"
25422
25423         mkdir -p $DIR/$tdir
25424         # Create some objects on all MDTs to trigger related logs objects
25425         for idx in $(seq $MDSCOUNT); do
25426                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
25427                         $DIR/$tdir/dir${idx} ||
25428                         error "Fail to create $DIR/$tdir/dir${idx}"
25429         done
25430
25431         sync; sleep 3
25432         wait_delete_completed # ensure old test cleanups are finished
25433         echo "before create:"
25434         $LFS df -i $MOUNT
25435         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25436
25437         for i in {1..10}; do
25438                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
25439                         error "Fail to create $DIR/$tdir/foo$i"
25440         done
25441
25442         sync; sleep 3
25443         echo "after create:"
25444         $LFS df -i $MOUNT
25445         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25446
25447         # allow for an llog to be cleaned up during the test
25448         [ $after_used -ge $((before_used + 10 - 1)) ] ||
25449                 error "before ($before_used) + 10 > after ($after_used)"
25450
25451         for i in {1..10}; do
25452                 rm -rf $DIR/$tdir/foo$i ||
25453                         error "Fail to remove $DIR/$tdir/foo$i"
25454         done
25455
25456         sleep 3 # avoid MDT return cached statfs
25457         wait_delete_completed
25458         echo "after unlink:"
25459         $LFS df -i $MOUNT
25460         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
25461
25462         # allow for an llog to be created during the test
25463         [ $after_used -le $((before_used + 1)) ] ||
25464                 error "after ($after_used) > before ($before_used) + 1"
25465 }
25466 run_test 803a "verify agent object for remote object"
25467
25468 test_803b() {
25469         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25470         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
25471                 skip "MDS needs to be newer than 2.13.56"
25472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25473
25474         for i in $(seq 0 $((MDSCOUNT - 1))); do
25475                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
25476         done
25477
25478         local before=0
25479         local after=0
25480
25481         local tmp
25482
25483         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25484         for i in $(seq 0 $((MDSCOUNT - 1))); do
25485                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25486                         awk '/getattr/ { print $2 }')
25487                 before=$((before + tmp))
25488         done
25489         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
25490         for i in $(seq 0 $((MDSCOUNT - 1))); do
25491                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
25492                         awk '/getattr/ { print $2 }')
25493                 after=$((after + tmp))
25494         done
25495
25496         [ $before -eq $after ] || error "getattr count $before != $after"
25497 }
25498 run_test 803b "remote object can getattr from cache"
25499
25500 test_804() {
25501         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25502         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
25503                 skip "MDS needs to be newer than 2.10.54"
25504         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
25505
25506         mkdir -p $DIR/$tdir
25507         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
25508                 error "Fail to create $DIR/$tdir/dir0"
25509
25510         local fid=$($LFS path2fid $DIR/$tdir/dir0)
25511         local dev=$(mdsdevname 2)
25512
25513         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25514                 grep ${fid} || error "NOT found agent entry for dir0"
25515
25516         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
25517                 error "Fail to create $DIR/$tdir/dir1"
25518
25519         touch $DIR/$tdir/dir1/foo0 ||
25520                 error "Fail to create $DIR/$tdir/dir1/foo0"
25521         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
25522         local rc=0
25523
25524         for idx in $(seq $MDSCOUNT); do
25525                 dev=$(mdsdevname $idx)
25526                 do_facet mds${idx} \
25527                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25528                         grep ${fid} && rc=$idx
25529         done
25530
25531         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
25532                 error "Fail to rename foo0 to foo1"
25533         if [ $rc -eq 0 ]; then
25534                 for idx in $(seq $MDSCOUNT); do
25535                         dev=$(mdsdevname $idx)
25536                         do_facet mds${idx} \
25537                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25538                         grep ${fid} && rc=$idx
25539                 done
25540         fi
25541
25542         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
25543                 error "Fail to rename foo1 to foo2"
25544         if [ $rc -eq 0 ]; then
25545                 for idx in $(seq $MDSCOUNT); do
25546                         dev=$(mdsdevname $idx)
25547                         do_facet mds${idx} \
25548                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
25549                         grep ${fid} && rc=$idx
25550                 done
25551         fi
25552
25553         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
25554
25555         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
25556                 error "Fail to link to $DIR/$tdir/dir1/foo2"
25557         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
25558                 error "Fail to rename foo2 to foo0"
25559         unlink $DIR/$tdir/dir1/foo0 ||
25560                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
25561         rm -rf $DIR/$tdir/dir0 ||
25562                 error "Fail to rm $DIR/$tdir/dir0"
25563
25564         for idx in $(seq $MDSCOUNT); do
25565                 dev=$(mdsdevname $idx)
25566                 rc=0
25567
25568                 stop mds${idx}
25569                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
25570                         rc=$?
25571                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
25572                         error "mount mds$idx failed"
25573                 df $MOUNT > /dev/null 2>&1
25574
25575                 # e2fsck should not return error
25576                 [ $rc -eq 0 ] ||
25577                         error "e2fsck detected error on MDT${idx}: rc=$rc"
25578         done
25579 }
25580 run_test 804 "verify agent entry for remote entry"
25581
25582 cleanup_805() {
25583         do_facet $SINGLEMDS zfs set quota=$old $fsset
25584         unlinkmany $DIR/$tdir/f- 1000000
25585         trap 0
25586 }
25587
25588 test_805() {
25589         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
25590         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
25591         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
25592                 skip "netfree not implemented before 0.7"
25593         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
25594                 skip "Need MDS version at least 2.10.57"
25595
25596         local fsset
25597         local freekb
25598         local usedkb
25599         local old
25600         local quota
25601         local pref="osd-zfs.$FSNAME-MDT0000."
25602
25603         # limit available space on MDS dataset to meet nospace issue
25604         # quickly. then ZFS 0.7.2 can use reserved space if asked
25605         # properly (using netfree flag in osd_declare_destroy()
25606         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
25607         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
25608                 gawk '{print $3}')
25609         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
25610         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
25611         let "usedkb=usedkb-freekb"
25612         let "freekb=freekb/2"
25613         if let "freekb > 5000"; then
25614                 let "freekb=5000"
25615         fi
25616         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
25617         trap cleanup_805 EXIT
25618         mkdir $DIR/$tdir
25619         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
25620                 error "Can't set PFL layout"
25621         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
25622         rm -rf $DIR/$tdir || error "not able to remove"
25623         do_facet $SINGLEMDS zfs set quota=$old $fsset
25624         trap 0
25625 }
25626 run_test 805 "ZFS can remove from full fs"
25627
25628 # Size-on-MDS test
25629 check_lsom_data()
25630 {
25631         local file=$1
25632         local expect=$(stat -c %s $file)
25633
25634         check_lsom_size $1 $expect
25635
25636         local blocks=$($LFS getsom -b $file)
25637         expect=$(stat -c %b $file)
25638         [[ $blocks == $expect ]] ||
25639                 error "$file expected blocks: $expect, got: $blocks"
25640 }
25641
25642 check_lsom_size()
25643 {
25644         local size
25645         local expect=$2
25646
25647         cancel_lru_locks mdc
25648
25649         size=$($LFS getsom -s $1)
25650         [[ $size == $expect ]] ||
25651                 error "$file expected size: $expect, got: $size"
25652 }
25653
25654 test_806() {
25655         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25656                 skip "Need MDS version at least 2.11.52"
25657
25658         local bs=1048576
25659
25660         touch $DIR/$tfile || error "touch $tfile failed"
25661
25662         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25663         save_lustre_params client "llite.*.xattr_cache" > $save
25664         lctl set_param llite.*.xattr_cache=0
25665         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25666
25667         # single-threaded write
25668         echo "Test SOM for single-threaded write"
25669         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
25670                 error "write $tfile failed"
25671         check_lsom_size $DIR/$tfile $bs
25672
25673         local num=32
25674         local size=$(($num * $bs))
25675         local offset=0
25676         local i
25677
25678         echo "Test SOM for single client multi-threaded($num) write"
25679         $TRUNCATE $DIR/$tfile 0
25680         for ((i = 0; i < $num; i++)); do
25681                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25682                 local pids[$i]=$!
25683                 offset=$((offset + $bs))
25684         done
25685         for (( i=0; i < $num; i++ )); do
25686                 wait ${pids[$i]}
25687         done
25688         check_lsom_size $DIR/$tfile $size
25689
25690         $TRUNCATE $DIR/$tfile 0
25691         for ((i = 0; i < $num; i++)); do
25692                 offset=$((offset - $bs))
25693                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25694                 local pids[$i]=$!
25695         done
25696         for (( i=0; i < $num; i++ )); do
25697                 wait ${pids[$i]}
25698         done
25699         check_lsom_size $DIR/$tfile $size
25700
25701         # multi-client writes
25702         num=$(get_node_count ${CLIENTS//,/ })
25703         size=$(($num * $bs))
25704         offset=0
25705         i=0
25706
25707         echo "Test SOM for multi-client ($num) writes"
25708         $TRUNCATE $DIR/$tfile 0
25709         for client in ${CLIENTS//,/ }; do
25710                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25711                 local pids[$i]=$!
25712                 i=$((i + 1))
25713                 offset=$((offset + $bs))
25714         done
25715         for (( i=0; i < $num; i++ )); do
25716                 wait ${pids[$i]}
25717         done
25718         check_lsom_size $DIR/$tfile $offset
25719
25720         i=0
25721         $TRUNCATE $DIR/$tfile 0
25722         for client in ${CLIENTS//,/ }; do
25723                 offset=$((offset - $bs))
25724                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25725                 local pids[$i]=$!
25726                 i=$((i + 1))
25727         done
25728         for (( i=0; i < $num; i++ )); do
25729                 wait ${pids[$i]}
25730         done
25731         check_lsom_size $DIR/$tfile $size
25732
25733         # verify truncate
25734         echo "Test SOM for truncate"
25735         $TRUNCATE $DIR/$tfile 1048576
25736         check_lsom_size $DIR/$tfile 1048576
25737         $TRUNCATE $DIR/$tfile 1234
25738         check_lsom_size $DIR/$tfile 1234
25739
25740         # verify SOM blocks count
25741         echo "Verify SOM block count"
25742         $TRUNCATE $DIR/$tfile 0
25743         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
25744                 error "failed to write file $tfile"
25745         check_lsom_data $DIR/$tfile
25746 }
25747 run_test 806 "Verify Lazy Size on MDS"
25748
25749 test_807() {
25750         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
25751         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25752                 skip "Need MDS version at least 2.11.52"
25753
25754         # Registration step
25755         changelog_register || error "changelog_register failed"
25756         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
25757         changelog_users $SINGLEMDS | grep -q $cl_user ||
25758                 error "User $cl_user not found in changelog_users"
25759
25760         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25761         save_lustre_params client "llite.*.xattr_cache" > $save
25762         lctl set_param llite.*.xattr_cache=0
25763         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25764
25765         rm -rf $DIR/$tdir || error "rm $tdir failed"
25766         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25767         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
25768         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
25769         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
25770                 error "truncate $tdir/trunc failed"
25771
25772         local bs=1048576
25773         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
25774                 error "write $tfile failed"
25775
25776         # multi-client wirtes
25777         local num=$(get_node_count ${CLIENTS//,/ })
25778         local offset=0
25779         local i=0
25780
25781         echo "Test SOM for multi-client ($num) writes"
25782         touch $DIR/$tfile || error "touch $tfile failed"
25783         $TRUNCATE $DIR/$tfile 0
25784         for client in ${CLIENTS//,/ }; do
25785                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
25786                 local pids[$i]=$!
25787                 i=$((i + 1))
25788                 offset=$((offset + $bs))
25789         done
25790         for (( i=0; i < $num; i++ )); do
25791                 wait ${pids[$i]}
25792         done
25793
25794         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
25795         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
25796         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
25797         check_lsom_data $DIR/$tdir/trunc
25798         check_lsom_data $DIR/$tdir/single_dd
25799         check_lsom_data $DIR/$tfile
25800
25801         rm -rf $DIR/$tdir
25802         # Deregistration step
25803         changelog_deregister || error "changelog_deregister failed"
25804 }
25805 run_test 807 "verify LSOM syncing tool"
25806
25807 check_som_nologged()
25808 {
25809         local lines=$($LFS changelog $FSNAME-MDT0000 |
25810                 grep 'x=trusted.som' | wc -l)
25811         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
25812 }
25813
25814 test_808() {
25815         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25816                 skip "Need MDS version at least 2.11.55"
25817
25818         # Registration step
25819         changelog_register || error "changelog_register failed"
25820
25821         touch $DIR/$tfile || error "touch $tfile failed"
25822         check_som_nologged
25823
25824         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
25825                 error "write $tfile failed"
25826         check_som_nologged
25827
25828         $TRUNCATE $DIR/$tfile 1234
25829         check_som_nologged
25830
25831         $TRUNCATE $DIR/$tfile 1048576
25832         check_som_nologged
25833
25834         # Deregistration step
25835         changelog_deregister || error "changelog_deregister failed"
25836 }
25837 run_test 808 "Check trusted.som xattr not logged in Changelogs"
25838
25839 check_som_nodata()
25840 {
25841         $LFS getsom $1
25842         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
25843 }
25844
25845 test_809() {
25846         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
25847                 skip "Need MDS version at least 2.11.56"
25848
25849         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
25850                 error "failed to create DoM-only file $DIR/$tfile"
25851         touch $DIR/$tfile || error "touch $tfile failed"
25852         check_som_nodata $DIR/$tfile
25853
25854         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
25855                 error "write $tfile failed"
25856         check_som_nodata $DIR/$tfile
25857
25858         $TRUNCATE $DIR/$tfile 1234
25859         check_som_nodata $DIR/$tfile
25860
25861         $TRUNCATE $DIR/$tfile 4097
25862         check_som_nodata $DIR/$file
25863 }
25864 run_test 809 "Verify no SOM xattr store for DoM-only files"
25865
25866 test_810() {
25867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25868         $GSS && skip_env "could not run with gss"
25869         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
25870                 skip "OST < 2.12.58 doesn't align checksum"
25871
25872         set_checksums 1
25873         stack_trap "set_checksums $ORIG_CSUM" EXIT
25874         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
25875
25876         local csum
25877         local before
25878         local after
25879         for csum in $CKSUM_TYPES; do
25880                 #define OBD_FAIL_OSC_NO_GRANT   0x411
25881                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
25882                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
25883                         eval set -- $i
25884                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
25885                         before=$(md5sum $DIR/$tfile)
25886                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
25887                         after=$(md5sum $DIR/$tfile)
25888                         [ "$before" == "$after" ] ||
25889                                 error "$csum: $before != $after bs=$1 seek=$2"
25890                 done
25891         done
25892 }
25893 run_test 810 "partial page writes on ZFS (LU-11663)"
25894
25895 test_812a() {
25896         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25897                 skip "OST < 2.12.51 doesn't support this fail_loc"
25898
25899         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25900         # ensure ost1 is connected
25901         stat $DIR/$tfile >/dev/null || error "can't stat"
25902         wait_osc_import_state client ost1 FULL
25903         # no locks, no reqs to let the connection idle
25904         cancel_lru_locks osc
25905
25906         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25907 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25908         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25909         wait_osc_import_state client ost1 CONNECTING
25910         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25911
25912         stat $DIR/$tfile >/dev/null || error "can't stat file"
25913 }
25914 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
25915
25916 test_812b() { # LU-12378
25917         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
25918                 skip "OST < 2.12.51 doesn't support this fail_loc"
25919
25920         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
25921         # ensure ost1 is connected
25922         stat $DIR/$tfile >/dev/null || error "can't stat"
25923         wait_osc_import_state client ost1 FULL
25924         # no locks, no reqs to let the connection idle
25925         cancel_lru_locks osc
25926
25927         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
25928 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
25929         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
25930         wait_osc_import_state client ost1 CONNECTING
25931         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
25932
25933         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
25934         wait_osc_import_state client ost1 IDLE
25935 }
25936 run_test 812b "do not drop no resend request for idle connect"
25937
25938 test_812c() {
25939         local old
25940
25941         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
25942
25943         $LFS setstripe -c 1 -o 0 $DIR/$tfile
25944         $LFS getstripe $DIR/$tfile
25945         $LCTL set_param osc.*.idle_timeout=10
25946         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
25947         # ensure ost1 is connected
25948         stat $DIR/$tfile >/dev/null || error "can't stat"
25949         wait_osc_import_state client ost1 FULL
25950         # no locks, no reqs to let the connection idle
25951         cancel_lru_locks osc
25952
25953 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
25954         $LCTL set_param fail_loc=0x80000533
25955         sleep 15
25956         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
25957 }
25958 run_test 812c "idle import vs lock enqueue race"
25959
25960 test_813() {
25961         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
25962         [ -z "$file_heat_sav" ] && skip "no file heat support"
25963
25964         local readsample
25965         local writesample
25966         local readbyte
25967         local writebyte
25968         local readsample1
25969         local writesample1
25970         local readbyte1
25971         local writebyte1
25972
25973         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
25974         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
25975
25976         $LCTL set_param -n llite.*.file_heat=1
25977         echo "Turn on file heat"
25978         echo "Period second: $period_second, Decay percentage: $decay_pct"
25979
25980         echo "QQQQ" > $DIR/$tfile
25981         echo "QQQQ" > $DIR/$tfile
25982         echo "QQQQ" > $DIR/$tfile
25983         cat $DIR/$tfile > /dev/null
25984         cat $DIR/$tfile > /dev/null
25985         cat $DIR/$tfile > /dev/null
25986         cat $DIR/$tfile > /dev/null
25987
25988         local out=$($LFS heat_get $DIR/$tfile)
25989
25990         $LFS heat_get $DIR/$tfile
25991         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25992         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25993         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25994         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25995
25996         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
25997         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
25998         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
25999         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26000
26001         sleep $((period_second + 3))
26002         echo "Sleep $((period_second + 3)) seconds..."
26003         # The recursion formula to calculate the heat of the file f is as
26004         # follow:
26005         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26006         # Where Hi is the heat value in the period between time points i*I and
26007         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26008         # to the weight of Ci.
26009         out=$($LFS heat_get $DIR/$tfile)
26010         $LFS heat_get $DIR/$tfile
26011         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26012         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26013         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26014         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26015
26016         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26017                 error "read sample ($readsample) is wrong"
26018         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26019                 error "write sample ($writesample) is wrong"
26020         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26021                 error "read bytes ($readbyte) is wrong"
26022         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26023                 error "write bytes ($writebyte) is wrong"
26024
26025         echo "QQQQ" > $DIR/$tfile
26026         echo "QQQQ" > $DIR/$tfile
26027         echo "QQQQ" > $DIR/$tfile
26028         cat $DIR/$tfile > /dev/null
26029         cat $DIR/$tfile > /dev/null
26030         cat $DIR/$tfile > /dev/null
26031         cat $DIR/$tfile > /dev/null
26032
26033         sleep $((period_second + 3))
26034         echo "Sleep $((period_second + 3)) seconds..."
26035
26036         out=$($LFS heat_get $DIR/$tfile)
26037         $LFS heat_get $DIR/$tfile
26038         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26039         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26040         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26041         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26042
26043         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26044                 4 * $decay_pct) / 100") -eq 1 ] ||
26045                 error "read sample ($readsample1) is wrong"
26046         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26047                 3 * $decay_pct) / 100") -eq 1 ] ||
26048                 error "write sample ($writesample1) is wrong"
26049         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26050                 20 * $decay_pct) / 100") -eq 1 ] ||
26051                 error "read bytes ($readbyte1) is wrong"
26052         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26053                 15 * $decay_pct) / 100") -eq 1 ] ||
26054                 error "write bytes ($writebyte1) is wrong"
26055
26056         echo "Turn off file heat for the file $DIR/$tfile"
26057         $LFS heat_set -o $DIR/$tfile
26058
26059         echo "QQQQ" > $DIR/$tfile
26060         echo "QQQQ" > $DIR/$tfile
26061         echo "QQQQ" > $DIR/$tfile
26062         cat $DIR/$tfile > /dev/null
26063         cat $DIR/$tfile > /dev/null
26064         cat $DIR/$tfile > /dev/null
26065         cat $DIR/$tfile > /dev/null
26066
26067         out=$($LFS heat_get $DIR/$tfile)
26068         $LFS heat_get $DIR/$tfile
26069         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26070         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26071         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26072         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26073
26074         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26075         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26076         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26077         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26078
26079         echo "Trun on file heat for the file $DIR/$tfile"
26080         $LFS heat_set -O $DIR/$tfile
26081
26082         echo "QQQQ" > $DIR/$tfile
26083         echo "QQQQ" > $DIR/$tfile
26084         echo "QQQQ" > $DIR/$tfile
26085         cat $DIR/$tfile > /dev/null
26086         cat $DIR/$tfile > /dev/null
26087         cat $DIR/$tfile > /dev/null
26088         cat $DIR/$tfile > /dev/null
26089
26090         out=$($LFS heat_get $DIR/$tfile)
26091         $LFS heat_get $DIR/$tfile
26092         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26093         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26094         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26095         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26096
26097         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26098         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26099         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26100         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26101
26102         $LFS heat_set -c $DIR/$tfile
26103         $LCTL set_param -n llite.*.file_heat=0
26104         echo "Turn off file heat support for the Lustre filesystem"
26105
26106         echo "QQQQ" > $DIR/$tfile
26107         echo "QQQQ" > $DIR/$tfile
26108         echo "QQQQ" > $DIR/$tfile
26109         cat $DIR/$tfile > /dev/null
26110         cat $DIR/$tfile > /dev/null
26111         cat $DIR/$tfile > /dev/null
26112         cat $DIR/$tfile > /dev/null
26113
26114         out=$($LFS heat_get $DIR/$tfile)
26115         $LFS heat_get $DIR/$tfile
26116         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26117         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26118         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26119         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26120
26121         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26122         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26123         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26124         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26125
26126         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26127         rm -f $DIR/$tfile
26128 }
26129 run_test 813 "File heat verfication"
26130
26131 test_814()
26132 {
26133         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26134         echo -n y >> $DIR/$tfile
26135         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26136         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26137 }
26138 run_test 814 "sparse cp works as expected (LU-12361)"
26139
26140 test_815()
26141 {
26142         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26143         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26144 }
26145 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26146
26147 test_816() {
26148         local ost1_imp=$(get_osc_import_name client ost1)
26149         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26150                          cut -d'.' -f2)
26151
26152         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26153         # ensure ost1 is connected
26154
26155         stat $DIR/$tfile >/dev/null || error "can't stat"
26156         wait_osc_import_state client ost1 FULL
26157         # no locks, no reqs to let the connection idle
26158         cancel_lru_locks osc
26159         lru_resize_disable osc
26160         local before
26161         local now
26162         before=$($LCTL get_param -n \
26163                  ldlm.namespaces.$imp_name.lru_size)
26164
26165         wait_osc_import_state client ost1 IDLE
26166         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26167         now=$($LCTL get_param -n \
26168               ldlm.namespaces.$imp_name.lru_size)
26169         [ $before == $now ] || error "lru_size changed $before != $now"
26170 }
26171 run_test 816 "do not reset lru_resize on idle reconnect"
26172
26173 cleanup_817() {
26174         umount $tmpdir
26175         exportfs -u localhost:$DIR/nfsexp
26176         rm -rf $DIR/nfsexp
26177 }
26178
26179 test_817() {
26180         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26181
26182         mkdir -p $DIR/nfsexp
26183         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26184                 error "failed to export nfs"
26185
26186         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26187         stack_trap cleanup_817 EXIT
26188
26189         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26190                 error "failed to mount nfs to $tmpdir"
26191
26192         cp /bin/true $tmpdir
26193         $DIR/nfsexp/true || error "failed to execute 'true' command"
26194 }
26195 run_test 817 "nfsd won't cache write lock for exec file"
26196
26197 test_818() {
26198         mkdir $DIR/$tdir
26199         $LFS setstripe -c1 -i0 $DIR/$tfile
26200         $LFS setstripe -c1 -i1 $DIR/$tfile
26201         stop $SINGLEMDS
26202         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26203         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26204         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26205                 error "start $SINGLEMDS failed"
26206         rm -rf $DIR/$tdir
26207 }
26208 run_test 818 "unlink with failed llog"
26209
26210 test_819a() {
26211         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26212         cancel_lru_locks osc
26213         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26214         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26215         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26216         rm -f $TDIR/$tfile
26217 }
26218 run_test 819a "too big niobuf in read"
26219
26220 test_819b() {
26221         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26222         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26223         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26224         cancel_lru_locks osc
26225         sleep 1
26226         rm -f $TDIR/$tfile
26227 }
26228 run_test 819b "too big niobuf in write"
26229
26230
26231 function test_820_start_ost() {
26232         sleep 5
26233
26234         for num in $(seq $OSTCOUNT); do
26235                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26236         done
26237 }
26238
26239 test_820() {
26240         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26241
26242         mkdir $DIR/$tdir
26243         umount_client $MOUNT || error "umount failed"
26244         for num in $(seq $OSTCOUNT); do
26245                 stop ost$num
26246         done
26247
26248         # mount client with no active OSTs
26249         # so that the client can't initialize max LOV EA size
26250         # from OSC notifications
26251         mount_client $MOUNT || error "mount failed"
26252         # delay OST starting to keep this 0 max EA size for a while
26253         test_820_start_ost &
26254
26255         # create a directory on MDS2
26256         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
26257                 error "Failed to create directory"
26258         # open intent should update default EA size
26259         # see mdc_update_max_ea_from_body()
26260         # notice this is the very first RPC to MDS2
26261         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
26262         ret=$?
26263         echo $out
26264         # With SSK, this situation can lead to -EPERM being returned.
26265         # In that case, simply retry.
26266         if [ $ret -ne 0 ] && $SHARED_KEY; then
26267                 if echo "$out" | grep -q "not permitted"; then
26268                         cp /etc/services $DIR/$tdir/mds2
26269                         ret=$?
26270                 fi
26271         fi
26272         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
26273 }
26274 run_test 820 "update max EA from open intent"
26275
26276 test_822() {
26277         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
26278
26279         save_lustre_params mds1 \
26280                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
26281         do_facet $SINGLEMDS "$LCTL set_param -n \
26282                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
26283         do_facet $SINGLEMDS "$LCTL set_param -n \
26284                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
26285
26286         # wait for statfs update to clear OS_STATFS_NOPRECREATE
26287         local maxage=$(do_facet mds1 $LCTL get_param -n \
26288                        osp.$FSNAME-OST0000*MDT0000.maxage)
26289         sleep $((maxage + 1))
26290
26291         #define OBD_FAIL_NET_ERROR_RPC          0x532
26292         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
26293
26294         stack_trap "restore_lustre_params < $p; rm $p"
26295
26296         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
26297                       osp.$FSNAME-OST0000*MDT0000.create_count")
26298         for i in $(seq 1 $count); do
26299                 touch $DIR/$tfile.${i} || error "touch failed"
26300         done
26301 }
26302 run_test 822 "test precreate failure"
26303
26304 #
26305 # tests that do cleanup/setup should be run at the end
26306 #
26307
26308 test_900() {
26309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26310         local ls
26311
26312         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
26313         $LCTL set_param fail_loc=0x903
26314
26315         cancel_lru_locks MGC
26316
26317         FAIL_ON_ERROR=true cleanup
26318         FAIL_ON_ERROR=true setup
26319 }
26320 run_test 900 "umount should not race with any mgc requeue thread"
26321
26322 # LUS-6253/LU-11185
26323 test_901() {
26324         local oldc
26325         local newc
26326         local olds
26327         local news
26328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26329
26330         # some get_param have a bug to handle dot in param name
26331         cancel_lru_locks MGC
26332         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26333         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26334         umount_client $MOUNT || error "umount failed"
26335         mount_client $MOUNT || error "mount failed"
26336         cancel_lru_locks MGC
26337         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
26338         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
26339
26340         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
26341         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
26342
26343         return 0
26344 }
26345 run_test 901 "don't leak a mgc lock on client umount"
26346
26347 # LU-13377
26348 test_902() {
26349         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
26350                 skip "client does not have LU-13377 fix"
26351         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
26352         $LCTL set_param fail_loc=0x1415
26353         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26354         cancel_lru_locks osc
26355         rm -f $DIR/$tfile
26356 }
26357 run_test 902 "test short write doesn't hang lustre"
26358
26359 complete $SECONDS
26360 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
26361 check_and_cleanup_lustre
26362 if [ "$I_MOUNTED" != "yes" ]; then
26363         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
26364 fi
26365 exit_status